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.
Fork of kpn_senml by
senml_cbor_parser.h
00001 /* _ __ ____ _ _ 00002 * | |/ / | _ \ | \ | | 00003 * | ' / | |_) | | \| | 00004 * | . \ | __/ | |\ | 00005 * |_|\_\ |_| |_| \_| 00006 * 00007 * (c) 2018 KPN 00008 * License: MIT License. 00009 * Author: Jan Bogaerts 00010 * 00011 * parse cbor header 00012 */ 00013 00014 #ifndef SENMLCBORPARSER 00015 #define SENMLCBORPARSER 00016 00017 #include <senml_base_parser.h> 00018 #include <senml_enums.h> 00019 #include <senml_logging.h> 00020 #include <senml_helpers.h> 00021 #include <cbor.h> 00022 00023 enum SenMLCborDataType {}; 00024 00025 #define SENML_CBOR_KEY 1 00026 #define SENML_CBOR_VALUE 2 00027 00028 00029 /** 00030 * Inernal helper class for parsing cbor data. 00031 */ 00032 class SenMLCborParser: public SenMLBaseParser { 00033 00034 public: 00035 SenMLCborParser(SenMLPack* root, SenMLStreamMethod format): SenMLBaseParser(root), state(0) 00036 { 00037 this->ctx.format = format; 00038 this->ctx.baseValue.baseUint = 0; //init to 0, so we get correct results for first element as well. 00039 this->ctx.baseSum.baseUint = 0; 00040 _streamCtx = &this->ctx; //set the global variable so that we don't have to pass it along on the stack all the time (saves mem & codesize) 00041 }; 00042 00043 //convert the cbor raw data into senml and actuate the records in the root pack. 00044 void parse(Stream* source); 00045 00046 00047 void parse(char* source, int length); 00048 00049 00050 private: 00051 unsigned char state; //keeps track of the current parse state 00052 int curLabel; //the cbor number that represents the current senml label (unit, value, boolvalue, basename,..). The next item to read has to be the value for the label 00053 StreamContext ctx; 00054 00055 unsigned int parseNext(); 00056 00057 void setValue(void* value, int length, SenMLDataType type); 00058 void setBinaryValue(const char* value, int length); 00059 void processDouble(double value); 00060 00061 void internalParse(); 00062 00063 unsigned int processBytes(SenMLDataType type); 00064 00065 unsigned int processArray(); 00066 00067 inline unsigned int processMap() 00068 { 00069 const bool is_indefinite = (peekChar() == (CBOR_MAP | CBOR_VAR_FOLLOWS)); 00070 uint64_t map_length = 0; 00071 size_t read_bytes; 00072 00073 if (is_indefinite){ 00074 log_debug("not supported"); 00075 } 00076 else 00077 read_bytes = decode_int(&map_length); 00078 00079 unsigned char curState = this->state; 00080 size_t i = 0; 00081 while (i < map_length) { 00082 size_t key_read_bytes, value_read_bytes; 00083 this->state = SENML_CBOR_KEY; 00084 key_read_bytes = this->parseNext(); /* key */ 00085 this->state = SENML_CBOR_VALUE; 00086 value_read_bytes = this->parseNext(); /* value */ 00087 if (key_read_bytes == 0 || value_read_bytes == 0) { 00088 log_debug("invalid input"); 00089 break; 00090 } 00091 read_bytes += key_read_bytes + value_read_bytes; 00092 ++i; 00093 } 00094 this->state = curState; //reset to the original state. was changed inside loop 00095 this->ctx.baseValue.baseUint = 0; //if there was a base value, reset it for the next run. 00096 return read_bytes; 00097 }; 00098 00099 inline unsigned int processUnsignedInt() 00100 { 00101 uint64_t val; 00102 size_t read_bytes = cbor_deserialize_uint64_t(&val); 00103 if(this->state == SENML_CBOR_VALUE){ 00104 switch (this->curLabel) 00105 { 00106 case SENML_CBOR_BV_LABEL: this->ctx.baseValue.baseUint = val; break; 00107 case SENML_CBOR_V_LABEL: 00108 uint64_t calculated = this->ctx.baseValue.baseUint + val; 00109 this->setValue((void*)&calculated, sizeof(uint64_t), CBOR_TYPE_UINT); 00110 break; 00111 } 00112 } 00113 else if(this->state == SENML_CBOR_KEY) //store the value type (basename, baseunit, value, stringvalue,...) 00114 this->curLabel = (int)val; 00115 return read_bytes; 00116 }; 00117 00118 inline unsigned int processInt() 00119 { 00120 int64_t val; 00121 size_t read_bytes = cbor_deserialize_int64_t(&val); 00122 if(this->state == SENML_CBOR_VALUE){ 00123 switch (this->curLabel) 00124 { 00125 case SENML_CBOR_BV_LABEL: this->ctx.baseValue.baseInt = val; break; 00126 case SENML_CBOR_V_LABEL: 00127 uint64_t calculated = this->ctx.baseValue.baseInt + val; 00128 this->setValue((void*)&calculated, sizeof(int64_t), CBOR_TYPE_INT); 00129 break; 00130 } 00131 } 00132 else if(this->state == SENML_CBOR_KEY) //store the value type (basename, baseunit, value, stringvalue,...) 00133 this->curLabel = val; 00134 return read_bytes; 00135 }; 00136 00137 00138 }; 00139 00140 #endif // SENMLCBORPARSER 00141 00142 00143 00144 00145 00146 00147
Generated on Tue Jul 12 2022 23:07:21 by
