Midnight Cow / ThingerIO

Dependencies:   DHT WIZnetInterface mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pson.h Source File

pson.h

00001 // The MIT License (MIT)
00002 //
00003 // Copyright (c) 2015 THINGER LTD
00004 // Author: alvarolb@gmail.com (Alvaro Luis Bustamante)
00005 //
00006 // Permission is hereby granted, free of charge, to any person obtaining a copy
00007 // of this software and associated documentation files (the "Software"), to deal
00008 // in the Software without restriction, including without limitation the rights
00009 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 // copies of the Software, and to permit persons to whom the Software is
00011 // furnished to do so, subject to the following conditions:
00012 //
00013 // The above copyright notice and this permission notice shall be included in
00014 // all copies or substantial portions of the Software.
00015 //
00016 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022 // THE SOFTWARE.
00023 
00024 #ifndef PSON_HPP
00025 #define PSON_HPP
00026 
00027 #include <stdint.h>
00028 #include <string.h>
00029 #include <math.h>
00030 #include <stdlib.h>
00031 
00032 namespace protoson {
00033 
00034     class memory_allocator{
00035     public:
00036         virtual void *allocate(size_t size) = 0;
00037         virtual void deallocate(void *) = 0;
00038     };
00039 
00040     template<size_t buffer_size>
00041     class circular_memory_allocator : public memory_allocator{
00042     private:
00043         uint8_t buffer_[buffer_size];
00044         size_t index_;
00045     public:
00046         circular_memory_allocator() : index_(0) {
00047         }
00048 
00049         virtual void *allocate(size_t size) {
00050             if (index_ + size > buffer_size) {
00051                 index_ = 0;
00052             }
00053             void *position = &buffer_[index_];
00054             index_ += size;
00055             return position;
00056         }
00057 
00058         virtual void deallocate(void *) {
00059 
00060         }
00061     };
00062 
00063     class dynamic_memory_allocator : public memory_allocator{
00064     public:
00065         virtual void *allocate(size_t size) {
00066             return malloc(size);
00067         }
00068 
00069         virtual void deallocate(void *ptr) {
00070             free(ptr);
00071         }
00072     };
00073 
00074     extern memory_allocator& pool;
00075 }
00076 
00077 inline void* operator new(size_t sz, protoson::memory_allocator& a)
00078 {
00079     return a.allocate(sz);
00080 }
00081 
00082 inline void operator delete(void* p, protoson::memory_allocator& a)
00083 {
00084     a.deallocate(p);
00085 }
00086 
00087 template<class T>
00088 void destroy(T* p, protoson::memory_allocator& a)
00089 {
00090     if (p) {
00091         p->~T();
00092         a.deallocate(p);
00093     }
00094 }
00095 
00096 namespace protoson {
00097 
00098     enum pb_wire_type{
00099         varint = 0,
00100         fixed_64 = 1,
00101         length_delimited = 2,
00102         fixed_32 = 5,
00103         pson_type = 6
00104     };
00105 
00106     template<class T>
00107     class pson_container {
00108 
00109         struct list_item{
00110             T item_;
00111             list_item* next_;
00112         };
00113 
00114     public:
00115 
00116         class iterator{
00117         public:
00118             iterator(list_item *current) : current(current) {
00119             }
00120 
00121         private:
00122             list_item * current;
00123 
00124         public:
00125             bool next(){
00126                 if(current==NULL) return false;
00127                 current = current->next_;
00128                 return true;
00129             }
00130 
00131             bool has_next(){
00132                 return current!=NULL && current->next_!=NULL;
00133             }
00134 
00135             bool valid(){
00136                 return current!=NULL;
00137             }
00138 
00139             T& item(){
00140                 return current->item_;
00141             }
00142         };
00143 
00144     private:
00145         list_item* item_;
00146 
00147     public:
00148         iterator begin() const{
00149             return iterator(item_);
00150         }
00151 
00152         pson_container() : item_(NULL) {
00153         }
00154 
00155         ~pson_container(){
00156             clear();
00157         }
00158 
00159         void clear(){
00160             list_item* current = item_;
00161             while(current!=NULL){
00162                 list_item* next = current->next_;
00163                 destroy(current, pool);
00164                 current = next;
00165             }
00166             item_ = NULL;
00167         }
00168 
00169         T& create_item(){
00170             list_item* new_list_item = new(pool) list_item();
00171             if(item_==NULL){
00172                 item_ = new_list_item;
00173             }
00174             else{
00175                 list_item * last = item_;
00176                 while(last->next_!=NULL) last = last->next_;
00177                 last->next_ = new_list_item;
00178             }
00179             return new_list_item->item_;
00180         }
00181     };
00182 
00183     class pson_object;
00184     class pson_array;
00185 
00186     class pson {
00187     public:
00188         enum field_type {
00189             null_field      = 0,
00190             varint_field    = 1,
00191             svarint_field   = 2,
00192             float_field     = 3,
00193             double_field    = 4,
00194             true_field      = 5,
00195             false_field     = 6,
00196             zero_field      = 7,
00197             one_field       = 8,
00198             string_field    = 9,
00199             empty_string    = 10,
00200             bytes_field     = 11,
00201             empty_bytes     = 12,
00202             object_field    = 13,
00203             array_field     = 14,
00204             empty           = 15,
00205             // a message tag is encoded in a 128-base varint [1-bit][3-bit wire type][4-bit field]
00206             // we have up to 4 bits (0-15) for encoding fields in the first byte
00207         };
00208 
00209         bool is_boolean() const{
00210             return field_type_ == true_field || field_type_ == false_field;
00211         }
00212 
00213         bool is_string() const{
00214             return field_type_ == string_field;
00215         }
00216 
00217         bool is_bytes() const{
00218             return field_type_ == bytes_field;
00219         }
00220 
00221         bool is_number() const{
00222             return  field_type_ == varint_field     ||
00223                     field_type_ == svarint_field    ||
00224                     field_type_ == float_field      ||
00225                     field_type_ == double_field     ||
00226                     field_type_ == zero_field       ||
00227                     field_type_ == one_field;
00228         }
00229 
00230         bool is_object() const{
00231             return field_type_ == object_field;
00232         }
00233 
00234         bool is_array() const{
00235             return field_type_ == array_field;
00236         }
00237 
00238         bool is_null() const{
00239             return field_type_ == null_field;
00240         }
00241 
00242         bool is_empty() const{
00243             return field_type_ == empty;
00244         }
00245 
00246         pson() : field_type_(empty), value_(NULL) {
00247         }
00248 
00249         template<class T>
00250         pson(T value) : field_type_(empty), value_(NULL){
00251             *this = value;
00252         }
00253 
00254         ~pson(){
00255             if(field_type_==object_field){
00256                 destroy((pson_object *) value_, pool);
00257             }else if(field_type_==array_field) {
00258                 destroy((pson_array *) value_, pool);
00259             }else{
00260                 pool.deallocate(value_);
00261             }
00262         }
00263 
00264         template<class T>
00265         void operator=(T value)
00266         {
00267             if(value==0){
00268                 field_type_ = zero_field;
00269             }else if(value==1) {
00270                 field_type_ = one_field;
00271             }else{
00272                 if(value<0){
00273                     field_type_ = svarint_field;
00274                 }else{
00275                     field_type_ = varint_field;
00276                 }
00277                 uint64_t uint_value = value>0 ? value : -value;
00278                 value_ = pool.allocate(pson::get_varint_size(uint_value));
00279                 pb_encode_varint(uint_value);
00280             }
00281         }
00282 
00283         void operator=(bool value){
00284             field_type_ = value ? true_field : false_field;
00285         }
00286 
00287         void operator=(float value) {
00288             if(value==(int32_t)value){
00289                 *this = (int32_t) value;
00290             }else{
00291                 field_type_ = float_field;
00292                 set(value);
00293             }
00294         }
00295 
00296         void operator=(double value) {
00297             if(value==(int64_t)value) {
00298                 *this = (int64_t) value;
00299             }else if(fabs(value-(float)value)<=0.00001){
00300                 field_type_ = float_field;
00301                 set((float)value);
00302             }else{
00303                 field_type_ = double_field;
00304                 set(value);
00305             }
00306         }
00307 
00308         void operator=(const char *str) {
00309             size_t str_size = strlen(str);
00310             if(str_size==0){
00311                 field_type_ = empty_string;
00312             }else{
00313                 field_type_ = string_field;
00314                 memcpy(allocate(str_size+1), str, str_size+1);
00315             }
00316         }
00317 
00318         operator const char *() {
00319             switch(field_type_){
00320                 case string_field:
00321                     return (const char*) value_;
00322                 case empty:
00323                     field_type_ = empty_string;
00324                 default:
00325                     return "";
00326             }
00327         }
00328 
00329         void set_bytes(const void* bytes, size_t size) {
00330             if(size>0){
00331                 size_t varint_size = get_varint_size(size);
00332                 value_ = pool.allocate(varint_size+size);
00333                 pb_encode_varint(size);
00334                 memcpy(((uint8_t*)value_)+varint_size, bytes, size);
00335                 field_type_ = bytes_field;
00336             }else{
00337                 field_type_ = empty_bytes;
00338             }
00339         }
00340 
00341         bool get_bytes(const void*& bytes, size_t& size){
00342             switch(field_type_){
00343                 case bytes_field:
00344                     size = pb_decode_varint();
00345                     bytes = (uint8_t*) value_ + get_varint_size(size);
00346                     return true;
00347                 case empty:
00348                     field_type_ = empty_bytes;
00349                 default:
00350                     return false;
00351             }
00352         }
00353 
00354         void* allocate(size_t size){
00355             value_ = pool.allocate(size);
00356             return value_;
00357         }
00358 
00359         operator pson_object &();
00360         operator pson_array &();
00361         pson & operator[](const char *name);
00362 
00363         operator bool(){
00364             switch(field_type_){
00365                 case zero_field:
00366                 case false_field:
00367                     return false;
00368                 case one_field:
00369                 case true_field:
00370                     return true;
00371                 case empty:
00372                     field_type_ = false_field;
00373                 default:
00374                     return false;
00375             }
00376         }
00377 
00378         template<class T>
00379         operator T() {
00380             switch(field_type_){
00381                 case zero_field:
00382                 case false_field:
00383                     return 0;
00384                 case one_field:
00385                 case true_field:
00386                     return 1;
00387                 case float_field:
00388                     return *(float*)value_;
00389                 case double_field:
00390                     return *(double*)value_;
00391                 case varint_field:
00392                     return pb_decode_varint();
00393                 case svarint_field:
00394                     return -pb_decode_varint();
00395                 case empty:
00396                     field_type_ = zero_field;
00397                 default:
00398                     return 0;
00399             }
00400         }
00401 
00402         void* get_value(){
00403             return value_;
00404         }
00405 
00406         void set_value(void* value){
00407             value_ = value;
00408         }
00409 
00410         field_type get_type() const{
00411             return field_type_;
00412         }
00413 
00414         void set_null(){
00415             field_type_ = null_field;
00416         }
00417 
00418         void set_type(field_type type){
00419             field_type_ = type;
00420         }
00421 
00422         uint8_t get_varint_size(uint64_t value) const{
00423             uint8_t size = 1;
00424             while(value>>=7) size++;
00425             return size;
00426         }
00427 
00428         void pb_encode_varint(uint64_t value) const
00429         {
00430             uint8_t count = 0;
00431             do
00432             {
00433                 uint8_t byte = (uint8_t)(value & 0x7F);
00434                 value >>= 7;
00435                 if(value) byte |= 0x80;
00436                 ((uint8_t*)value_)[count] = byte;
00437                 count++;
00438             }while(value);
00439         }
00440 
00441         uint64_t pb_decode_varint() const
00442         {
00443             if(value_==NULL) return 0;
00444             uint64_t value = 0;
00445             uint8_t pos = 0;
00446             uint8_t byte = 0;
00447             do{
00448                 byte = ((uint8_t*)value_)[pos];
00449                 value |= (uint64_t)(byte&0x7F) << pos*7;
00450                 pos++;
00451             }while(byte>=0x80);
00452             return value;
00453         }
00454 
00455     private:
00456         void* value_;
00457         field_type field_type_;
00458 
00459         template<class T>
00460         void set(T value) {
00461             memcpy(allocate(sizeof(T)), &value, sizeof(T));
00462         }
00463     };
00464 
00465     class pson_pair{
00466     private:
00467         char* name_;
00468         pson value_;
00469     public:
00470         pson_pair() : name_(NULL){
00471         }
00472 
00473         ~pson_pair(){
00474             destroy(name_, pool);
00475         }
00476 
00477         void set_name(const char *name) {
00478             size_t name_size = strlen(name) + 1;
00479             memcpy(allocate_name(name_size), name, name_size);
00480         }
00481 
00482         char* allocate_name(size_t size){
00483             name_ = (char*)pool.allocate(size);
00484             return name_;
00485         }
00486 
00487         pson& value(){
00488             return value_;
00489         }
00490 
00491         char* name() const{
00492             return name_;
00493         }
00494     };
00495 
00496     class pson_object : public pson_container<pson_pair> {
00497     public:
00498         pson &operator[](const char *name) {
00499             for(iterator it=begin(); it.valid(); it.next()){
00500                 if(strcmp(it.item().name(), name)==0){
00501                     return it.item().value();
00502                 }
00503             }
00504             pson_pair & pair = create_item();
00505             pair.set_name(name);
00506             return pair.value();
00507         };
00508     };
00509 
00510     class pson_array : public pson_container<pson> {
00511     public:
00512         template<class T>
00513         pson_array& add(T item_value){
00514             create_item() = item_value;
00515             return *this;
00516         }
00517     };
00518 
00519     inline pson::operator pson_object &() {
00520         if (field_type_ != object_field) {
00521             value_ = new(pool) pson_object;
00522             field_type_ = object_field;
00523         }
00524         return *((pson_object *)value_);
00525     }
00526 
00527     inline pson::operator pson_array &() {
00528         if (field_type_ != array_field) {
00529             value_ = new(pool) pson_array;
00530             field_type_ = array_field;
00531         }
00532         return *((pson_array *)value_);
00533     }
00534 
00535     inline pson &pson::operator[](const char *name) {
00536         return ((pson_object &) *this)[name];
00537     }
00538 
00539     ////////////////////////////
00540     /////// PSON_DECODER ///////
00541     ////////////////////////////
00542 
00543     class pson_decoder {
00544 
00545     protected:
00546         size_t read_;
00547 
00548         virtual bool read(void* buffer, size_t size){
00549             read_+=size;
00550             return true;
00551         }
00552 
00553     public:
00554 
00555         pson_decoder() : read_(0) {
00556 
00557         }
00558 
00559         void reset(){
00560             read_ = 0;
00561         }
00562 
00563         size_t bytes_read(){
00564             return read_;
00565         }
00566 
00567         bool pb_decode_tag(pb_wire_type& wire_type, uint32_t& field_number)
00568         {
00569             uint32_t temp = pb_decode_varint32();
00570             wire_type = (pb_wire_type)(temp & 0x07);
00571             field_number = temp >> 3;
00572             return true;
00573         }
00574 
00575         uint32_t pb_decode_varint32()
00576         {
00577             uint32_t varint = 0;
00578             if(try_pb_decode_varint32(varint)){
00579                 return varint;
00580             }
00581             return 0;
00582         }
00583 
00584         bool try_pb_decode_varint32(uint32_t& varint){
00585             varint = 0;
00586             uint8_t byte;
00587             uint8_t bit_pos = 0;
00588             do{
00589                 if(!read(&byte, 1) || bit_pos>=32){
00590                     return false;
00591                 }
00592                 varint |= (uint32_t)(byte&0x7F) << bit_pos;
00593                 bit_pos += 7;
00594             }while(byte>=0x80);
00595             return true;
00596         }
00597 
00598         uint64_t pb_decode_varint64()
00599         {
00600             uint64_t varint = 0;
00601             uint8_t byte;
00602             uint8_t bit_pos = 0;
00603             do{
00604                 if(!read(&byte, 1) || bit_pos>=64){
00605                     return varint;
00606                 }
00607                 varint |= (uint32_t)(byte&0x7F) << bit_pos;
00608                 bit_pos += 7;
00609             }while(byte>=0x80);
00610             return varint;
00611         }
00612 
00613         bool pb_skip(size_t size){
00614             uint8_t byte;
00615             bool success = true;
00616             for(size_t i=0; i<size; i++){
00617                 success &= read(&byte, 1);
00618             }
00619             return success;
00620         }
00621 
00622         bool pb_skip_varint(){
00623             uint8_t byte;
00624             bool success = true;
00625             do{
00626                 success &= read(&byte, 1);
00627             }while(byte>0x80);
00628             return success;
00629         }
00630 
00631         bool pb_read_string(char *str, size_t size){
00632             bool success = read(str, size);
00633             str[size]=0;
00634             return success;
00635         }
00636 
00637         bool pb_read_varint(pson& value)
00638         {
00639             uint8_t temp[10];
00640             uint8_t byte=0;
00641             uint8_t bytes_read=0;
00642             do{
00643                 if(!read(&byte, 1)) return false;
00644                 temp[bytes_read] = byte;
00645                 bytes_read++;
00646             }while(byte>=0x80);
00647             memcpy(value.allocate(bytes_read), temp, bytes_read);
00648             return true;
00649         }
00650 
00651     public:
00652 
00653         void decode(pson_object & object, size_t size){
00654             size_t start_read = bytes_read();
00655             while(size-(bytes_read()-start_read)>0){
00656                 decode(object.create_item());
00657             }
00658         }
00659 
00660         void decode(pson_array & array, size_t size){
00661             size_t start_read = bytes_read();
00662             while(size-(bytes_read()-start_read)>0){
00663                 decode(array.create_item());
00664             }
00665         }
00666 
00667         void decode(pson_pair & pair){
00668             uint32_t name_size = pb_decode_varint32();
00669             pb_read_string(pair.allocate_name(name_size+1), name_size);
00670             decode(pair.value());
00671         }
00672 
00673         void decode(pson& value) {
00674             uint32_t field_number;
00675             pb_wire_type wire_type;
00676             pb_decode_tag(wire_type, field_number);
00677             value.set_type((pson::field_type)field_number);
00678             if(wire_type==length_delimited){
00679                 uint32_t size = pb_decode_varint32();
00680                 switch(field_number){
00681                     case pson::string_field:
00682                         pb_read_string((char*)value.allocate(size + 1), size);
00683                         break;
00684                     case pson::bytes_field: {
00685                         uint8_t varint_size = value.get_varint_size(size);
00686                         read((char*)value.allocate(size + varint_size) + varint_size, size);
00687                         value.pb_encode_varint(size);
00688                     }
00689                         break;
00690                     case pson::object_field:
00691                         value.set_value(new (pool) pson_object);
00692                         decode(*(pson_object *)value.get_value(), size);
00693                         break;
00694                     case pson::array_field:
00695                         value.set_value(new (pool) pson_array);
00696                         decode(*(pson_array *)value.get_value(), size);
00697                         break;
00698                     default:
00699                         pb_skip(size);
00700                         break;
00701                 }
00702             }else {
00703                 switch (field_number) {
00704                     case pson::svarint_field:
00705                     case pson::varint_field:
00706                         pb_read_varint(value);
00707                         break;
00708                     case pson::float_field:
00709                         read(value.allocate(4), 4);
00710                         break;
00711                     case pson::double_field:
00712                         read(value.allocate(8), 8);
00713                         break;
00714                     default:
00715                         break;
00716                 }
00717             }
00718         }
00719     };
00720 
00721     ////////////////////////////
00722     /////// PSON_ENCODER ///////
00723     ////////////////////////////
00724 
00725     class pson_encoder {
00726 
00727     protected:
00728         size_t written_;
00729 
00730         virtual void write(const void* buffer, size_t size){
00731             written_+=size;
00732         }
00733 
00734     public:
00735 
00736         pson_encoder() : written_(0) {
00737         }
00738 
00739         void reset(){
00740             written_ = 0;
00741         }
00742 
00743         size_t bytes_written(){
00744             return written_;
00745         }
00746 
00747         void pb_encode_tag(pb_wire_type wire_type, uint32_t field_number){
00748             uint64_t tag = ((uint64_t)field_number << 3) | wire_type;
00749             pb_encode_varint(tag);
00750         }
00751 
00752         void pb_encode_varint(uint32_t field, uint64_t value)
00753         {
00754             pb_encode_tag(varint, field);
00755             pb_encode_varint(value);
00756         }
00757 
00758         uint8_t pb_write_varint(void * buffer)
00759         {
00760             uint8_t byte=0;
00761             uint8_t bytes_written=0;
00762             do{
00763                 byte = *((uint8_t*)buffer + bytes_written);
00764                 bytes_written++;
00765             }while(byte>=0x80);
00766             write(buffer, bytes_written);
00767             return bytes_written;
00768         }
00769 
00770         void pb_encode_varint(uint64_t value)
00771         {
00772             do
00773             {
00774                 uint8_t byte = (uint8_t)(value & 0x7F);
00775                 value >>= 7;
00776                 if(value>0) byte |= 0x80;
00777                 write(&byte, 1);
00778             }while(value>0);
00779         }
00780 
00781         void pb_encode_string(const char* str, uint32_t field_number){
00782             pb_encode_tag(length_delimited, field_number);
00783             pb_encode_string(str);
00784         }
00785 
00786         void pb_encode_string(const char* str){
00787             size_t string_size = strlen(str);
00788             pb_encode_varint(string_size);
00789             write(str, string_size);
00790         }
00791 
00792         template<class T>
00793         void pb_encode_submessage(T& element, uint32_t field_number)
00794         {
00795             pb_encode_tag(length_delimited, field_number);
00796             pson_encoder sink;
00797             sink.encode(element);
00798             pb_encode_varint(sink.bytes_written());
00799             encode(element);
00800         }
00801 
00802         void pb_encode_fixed32(void* value){
00803             write(value, 4);
00804         }
00805 
00806         void pb_encode_fixed64(void* value){
00807             write(value, 8);
00808         }
00809 
00810         void pb_encode_fixed32(uint32_t field, void*value)
00811         {
00812             pb_encode_tag(fixed_32, field);
00813             pb_encode_fixed32(value);
00814         }
00815 
00816         void pb_encode_fixed64(uint32_t field, void*value)
00817         {
00818             pb_encode_tag(fixed_64, field);
00819             pb_encode_fixed64(value);
00820         }
00821 
00822     public:
00823 
00824         void encode(pson_object & object){
00825             pson_container<pson_pair>::iterator it = object.begin();
00826             while(it.valid()){
00827                 encode(it.item());
00828                 it.next();
00829             }
00830         }
00831 
00832         void encode(pson_array & array){
00833             pson_container<pson>::iterator it = array.begin();
00834             while(it.valid()){
00835                 encode(it.item());
00836                 it.next();
00837             }
00838         }
00839 
00840         void encode(pson_pair & pair){
00841             pb_encode_string(pair.name());
00842             encode(pair.value());
00843         }
00844 
00845         void encode(pson & value) {
00846             switch (value.get_type()) {
00847                 case pson::string_field:
00848                     pb_encode_string((const char*)value.get_value(), pson::string_field);
00849                     break;
00850                 case pson::bytes_field:
00851                     pb_encode_tag(length_delimited, pson::bytes_field);
00852                     write(((const char *) value.get_value()) + pb_write_varint(value.get_value()), value.pb_decode_varint());
00853                     break;
00854                 case pson::svarint_field:
00855                 case pson::varint_field:
00856                     pb_encode_tag(varint, value.get_type());
00857                     pb_write_varint(value.get_value());
00858                     break;
00859                 case pson::float_field:
00860                     pb_encode_fixed32(pson::float_field, value.get_value());
00861                     break;
00862                 case pson::double_field:
00863                     pb_encode_fixed64(pson::double_field, value.get_value());
00864                     break;
00865                 case pson::object_field:
00866                     pb_encode_submessage(*(pson_object *) value.get_value(), pson::object_field);
00867                     break;
00868                 case pson::array_field:
00869                     pb_encode_submessage(*(pson_array *) value.get_value(), pson::array_field);
00870                     break;
00871                 default:
00872                     pb_encode_tag(varint, value.get_type());
00873                     break;
00874             }
00875         }
00876     };
00877 }
00878 
00879 #endif