/home/coin/SVN-release/CoinAll-1.1.0/Alps/src/AlpsEncoded.h

Go to the documentation of this file.
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 // AlpsEncoded is modified from BCP_buffer and CoinEncoded
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     //std::string type_;   
00048 
00049     int type_;
00050 
00052     int size_;
00053 
00055     // const char* representation_;   //why const ??? XY
00056     char* representation_;
00057     
00058  public:
00059     
00062 
00065     AlpsEncoded() 
00066         : 
00067         pos_(0), 
00068         maxSize_(0x4000/*16K*/), 
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             //     const char msg [100] = "Incorrest position setting.";
00113             //throw AlpsException(__FILE__, __LINE__, msg);
00114             throw CoinError("Incorrest position setting.", "setPosition",
00115                             "AlpsEncoded");
00116         }
00117         pos_ = pos;
00118     }
00119   
00120     inline void setRepresentation(char*& buf) {
00121         //> 0x4000/*16K*/ ? (strlen(buf)+1) : 0x4000;
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/*4K*/);
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     // Following functiosn are used in parallel code only.
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_ += 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( sizeof(int) + sizeof(T) * length );
00192         memcpy(representation_ + size_, &length, sizeof(int));
00193         size_ += sizeof(int);
00194         if (length > 0){
00195             memcpy(representation_ + size_, values, sizeof(T) * length);
00196             size_ += sizeof(T) * length;
00197         }
00198         return *this;
00199     }
00200 
00214     template <class T> AlpsEncoded& readRep(T*& values, 
00215                                             int& length,
00216                                             bool needAllocateMemory = true)
00217        {
00218         
00219         if (needAllocateMemory) {
00220             // Need allocate memeory for arrary "values".
00221             
00222 #ifdef PARANOID
00223             if (pos_ + sizeof(int) > size_) {
00224                 throw CoinError("Reading over the end of buffer.", 
00225                                 "readRep(T*& values, int& length,...", 
00226                                 "AlpsEncoded");
00227             }
00228 #endif
00229             memcpy(&length, representation_ + pos_, sizeof(int));
00230             pos_ += sizeof(int);
00231             if (length > 0){
00232 #ifdef PARANOID
00233                 if (pos_ + sizeof(T)*length > size_) {
00234                     throw CoinError("Reading over the end of buffer.", 
00235                                     "readRep(T*& values, int& length,...",
00236                                     "AlpsEncoded");
00237                 }
00238 #endif
00239                 values = new T[length];
00240                 memcpy(values, representation_ + pos_, sizeof(T)*length);
00241                 pos_ += sizeof(T) * length;
00242             }
00243             
00244         } 
00245         else { /* values has been allocated memory. */
00246 
00247             int l;
00248 #ifdef PARANOID
00249             if (pos_ + sizeof(int) > size_) {
00250                 throw CoinError("Reading over the end of buffer.", 
00251                                 "readRep(T*& values, int& length,...",
00252                                 "AlpsEncoded");
00253             }
00254 #endif
00255             memcpy(&l, representation_ + pos_, sizeof(int));
00256             pos_ += sizeof(int);
00257             if (l != length) {
00258                 throw CoinError("Reading over the end of buffer.", 
00259                                 "readRep(T*& values, int& length,...", 
00260                                 "AlpsEncoded");
00261             }
00262             if (length > 0){
00263 #ifdef PARANOID
00264                 if (pos_ + sizeof(T)*length > size_) {
00265                     throw CoinError("Reading over the end of buffer.", 
00266                                     "readRep(T*& values, int& length,...",
00267                                     "AlpsEncoded");
00268                 }
00269 #endif
00270                 memcpy(values, representation_ + pos_, sizeof(T)*length);
00271                 pos_ += sizeof(T) * length;
00272             }       
00273         }
00274         
00275         return *this;
00276     }
00277 
00279     AlpsEncoded& writeRep(std::string& value){
00280         // must define here, 'cos in *_message.C we have only templated members
00281         const int len = static_cast<const int> (value.length());
00282         make_fit( sizeof(int) + len );
00283         memcpy(representation_ + size_, &len, sizeof(int));
00284         size_ += sizeof(int);
00285         if (len > 0){
00286             memcpy(representation_ + size_, value.c_str(), len);
00287             size_ += len;
00288         }
00289         return *this;
00290     }
00291 
00293     AlpsEncoded& readRep(std::string& value){
00294         int len;
00295         readRep(len);
00296         value.assign(representation_ + pos_, len);
00297         pos_ += len;
00298         return *this;
00299     }
00300     
00302     template <class T> AlpsEncoded& writeRep(const std::vector<T>& vec) {
00303         int objnum = vec.size();
00304         int new_bytes = objnum * sizeof(T);
00305         make_fit( sizeof(int) + new_bytes );
00306         memcpy(representation_ + size_, &objnum, sizeof(int));
00307         size_ += sizeof(int);
00308         if (objnum > 0){
00309             memcpy(representation_ + size_, &vec[0], new_bytes);
00310             size_ += new_bytes;
00311         }
00312         return *this;
00313    }
00314     
00316    template <class T> AlpsEncoded& readRep(std::vector<T>& vec) {
00317        int objnum;
00318 #ifdef PARANOID
00319        if (pos_ + sizeof(int) > size_)
00320            throw CoinError("Reading over the end of buffer.", 
00321                            "AlpsEncoded", "readRep(std::vector<T>& vec");
00322 #endif
00323        memcpy(&objnum, representation_ + pos_, sizeof(int));
00324        pos_ += sizeof(int);
00325        vec.clear();
00326        if (objnum > 0){
00327 #ifdef PARANOID
00328            if (pos_ + sizeof(T)*objnum > size_)
00329                throw CoinError("Reading over the end of buffer.", 
00330                                "AlpsEncoded", "readRep(std::vector<T>& vec");
00331 #endif
00332            vec.insert(vec.end(), objnum, T());
00333            memcpy(&vec[0], representation_ + pos_, objnum * sizeof(T));
00334            pos_ += objnum * sizeof(T);
00335        }
00336        return *this;
00337    }
00340 };
00341 
00342 #endif

Generated on Sun Nov 14 14:06:28 2010 for Coin-All by  doxygen 1.4.7