00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __BUFFER_H
00018 #define __BUFFER_H 1
00019
00020 #include <vector>
00021
00022 #include "exceptions.h"
00023
00024 namespace isc {
00025 namespace dns {
00026
00031 class InvalidBufferPosition : public Exception {
00032 public:
00033 InvalidBufferPosition(const char* file, size_t line, const char* what) :
00034 isc::dns::Exception(file, line, what) {}
00035 };
00036
00085 class InputBuffer {
00086 public:
00089
00090
00091
00092
00093
00094
00095
00096 InputBuffer(const void* data, size_t len) :
00097 position_(0), data_(static_cast<const uint8_t*>(data)), len_(len) {}
00099
00102
00103
00104 size_t getLength() const { return (len_); }
00106 size_t getPosition() const { return (position_); }
00108
00112
00113
00114
00115
00116
00117
00118
00119 void setPosition(size_t position)
00120 {
00121 if (position > len_)
00122 dns_throw(InvalidBufferPosition, "position is too large");
00123 position_ = position;
00124 }
00126
00129
00130
00131
00132
00133
00134 uint8_t readUint8()
00135 {
00136 if (position_ + sizeof(uint8_t) > len_) {
00137 dns_throw(InvalidBufferPosition, "read beyond end of buffer");
00138 }
00139
00140 return (data_[position_++]);
00141 }
00147 uint16_t readUint16()
00148 {
00149 uint16_t data;
00150 const uint8_t* cp;
00151
00152 if (position_ + sizeof(data) > len_) {
00153 dns_throw(InvalidBufferPosition, "read beyond end of buffer");
00154 }
00155
00156 cp = &data_[position_];
00157 data = ((unsigned int)(cp[0])) << 8;
00158 data |= ((unsigned int)(cp[1]));
00159 position_ += sizeof(data);
00160
00161 return (data);
00162 }
00168 uint32_t readUint32()
00169 {
00170 uint32_t data;
00171 const uint8_t* cp;
00172
00173 if (position_ + sizeof(data) > len_) {
00174 dns_throw(InvalidBufferPosition, "read beyond end of buffer");
00175 }
00176
00177 cp = &data_[position_];
00178 data = ((unsigned int)(cp[0])) << 24;
00179 data |= ((unsigned int)(cp[1])) << 16;
00180 data |= ((unsigned int)(cp[2])) << 8;
00181 data |= ((unsigned int)(cp[3]));
00182 position_ += sizeof(data);
00183
00184 return (data);
00185 }
00193 void readData(void* data, size_t len)
00194 {
00195 if (position_ + len > len_) {
00196 dns_throw(InvalidBufferPosition, "read beyond end of buffer");
00197 }
00198
00199 memcpy(data, &data_[position_], len);
00200 position_ += len;
00201 }
00203
00204 private:
00205 size_t position_;
00206 const uint8_t* data_;
00207 size_t len_;
00208 };
00209
00258 class OutputBuffer {
00259 public:
00263
00264
00265
00266
00267 OutputBuffer(size_t len) { data_.reserve(len); }
00269
00273
00274
00275 size_t getCapacity() const { return (data_.capacity()); }
00283 const void* getData() const { return (&data_[0]); }
00285 size_t getLength() const { return (data_.size()); }
00292 uint8_t operator[](size_t pos) const
00293 {
00294 if (pos >= data_.size()) {
00295 dns_throw(InvalidBufferPosition, "read at invalid position");
00296 }
00297 return (data_[pos]);
00298 }
00300
00304
00305
00306
00307
00308
00309
00310
00311 void skip(size_t len) { data_.insert(data_.end(), len, 0); }
00316 void clear() { data_.clear(); }
00320 void writeUint8(uint8_t data) { data_.push_back(data); }
00321
00326 void writeUint16(uint16_t data)
00327 {
00328 data_.push_back(static_cast<uint8_t>((data & 0xff00U) >> 8));
00329 data_.push_back(static_cast<uint8_t>(data & 0x00ffU));
00330 }
00342 void writeUint16At(uint16_t data, size_t pos)
00343 {
00344 if (pos + sizeof(data) >= data_.size()) {
00345 dns_throw(InvalidBufferPosition, "write at invalid position");
00346 }
00347
00348 data_[pos] = static_cast<uint8_t>((data & 0xff00U) >> 8);
00349 data_[pos + 1] = static_cast<uint8_t>(data & 0x00ffU);
00350 }
00355 void writeUint32(uint32_t data)
00356 {
00357 data_.push_back(static_cast<uint8_t>((data & 0xff000000) >> 24));
00358 data_.push_back(static_cast<uint8_t>((data & 0x00ff0000) >> 16));
00359 data_.push_back(static_cast<uint8_t>((data & 0x0000ff00) >> 8));
00360 data_.push_back(static_cast<uint8_t>(data & 0x000000ff));
00361 }
00368 void writeData(const void *data, size_t len)
00369 {
00370 const uint8_t* cp = static_cast<const uint8_t*>(data);
00371 data_.insert(data_.end(), cp, cp + len);
00372 }
00374
00375 private:
00376 std::vector<uint8_t> data_;
00377 };
00378 }
00379 }
00380 #endif // __BUFFER_H
00381
00382
00383
00384