buffer.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. #ifndef __BUFFER_HH
  16. #define __BUFFER_HH 1
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <netinet/in.h>
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <stdexcept>
  23. #include <algorithm>
  24. #include <vector>
  25. #include <dns/exceptions.h>
  26. namespace isc {
  27. // Abstraction of buffers for socket I/O. This is a tentative idea and should
  28. // be revisited.
  29. class Buffer {
  30. public:
  31. virtual ~Buffer() {}
  32. virtual void reserve(size_t len) = 0;
  33. virtual void writeData(const void *cp, size_t len) = 0;
  34. virtual void writeUint32(uint32_t data) = 0;
  35. virtual void writeUint16(uint16_t data) = 0;
  36. virtual void writeUint16At(uint16_t data, size_t pos) = 0;
  37. virtual void writeUint8(uint8_t data) = 0;
  38. virtual int sendTo(int s, const struct sockaddr& to, socklen_t to_len) = 0;
  39. virtual size_t getSize() const = 0;
  40. virtual size_t getSpace() const = 0;
  41. virtual size_t getCurrent() const = 0;
  42. virtual void setCurrent(size_t pos) = 0;
  43. virtual uint8_t readUint8() = 0;
  44. virtual uint16_t readUint16() = 0;
  45. virtual uint32_t readUint32() = 0;
  46. virtual void readData(void* data, size_t len) = 0;
  47. virtual int recvFrom(int s, struct sockaddr *from,
  48. socklen_t *from_len) = 0;
  49. };
  50. // I/O Buffer with a single array-style storage
  51. class SingleBuffer : public Buffer {
  52. public:
  53. SingleBuffer() : _readpos(0) { buf_.reserve(4096); }
  54. void reserve(size_t len) // XXX: API and implementation should be revisited
  55. {
  56. buf_.resize(len);
  57. }
  58. void writeData(const void *data, size_t len)
  59. {
  60. const uint8_t* cp = static_cast<const uint8_t*>(data);
  61. buf_.insert(buf_.end(), cp, cp + len);
  62. }
  63. void writeUint32(uint32_t data)
  64. {
  65. data = htonl(data);
  66. uint8_t* cp = static_cast<uint8_t*>((void*)&data);
  67. buf_.insert(buf_.end(), cp, cp + sizeof(uint32_t));
  68. }
  69. void writeUint16(uint16_t data)
  70. {
  71. data = htons(data);
  72. uint8_t* cp = static_cast<uint8_t*>((void*)&data);
  73. buf_.insert(buf_.end(), cp, cp + sizeof(uint16_t));
  74. }
  75. void writeUint16At(uint16_t data, size_t pos)
  76. {
  77. if (pos + sizeof(data) >= buf_.size())
  78. throw isc::ISCBufferInvalidPosition();
  79. data = htons(data);
  80. uint8_t* cp = static_cast<uint8_t*>((void*)&data);
  81. copy(cp, cp + sizeof(uint16_t), buf_.begin() + pos);
  82. }
  83. void writeUint8(uint8_t data)
  84. {
  85. buf_.push_back(data);
  86. }
  87. int sendTo(int s, const struct sockaddr& to, socklen_t to_len);
  88. size_t getSize() const { return (buf_.size()); }
  89. size_t getSpace() const { return (buf_.size() - _readpos); }
  90. size_t getCurrent() const { return (_readpos); }
  91. void setCurrent(size_t pos)
  92. {
  93. if (pos >= buf_.size())
  94. throw isc::ISCBufferInvalidPosition();
  95. _readpos = pos;
  96. }
  97. uint8_t readUint8();
  98. uint16_t readUint16();
  99. uint32_t readUint32();
  100. void readData(void* data, size_t len);
  101. int recvFrom(int s, struct sockaddr* from, socklen_t* from_len);
  102. private:
  103. size_t _readpos;
  104. std::vector<uint8_t> buf_;
  105. };
  106. inline uint8_t
  107. SingleBuffer::readUint8()
  108. {
  109. if (_readpos + sizeof(uint8_t) > buf_.size())
  110. throw ISCBufferInvalidPosition();
  111. return (buf_[_readpos++]);
  112. }
  113. inline uint16_t
  114. SingleBuffer::readUint16()
  115. {
  116. uint16_t data;
  117. if (_readpos + sizeof(data) > buf_.size())
  118. throw ISCBufferInvalidPosition();
  119. memcpy((void*)&data, &buf_[_readpos], sizeof(data));
  120. _readpos += sizeof(data);
  121. return (ntohs(data));
  122. }
  123. inline uint32_t
  124. SingleBuffer::readUint32()
  125. {
  126. uint32_t data;
  127. if (_readpos + sizeof(data) > buf_.size())
  128. throw ISCBufferInvalidPosition();
  129. memcpy((void*)&data, &buf_[_readpos], sizeof(data));
  130. _readpos += sizeof(data);
  131. return (ntohl(data));
  132. }
  133. inline void
  134. SingleBuffer::readData(void *data, size_t len)
  135. {
  136. if (_readpos + len > buf_.size())
  137. throw ISCBufferInvalidPosition();
  138. memcpy(data, &buf_[_readpos], len);
  139. _readpos += len;
  140. }
  141. }
  142. #endif // __BUFFER_HH
  143. // Local Variables:
  144. // mode: c++
  145. // End: