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 int 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 int size() const { return size_; }
00107 const char* representation() const { return representation_; }
00109
00110 inline void setPosition(const int 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(const int addSize){
00131 assert(addSize > 0);
00132 size_t addSize1 = static_cast<size_t>(addSize);
00133
00134 if (maxSize_ < size_ + addSize1){
00135 maxSize_ = 4 * (size_ + addSize1 + 0x1000);
00136 char* newRep = new char[maxSize_];
00137 if (size_)
00138 memcpy(newRep, representation_, size_);
00139 delete[] representation_;
00140 representation_ = newRep;
00141 }
00142 }
00143
00146 inline void clear(){
00147 size_ = 0;
00148 pos_ = 0;
00149 type_ = 0;
00150 if (representation_ != 0) {
00151 delete representation_;
00152 representation_ = 0;
00153 }
00154 }
00155
00156
00157
00158
00159
00163 template <class T> AlpsEncoded& writeRep(const T& value) {
00164 make_fit( sizeof(T) );
00165 memcpy(representation_ + size_, &value, sizeof(T));
00166 size_ += static_cast<int>(sizeof(T));
00167 return *this;
00168 }
00169
00173 template <class T> AlpsEncoded& readRep(T& value){
00174 #ifdef PARANOID
00175 if (pos_ + sizeof(T) > size_) {
00176 throw CoinError("Reading over the end of buffer.",
00177 "readRep(const T& value)", "AlpsEncoded");
00178 }
00179 #endif
00180 memcpy(&value, representation_ + pos_, sizeof(T));
00181 pos_ += sizeof(T);
00182 return *this;
00183 }
00184
00185
00189 template <class T> AlpsEncoded& writeRep(const T* const values,
00190 const int length){
00191 make_fit( static_cast<int>(sizeof(int)) +
00192 static_cast<int>(sizeof(T)) * length );
00193 memcpy(representation_ + size_, &length, sizeof(int));
00194 size_ += static_cast<int>(sizeof(int));
00195 if (length > 0){
00196 memcpy(representation_ + size_, values,
00197 static_cast<int>(sizeof(T)) * length);
00198 size_ += static_cast<int>(sizeof(T)) * length;
00199 }
00200 return *this;
00201 }
00202
00216 template <class T> AlpsEncoded& readRep(T*& values,
00217 int& length,
00218 bool needAllocateMemory = true)
00219 {
00220
00221 if (needAllocateMemory) {
00222
00223
00224 #ifdef PARANOID
00225 if (pos_ + sizeof(int) > size_) {
00226 throw CoinError("Reading over the end of buffer.",
00227 "readRep(T*& values, int& length,...",
00228 "AlpsEncoded");
00229 }
00230 #endif
00231 memcpy(&length, representation_ + pos_, sizeof(int));
00232 pos_ += sizeof(int);
00233 if (length > 0){
00234 #ifdef PARANOID
00235 if (pos_ + sizeof(T)*length > size_) {
00236 throw CoinError("Reading over the end of buffer.",
00237 "readRep(T*& values, int& length,...",
00238 "AlpsEncoded");
00239 }
00240 #endif
00241 values = new T[length];
00242 memcpy(values, representation_ + pos_, sizeof(T)*length);
00243 pos_ += sizeof(T) * length;
00244 }
00245
00246 }
00247 else {
00248
00249 int l;
00250 #ifdef PARANOID
00251 if (pos_ + sizeof(int) > size_) {
00252 throw CoinError("Reading over the end of buffer.",
00253 "readRep(T*& values, int& length,...",
00254 "AlpsEncoded");
00255 }
00256 #endif
00257 memcpy(&l, representation_ + pos_, sizeof(int));
00258 pos_ += sizeof(int);
00259 if (l != length) {
00260 throw CoinError("Reading over the end of buffer.",
00261 "readRep(T*& values, int& length,...",
00262 "AlpsEncoded");
00263 }
00264 if (length > 0){
00265 #ifdef PARANOID
00266 if (pos_ + sizeof(T)*length > size_) {
00267 throw CoinError("Reading over the end of buffer.",
00268 "readRep(T*& values, int& length,...",
00269 "AlpsEncoded");
00270 }
00271 #endif
00272 memcpy(values, representation_ + pos_, sizeof(T)*length);
00273 pos_ += sizeof(T) * length;
00274 }
00275 }
00276
00277 return *this;
00278 }
00279
00281 AlpsEncoded& writeRep(std::string& value){
00282
00283 const int len = static_cast<const int> (value.length());
00284 make_fit( static_cast<int>(sizeof(int)) + len );
00285 memcpy(representation_ + size_, &len, static_cast<int>(sizeof(int)));
00286 size_ += static_cast<int>(sizeof(int));
00287 if (len > 0){
00288 memcpy(representation_ + size_, value.c_str(), len);
00289 size_ += len;
00290 }
00291 return *this;
00292 }
00293
00295 AlpsEncoded& readRep(std::string& value){
00296 int len;
00297 readRep(len);
00298 value.assign(representation_ + pos_, len);
00299 pos_ += len;
00300 return *this;
00301 }
00302
00304 template <class T> AlpsEncoded& writeRep(const std::vector<T>& vec) {
00305 int objnum = vec.size();
00306 int new_bytes = objnum * sizeof(T);
00307 make_fit( sizeof(int) + new_bytes );
00308 memcpy(representation_ + size_, &objnum, sizeof(int));
00309 size_ += sizeof(int);
00310 if (objnum > 0){
00311 memcpy(representation_ + size_, &vec[0], new_bytes);
00312 size_ += new_bytes;
00313 }
00314 return *this;
00315 }
00316
00318 template <class T> AlpsEncoded& readRep(std::vector<T>& vec) {
00319 int objnum;
00320 #ifdef PARANOID
00321 if (pos_ + sizeof(int) > size_)
00322 throw CoinError("Reading over the end of buffer.",
00323 "AlpsEncoded", "readRep(std::vector<T>& vec");
00324 #endif
00325 memcpy(&objnum, representation_ + pos_, sizeof(int));
00326 pos_ += sizeof(int);
00327 vec.clear();
00328 if (objnum > 0){
00329 #ifdef PARANOID
00330 if (pos_ + sizeof(T)*objnum > size_)
00331 throw CoinError("Reading over the end of buffer.",
00332 "AlpsEncoded", "readRep(std::vector<T>& vec");
00333 #endif
00334 vec.insert(vec.end(), objnum, T());
00335 memcpy(&vec[0], representation_ + pos_, objnum * sizeof(T));
00336 pos_ += objnum * sizeof(T);
00337 }
00338 return *this;
00339 }
00342 };
00343
00344 #endif