Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DHT WIZnetInterface mbed-src
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
Generated on Wed Jul 13 2022 02:25:39 by
