Thinger.io Client Library for ARM mbed platform. This is a generic library that provides a base class that can be used to other develop hardware specific libraries.

Fork of ThingerClient by Alvaro Luis Bustamante

Committer:
alvarolb
Date:
Sat Dec 26 13:18:01 2015 +0000
Revision:
4:de51256455f7
Parent:
0:b75d784c7c1a
Adapter pson to properly work in ARM Mbed old compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
alvarolb 4:de51256455f7 1 // The MIT License (MIT)
alvarolb 4:de51256455f7 2 //
alvarolb 4:de51256455f7 3 // Copyright (c) 2015 THINGER LTD
alvarolb 4:de51256455f7 4 // Author: alvarolb@gmail.com (Alvaro Luis Bustamante)
alvarolb 4:de51256455f7 5 //
alvarolb 4:de51256455f7 6 // Permission is hereby granted, free of charge, to any person obtaining a copy
alvarolb 4:de51256455f7 7 // of this software and associated documentation files (the "Software"), to deal
alvarolb 4:de51256455f7 8 // in the Software without restriction, including without limitation the rights
alvarolb 4:de51256455f7 9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
alvarolb 4:de51256455f7 10 // copies of the Software, and to permit persons to whom the Software is
alvarolb 4:de51256455f7 11 // furnished to do so, subject to the following conditions:
alvarolb 4:de51256455f7 12 //
alvarolb 4:de51256455f7 13 // The above copyright notice and this permission notice shall be included in
alvarolb 4:de51256455f7 14 // all copies or substantial portions of the Software.
alvarolb 4:de51256455f7 15 //
alvarolb 4:de51256455f7 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
alvarolb 4:de51256455f7 17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
alvarolb 4:de51256455f7 18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
alvarolb 4:de51256455f7 19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
alvarolb 4:de51256455f7 20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
alvarolb 4:de51256455f7 21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
alvarolb 4:de51256455f7 22 // THE SOFTWARE.
alvarolb 4:de51256455f7 23
alvarolb 4:de51256455f7 24 #ifndef PSON_HPP
alvarolb 4:de51256455f7 25 #define PSON_HPP
alvarolb 4:de51256455f7 26
alvarolb 4:de51256455f7 27 #include <stdint.h>
alvarolb 4:de51256455f7 28 #include <string.h>
alvarolb 4:de51256455f7 29 #include <math.h>
alvarolb 4:de51256455f7 30 #include <stdlib.h>
alvarolb 4:de51256455f7 31
alvarolb 4:de51256455f7 32 namespace protoson {
alvarolb 4:de51256455f7 33
alvarolb 4:de51256455f7 34 class memory_allocator{
alvarolb 4:de51256455f7 35 public:
alvarolb 4:de51256455f7 36 virtual void *allocate(size_t size) = 0;
alvarolb 4:de51256455f7 37 virtual void deallocate(void *) = 0;
alvarolb 4:de51256455f7 38 };
alvarolb 4:de51256455f7 39
alvarolb 4:de51256455f7 40 template<size_t buffer_size>
alvarolb 4:de51256455f7 41 class circular_memory_allocator : public memory_allocator{
alvarolb 4:de51256455f7 42 private:
alvarolb 4:de51256455f7 43 uint8_t buffer_[buffer_size];
alvarolb 4:de51256455f7 44 size_t index_;
alvarolb 4:de51256455f7 45 public:
alvarolb 4:de51256455f7 46 circular_memory_allocator() : index_(0) {
alvarolb 4:de51256455f7 47 }
alvarolb 4:de51256455f7 48
alvarolb 4:de51256455f7 49 virtual void *allocate(size_t size) {
alvarolb 4:de51256455f7 50 if (index_ + size > buffer_size) {
alvarolb 4:de51256455f7 51 index_ = 0;
alvarolb 4:de51256455f7 52 }
alvarolb 4:de51256455f7 53 void *position = &buffer_[index_];
alvarolb 4:de51256455f7 54 index_ += size;
alvarolb 4:de51256455f7 55 return position;
alvarolb 4:de51256455f7 56 }
alvarolb 4:de51256455f7 57
alvarolb 4:de51256455f7 58 virtual void deallocate(void *) {
alvarolb 4:de51256455f7 59
alvarolb 4:de51256455f7 60 }
alvarolb 4:de51256455f7 61 };
alvarolb 4:de51256455f7 62
alvarolb 4:de51256455f7 63 class dynamic_memory_allocator : public memory_allocator{
alvarolb 4:de51256455f7 64 public:
alvarolb 4:de51256455f7 65 virtual void *allocate(size_t size) {
alvarolb 4:de51256455f7 66 return malloc(size);
alvarolb 4:de51256455f7 67 }
alvarolb 4:de51256455f7 68
alvarolb 4:de51256455f7 69 virtual void deallocate(void *ptr) {
alvarolb 4:de51256455f7 70 free(ptr);
alvarolb 4:de51256455f7 71 }
alvarolb 4:de51256455f7 72 };
alvarolb 4:de51256455f7 73
alvarolb 4:de51256455f7 74 extern memory_allocator& pool;
alvarolb 4:de51256455f7 75 }
alvarolb 4:de51256455f7 76
alvarolb 4:de51256455f7 77 inline void* operator new(size_t sz, protoson::memory_allocator& a)
alvarolb 4:de51256455f7 78 {
alvarolb 4:de51256455f7 79 return a.allocate(sz);
alvarolb 4:de51256455f7 80 }
alvarolb 4:de51256455f7 81
alvarolb 4:de51256455f7 82 inline void operator delete(void* p, protoson::memory_allocator& a)
alvarolb 4:de51256455f7 83 {
alvarolb 4:de51256455f7 84 a.deallocate(p);
alvarolb 4:de51256455f7 85 }
alvarolb 4:de51256455f7 86
alvarolb 4:de51256455f7 87 template<class T>
alvarolb 4:de51256455f7 88 void destroy(T* p, protoson::memory_allocator& a)
alvarolb 4:de51256455f7 89 {
alvarolb 4:de51256455f7 90 if (p) {
alvarolb 4:de51256455f7 91 p->~T();
alvarolb 4:de51256455f7 92 a.deallocate(p);
alvarolb 4:de51256455f7 93 }
alvarolb 4:de51256455f7 94 }
alvarolb 4:de51256455f7 95
alvarolb 4:de51256455f7 96 namespace protoson {
alvarolb 4:de51256455f7 97
alvarolb 4:de51256455f7 98 enum pb_wire_type{
alvarolb 4:de51256455f7 99 varint = 0,
alvarolb 4:de51256455f7 100 fixed_64 = 1,
alvarolb 4:de51256455f7 101 length_delimited = 2,
alvarolb 4:de51256455f7 102 fixed_32 = 5,
alvarolb 4:de51256455f7 103 pson_type = 6
alvarolb 4:de51256455f7 104 };
alvarolb 4:de51256455f7 105
alvarolb 4:de51256455f7 106 template<class T>
alvarolb 4:de51256455f7 107 class pson_container {
alvarolb 4:de51256455f7 108
alvarolb 4:de51256455f7 109 struct list_item{
alvarolb 4:de51256455f7 110 T item_;
alvarolb 4:de51256455f7 111 list_item* next_;
alvarolb 4:de51256455f7 112 };
alvarolb 4:de51256455f7 113
alvarolb 4:de51256455f7 114 public:
alvarolb 4:de51256455f7 115
alvarolb 4:de51256455f7 116 class iterator{
alvarolb 4:de51256455f7 117 public:
alvarolb 4:de51256455f7 118 iterator(list_item *current) : current(current) {
alvarolb 4:de51256455f7 119 }
alvarolb 4:de51256455f7 120
alvarolb 4:de51256455f7 121 private:
alvarolb 4:de51256455f7 122 list_item * current;
alvarolb 4:de51256455f7 123
alvarolb 4:de51256455f7 124 public:
alvarolb 4:de51256455f7 125 bool next(){
alvarolb 4:de51256455f7 126 if(current==NULL) return false;
alvarolb 4:de51256455f7 127 current = current->next_;
alvarolb 4:de51256455f7 128 return true;
alvarolb 4:de51256455f7 129 }
alvarolb 4:de51256455f7 130
alvarolb 4:de51256455f7 131 bool has_next(){
alvarolb 4:de51256455f7 132 return current!=NULL && current->next_!=NULL;
alvarolb 4:de51256455f7 133 }
alvarolb 4:de51256455f7 134
alvarolb 4:de51256455f7 135 bool valid(){
alvarolb 4:de51256455f7 136 return current!=NULL;
alvarolb 4:de51256455f7 137 }
alvarolb 4:de51256455f7 138
alvarolb 4:de51256455f7 139 T& item(){
alvarolb 4:de51256455f7 140 return current->item_;
alvarolb 4:de51256455f7 141 }
alvarolb 4:de51256455f7 142 };
alvarolb 4:de51256455f7 143
alvarolb 4:de51256455f7 144 private:
alvarolb 4:de51256455f7 145 list_item* item_;
alvarolb 4:de51256455f7 146
alvarolb 4:de51256455f7 147 public:
alvarolb 4:de51256455f7 148 iterator begin() const{
alvarolb 4:de51256455f7 149 return iterator(item_);
alvarolb 4:de51256455f7 150 }
alvarolb 4:de51256455f7 151
alvarolb 4:de51256455f7 152 pson_container() : item_(NULL) {
alvarolb 4:de51256455f7 153 }
alvarolb 4:de51256455f7 154
alvarolb 4:de51256455f7 155 ~pson_container(){
alvarolb 4:de51256455f7 156 clear();
alvarolb 4:de51256455f7 157 }
alvarolb 4:de51256455f7 158
alvarolb 4:de51256455f7 159 size_t size() const{
alvarolb 4:de51256455f7 160 size_t size = 0;
alvarolb 4:de51256455f7 161 list_item* current = item_;
alvarolb 4:de51256455f7 162 while(current!=NULL){
alvarolb 4:de51256455f7 163 current = current->next_;
alvarolb 4:de51256455f7 164 size++;
alvarolb 4:de51256455f7 165 }
alvarolb 4:de51256455f7 166 return size;
alvarolb 4:de51256455f7 167 }
alvarolb 4:de51256455f7 168
alvarolb 4:de51256455f7 169 T* operator[](size_t index){
alvarolb 4:de51256455f7 170 list_item* current = item_;
alvarolb 4:de51256455f7 171 size_t current_index = 0;
alvarolb 4:de51256455f7 172 while(current!=NULL){
alvarolb 4:de51256455f7 173 if(current_index==index){
alvarolb 4:de51256455f7 174 return &current->item_;
alvarolb 4:de51256455f7 175 }
alvarolb 4:de51256455f7 176 current = current->next_;
alvarolb 4:de51256455f7 177 current_index++;
alvarolb 4:de51256455f7 178 }
alvarolb 4:de51256455f7 179 return NULL;
alvarolb 4:de51256455f7 180 }
alvarolb 4:de51256455f7 181
alvarolb 4:de51256455f7 182 void clear(){
alvarolb 4:de51256455f7 183 list_item* current = item_;
alvarolb 4:de51256455f7 184 while(current!=NULL){
alvarolb 4:de51256455f7 185 list_item* next = current->next_;
alvarolb 4:de51256455f7 186 destroy(current, pool);
alvarolb 4:de51256455f7 187 current = next;
alvarolb 4:de51256455f7 188 }
alvarolb 4:de51256455f7 189 item_ = NULL;
alvarolb 4:de51256455f7 190 }
alvarolb 4:de51256455f7 191
alvarolb 4:de51256455f7 192 T& create_item(){
alvarolb 4:de51256455f7 193 list_item* new_list_item = new(pool) list_item();
alvarolb 4:de51256455f7 194 if(item_==NULL){
alvarolb 4:de51256455f7 195 item_ = new_list_item;
alvarolb 4:de51256455f7 196 }
alvarolb 4:de51256455f7 197 else{
alvarolb 4:de51256455f7 198 list_item * last = item_;
alvarolb 4:de51256455f7 199 while(last->next_!=NULL) last = last->next_;
alvarolb 4:de51256455f7 200 last->next_ = new_list_item;
alvarolb 4:de51256455f7 201 }
alvarolb 4:de51256455f7 202 return new_list_item->item_;
alvarolb 4:de51256455f7 203 }
alvarolb 4:de51256455f7 204 };
alvarolb 4:de51256455f7 205
alvarolb 4:de51256455f7 206 class pson_object;
alvarolb 4:de51256455f7 207 class pson_array;
alvarolb 4:de51256455f7 208
alvarolb 4:de51256455f7 209 class pson {
alvarolb 4:de51256455f7 210 public:
alvarolb 4:de51256455f7 211 enum field_type {
alvarolb 4:de51256455f7 212 null_field = 0,
alvarolb 4:de51256455f7 213 varint_field = 1,
alvarolb 4:de51256455f7 214 svarint_field = 2,
alvarolb 4:de51256455f7 215 float_field = 3,
alvarolb 4:de51256455f7 216 double_field = 4,
alvarolb 4:de51256455f7 217 true_field = 5,
alvarolb 4:de51256455f7 218 false_field = 6,
alvarolb 4:de51256455f7 219 zero_field = 7,
alvarolb 4:de51256455f7 220 one_field = 8,
alvarolb 4:de51256455f7 221 string_field = 9,
alvarolb 4:de51256455f7 222 empty_string = 10,
alvarolb 4:de51256455f7 223 bytes_field = 11,
alvarolb 4:de51256455f7 224 empty_bytes = 12,
alvarolb 4:de51256455f7 225 object_field = 13,
alvarolb 4:de51256455f7 226 array_field = 14,
alvarolb 4:de51256455f7 227 empty = 15,
alvarolb 4:de51256455f7 228 // a message tag is encoded in a 128-base varint [1-bit][3-bit wire type][4-bit field]
alvarolb 4:de51256455f7 229 // we have up to 4 bits (0-15) for encoding fields in the first byte
alvarolb 4:de51256455f7 230 };
alvarolb 4:de51256455f7 231
alvarolb 4:de51256455f7 232 bool is_boolean() const{
alvarolb 4:de51256455f7 233 return field_type_ == true_field || field_type_ == false_field;
alvarolb 4:de51256455f7 234 }
alvarolb 4:de51256455f7 235
alvarolb 4:de51256455f7 236 bool is_string() const{
alvarolb 4:de51256455f7 237 return field_type_ == string_field;
alvarolb 4:de51256455f7 238 }
alvarolb 4:de51256455f7 239
alvarolb 4:de51256455f7 240 bool is_bytes() const{
alvarolb 4:de51256455f7 241 return field_type_ == bytes_field;
alvarolb 4:de51256455f7 242 }
alvarolb 4:de51256455f7 243
alvarolb 4:de51256455f7 244 bool is_number() const{
alvarolb 4:de51256455f7 245 return field_type_ == varint_field ||
alvarolb 4:de51256455f7 246 field_type_ == svarint_field ||
alvarolb 4:de51256455f7 247 field_type_ == float_field ||
alvarolb 4:de51256455f7 248 field_type_ == double_field ||
alvarolb 4:de51256455f7 249 field_type_ == zero_field ||
alvarolb 4:de51256455f7 250 field_type_ == one_field;
alvarolb 4:de51256455f7 251 }
alvarolb 4:de51256455f7 252
alvarolb 4:de51256455f7 253 bool is_object() const{
alvarolb 4:de51256455f7 254 return field_type_ == object_field;
alvarolb 4:de51256455f7 255 }
alvarolb 4:de51256455f7 256
alvarolb 4:de51256455f7 257 bool is_array() const{
alvarolb 4:de51256455f7 258 return field_type_ == array_field;
alvarolb 4:de51256455f7 259 }
alvarolb 4:de51256455f7 260
alvarolb 4:de51256455f7 261 bool is_null() const{
alvarolb 4:de51256455f7 262 return field_type_ == null_field;
alvarolb 4:de51256455f7 263 }
alvarolb 4:de51256455f7 264
alvarolb 4:de51256455f7 265 bool is_empty() const{
alvarolb 4:de51256455f7 266 return field_type_ == empty;
alvarolb 4:de51256455f7 267 }
alvarolb 4:de51256455f7 268
alvarolb 4:de51256455f7 269 pson() : value_(NULL), field_type_(empty) {
alvarolb 4:de51256455f7 270 }
alvarolb 4:de51256455f7 271
alvarolb 4:de51256455f7 272 template<class T>
alvarolb 4:de51256455f7 273 pson(T value) : value_(NULL), field_type_(empty){
alvarolb 4:de51256455f7 274 *this = value;
alvarolb 4:de51256455f7 275 }
alvarolb 4:de51256455f7 276
alvarolb 4:de51256455f7 277 ~pson(){
alvarolb 4:de51256455f7 278 if(field_type_==object_field){
alvarolb 4:de51256455f7 279 destroy((pson_object *) value_, pool);
alvarolb 4:de51256455f7 280 }else if(field_type_==array_field) {
alvarolb 4:de51256455f7 281 destroy((pson_array *) value_, pool);
alvarolb 4:de51256455f7 282 }else{
alvarolb 4:de51256455f7 283 pool.deallocate(value_);
alvarolb 4:de51256455f7 284 }
alvarolb 4:de51256455f7 285 }
alvarolb 4:de51256455f7 286
alvarolb 4:de51256455f7 287 template<class T>
alvarolb 4:de51256455f7 288 void operator=(T value)
alvarolb 4:de51256455f7 289 {
alvarolb 4:de51256455f7 290 if(value==0){
alvarolb 4:de51256455f7 291 field_type_ = zero_field;
alvarolb 4:de51256455f7 292 }else if(value==1) {
alvarolb 4:de51256455f7 293 field_type_ = one_field;
alvarolb 4:de51256455f7 294 }else{
alvarolb 4:de51256455f7 295 field_type_ = value>0 ? varint_field : svarint_field;
alvarolb 4:de51256455f7 296 uint64_t uint_value = value>0 ? value : -value;
alvarolb 4:de51256455f7 297 value_ = pool.allocate(pson::get_varint_size(uint_value));
alvarolb 4:de51256455f7 298 pb_encode_varint(uint_value);
alvarolb 4:de51256455f7 299 }
alvarolb 4:de51256455f7 300 }
alvarolb 4:de51256455f7 301
alvarolb 4:de51256455f7 302 void operator=(bool value){
alvarolb 4:de51256455f7 303 field_type_ = value ? true_field : false_field;
alvarolb 4:de51256455f7 304 }
alvarolb 4:de51256455f7 305
alvarolb 4:de51256455f7 306 void operator=(float value) {
alvarolb 4:de51256455f7 307 if(value==(int32_t)value){
alvarolb 4:de51256455f7 308 *this = (int32_t) value;
alvarolb 4:de51256455f7 309 }else{
alvarolb 4:de51256455f7 310 field_type_ = float_field;
alvarolb 4:de51256455f7 311 set(value);
alvarolb 4:de51256455f7 312 }
alvarolb 4:de51256455f7 313 }
alvarolb 4:de51256455f7 314
alvarolb 4:de51256455f7 315 void operator=(double value) {
alvarolb 4:de51256455f7 316 if(value==(int64_t)value) {
alvarolb 4:de51256455f7 317 *this = (int64_t) value;
alvarolb 4:de51256455f7 318 }else if(fabs(value-(float)value)<=0.00001){
alvarolb 4:de51256455f7 319 field_type_ = float_field;
alvarolb 4:de51256455f7 320 set((float)value);
alvarolb 4:de51256455f7 321 }else{
alvarolb 4:de51256455f7 322 field_type_ = double_field;
alvarolb 4:de51256455f7 323 set(value);
alvarolb 4:de51256455f7 324 }
alvarolb 4:de51256455f7 325 }
alvarolb 4:de51256455f7 326
alvarolb 4:de51256455f7 327 void operator=(const char *str) {
alvarolb 4:de51256455f7 328 size_t str_size = strlen(str);
alvarolb 4:de51256455f7 329 if(str_size==0){
alvarolb 4:de51256455f7 330 field_type_ = empty_string;
alvarolb 4:de51256455f7 331 }else{
alvarolb 4:de51256455f7 332 field_type_ = string_field;
alvarolb 4:de51256455f7 333 memcpy(allocate(str_size+1), str, str_size+1);
alvarolb 4:de51256455f7 334 }
alvarolb 4:de51256455f7 335 }
alvarolb 4:de51256455f7 336
alvarolb 4:de51256455f7 337 void set_bytes(const void* bytes, size_t size) {
alvarolb 4:de51256455f7 338 if(size>0){
alvarolb 4:de51256455f7 339 size_t varint_size = get_varint_size(size);
alvarolb 4:de51256455f7 340 value_ = pool.allocate(varint_size+size);
alvarolb 4:de51256455f7 341 pb_encode_varint(size);
alvarolb 4:de51256455f7 342 memcpy(((uint8_t*)value_)+varint_size, bytes, size);
alvarolb 4:de51256455f7 343 field_type_ = bytes_field;
alvarolb 4:de51256455f7 344 }else{
alvarolb 4:de51256455f7 345 field_type_ = empty_bytes;
alvarolb 4:de51256455f7 346 }
alvarolb 4:de51256455f7 347 }
alvarolb 4:de51256455f7 348
alvarolb 4:de51256455f7 349 bool get_bytes(const void*& bytes, size_t& size){
alvarolb 4:de51256455f7 350 switch(field_type_){
alvarolb 4:de51256455f7 351 case bytes_field:
alvarolb 4:de51256455f7 352 size = pb_decode_varint();
alvarolb 4:de51256455f7 353 bytes = (uint8_t*) value_ + get_varint_size(size);
alvarolb 4:de51256455f7 354 return true;
alvarolb 4:de51256455f7 355 case empty:
alvarolb 4:de51256455f7 356 field_type_ = empty_bytes;
alvarolb 4:de51256455f7 357 default:
alvarolb 4:de51256455f7 358 return false;
alvarolb 4:de51256455f7 359 }
alvarolb 4:de51256455f7 360 }
alvarolb 4:de51256455f7 361
alvarolb 4:de51256455f7 362 void* allocate(size_t size){
alvarolb 4:de51256455f7 363 value_ = pool.allocate(size);
alvarolb 4:de51256455f7 364 return value_;
alvarolb 4:de51256455f7 365 }
alvarolb 4:de51256455f7 366
alvarolb 4:de51256455f7 367 operator pson_object &();
alvarolb 4:de51256455f7 368 operator pson_array &();
alvarolb 4:de51256455f7 369 pson & operator[](const char *name);
alvarolb 4:de51256455f7 370
alvarolb 4:de51256455f7 371 operator const char *() {
alvarolb 4:de51256455f7 372 switch(field_type_){
alvarolb 4:de51256455f7 373 case string_field:
alvarolb 4:de51256455f7 374 return (const char*) value_;
alvarolb 4:de51256455f7 375 case empty:
alvarolb 4:de51256455f7 376 field_type_ = empty_string;
alvarolb 4:de51256455f7 377 default:
alvarolb 4:de51256455f7 378 return "";
alvarolb 4:de51256455f7 379 }
alvarolb 4:de51256455f7 380 }
alvarolb 4:de51256455f7 381
alvarolb 4:de51256455f7 382 operator bool(){
alvarolb 4:de51256455f7 383 switch(field_type_){
alvarolb 4:de51256455f7 384 case zero_field:
alvarolb 4:de51256455f7 385 case false_field:
alvarolb 4:de51256455f7 386 return false;
alvarolb 4:de51256455f7 387 case one_field:
alvarolb 4:de51256455f7 388 case true_field:
alvarolb 4:de51256455f7 389 return true;
alvarolb 4:de51256455f7 390 case empty:
alvarolb 4:de51256455f7 391 field_type_ = false_field;
alvarolb 4:de51256455f7 392 default:
alvarolb 4:de51256455f7 393 return 0;
alvarolb 4:de51256455f7 394 }
alvarolb 4:de51256455f7 395 }
alvarolb 4:de51256455f7 396
alvarolb 4:de51256455f7 397 operator char(){
alvarolb 4:de51256455f7 398 return get_value<char>();
alvarolb 4:de51256455f7 399 }
alvarolb 4:de51256455f7 400
alvarolb 4:de51256455f7 401 operator unsigned char(){
alvarolb 4:de51256455f7 402 return get_value<unsigned char>();
alvarolb 4:de51256455f7 403 }
alvarolb 4:de51256455f7 404
alvarolb 4:de51256455f7 405 operator short(){
alvarolb 4:de51256455f7 406 return get_value<short>();
alvarolb 4:de51256455f7 407 }
alvarolb 4:de51256455f7 408
alvarolb 4:de51256455f7 409 operator unsigned short(){
alvarolb 4:de51256455f7 410 return get_value<unsigned short>();
alvarolb 4:de51256455f7 411 }
alvarolb 4:de51256455f7 412
alvarolb 4:de51256455f7 413 operator int(){
alvarolb 4:de51256455f7 414 return get_value<int>();
alvarolb 4:de51256455f7 415 }
alvarolb 4:de51256455f7 416
alvarolb 4:de51256455f7 417 operator unsigned int(){
alvarolb 4:de51256455f7 418 return get_value<int>();
alvarolb 4:de51256455f7 419 }
alvarolb 4:de51256455f7 420
alvarolb 4:de51256455f7 421 operator long(){
alvarolb 4:de51256455f7 422 return get_value<long>();
alvarolb 4:de51256455f7 423 }
alvarolb 4:de51256455f7 424
alvarolb 4:de51256455f7 425 operator unsigned long(){
alvarolb 4:de51256455f7 426 return get_value<unsigned long>();
alvarolb 4:de51256455f7 427 }
alvarolb 4:de51256455f7 428
alvarolb 4:de51256455f7 429 operator float(){
alvarolb 4:de51256455f7 430 return get_value<float>();
alvarolb 4:de51256455f7 431 }
alvarolb 4:de51256455f7 432
alvarolb 4:de51256455f7 433 operator double(){
alvarolb 4:de51256455f7 434 return get_value<double>();
alvarolb 4:de51256455f7 435 }
alvarolb 4:de51256455f7 436
alvarolb 4:de51256455f7 437 template<class T>
alvarolb 4:de51256455f7 438 operator T() {
alvarolb 4:de51256455f7 439 return get_value<T>();
alvarolb 4:de51256455f7 440 }
alvarolb 4:de51256455f7 441
alvarolb 4:de51256455f7 442 template<class T>
alvarolb 4:de51256455f7 443 T get_value(){
alvarolb 4:de51256455f7 444 switch(field_type_){
alvarolb 4:de51256455f7 445 case one_field:
alvarolb 4:de51256455f7 446 case true_field:
alvarolb 4:de51256455f7 447 return 1;
alvarolb 4:de51256455f7 448 case float_field:
alvarolb 4:de51256455f7 449 return *(float*)value_;
alvarolb 4:de51256455f7 450 case double_field:
alvarolb 4:de51256455f7 451 return *(double*)value_;
alvarolb 4:de51256455f7 452 case varint_field:
alvarolb 4:de51256455f7 453 return pb_decode_varint();
alvarolb 4:de51256455f7 454 case svarint_field:
alvarolb 4:de51256455f7 455 return -pb_decode_varint();
alvarolb 4:de51256455f7 456 case empty:
alvarolb 4:de51256455f7 457 field_type_ = zero_field;
alvarolb 4:de51256455f7 458 default:
alvarolb 4:de51256455f7 459 return 0;
alvarolb 4:de51256455f7 460 }
alvarolb 4:de51256455f7 461 }
alvarolb 4:de51256455f7 462
alvarolb 4:de51256455f7 463 void* get_value(){
alvarolb 4:de51256455f7 464 return value_;
alvarolb 4:de51256455f7 465 }
alvarolb 4:de51256455f7 466
alvarolb 4:de51256455f7 467 void set_value(void* value){
alvarolb 4:de51256455f7 468 value_ = value;
alvarolb 4:de51256455f7 469 }
alvarolb 4:de51256455f7 470
alvarolb 4:de51256455f7 471 field_type get_type() const{
alvarolb 4:de51256455f7 472 return field_type_;
alvarolb 4:de51256455f7 473 }
alvarolb 4:de51256455f7 474
alvarolb 4:de51256455f7 475 void set_null(){
alvarolb 4:de51256455f7 476 field_type_ = null_field;
alvarolb 4:de51256455f7 477 }
alvarolb 4:de51256455f7 478
alvarolb 4:de51256455f7 479 void set_type(field_type type){
alvarolb 4:de51256455f7 480 field_type_ = type;
alvarolb 4:de51256455f7 481 }
alvarolb 4:de51256455f7 482
alvarolb 4:de51256455f7 483 uint8_t get_varint_size(uint64_t value) const{
alvarolb 4:de51256455f7 484 uint8_t size = 1;
alvarolb 4:de51256455f7 485 while(value>>=7) size++;
alvarolb 4:de51256455f7 486 return size;
alvarolb 4:de51256455f7 487 }
alvarolb 4:de51256455f7 488
alvarolb 4:de51256455f7 489 void pb_encode_varint(uint64_t value) const
alvarolb 4:de51256455f7 490 {
alvarolb 4:de51256455f7 491 uint8_t count = 0;
alvarolb 4:de51256455f7 492 do
alvarolb 4:de51256455f7 493 {
alvarolb 4:de51256455f7 494 uint8_t byte = (uint8_t)(value & 0x7F);
alvarolb 4:de51256455f7 495 value >>= 7;
alvarolb 4:de51256455f7 496 if(value) byte |= 0x80;
alvarolb 4:de51256455f7 497 ((uint8_t*)value_)[count] = byte;
alvarolb 4:de51256455f7 498 count++;
alvarolb 4:de51256455f7 499 }while(value);
alvarolb 4:de51256455f7 500 }
alvarolb 4:de51256455f7 501
alvarolb 4:de51256455f7 502 uint64_t pb_decode_varint() const
alvarolb 4:de51256455f7 503 {
alvarolb 4:de51256455f7 504 if(value_==NULL) return 0;
alvarolb 4:de51256455f7 505 uint64_t value = 0;
alvarolb 4:de51256455f7 506 uint8_t pos = 0;
alvarolb 4:de51256455f7 507 uint8_t byte = 0;
alvarolb 4:de51256455f7 508 do{
alvarolb 4:de51256455f7 509 byte = ((uint8_t*)value_)[pos];
alvarolb 4:de51256455f7 510 value |= (uint64_t)(byte&0x7F) << pos*7;
alvarolb 4:de51256455f7 511 pos++;
alvarolb 4:de51256455f7 512 }while(byte>=0x80);
alvarolb 4:de51256455f7 513 return value;
alvarolb 4:de51256455f7 514 }
alvarolb 4:de51256455f7 515
alvarolb 4:de51256455f7 516 private:
alvarolb 4:de51256455f7 517 void* value_;
alvarolb 4:de51256455f7 518 field_type field_type_;
alvarolb 4:de51256455f7 519
alvarolb 4:de51256455f7 520 template<class T>
alvarolb 4:de51256455f7 521 void set(T value) {
alvarolb 4:de51256455f7 522 memcpy(allocate(sizeof(T)), &value, sizeof(T));
alvarolb 4:de51256455f7 523 }
alvarolb 4:de51256455f7 524 };
alvarolb 4:de51256455f7 525
alvarolb 4:de51256455f7 526 class pson_pair{
alvarolb 4:de51256455f7 527 private:
alvarolb 4:de51256455f7 528 char* name_;
alvarolb 4:de51256455f7 529 pson value_;
alvarolb 4:de51256455f7 530 public:
alvarolb 4:de51256455f7 531 pson_pair() : name_(NULL){
alvarolb 4:de51256455f7 532 }
alvarolb 4:de51256455f7 533
alvarolb 4:de51256455f7 534 ~pson_pair(){
alvarolb 4:de51256455f7 535 destroy(name_, pool);
alvarolb 4:de51256455f7 536 }
alvarolb 4:de51256455f7 537
alvarolb 4:de51256455f7 538 void set_name(const char *name) {
alvarolb 4:de51256455f7 539 size_t name_size = strlen(name) + 1;
alvarolb 4:de51256455f7 540 memcpy(allocate_name(name_size), name, name_size);
alvarolb 4:de51256455f7 541 }
alvarolb 4:de51256455f7 542
alvarolb 4:de51256455f7 543 char* allocate_name(size_t size){
alvarolb 4:de51256455f7 544 name_ = (char*)pool.allocate(size);
alvarolb 4:de51256455f7 545 return name_;
alvarolb 4:de51256455f7 546 }
alvarolb 4:de51256455f7 547
alvarolb 4:de51256455f7 548 pson& value(){
alvarolb 4:de51256455f7 549 return value_;
alvarolb 4:de51256455f7 550 }
alvarolb 4:de51256455f7 551
alvarolb 4:de51256455f7 552 char* name() const{
alvarolb 4:de51256455f7 553 return name_;
alvarolb 4:de51256455f7 554 }
alvarolb 4:de51256455f7 555 };
alvarolb 4:de51256455f7 556
alvarolb 4:de51256455f7 557 class pson_object : public pson_container<pson_pair> {
alvarolb 4:de51256455f7 558 public:
alvarolb 4:de51256455f7 559 pson &operator[](const char *name) {
alvarolb 4:de51256455f7 560 for(iterator it=begin(); it.valid(); it.next()){
alvarolb 4:de51256455f7 561 if(strcmp(it.item().name(), name)==0){
alvarolb 4:de51256455f7 562 return it.item().value();
alvarolb 4:de51256455f7 563 }
alvarolb 4:de51256455f7 564 }
alvarolb 4:de51256455f7 565 pson_pair & pair = create_item();
alvarolb 4:de51256455f7 566 pair.set_name(name);
alvarolb 4:de51256455f7 567 return pair.value();
alvarolb 4:de51256455f7 568 };
alvarolb 4:de51256455f7 569 };
alvarolb 4:de51256455f7 570
alvarolb 4:de51256455f7 571 class pson_array : public pson_container<pson> {
alvarolb 4:de51256455f7 572 public:
alvarolb 4:de51256455f7 573 template<class T>
alvarolb 4:de51256455f7 574 pson_array& add(T item_value){
alvarolb 4:de51256455f7 575 create_item() = item_value;
alvarolb 4:de51256455f7 576 return *this;
alvarolb 4:de51256455f7 577 }
alvarolb 4:de51256455f7 578 };
alvarolb 4:de51256455f7 579
alvarolb 4:de51256455f7 580 inline pson::operator pson_object &() {
alvarolb 4:de51256455f7 581 if (field_type_ != object_field) {
alvarolb 4:de51256455f7 582 value_ = new(pool) pson_object;
alvarolb 4:de51256455f7 583 field_type_ = object_field;
alvarolb 4:de51256455f7 584 }
alvarolb 4:de51256455f7 585 return *((pson_object *)value_);
alvarolb 4:de51256455f7 586 }
alvarolb 4:de51256455f7 587
alvarolb 4:de51256455f7 588 inline pson::operator pson_array &() {
alvarolb 4:de51256455f7 589 if (field_type_ != array_field) {
alvarolb 4:de51256455f7 590 value_ = new(pool) pson_array;
alvarolb 4:de51256455f7 591 field_type_ = array_field;
alvarolb 4:de51256455f7 592 }
alvarolb 4:de51256455f7 593 return *((pson_array *)value_);
alvarolb 4:de51256455f7 594 }
alvarolb 4:de51256455f7 595
alvarolb 4:de51256455f7 596 inline pson &pson::operator[](const char *name) {
alvarolb 4:de51256455f7 597 return ((pson_object &) *this)[name];
alvarolb 4:de51256455f7 598 }
alvarolb 4:de51256455f7 599
alvarolb 4:de51256455f7 600 ////////////////////////////
alvarolb 4:de51256455f7 601 /////// PSON_DECODER ///////
alvarolb 4:de51256455f7 602 ////////////////////////////
alvarolb 4:de51256455f7 603
alvarolb 4:de51256455f7 604 class pson_decoder {
alvarolb 4:de51256455f7 605
alvarolb 4:de51256455f7 606 protected:
alvarolb 4:de51256455f7 607 size_t read_;
alvarolb 4:de51256455f7 608
alvarolb 4:de51256455f7 609 virtual bool read(void* buffer, size_t size){
alvarolb 4:de51256455f7 610 read_+=size;
alvarolb 4:de51256455f7 611 return true;
alvarolb 4:de51256455f7 612 }
alvarolb 4:de51256455f7 613
alvarolb 4:de51256455f7 614 public:
alvarolb 4:de51256455f7 615
alvarolb 4:de51256455f7 616 pson_decoder() : read_(0) {
alvarolb 4:de51256455f7 617
alvarolb 4:de51256455f7 618 }
alvarolb 4:de51256455f7 619
alvarolb 4:de51256455f7 620 void reset(){
alvarolb 4:de51256455f7 621 read_ = 0;
alvarolb 4:de51256455f7 622 }
alvarolb 4:de51256455f7 623
alvarolb 4:de51256455f7 624 size_t bytes_read(){
alvarolb 4:de51256455f7 625 return read_;
alvarolb 4:de51256455f7 626 }
alvarolb 4:de51256455f7 627
alvarolb 4:de51256455f7 628 bool pb_decode_tag(pb_wire_type& wire_type, uint32_t& field_number)
alvarolb 4:de51256455f7 629 {
alvarolb 4:de51256455f7 630 uint32_t temp = pb_decode_varint32();
alvarolb 4:de51256455f7 631 wire_type = (pb_wire_type)(temp & 0x07);
alvarolb 4:de51256455f7 632 field_number = temp >> 3;
alvarolb 4:de51256455f7 633 return true;
alvarolb 4:de51256455f7 634 }
alvarolb 4:de51256455f7 635
alvarolb 4:de51256455f7 636 uint32_t pb_decode_varint32()
alvarolb 4:de51256455f7 637 {
alvarolb 4:de51256455f7 638 uint32_t varint = 0;
alvarolb 4:de51256455f7 639 if(try_pb_decode_varint32(varint)){
alvarolb 4:de51256455f7 640 return varint;
alvarolb 4:de51256455f7 641 }
alvarolb 4:de51256455f7 642 return 0;
alvarolb 4:de51256455f7 643 }
alvarolb 4:de51256455f7 644
alvarolb 4:de51256455f7 645 bool try_pb_decode_varint32(uint32_t& varint){
alvarolb 4:de51256455f7 646 varint = 0;
alvarolb 4:de51256455f7 647 uint8_t byte;
alvarolb 4:de51256455f7 648 uint8_t bit_pos = 0;
alvarolb 4:de51256455f7 649 do{
alvarolb 4:de51256455f7 650 if(!read(&byte, 1) || bit_pos>=32){
alvarolb 4:de51256455f7 651 return false;
alvarolb 4:de51256455f7 652 }
alvarolb 4:de51256455f7 653 varint |= (uint32_t)(byte&0x7F) << bit_pos;
alvarolb 4:de51256455f7 654 bit_pos += 7;
alvarolb 4:de51256455f7 655 }while(byte>=0x80);
alvarolb 4:de51256455f7 656 return true;
alvarolb 4:de51256455f7 657 }
alvarolb 4:de51256455f7 658
alvarolb 4:de51256455f7 659 uint64_t pb_decode_varint64()
alvarolb 4:de51256455f7 660 {
alvarolb 4:de51256455f7 661 uint64_t varint = 0;
alvarolb 4:de51256455f7 662 uint8_t byte;
alvarolb 4:de51256455f7 663 uint8_t bit_pos = 0;
alvarolb 4:de51256455f7 664 do{
alvarolb 4:de51256455f7 665 if(!read(&byte, 1) || bit_pos>=64){
alvarolb 4:de51256455f7 666 return varint;
alvarolb 4:de51256455f7 667 }
alvarolb 4:de51256455f7 668 varint |= (uint32_t)(byte&0x7F) << bit_pos;
alvarolb 4:de51256455f7 669 bit_pos += 7;
alvarolb 4:de51256455f7 670 }while(byte>=0x80);
alvarolb 4:de51256455f7 671 return varint;
alvarolb 4:de51256455f7 672 }
alvarolb 4:de51256455f7 673
alvarolb 4:de51256455f7 674 bool pb_skip(size_t size){
alvarolb 4:de51256455f7 675 uint8_t byte;
alvarolb 4:de51256455f7 676 bool success = true;
alvarolb 4:de51256455f7 677 for(size_t i=0; i<size; i++){
alvarolb 4:de51256455f7 678 success &= read(&byte, 1);
alvarolb 4:de51256455f7 679 }
alvarolb 4:de51256455f7 680 return success;
alvarolb 4:de51256455f7 681 }
alvarolb 4:de51256455f7 682
alvarolb 4:de51256455f7 683 bool pb_skip_varint(){
alvarolb 4:de51256455f7 684 uint8_t byte;
alvarolb 4:de51256455f7 685 bool success = true;
alvarolb 4:de51256455f7 686 do{
alvarolb 4:de51256455f7 687 success &= read(&byte, 1);
alvarolb 4:de51256455f7 688 }while(byte>0x80);
alvarolb 4:de51256455f7 689 return success;
alvarolb 4:de51256455f7 690 }
alvarolb 4:de51256455f7 691
alvarolb 4:de51256455f7 692 bool pb_read_string(char *str, size_t size){
alvarolb 4:de51256455f7 693 bool success = read(str, size);
alvarolb 4:de51256455f7 694 str[size]=0;
alvarolb 4:de51256455f7 695 return success;
alvarolb 4:de51256455f7 696 }
alvarolb 4:de51256455f7 697
alvarolb 4:de51256455f7 698 bool pb_read_varint(pson& value)
alvarolb 4:de51256455f7 699 {
alvarolb 4:de51256455f7 700 uint8_t temp[10];
alvarolb 4:de51256455f7 701 uint8_t byte=0;
alvarolb 4:de51256455f7 702 uint8_t bytes_read=0;
alvarolb 4:de51256455f7 703 do{
alvarolb 4:de51256455f7 704 if(!read(&byte, 1)) return false;
alvarolb 4:de51256455f7 705 temp[bytes_read] = byte;
alvarolb 4:de51256455f7 706 bytes_read++;
alvarolb 4:de51256455f7 707 }while(byte>=0x80);
alvarolb 4:de51256455f7 708 memcpy(value.allocate(bytes_read), temp, bytes_read);
alvarolb 4:de51256455f7 709 return true;
alvarolb 4:de51256455f7 710 }
alvarolb 4:de51256455f7 711
alvarolb 4:de51256455f7 712 public:
alvarolb 4:de51256455f7 713
alvarolb 4:de51256455f7 714 void decode(pson_object & object, size_t size){
alvarolb 4:de51256455f7 715 size_t start_read = bytes_read();
alvarolb 4:de51256455f7 716 while(size-(bytes_read()-start_read)>0){
alvarolb 4:de51256455f7 717 decode(object.create_item());
alvarolb 4:de51256455f7 718 }
alvarolb 4:de51256455f7 719 }
alvarolb 4:de51256455f7 720
alvarolb 4:de51256455f7 721 void decode(pson_array & array, size_t size){
alvarolb 4:de51256455f7 722 size_t start_read = bytes_read();
alvarolb 4:de51256455f7 723 while(size-(bytes_read()-start_read)>0){
alvarolb 4:de51256455f7 724 decode(array.create_item());
alvarolb 4:de51256455f7 725 }
alvarolb 4:de51256455f7 726 }
alvarolb 4:de51256455f7 727
alvarolb 4:de51256455f7 728 void decode(pson_pair & pair){
alvarolb 4:de51256455f7 729 uint32_t name_size = pb_decode_varint32();
alvarolb 4:de51256455f7 730 pb_read_string(pair.allocate_name(name_size+1), name_size);
alvarolb 4:de51256455f7 731 decode(pair.value());
alvarolb 4:de51256455f7 732 }
alvarolb 4:de51256455f7 733
alvarolb 4:de51256455f7 734 void decode(pson& value) {
alvarolb 4:de51256455f7 735 uint32_t field_number;
alvarolb 4:de51256455f7 736 pb_wire_type wire_type;
alvarolb 4:de51256455f7 737 pb_decode_tag(wire_type, field_number);
alvarolb 4:de51256455f7 738 value.set_type((pson::field_type)field_number);
alvarolb 4:de51256455f7 739 if(wire_type==length_delimited){
alvarolb 4:de51256455f7 740 uint32_t size = pb_decode_varint32();
alvarolb 4:de51256455f7 741 switch(field_number){
alvarolb 4:de51256455f7 742 case pson::string_field:
alvarolb 4:de51256455f7 743 pb_read_string((char*)value.allocate(size + 1), size);
alvarolb 4:de51256455f7 744 break;
alvarolb 4:de51256455f7 745 case pson::bytes_field: {
alvarolb 4:de51256455f7 746 uint8_t varint_size = value.get_varint_size(size);
alvarolb 4:de51256455f7 747 read((char*)value.allocate(size + varint_size) + varint_size, size);
alvarolb 4:de51256455f7 748 value.pb_encode_varint(size);
alvarolb 4:de51256455f7 749 }
alvarolb 4:de51256455f7 750 break;
alvarolb 4:de51256455f7 751 case pson::object_field:
alvarolb 4:de51256455f7 752 value.set_value(new (pool) pson_object);
alvarolb 4:de51256455f7 753 decode(*(pson_object *)value.get_value(), size);
alvarolb 4:de51256455f7 754 break;
alvarolb 4:de51256455f7 755 case pson::array_field:
alvarolb 4:de51256455f7 756 value.set_value(new (pool) pson_array);
alvarolb 4:de51256455f7 757 decode(*(pson_array *)value.get_value(), size);
alvarolb 4:de51256455f7 758 break;
alvarolb 4:de51256455f7 759 default:
alvarolb 4:de51256455f7 760 pb_skip(size);
alvarolb 4:de51256455f7 761 break;
alvarolb 4:de51256455f7 762 }
alvarolb 4:de51256455f7 763 }else {
alvarolb 4:de51256455f7 764 switch (field_number) {
alvarolb 4:de51256455f7 765 case pson::svarint_field:
alvarolb 4:de51256455f7 766 case pson::varint_field:
alvarolb 4:de51256455f7 767 pb_read_varint(value);
alvarolb 4:de51256455f7 768 break;
alvarolb 4:de51256455f7 769 case pson::float_field:
alvarolb 4:de51256455f7 770 read(value.allocate(4), 4);
alvarolb 4:de51256455f7 771 break;
alvarolb 4:de51256455f7 772 case pson::double_field:
alvarolb 4:de51256455f7 773 read(value.allocate(8), 8);
alvarolb 4:de51256455f7 774 break;
alvarolb 4:de51256455f7 775 default:
alvarolb 4:de51256455f7 776 break;
alvarolb 4:de51256455f7 777 }
alvarolb 4:de51256455f7 778 }
alvarolb 4:de51256455f7 779 }
alvarolb 4:de51256455f7 780 };
alvarolb 4:de51256455f7 781
alvarolb 4:de51256455f7 782 ////////////////////////////
alvarolb 4:de51256455f7 783 /////// PSON_ENCODER ///////
alvarolb 4:de51256455f7 784 ////////////////////////////
alvarolb 4:de51256455f7 785
alvarolb 4:de51256455f7 786 class pson_encoder {
alvarolb 4:de51256455f7 787
alvarolb 4:de51256455f7 788 protected:
alvarolb 4:de51256455f7 789 size_t written_;
alvarolb 4:de51256455f7 790
alvarolb 4:de51256455f7 791 virtual void write(const void* buffer, size_t size){
alvarolb 4:de51256455f7 792 written_+=size;
alvarolb 4:de51256455f7 793 }
alvarolb 4:de51256455f7 794
alvarolb 4:de51256455f7 795 public:
alvarolb 4:de51256455f7 796
alvarolb 4:de51256455f7 797 pson_encoder() : written_(0) {
alvarolb 4:de51256455f7 798 }
alvarolb 4:de51256455f7 799
alvarolb 4:de51256455f7 800 void reset(){
alvarolb 4:de51256455f7 801 written_ = 0;
alvarolb 4:de51256455f7 802 }
alvarolb 4:de51256455f7 803
alvarolb 4:de51256455f7 804 size_t bytes_written(){
alvarolb 4:de51256455f7 805 return written_;
alvarolb 4:de51256455f7 806 }
alvarolb 4:de51256455f7 807
alvarolb 4:de51256455f7 808 void pb_encode_tag(pb_wire_type wire_type, uint32_t field_number){
alvarolb 4:de51256455f7 809 uint64_t tag = ((uint64_t)field_number << 3) | wire_type;
alvarolb 4:de51256455f7 810 pb_encode_varint(tag);
alvarolb 4:de51256455f7 811 }
alvarolb 4:de51256455f7 812
alvarolb 4:de51256455f7 813 void pb_encode_varint(uint32_t field, uint64_t value)
alvarolb 4:de51256455f7 814 {
alvarolb 4:de51256455f7 815 pb_encode_tag(varint, field);
alvarolb 4:de51256455f7 816 pb_encode_varint(value);
alvarolb 4:de51256455f7 817 }
alvarolb 4:de51256455f7 818
alvarolb 4:de51256455f7 819 uint8_t pb_write_varint(void * buffer)
alvarolb 4:de51256455f7 820 {
alvarolb 4:de51256455f7 821 uint8_t byte=0;
alvarolb 4:de51256455f7 822 uint8_t bytes_written=0;
alvarolb 4:de51256455f7 823 do{
alvarolb 4:de51256455f7 824 byte = *((uint8_t*)buffer + bytes_written);
alvarolb 4:de51256455f7 825 bytes_written++;
alvarolb 4:de51256455f7 826 }while(byte>=0x80);
alvarolb 4:de51256455f7 827 write(buffer, bytes_written);
alvarolb 4:de51256455f7 828 return bytes_written;
alvarolb 4:de51256455f7 829 }
alvarolb 4:de51256455f7 830
alvarolb 4:de51256455f7 831 void pb_encode_varint(uint64_t value)
alvarolb 4:de51256455f7 832 {
alvarolb 4:de51256455f7 833 do
alvarolb 4:de51256455f7 834 {
alvarolb 4:de51256455f7 835 uint8_t byte = (uint8_t)(value & 0x7F);
alvarolb 4:de51256455f7 836 value >>= 7;
alvarolb 4:de51256455f7 837 if(value>0) byte |= 0x80;
alvarolb 4:de51256455f7 838 write(&byte, 1);
alvarolb 4:de51256455f7 839 }while(value>0);
alvarolb 4:de51256455f7 840 }
alvarolb 4:de51256455f7 841
alvarolb 4:de51256455f7 842 void pb_encode_string(const char* str, uint32_t field_number){
alvarolb 4:de51256455f7 843 pb_encode_tag(length_delimited, field_number);
alvarolb 4:de51256455f7 844 pb_encode_string(str);
alvarolb 4:de51256455f7 845 }
alvarolb 4:de51256455f7 846
alvarolb 4:de51256455f7 847 void pb_encode_string(const char* str){
alvarolb 4:de51256455f7 848 size_t string_size = strlen(str);
alvarolb 4:de51256455f7 849 pb_encode_varint(string_size);
alvarolb 4:de51256455f7 850 write(str, string_size);
alvarolb 4:de51256455f7 851 }
alvarolb 4:de51256455f7 852
alvarolb 4:de51256455f7 853 template<class T>
alvarolb 4:de51256455f7 854 void pb_encode_submessage(T& element, uint32_t field_number)
alvarolb 4:de51256455f7 855 {
alvarolb 4:de51256455f7 856 pb_encode_tag(length_delimited, field_number);
alvarolb 4:de51256455f7 857 pson_encoder sink;
alvarolb 4:de51256455f7 858 sink.encode(element);
alvarolb 4:de51256455f7 859 pb_encode_varint(sink.bytes_written());
alvarolb 4:de51256455f7 860 encode(element);
alvarolb 4:de51256455f7 861 }
alvarolb 4:de51256455f7 862
alvarolb 4:de51256455f7 863 void pb_encode_fixed32(void* value){
alvarolb 4:de51256455f7 864 write(value, 4);
alvarolb 4:de51256455f7 865 }
alvarolb 4:de51256455f7 866
alvarolb 4:de51256455f7 867 void pb_encode_fixed64(void* value){
alvarolb 4:de51256455f7 868 write(value, 8);
alvarolb 4:de51256455f7 869 }
alvarolb 4:de51256455f7 870
alvarolb 4:de51256455f7 871 void pb_encode_fixed32(uint32_t field, void*value)
alvarolb 4:de51256455f7 872 {
alvarolb 4:de51256455f7 873 pb_encode_tag(fixed_32, field);
alvarolb 4:de51256455f7 874 pb_encode_fixed32(value);
alvarolb 4:de51256455f7 875 }
alvarolb 4:de51256455f7 876
alvarolb 4:de51256455f7 877 void pb_encode_fixed64(uint32_t field, void*value)
alvarolb 4:de51256455f7 878 {
alvarolb 4:de51256455f7 879 pb_encode_tag(fixed_64, field);
alvarolb 4:de51256455f7 880 pb_encode_fixed64(value);
alvarolb 4:de51256455f7 881 }
alvarolb 4:de51256455f7 882
alvarolb 4:de51256455f7 883 public:
alvarolb 4:de51256455f7 884
alvarolb 4:de51256455f7 885 void encode(pson_object & object){
alvarolb 4:de51256455f7 886 pson_container<pson_pair>::iterator it = object.begin();
alvarolb 4:de51256455f7 887 while(it.valid()){
alvarolb 4:de51256455f7 888 encode(it.item());
alvarolb 4:de51256455f7 889 it.next();
alvarolb 4:de51256455f7 890 }
alvarolb 4:de51256455f7 891 }
alvarolb 4:de51256455f7 892
alvarolb 4:de51256455f7 893 void encode(pson_array & array){
alvarolb 4:de51256455f7 894 pson_container<pson>::iterator it = array.begin();
alvarolb 4:de51256455f7 895 while(it.valid()){
alvarolb 4:de51256455f7 896 encode(it.item());
alvarolb 4:de51256455f7 897 it.next();
alvarolb 4:de51256455f7 898 }
alvarolb 4:de51256455f7 899 }
alvarolb 4:de51256455f7 900
alvarolb 4:de51256455f7 901 void encode(pson_pair & pair){
alvarolb 4:de51256455f7 902 pb_encode_string(pair.name());
alvarolb 4:de51256455f7 903 encode(pair.value());
alvarolb 4:de51256455f7 904 }
alvarolb 4:de51256455f7 905
alvarolb 4:de51256455f7 906 void encode(pson & value) {
alvarolb 4:de51256455f7 907 switch (value.get_type()) {
alvarolb 4:de51256455f7 908 case pson::string_field:
alvarolb 4:de51256455f7 909 pb_encode_string((const char*)value.get_value(), pson::string_field);
alvarolb 4:de51256455f7 910 break;
alvarolb 4:de51256455f7 911 case pson::bytes_field:
alvarolb 4:de51256455f7 912 pb_encode_tag(length_delimited, pson::bytes_field);
alvarolb 4:de51256455f7 913 write(((const char *) value.get_value()) + pb_write_varint(value.get_value()), value.pb_decode_varint());
alvarolb 4:de51256455f7 914 break;
alvarolb 4:de51256455f7 915 case pson::svarint_field:
alvarolb 4:de51256455f7 916 case pson::varint_field:
alvarolb 4:de51256455f7 917 pb_encode_tag(varint, value.get_type());
alvarolb 4:de51256455f7 918 pb_write_varint(value.get_value());
alvarolb 4:de51256455f7 919 break;
alvarolb 4:de51256455f7 920 case pson::float_field:
alvarolb 4:de51256455f7 921 pb_encode_fixed32(pson::float_field, value.get_value());
alvarolb 4:de51256455f7 922 break;
alvarolb 4:de51256455f7 923 case pson::double_field:
alvarolb 4:de51256455f7 924 pb_encode_fixed64(pson::double_field, value.get_value());
alvarolb 4:de51256455f7 925 break;
alvarolb 4:de51256455f7 926 case pson::object_field:
alvarolb 4:de51256455f7 927 pb_encode_submessage(*(pson_object *) value.get_value(), pson::object_field);
alvarolb 4:de51256455f7 928 break;
alvarolb 4:de51256455f7 929 case pson::array_field:
alvarolb 4:de51256455f7 930 pb_encode_submessage(*(pson_array *) value.get_value(), pson::array_field);
alvarolb 4:de51256455f7 931 break;
alvarolb 4:de51256455f7 932 default:
alvarolb 4:de51256455f7 933 pb_encode_tag(varint, value.get_type());
alvarolb 4:de51256455f7 934 break;
alvarolb 4:de51256455f7 935 }
alvarolb 4:de51256455f7 936 }
alvarolb 4:de51256455f7 937 };
alvarolb 4:de51256455f7 938 }
alvarolb 4:de51256455f7 939
alvarolb 4:de51256455f7 940 #endif