GraphParser.h

Go to the documentation of this file.
00001 // $Id: GraphParser.h 241 2006-07-05 07:29:52Z bingmann $
00002 
00003 #ifndef VGS_GraphParser_H
00004 #define VGS_GraphParser_H
00005 
00006 #include "ByteInBuffer.h"
00007 #include "AttributeProperties.h"
00008 
00009 #include <iostream>
00010 
00011 namespace VGServer {
00012 
00014 class GraphParserException : std::runtime_error
00015 {
00016 public:
00017     explicit GraphParserException(const std::string &arg) throw()
00018         : std::runtime_error(arg)
00019     {
00020     }
00021 };
00022 
00027 class GraphParserCallbackAdapter
00028 {
00029 public:
00030     typedef std::vector<AnyType> AnyTypeVector;
00031 
00032     void eventStartParse()
00033     {
00034     }
00035     void eventError(const std::string& /* error string */)
00036     {
00037     }
00038 
00039     void eventVertexAttributes(const class AttributePropertiesList &)
00040     {
00041     }
00042 
00043     void eventEdgeAttributes(const class AttributePropertiesList &)
00044     {
00045     }
00046 
00047     void eventStartVertexBody(unsigned int /* vertexnum */)
00048     {
00049     }
00050     void eventVertex(const AnyTypeVector& /* values */)
00051     {
00052     }
00053 
00054     void eventStartEdgeBody(unsigned int /* edgenum */)
00055     {
00056     }
00057     void eventEdge(const AnyTypeVector& /* values */)
00058     {
00059     }
00060 
00065     bool eventAnimationParseData()
00066     {
00067         return true;
00068     }
00069 
00073     ByteBuffer* eventAnimationDataBuffer()
00074     {
00075         return NULL;
00076     }
00077 
00078     void eventStartAnimation(unsigned int /* frames */)
00079     {
00080     }
00081     void eventStartAnimationFrame(unsigned int /* framenum */,
00082                                   unsigned int /* operationsnum */)
00083     {
00084     }
00085         
00086     void eventAnimationAddVertex(unsigned int /* framenum */,
00087                                  const AnyTypeVector& /* values */)
00088     {
00089     }
00090     void eventAnimationSetVertex(unsigned int /* framenum */,
00091                                  const AnyTypeVector& /* old values */,
00092                                  const AnyTypeVector& /* new values */)
00093     {
00094     }
00095     void eventAnimationDelVertex(unsigned int /* framenum */,
00096                                  const AnyTypeVector& /* values */)
00097     {
00098     }
00099         
00100     void eventAnimationAddEdge(unsigned int /* framenum */,
00101                                const AnyTypeVector& /* values */)
00102     {
00103     }
00104     void eventAnimationSetEdge(unsigned int /* framenum */,
00105                                const AnyTypeVector& /* old values */,
00106                                const AnyTypeVector& /* new values */)
00107     {
00108     }
00109     void eventAnimationDelEdge(unsigned int /* framenum */,
00110                                const AnyTypeVector& /* values */)
00111     {
00112     }
00113 };
00114 
00118 template <class Callback>
00119 class GraphParser
00120 {
00121 protected:
00123     Callback    &callback;
00124 
00125     // save the two attribute properties list for later deserialization of the
00126     // body data.
00127     AttributePropertiesList vertexattr, edgeattr;
00128 
00129 public:
00131     GraphParser(Callback &cb)
00132         : callback(cb)
00133     {
00134     }
00135 
00138     GraphParser(Callback &cb, const AttributePropertiesList &_vertexattr, const AttributePropertiesList &_edgeattr)
00139         : callback(cb), vertexattr(_vertexattr), edgeattr(_edgeattr)
00140     {
00141     }
00142 
00145     static bool parse(Callback &cb, const ByteBuffer &bb)
00146     {
00147         GraphParser gp (cb);
00148 
00149         return gp.parse(bb);
00150     }
00151 
00154     bool parse(const ByteBuffer &bbdata)
00155     {
00156         ByteInBuffer bb (bbdata);
00157 
00158         callback.eventStartParse();
00159 
00160         // see if the version signature is correct
00161         unsigned int versig = (bb.remaining() > 4) ? bb.fetch_unsigned_int() : 0;
00162         if (versig != 0x00010000 )
00163             throw GraphParserException("Invalid binary format version encountered");
00164 
00165         // get the first char describing the section
00166         while (bb.remaining() > 0)
00167         {
00168             unsigned char sect = bb.fetch_unsigned_char();
00169             
00170             switch(sect)
00171             {
00172             case 0: // section=0 is the termination
00173                 return true;
00174             
00175             case 1: // section 1 are the vertex attribute properties 
00176                 parseVertexAttrlist(bb);
00177                 break;
00178                         
00179             case 2: // section 2 are the edge attribute properties
00180                 parseEdgeAttrlist(bb);
00181                 break;
00182                 
00183             case 3: // section 3 is the vertex body data
00184                 parseVertexBodyData(bb);
00185                 break;
00186                 
00187             case 4: // section 4 is the edge body data
00188                 parseEdgeBodyData(bb);
00189                 break;
00190                 
00191             case 5: // section 5 is the animation sequence
00192                 parseAnimationStart(bb);
00193                 break;
00194                 
00195             case 0x10: // section 0x10 is the directed flag within GraphProperties
00196                 parseGraphProperties(bb);
00197                 break;
00198                 
00199             case 0xFF: // error section contains a single string
00200             {
00201                 std::string errstr = bb.fetchString();
00202                 callback.eventError(errstr);
00203                 break;
00204             }
00205                     
00206             default:
00207                 throw GraphParserException("Invalid section within binary format");
00208             }
00209         }
00210 
00211         if (bb.remaining() > 0)
00212         {
00213             std::cerr << "Incomplete deserialization\n";
00214             callback.eventError("Incomplete deserialization");
00215             return false;
00216         }
00217         return true;
00218     }
00219 
00223     static void parseAnimation(Callback &cb, const ByteBuffer &bb,
00224                                const AttributePropertiesList &vertexattr, const AttributePropertiesList &edgeattr)
00225     {
00226         GraphParser gp (cb, vertexattr, edgeattr);
00227 
00228         return gp.parseAnimation(bb);
00229     }
00230 
00234     void parseAnimation(const ByteBuffer &bbdata)
00235     {
00236         ByteInBuffer bb (bbdata);
00237 
00238         assert(vertexattr.defbytes > 0);
00239         assert(edgeattr.defbytes > 0);
00240 
00241         parseAnimationData(bb);
00242     }
00243 
00244 protected:
00245     // *** Internal functions parsing various parts of the data stream
00246 
00247     void parseVertexAttrlist(class ByteInBuffer &bb)
00248     {
00249         parseAttrlist(bb, vertexattr);
00250         callback.eventVertexAttributes(static_cast<const AttributePropertiesList&>(vertexattr));
00251     }
00252 
00253     void parseEdgeAttrlist(class ByteInBuffer &bb)
00254     {
00255         parseAttrlist(bb, edgeattr);
00256         callback.eventEdgeAttributes(static_cast<const AttributePropertiesList&>(edgeattr));
00257     }
00258 
00259     void parseAttrlist(class ByteInBuffer &bb, class AttributePropertiesList &apl)
00260     {
00261         apl.clear();
00262 
00263         unsigned int attrlen = bb.fetch_unsigned_short();
00264 
00265         apl.defbytes = bb.fetch_unsigned_char();
00266 
00267         for(unsigned int ai = 0; ai < attrlen; ai++)
00268         {
00269             attrtype_t at = static_cast<attrtype_t>(bb.fetch_unsigned_char());
00270 
00271             if (!AnyType::isValidAttrtype(at))
00272                 throw GraphParserException("Invalid attribute type id encountered");
00273 
00274             std::string name = bb.fetchString();
00275             
00276             apl.push_back( AttributeProperties(name, at) );
00277             
00278             // read default value
00279             if (at == ATTRTYPE_BOOL) {
00280                 apl.back().setInteger(bb.fetch_unsigned_char());
00281             }
00282             else {
00283                 bb.fetchAnyType(apl.back());
00284             }
00285         }
00286     }
00287     
00288     static bool getBit(int bitnum, char *bitfield)
00289     {
00290         int idx = bitnum / 8;
00291         bitnum %= 8;
00292         return (bitfield[idx] & (1 << bitnum)) != 0;        
00293     }
00294 
00295     void parseVertexBodyData(class ByteInBuffer &bb)
00296     {
00297         unsigned int objnum = bb.fetch_unsigned_int();
00298         callback.eventStartVertexBody(objnum);
00299         
00300         char defbits[vertexattr.defbytes];
00301         std::vector<AnyType> values;
00302         values.resize(vertexattr.size(), AnyType(ATTRTYPE_INVALID));
00303 
00304         for(unsigned int oi = 0; oi < objnum; oi++)
00305         {
00306             // read the default bitfield
00307             bb.fetchBytes(defbits, vertexattr.defbytes);
00308 
00309             for(unsigned int ai = 0; ai < vertexattr.size(); ai++)
00310             {
00311                 if (vertexattr[ai].getType() == ATTRTYPE_BOOL) {
00312                     values[ai].resetType(ATTRTYPE_BOOL);
00313                     values[ai].setInteger( getBit(ai, defbits) );
00314                 }
00315                 else if (getBit(ai, defbits)) {
00316                     // default bit is set. so put the default value into the object array
00317                     values[ai] = vertexattr[ai];
00318                 }
00319                 else {
00320                     values[ai].resetType(vertexattr[ai].getType());
00321                     bb.fetchAnyType(values[ai]);
00322                 }
00323             }
00324             
00325             callback.eventVertex(values);
00326         }
00327     }
00328 
00329     void parseEdgeBodyData(class ByteInBuffer &bb)
00330     {
00331         unsigned int objnum = bb.fetch_unsigned_int();
00332         callback.eventStartEdgeBody(objnum);
00333         
00334         char defbits[edgeattr.defbytes];
00335         std::vector<AnyType> values;
00336         values.resize(edgeattr.size(), AnyType(ATTRTYPE_INVALID));
00337 
00338         for(unsigned int oi = 0; oi < objnum; oi++)
00339         {
00340             // read the default bitfield
00341             bb.fetchBytes(defbits, edgeattr.defbytes);
00342 
00343             for(unsigned int ai = 0; ai < edgeattr.size(); ai++)
00344             {
00345                 if (edgeattr[ai].getType() == ATTRTYPE_BOOL) {
00346                     values[ai].resetType(ATTRTYPE_BOOL);
00347                     values[ai].setInteger( getBit(ai, defbits) );
00348                 }
00349                 else if (getBit(ai, defbits)) {
00350                     // default bit is set. so put the default value into the object array
00351                     values[ai] = edgeattr[ai];
00352                 }
00353                 else {
00354                     values[ai].resetType(edgeattr[ai].getType());
00355                     bb.fetchAnyType(values[ai]);
00356                 }
00357             }
00358             
00359             callback.eventEdge(values);
00360         }
00361     }
00362     
00363     void parseAnimationStart(class ByteInBuffer &bb)
00364     {
00365         unsigned int anisize = bb.fetch_unsigned_int();
00366 
00367         if (callback.eventAnimationParseData())
00368         {
00369             parseAnimationData(bb);
00370         }
00371         else
00372         {
00373             // save the animation data block for later parsing
00374 
00375             ByteBuffer *anidata = callback.eventAnimationDataBuffer();
00376             assert(anidata);
00377             if (!anidata) return;
00378 
00379             bb.fetchBytes(*anidata, anisize);
00380         }
00381     }
00382 
00383     void parseAnimationData(class  ByteInBuffer &bb)
00384     {
00385         unsigned int framenum = bb.fetch_unsigned_int();
00386         callback.eventStartAnimation(framenum);
00387 
00388         for(unsigned int fn = 0; fn < framenum; fn++)
00389         {
00390             parseAnimationFrame(bb, fn);
00391         }       
00392     }
00393 
00394     void parseAnimationFrame(class ByteInBuffer &bb, unsigned int framenum)
00395     {
00396         unsigned int opnum = bb.fetch_unsigned_int();
00397         callback.eventStartAnimationFrame(framenum, opnum);
00398         
00399         std::vector<AnyType> oldvals, newvals;
00400 
00401         for(unsigned int on = 0; on < opnum; on++)
00402         {
00403             unsigned char opid = bb.fetch_unsigned_char();
00404             
00405             switch(opid)
00406             {
00407             default:
00408             case 0: // invalid id
00409                 throw GraphParserException("Invalid animation operation id encountered.");
00410             
00411             case 1: // CHG_ADDVERTEX
00412                 parseAnimationVertexData(bb, newvals);
00413                 callback.eventAnimationAddVertex(framenum, newvals);
00414                 break;
00415                         
00416             case 2: // CHG_SETVERTEX
00417                 parseAnimationVertexData(bb, oldvals);
00418                 parseAnimationVertexData(bb, newvals);
00419                 callback.eventAnimationSetVertex(framenum, oldvals, newvals);
00420                 break;
00421 
00422             case 3: // CHG_DELVERTEX
00423                 parseAnimationVertexData(bb, oldvals);
00424                 callback.eventAnimationDelVertex(framenum, oldvals);
00425                 break;
00426                         
00427             case 4: // CHG_ADDEDGE
00428                 parseAnimationEdgeData(bb, newvals);
00429                 callback.eventAnimationAddEdge(framenum, newvals);
00430                 break;
00431                         
00432             case 5: // CHG_SETEDGE
00433                 parseAnimationEdgeData(bb, oldvals);
00434                 parseAnimationEdgeData(bb, newvals);
00435                 callback.eventAnimationSetEdge(framenum, oldvals, newvals);
00436                 break;
00437                         
00438             case 6: // CHG_DELEDGE
00439                 parseAnimationEdgeData(bb, oldvals);
00440                 callback.eventAnimationDelEdge(framenum, oldvals);
00441                 break;
00442             }
00443         }
00444     }
00445 
00446     void parseAnimationVertexData(class ByteInBuffer &bb, std::vector<AnyType>& values)
00447     {
00448         char defbits[vertexattr.defbytes];
00449         values.resize(vertexattr.size(), AnyType(ATTRTYPE_INVALID));
00450 
00451         // read the default bitfield
00452         bb.fetchBytes(defbits, vertexattr.defbytes);
00453 
00454         for(unsigned int ai = 0; ai < vertexattr.size(); ai++)
00455         {
00456             if (vertexattr[ai].getType() == ATTRTYPE_BOOL) {
00457                 values[ai].resetType(ATTRTYPE_BOOL);
00458                 values[ai].setInteger( getBit(ai, defbits) );
00459             }
00460             else if (getBit(ai, defbits)) {
00461                 // default bit is set. so put the default value into the object array
00462                 values[ai] = vertexattr[ai];
00463             }
00464             else {
00465                 values[ai].resetType(vertexattr[ai].getType());
00466                 bb.fetchAnyType(values[ai]);
00467             }
00468         }
00469     }
00470 
00471     void parseAnimationEdgeData(class ByteInBuffer &bb, std::vector<AnyType>& values)
00472     {
00473         char defbits[edgeattr.defbytes];
00474         values.resize(edgeattr.size(), AnyType(ATTRTYPE_INVALID));
00475 
00476         // read the default bitfield
00477         bb.fetchBytes(defbits, edgeattr.defbytes);
00478 
00479         for(unsigned int ai = 0; ai < edgeattr.size(); ai++)
00480         {
00481             if (edgeattr[ai].getType() == ATTRTYPE_BOOL) {
00482                 values[ai].resetType(ATTRTYPE_BOOL);
00483                 values[ai].setInteger( getBit(ai, defbits) );
00484             }
00485             else if (getBit(ai, defbits)) {
00486                 // default bit is set. so put the default value into the object array
00487                 values[ai] = edgeattr[ai];
00488             }
00489             else {
00490                 values[ai].resetType(edgeattr[ai].getType());
00491                 bb.fetchAnyType(values[ai]);
00492             }
00493         }
00494     }
00495     
00496     void parseGraphProperties(class ByteInBuffer &bb)
00497     {
00498         /*unsigned char directed = */ bb.fetch_unsigned_char();
00499     }
00500 };
00501 
00502 } // namespace VGServer
00503 
00504 #endif // VGS_GraphParser_H

Generated on Wed Sep 27 14:34:00 2006 for VGServer by  doxygen 1.4.7