00001 #ifndef AlpsEncoded_h
00002 #define AlpsEncoded_h
00003
00004 #include <cstring>
00005 #include <string>
00006 #include <memory>
00007 #include <vector>
00008
00009 #include "CoinError.hpp"
00010
00011 #include "Alps.h"
00012
00013
00014
00015
00023
00024
00025 class AlpsEncoded {
00026
00027 private:
00028
00030
00031 AlpsEncoded(const AlpsEncoded&);
00032 AlpsEncoded& operator=(const AlpsEncoded&);
00034
00035 private:
00036
00038 size_t pos_;
00039
00041 size_t maxSize_;
00042
00047
00048
00049 int type_;
00050
00052 size_t size_;
00053
00055
00056 char* representation_;
00057
00058 public:
00059
00062
00065 AlpsEncoded()
00066 :
00067 pos_(0),
00068 maxSize_(0x4000),
00069 type_(0),
00070 size_(0),
00071 representation_(new char[maxSize_])
00072 {}
00073
00075 AlpsEncoded(int t)
00076 :
00077 pos_(0),
00078 maxSize_(0),
00079 type_(t),
00080 size_(0),
00081 representation_(0)
00082 {}
00083
00085 AlpsEncoded(int t, int s, char*& r)
00086 :
00087 pos_(0),
00088 maxSize_(s + 4),
00089 type_(t),
00090 size_(s),
00091 representation_(r)
00092 { r = NULL; }
00093
00095 ~AlpsEncoded() {
00096 if (representation_) {
00097 delete [] representation_;
00098 representation_ = 0;
00099 }
00100 }
00104
00105 int type() const { return type_; }
00106 size_t size() const { return size_; }
00107 const char* representation() const { return representation_; }
00109
00110 inline void setPosition(const size_t pos) {
00111 if (pos < 0 || pos >= size()) {
00112
00113
00114 throw CoinError("Incorrest position setting.", "setPosition",
00115 "AlpsEncoded");
00116 }
00117 pos_ = pos;
00118 }
00119
00120 inline void setRepresentation(char*& buf) {
00121
00122 maxSize_ = strlen(buf) + 1;
00123 representation_ = buf;
00124 buf = 0;
00125 }
00126
00130 inline void make_fit(size_t addSize){
00131 assert(addSize > 0);
00132
00133 if (maxSize_ < size_ + addSize){
00134 maxSize_ = 4 * (size_ + addSize + 0x1000);
00135 char* newRep = new char[maxSize_];
00136 if (size_)
00137 memcpy(newRep, representation_, size_);
00138 delete[] representation_;
00139 representation_ = newRep;
00140 }
00141 }
00142
00145 inline void clear(){
00146 size_ = 0;
00147 pos_ = 0;
00148 type_ = 0;
00149 if (representation_ != 0) {
00150 delete representation_;
00151 representation_ = 0;
00152 }
00153 }
00154
00155
00156
00157
00158
00162 template <class T> AlpsEncoded& writeRep(const T& value) {
00163 make_fit( sizeof(T) );
00164 memcpy(representation_ + size_, &value, sizeof(T));
00165 size_ += sizeof(T);
00166 return *this;
00167 }
00168
00172 template <class T> AlpsEncoded& readRep(T& value){
00173 #ifdef PARANOID
00174 if (pos_ + sizeof(T) > size_) {
00175 throw CoinError("Reading over the end of buffer.",
00176 "readRep(const T& value)", "AlpsEncoded");
00177 }
00178 #endif
00179 memcpy(&value, representation_ + pos_, sizeof(T));
00180 pos_ += sizeof(T);
00181 return *this;
00182 }
00183
00184
00188 template <class T> AlpsEncoded& writeRep(const T* const values,
00189 const size_t length){
00190 make_fit( sizeof(int) + sizeof(T) * length );
00191 memcpy(representation_ + size_, &length, sizeof(int));
00192 size_ += sizeof(int);
00193 if (length > 0){
00194 memcpy(representation_ + size_, values, sizeof(T) * length);
00195 size_ += sizeof(T) * length;
00196 }
00197 return *this;
00198 }
00199
00213 template <class T> AlpsEncoded& readRep(T*& values,
00214 int& length,
00215 bool needAllocateMemory = true)
00216 {
00217
00218 if (needAllocateMemory) {
00219
00220
00221 #ifdef PARANOID
00222 if (pos_ + sizeof(int) > size_) {
00223 throw CoinError("Reading over the end of buffer.",
00224 "readRep(T*& values, int& length,...",
00225 "AlpsEncoded");
00226 }
00227 #endif
00228 memcpy(&length, representation_ + pos_, sizeof(int));
00229 pos_ += sizeof(int);
00230 if (length > 0){
00231 #ifdef PARANOID
00232 if (pos_ + sizeof(T)*length > size_) {
00233 throw CoinError("Reading over the end of buffer.",
00234 "readRep(T*& values, int& length,...",
00235 "AlpsEncoded");
00236 }
00237 #endif
00238 values = new T[length];
00239 memcpy(values, representation_ + pos_, sizeof(T)*length);
00240 pos_ += sizeof(T) * length;
00241 }
00242
00243 }
00244 else {
00245
00246 int l;
00247 #ifdef PARANOID
00248 if (pos_ + sizeof(int) > size_) {
00249 throw CoinError("Reading over the end of buffer.",
00250 "readRep(T*& values, int& length,...",
00251 "AlpsEncoded");
00252 }
00253 #endif
00254 memcpy(&l, representation_ + pos_, sizeof(int));
00255 pos_ += sizeof(int);
00256 if (l != length) {
00257 throw CoinError("Reading over the end of buffer.",
00258 "readRep(T*& values, int& length,...",
00259 "AlpsEncoded");
00260 }
00261 if (length > 0){
00262 #ifdef PARANOID
00263 if (pos_ + sizeof(T)*length > size_) {
00264 throw CoinError("Reading over the end of buffer.",
00265 "readRep(T*& values, int& length,...",
00266 "AlpsEncoded");
00267 }
00268 #endif
00269 memcpy(values, representation_ + pos_, sizeof(T)*length);
00270 pos_ += sizeof(T) * length;
00271 }
00272 }
00273
00274 return *this;
00275 }
00276
00278 AlpsEncoded& writeRep(std::string& value){
00279
00280 const int len = static_cast<const int> (value.length());
00281 make_fit( sizeof(int) + len );
00282 memcpy(representation_ + size_, &len, sizeof(int));
00283 size_ += sizeof(int);
00284 if (len > 0){
00285 memcpy(representation_ + size_, value.c_str(), len);
00286 size_ += len;
00287 }
00288 return *this;
00289 }
00290
00292 AlpsEncoded& readRep(std::string& value){
00293 int len;
00294 readRep(len);
00295 value.assign(representation_ + pos_, len);
00296 pos_ += len;
00297 return *this;
00298 }
00299
00301 template <class T> AlpsEncoded& writeRep(const std::vector<T>& vec) {
00302 int objnum = vec.size();
00303 int new_bytes = objnum * sizeof(T);
00304 make_fit( sizeof(int) + new_bytes );
00305 memcpy(representation_ + size_, &objnum, sizeof(int));
00306 size_ += sizeof(int);
00307 if (objnum > 0){
00308 memcpy(representation_ + size_, &vec[0], new_bytes);
00309 size_ += new_bytes;
00310 }
00311 return *this;
00312 }
00313
00315 template <class T> AlpsEncoded& readRep(std::vector<T>& vec) {
00316 int objnum;
00317 #ifdef PARANOID
00318 if (pos_ + sizeof(int) > size_)
00319 throw CoinError("Reading over the end of buffer.",
00320 "AlpsEncoded", "readRep(std::vector<T>& vec");
00321 #endif
00322 memcpy(&objnum, representation_ + pos_, sizeof(int));
00323 pos_ += sizeof(int);
00324 vec.clear();
00325 if (objnum > 0){
00326 #ifdef PARANOID
00327 if (pos_ + sizeof(T)*objnum > size_)
00328 throw CoinError("Reading over the end of buffer.",
00329 "AlpsEncoded", "readRep(std::vector<T>& vec");
00330 #endif
00331 vec.insert(vec.end(), objnum, T());
00332 memcpy(&vec[0], representation_ + pos_, objnum * sizeof(T));
00333 pos_ += objnum * sizeof(T);
00334 }
00335 return *this;
00336 }
00339 };
00340
00341 #endif