$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

hierarchicSerializer.h

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00028 #ifndef HIERARCHIC_SERIALIZER_H
00029 #define HIERARCHIC_SERIALIZER_H
00030 
00031 #include "core/dynamics.h"
00032 #include <map>
00033 #include <cstring>
00034 
00035 namespace plb {
00036 
00037 class HierarchicUnserializer {
00038 public:
00039     HierarchicUnserializer(std::vector<char> const& data_, pluint currentPos_)
00040         : data(data_),
00041           currentPos(currentPos_),
00042           idIndirect(0)
00043     {
00044         readHeader();
00045     }
00046     HierarchicUnserializer(std::vector<char> const& data_, pluint currentPos_,
00047                            std::map<int,int> const* idIndirect_)
00048         : data(data_),
00049           currentPos(currentPos_),
00050           idIndirect(idIndirect_)
00051     {
00052         readHeader();
00053     }
00054     int getNumObjects() const {
00055         return numObjects;
00056     }
00057     int getId() const {
00058         if (!idIndirect) {
00059             return id;
00060         }
00061         else {
00062             std::map<int,int>::const_iterator it = idIndirect->find(id);
00063             PLB_ASSERT( it != idIndirect->end() );
00064             return it->second;
00065         }
00066     }
00067     int getNumVal() const {
00068         return numValInObject;
00069     }
00070     pluint getCurrentPos() const {
00071         return currentPos;
00072     }
00073     template<typename T> bool readValue(T& value) {
00074         read(value);
00075         --numRepetitions;
00076         --numValInObject;
00077         return advance();
00078     }
00079     template<typename T> T readValue() {
00080         T value;
00081         readValue<T>(value);
00082         return value;
00083     }
00084     template<typename T> bool readValues(std::vector<T>& values) {
00085         PLB_PRECONDITION((plint)values.size()<=numRepetitions);
00086         for (pluint iVal=0; iVal<values.size(); ++iVal) {
00087             read(values[iVal]);
00088         }
00089         numRepetitions -= values.size();
00090         numValInObject -= values.size();
00091         return advance();
00092     }
00093     template<typename T, int ndim> bool readValues(Array<T,ndim>& values) {
00094         for (plint iVal=0; iVal<ndim; ++iVal) {
00095             read(values[iVal]);
00096         }
00097         numRepetitions -= ndim;
00098         numValInObject -= ndim;
00099         return advance();
00100     }
00101     void remapId(std::map<int,int> const& indirect) {
00102         std::map<int,int>::const_iterator it = indirect.find(id);
00103         PLB_ASSERT( it != indirect.end() );
00104         id = it->second;
00105     }
00106 private:
00107     void readHeader() {
00108         read(numObjects);
00109         read(id);
00110         read(numValInObject);
00111         read(currentTypeSize);
00112         read(numRepetitions);
00113     }
00114     template<typename T> void read(T& value) {
00115         PLB_PRECONDITION(currentPos+sizeof(value)<=data.size());
00116         if (sizeof(value)>0) {
00117             //value = *( (T const*) (&data[currentPos]) );
00118             memcpy((void*)(&value), (void*)(&data[currentPos]), sizeof(T));
00119             currentPos += sizeof(value);
00120         }
00121     }
00122     bool advance() {
00123         if (numValInObject==0) {
00124             --numObjects;
00125             if (numObjects>0) {
00126                 read(id);
00127                 read(numValInObject);
00128             }
00129             else {
00130                 // Return if there's no object left, to avoid that the
00131                 //   next repetition is mistakingly parsed.
00132                 return false;
00133             }
00134         }
00135         if (numRepetitions==0) {
00136             read(currentTypeSize);
00137             read(numRepetitions);
00138         }
00139         return true;
00140     }
00141 private:
00142     std::vector<char> const& data;
00143     pluint currentPos;
00144     int    numObjects;
00145     int    id;
00146     int    numValInObject;
00147     int    numRepetitions;
00148     int    currentTypeSize;
00149     std::map<int,int> const* idIndirect;
00150 };
00151 
00152 class HierarchicSerializer {
00153 public:
00154     HierarchicSerializer(std::vector<char>& data_, int topMostObjectId)
00155         : data(data_),
00156           currentPos(data.size())
00157     {
00158         numDynamicsPos = assignPointer();
00159         nextDynamics(topMostObjectId);
00160     }
00161     void nextDynamics(int id) {
00162         write(id);
00163         numValInDynamicsPos = assignPointer();
00164         currentTypeSize = 0;
00165         incrementInt(numDynamicsPos);
00166     }
00167     template<typename T> void addValue(T value)
00168     {
00169         PLB_PRECONDITION( currentPos > sizeof(int) );
00170         if (sizeof(value) != currentTypeSize) {
00171             currentTypeSize = sizeof(value);
00172             write(currentTypeSize);
00173             numRepetitionsPos = assignPointer();
00174         }
00175         write(value);
00176         incrementInt(numRepetitionsPos);
00177         incrementInt(numValInDynamicsPos);
00178     }
00179     template<typename T> void addValues(std::vector<T> const& values)
00180     {
00181         PLB_PRECONDITION( currentPos > sizeof(int) );
00182         if (values.empty()) return;
00183         addValue(values[0]);
00184         for (pluint iVal=1; iVal<values.size(); ++iVal) {
00185             write(values[iVal]);
00186             incrementInt(numRepetitionsPos);
00187             incrementInt(numValInDynamicsPos);
00188         }
00189     }
00190     template<typename T, int ndim> void addValues(Array<T,ndim> const& values)
00191     {
00192         PLB_PRECONDITION( ndim>0 );
00193         addValue(values[0]);
00194         for (pluint iVal=1; iVal<ndim; ++iVal) {
00195             write(values[iVal]);
00196             incrementInt(numRepetitionsPos);
00197             incrementInt(numValInDynamicsPos);
00198         }
00199     }
00200 private:
00201     template<typename T> void write(T value) {
00202         if (sizeof(value)==0) return;
00203         data.resize(currentPos+sizeof(value));
00204         //*( (T*) (&data[currentPos]) ) = value;
00205         memcpy((void*)(&data[currentPos]), (void*)(&value), sizeof(value));
00206         currentPos += sizeof(T);
00207     }
00208     pluint assignPointer() {
00209         data.resize(currentPos+sizeof(int));
00210         pluint ptr = currentPos;
00211         int zero=0;
00212         memcpy((void*)(&data[ptr]), (void*)(&zero), sizeof(int));
00213         //*( (int*) (&data[ptr]) ) = 0;
00214         currentPos += sizeof(int);
00215         return ptr;
00216     }
00217     void incrementInt(pluint pos) {
00218         PLB_PRECONDITION(pos+sizeof(int)<=data.size());
00219         //++(*( (int*) (&data[pos]) ) );
00220         int value;
00221         memcpy((void*)(&value), (void*)(&data[pos]), sizeof(int));
00222         ++value;
00223         memcpy((void*)(&data[pos]), (void*)(&value), sizeof(int));
00224     }
00225 private:
00226     std::vector<char>& data;
00227     pluint currentPos;
00228     pluint numDynamicsPos;
00229     pluint numValInDynamicsPos;
00230     pluint numRepetitionsPos;
00231     int    currentTypeSize;
00232 };
00233 
00234 }  // namespace plb
00235 
00236 #endif  // HIERARCHIC_SERIALIZER_H