├── README.md ├── examples ├── led_controller │ └── led_controller.ino ├── test_mega │ └── test_mega.ino └── test_uno_writer │ └── test_uno_writer.ino ├── keywords.txt ├── library.properties ├── msgpck.cpp └── msgpck.h /README.md: -------------------------------------------------------------------------------- 1 | # arduino_msgpack 2 | This Arduino library provides a light weight serializer and parser for messagepack. 3 | 4 | ## Install 5 | Download the zip, and import it with your Arduino IDE: *Sketch>Include Library>Add .zip library* 6 | 7 | ## Usage 8 | See the either the `.h` file, or the examples (`led_controller` and `test_uno_writer`). 9 | 10 | In short: 11 | * functions like `msgpck_what_next(Stream * s);` watch the next type of data without reading it (without advancing the buffer of Stream `s`). 12 | * functions like `msgpck_read_bool(Stream * s, bool *b)` read a value from Stream `s`. 13 | * functions like `msgpck_write_bool(Stream * s, bool b)` write a value on Stream `s`. 14 | 15 | Notes: 16 | * Stream are used as much as possible in order not to add to much overhead with buffers. Therefore you should be able to store the minimum number of value at a given time. 17 | * Map and Array related functions concern only their headers. Ex: If you want to write an array containing two elements you should write the array header, then write the two elements. 18 | 19 | 20 | 21 | ## Limitations 22 | Currently the library does **not** support: 23 | * 8 bytes float (Only 4 bytes floats are supported by default on every Arduino and floats are anyway not recommended on Arduino) 24 | * 2^32 char long (or longer) strings 25 | * 2^32 byte long (or longer) bins 26 | * extention types. 27 | -------------------------------------------------------------------------------- /examples/led_controller/led_controller.ino: -------------------------------------------------------------------------------- 1 | #include "msgpck.h" 2 | 3 | /* 4 | * This is an example of message pack library use for Arduino Uno. 5 | * 6 | * It reads the serial port expecting messages like {"pin":6, "val":true} 7 | * to turn the pin 6 or 7 to high or low. 8 | * It also listen on pin 8 and forward its value with the same format. 9 | * 10 | * 11 | * Exchanged Message Pack data: 12 | * 13 | * Turn led 6 on: 0x82 0xa3 0x70 0x69 0x6e 0x06 0xa3 0x76 0x61 0x6c 0xc3 14 | * Turn led 6 off: 0x82 0xa3 0x70 0x69 0x6e 0x06 0xa3 0x76 0x61 0x6c 0xc2 15 | * Turn led 7 on: 0x82 0xa3 0x70 0x69 0x6e 0x07 0xa3 0x76 0x61 0x6c 0xc3 16 | * Turn led 7 off: 0x82 0xa3 0x70 0x69 0x6e 0x07 0xa3 0x76 0x61 0x6c 0xc2 17 | * 18 | * Button 8 is pressed: 0x82 0xa3 0x70 0x69 0x6e 0x08 0xa3 0x76 0x61 0x6c 0xc3 19 | * Button 8 isn't pressed: 0x82 0xa3 0x70 0x69 0x6e 0x08 0xa3 0x76 0x61 0x6c 0xc2 20 | * 21 | * Wiring: 22 | * Connect pin 6 to a led 23 | * Connect pin 7 to a led 24 | * Connect pin 8 to a button 25 | */ 26 | 27 | void setup() { 28 | 29 | pinMode(6, OUTPUT); 30 | pinMode(7, OUTPUT); 31 | pinMode(8, INPUT); 32 | 33 | Serial.begin(9600); 34 | 35 | } 36 | 37 | 38 | 39 | /* 40 | * This function understand message form like this {"pin":6, "val":true} 41 | */ 42 | bool read_message() { 43 | bool res = true; 44 | if(Serial.available() > 0) { 45 | uint8_t i; 46 | char buf[8]; 47 | uint32_t map_size; 48 | uint32_t r_size; 49 | uint8_t pin; 50 | bool level; 51 | res &= msgpck_map_next(&Serial); 52 | if(!res) 53 | return false; 54 | res &= msgpck_read_map_size(&Serial, &map_size); 55 | if(!res) 56 | return false; 57 | res &= (map_size == 2); 58 | res &= msgpck_read_string(&Serial, buf, 3, &r_size); 59 | if(!res) 60 | return false; 61 | res &= (buf[0] == 'p'); 62 | res &= (buf[1] == 'i'); 63 | res &= (buf[2] == 'n'); 64 | res &= msgpck_read_integer(&Serial, &pin, 1); 65 | if(!res) 66 | return false; 67 | res &= msgpck_read_string(&Serial, buf, 3, &r_size); 68 | if(!res) 69 | return false; 70 | res &= (buf[0] == 'v'); 71 | res &= (buf[1] == 'a'); 72 | res &= (buf[2] == 'l'); 73 | res &= msgpck_read_bool(&Serial, &level); 74 | if(!res) 75 | return false; 76 | 77 | if((pin == 6) || (pin == 7)) 78 | digitalWrite(pin, level); 79 | } 80 | return res; 81 | } 82 | 83 | bool button; 84 | 85 | void loop() { 86 | if(!read_message())//If read return false, a message is corrupt, so we flush the buffer 87 | Serial.flush(); 88 | 89 | bool new_val = digitalRead(8); 90 | if(button != new_val) { 91 | button = new_val; 92 | msgpck_write_map_header(&Serial, 2); //Map containing two pair of element 93 | msgpck_write_string(&Serial, "pin"); //key: String "pin" 94 | msgpck_write_integer(&Serial, 8); //Value: integer 8 95 | msgpck_write_string(&Serial, "val"); //key: String "val" 96 | msgpck_write_bool(&Serial, button); //Value: bool 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /examples/test_mega/test_mega.ino: -------------------------------------------------------------------------------- 1 | #include "msgpck.h" 2 | 3 | /* 4 | * This is an example of message pack library use for Arduino mega. 5 | * 6 | * It writes some message pack serialized data on Serial1 and receives them on Serial2. 7 | * Serial is used, plugged with your computer, in order to display the json corresponding 8 | * to data exchanged on your serial console. 9 | * 10 | * Expected output: 11 | * Start 12 | * {"nil": nil, "bool": false, "uint": 12, "int": -256, "float": 0.50, "array": [5, 2500, -1503]} 13 | * Done 14 | * 15 | * Exchanged Message Pack data: 16 | * 17 | * 0x86 0xa3 0x6e 0x69 0x6c 0xc0 0xa4 0x62 18 | * 0x6f 0x6f 0x6c 0xc2 0xa4 0x75 0x69 0x6e 19 | * 0x74 0x0c 0xa3 0x69 0x6e 0x74 0xd1 0xff 20 | * 0x00 0xa5 0x66 0x6c 0x6f 0x61 0x74 0xca 21 | * 0x3f 0xe0 0x00 0x00 0xa5 0x61 0x72 0x72 22 | * 0x61 0x79 0x93 0x05 0xcd 0x09 0xc4 0xd1 23 | * 0xfa 0x21 24 | * 25 | * Wiring: 26 | * Connect Rx1 with Tx2 27 | * Connect Rx2 with Tx1 28 | */ 29 | 30 | void setup() { 31 | // put your setup code here, to run once: 32 | Serial.begin(115200); 33 | Serial1.begin(115200); 34 | Serial2.begin(115200); 35 | 36 | Serial.println("Start"); 37 | 38 | msgpck_write_map_header(&Serial1, 6); 39 | 40 | msgpck_write_string(&Serial1, "nil", 3); 41 | msgpck_write_nil(&Serial1); 42 | 43 | msgpck_write_string(&Serial1, "bool", 4); 44 | msgpck_write_bool(&Serial1, false); 45 | 46 | msgpck_write_string(&Serial1, "uint", 4); 47 | msgpck_write_integer(&Serial1, 12); 48 | 49 | msgpck_write_string(&Serial1, "int", 3); 50 | msgpck_write_integer(&Serial1, -256); 51 | 52 | msgpck_write_string(&Serial1, "float", 5); 53 | float f = 0.5; 54 | msgpck_write_float(&Serial1, f); 55 | 56 | 57 | msgpck_write_string(&Serial1, "array", 5); 58 | msgpck_write_array_header(&Serial1, 3); 59 | uint8_t u0 = 5; 60 | uint16_t u1 = 2500; 61 | int32_t i0 = -1503; 62 | msgpck_write_integer(&Serial1, u0); 63 | msgpck_write_integer(&Serial1, u1); 64 | msgpck_write_integer(&Serial1, i0); 65 | 66 | 67 | delay(1000); 68 | msgpck_to_json(&Serial, &Serial2); 69 | 70 | Serial.println(); 71 | Serial.println("Done"); 72 | } 73 | 74 | void loop() { 75 | // put your main code here, to run repeatedly: 76 | 77 | } 78 | -------------------------------------------------------------------------------- /examples/test_uno_writer/test_uno_writer.ino: -------------------------------------------------------------------------------- 1 | #include "msgpck.h" 2 | /* 3 | * This is an example of message pack library use for Arduino uno. 4 | * 5 | * It writes some message pack serialized data on Serial. 6 | * 7 | * Expected output: 8 | * 9 | * 0x86 0xa3 0x6e 0x69 0x6c 0xc0 0xa4 0x62 10 | * 0x6f 0x6f 0x6c 0xc2 0xa4 0x75 0x69 0x6e 11 | * 0x74 0x0c 0xa3 0x69 0x6e 0x74 0xd1 0xff 12 | * 0x00 0xa5 0x66 0x6c 0x6f 0x61 0x74 0xca 13 | * 0x3f 0xe0 0x00 0x00 0xa5 0x61 0x72 0x72 14 | * 0x61 0x79 0x93 0x05 0xcd 0x09 0xc4 0xd1 15 | * 0xfa 0x21 16 | */ 17 | void setup() { 18 | // put your setup code here, to run once: 19 | Serial.begin(115200); 20 | delay(100); 21 | 22 | msgpck_write_map_header(&Serial, 6); 23 | 24 | msgpck_write_string(&Serial, "nil", 3); 25 | msgpck_write_nil(&Serial); 26 | 27 | msgpck_write_string(&Serial, "bool", 4); 28 | msgpck_write_bool(&Serial, false); 29 | 30 | msgpck_write_string(&Serial, "uint", 4); 31 | msgpck_write_integer(&Serial, 12); 32 | 33 | msgpck_write_string(&Serial, "int", 3); 34 | msgpck_write_integer(&Serial, -256); 35 | 36 | msgpck_write_string(&Serial, "float", 5); 37 | msgpck_write_float(&Serial, 0.5f); 38 | 39 | 40 | msgpck_write_string(&Serial, "array", 5); 41 | msgpck_write_array_header(&Serial, 3); 42 | uint8_t u0 = 5; 43 | uint16_t u1 = 2500; 44 | int32_t i0 = -1503; 45 | msgpck_write_integer(&Serial, u0); 46 | msgpck_write_integer(&Serial, u1); 47 | msgpck_write_integer(&Serial, i0); 48 | 49 | } 50 | 51 | void loop() { 52 | // put your main code here, to run repeatedly: 53 | 54 | } 55 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | msgpck_what_next KEYWORD2 2 | msgpck_nil_next KEYWORD2 3 | msgpck_bool_next KEYWORD2 4 | msgpck_integer_next KEYWORD2 5 | msgpck_signed_next KEYWORD2 6 | msgpck_float_next KEYWORD2 7 | msgpck_string_next KEYWORD2 8 | msgpck_bin_next KEYWORD2 9 | msgpck_array_next KEYWORD2 10 | msgpck_map_next KEYWORD2 11 | msgpck_read_nil KEYWORD2 12 | msgpck_read_bool KEYWORD2 13 | msgpck_read_integer KEYWORD2 14 | msgpck_read_float KEYWORD2 15 | msgpck_read_string KEYWORD2 16 | msgpck_read_string KEYWORD2 17 | msgpck_read_bin KEYWORD2 18 | msgpck_read_array_size KEYWORD2 19 | msgpck_read_map_size KEYWORD2 20 | msgpck_write_nil KEYWORD2 21 | msgpck_write_bool KEYWORD2 22 | msgpck_write_integer KEYWORD2 23 | msgpck_write_integer KEYWORD2 24 | msgpck_write_integer KEYWORD2 25 | msgpck_write_integer KEYWORD2 26 | msgpck_write_integer KEYWORD2 27 | msgpck_write_integer KEYWORD2 28 | msgpck_write_integer KEYWORD2 29 | msgpck_write_integer KEYWORD2 30 | msgpck_write_string KEYWORD2 31 | msgpck_write_bin KEYWORD2 32 | msgpck_write_array_header KEYWORD2 33 | msgpck_write_map_header KEYWORD2 34 | msgpck_to_json KEYWORD2 35 | msgpck_empty RESERVED_WORD_2 36 | msgpck_nil RESERVED_WORD_2 37 | msgpck_bool RESERVED_WORD_2 38 | msgpck_uint RESERVED_WORD_2 39 | msgpck_sint RESERVED_WORD_2 40 | msgpck_float RESERVED_WORD_2 41 | msgpck_string RESERVED_WORD_2 42 | msgpck_bin RESERVED_WORD_2 43 | msgpck_ext RESERVED_WORD_2 44 | msgpck_array RESERVED_WORD_2 45 | msgpck_map RESERVED_WORD_2 46 | msgpck_unknown RESERVED_WORD_2 47 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Message Pack for Arduino 2 | version=1.0.1 3 | author=HEADS 4 | maintainer=HEADS 5 | sentence=This is a library for the Serialize date into Message pack format. 6 | paragraph=This is a library for the Serialize date into Message pack format. 7 | category=Data Processing 8 | url=https://github.com/HEADS-project/arduino_msgpack 9 | architectures=* 10 | -------------------------------------------------------------------------------- /msgpck.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2014 SINTEF 3 | * 4 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3, 29 June 2007; 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.gnu.org/licenses/lgpl-3.0.txt 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Arduino.h" 18 | #include "msgpck.h" 19 | 20 | #define msgpck_empty 0xff 21 | #define msgpck_nil 0xc0 22 | #define msgpck_bool 0xc2 23 | #define msgpck_uint 0xcc 24 | #define msgpck_sint 0xd0 25 | #define msgpck_float 0xca 26 | #define msgpck_string 0xd9 27 | #define msgpck_bin 0xc4 28 | #define msgpck_ext 0xc7 29 | #define msgpck_array 0xdc 30 | #define msgpck_map 0xde 31 | #define msgpck_unknown 0x00 32 | 33 | uint8_t msgpck_what_next(Stream * s) { 34 | int b = s->peek(); 35 | switch(b){ 36 | case -1: 37 | return msgpck_empty; 38 | break; 39 | 40 | case 0xc0: 41 | return msgpck_nil; 42 | break; 43 | 44 | case 0xc2: 45 | return msgpck_bool; 46 | break; 47 | 48 | case 0xc3: 49 | return msgpck_bool; 50 | break; 51 | 52 | case 0xc4: 53 | return msgpck_bin; 54 | break; 55 | 56 | case 0xc5: 57 | return msgpck_bin; 58 | break; 59 | 60 | case 0xc6: 61 | return msgpck_bin; 62 | break; 63 | 64 | case 0xca: 65 | return msgpck_float; 66 | break; 67 | 68 | case 0xcb: 69 | return msgpck_float; 70 | break; 71 | 72 | case 0xcc: 73 | return msgpck_uint; 74 | break; 75 | 76 | case 0xcd: 77 | return msgpck_uint; 78 | break; 79 | 80 | case 0xce: 81 | return msgpck_uint; 82 | break; 83 | 84 | case 0xcf: 85 | return msgpck_uint; 86 | break; 87 | 88 | case 0xd0: 89 | return msgpck_sint; 90 | break; 91 | 92 | case 0xd1: 93 | return msgpck_sint; 94 | break; 95 | 96 | case 0xd2: 97 | return msgpck_sint; 98 | break; 99 | 100 | case 0xd3: 101 | return msgpck_sint; 102 | break; 103 | 104 | case 0xd4: 105 | return msgpck_ext; 106 | break; 107 | 108 | case 0xd5: 109 | return msgpck_ext; 110 | break; 111 | 112 | case 0xd6: 113 | return msgpck_ext; 114 | break; 115 | 116 | case 0xd7: 117 | return msgpck_ext; 118 | break; 119 | 120 | case 0xd8: 121 | return msgpck_ext; 122 | break; 123 | 124 | case 0xd9: 125 | return msgpck_string; 126 | break; 127 | 128 | case 0xda: 129 | return msgpck_string; 130 | break; 131 | 132 | case 0xdb: 133 | return msgpck_string; 134 | break; 135 | 136 | case 0xdc: 137 | return msgpck_array; 138 | break; 139 | 140 | case 0xdd: 141 | return msgpck_array; 142 | break; 143 | 144 | case 0xde: 145 | return msgpck_map; 146 | break; 147 | 148 | case 0xdf: 149 | return msgpck_map; 150 | break; 151 | 152 | default: 153 | if(b >= 224) 154 | return msgpck_uint; 155 | if(b < 128) 156 | return msgpck_sint; 157 | if((b >> 5) == 5) 158 | return msgpck_string; 159 | if((b >> 4) == 8) 160 | return msgpck_map; 161 | if((b >> 4) == 9) 162 | return msgpck_array; 163 | 164 | return msgpck_unknown; 165 | } 166 | } 167 | 168 | bool msgpck_nil_next(Stream * s) { 169 | int b = s->peek(); 170 | return (b != -1) && (b == 0xc0); 171 | } 172 | 173 | bool msgpck_bool_next(Stream * s) { 174 | int b = s->peek(); 175 | return (b != -1) && ((b == 0xc2) || (b == 0xc3)); 176 | } 177 | 178 | bool msgpck_integer_next(Stream * s) { 179 | int b = s->peek(); 180 | return ((b < 128) || 181 | (b >= 224) || 182 | (b == 0xcc) || 183 | (b == 0xcd) || 184 | (b == 0xce) || 185 | (b == 0xcf) || 186 | (b == 0xd0) || 187 | (b == 0xd1) || 188 | (b == 0xd2) || 189 | (b == 0xd3)); 190 | } 191 | 192 | bool msgpck_signed_next(Stream * s) { 193 | int b = s->peek(); 194 | return (b != -1) && ((b >= 224) || 195 | (b == 0xd0) || 196 | (b == 0xd1) || 197 | (b == 0xd2) || 198 | (b == 0xd3)); 199 | } 200 | 201 | bool msgpck_float_next(Stream * s) { 202 | int b = s->peek(); 203 | return (b != -1) && ((b == 0xca) || (b == 0xcb)); 204 | } 205 | 206 | bool msgpck_string_next(Stream * s) { 207 | int b = s->peek(); 208 | return (b != -1) && (((b >> 5) == 5) || 209 | (b == 0xd9) || 210 | (b == 0xda) || 211 | (b == 0xdb)); 212 | } 213 | 214 | bool msgpck_bin_next(Stream * s) { 215 | int b = s->peek(); 216 | return (b != -1) && ((b == 0xc4) || 217 | (b == 0xc5) || 218 | (b == 0xc6)); 219 | } 220 | 221 | bool msgpck_array_next(Stream * s) { 222 | int b = s->peek(); 223 | return (b != -1) && (((b >> 4) == 9) || 224 | (b == 0xdc) || 225 | (b == 0xdd)); 226 | } 227 | 228 | bool msgpck_map_next(Stream * s) { 229 | int b = s->peek(); 230 | return (b != -1) && (((b >> 4) == 8) || 231 | (b == 0xde) || 232 | (b == 0xdf)); 233 | } 234 | 235 | bool msgpck_read_nil(Stream * s) { 236 | uint8_t rfb; 237 | return ((s->readBytes(&rfb,1) == 1) && (rfb == 0xc0)); 238 | } 239 | 240 | bool msgpck_read_bool(Stream * s, bool *b) { 241 | uint8_t rfb; 242 | uint8_t dmp = s->readBytes(&rfb,1); 243 | *b = (rfb == 0xc3); 244 | return ((dmp == 1) && ((rfb == 0xc3) || (rfb == 0xc2))); 245 | } 246 | 247 | bool msgpck_read_integer(Stream * s, byte *b, uint8_t max_size) { 248 | byte fb; 249 | uint8_t read_size; 250 | bool neg = false; 251 | if (s->readBytes(&fb,1) != 1) 252 | return false; 253 | if(fb < 128) { 254 | *b = fb; 255 | read_size = 0; 256 | return true; 257 | } else if (fb >= 224) { 258 | *b = fb; 259 | read_size = 0; 260 | uint8_t i; 261 | for(i = max_size-1; i >= 1; i--) { 262 | b[i] = 0xff; 263 | } 264 | return true; 265 | } else if (fb == 0xcc) { 266 | read_size = 1; 267 | } else if (fb == 0xcd) { 268 | read_size = 2; 269 | } else if (fb == 0xce) { 270 | read_size = 4; 271 | } else if (fb == 0xcf) { 272 | read_size = 8; 273 | } else if (fb == 0xd0) { 274 | read_size = 1; 275 | neg = true; 276 | } else if (fb == 0xd1) { 277 | read_size = 2; 278 | neg = true; 279 | } else if (fb == 0xd2) { 280 | read_size = 4; 281 | neg = true; 282 | } else if (fb == 0xd3) { 283 | read_size = 8; 284 | neg = true; 285 | } else { 286 | return false; 287 | } 288 | if(read_size > max_size) 289 | return false; 290 | 291 | bool res = true; 292 | int8_t i; 293 | for(i = read_size-1; i >= 0; i--) { 294 | res &= s->readBytes(&b[i],1); 295 | } 296 | 297 | if(neg && ((b[read_size-1] >> 7) == 1)) { 298 | for(i = max_size-1; i >= read_size; i--) { 299 | b[i] = 0xff; 300 | } 301 | } else { 302 | for(i = max_size-1; i >= read_size; i--) { 303 | b[i] = 0x00; 304 | } 305 | } 306 | return res; 307 | } 308 | 309 | bool msgpck_read_float(Stream * s, float *f) { 310 | byte fb; 311 | uint8_t read_size; 312 | bool b = true; 313 | if (s->readBytes(&fb,1) != 1) 314 | return false; 315 | if(fb == 0xca) { 316 | read_size = 4; 317 | union float_to_byte { 318 | float f; 319 | byte b[4]; 320 | } b2f; 321 | b = s->readBytes(&(b2f.b[3]),1) == 1; 322 | b = s->readBytes(&(b2f.b[2]),1) == 1; 323 | b = s->readBytes(&(b2f.b[1]),1) == 1; 324 | b = s->readBytes(&(b2f.b[0]),1) == 1; 325 | *f = b2f.f; 326 | return b; 327 | } else if (fb == 0xcb) { 328 | uint64_t dmp; 329 | uint8_t * p = (uint8_t *) &dmp; 330 | read_size = 8; 331 | s->readBytes(p,read_size); 332 | } else { 333 | return false; 334 | } 335 | return false; 336 | } 337 | 338 | bool msgpck_read_string_length(Stream * s, uint32_t *str_size) { 339 | *str_size = 0; 340 | uint8_t fb; 341 | bool b = true; 342 | uint32_t read_size = 0; 343 | uint8_t * p = (uint8_t *) &read_size; 344 | if(s->readBytes(&fb,1) != 1) { 345 | return false; 346 | } 347 | 348 | if((fb >> 5) == 5) { 349 | read_size = fb & 0x1f; 350 | } else if(fb == 0xd9) { 351 | b &= s->readBytes(&p[0],1) == 1; 352 | } else if(fb == 0xda) { 353 | b &= s->readBytes(&p[1],1) == 1; 354 | b &= s->readBytes(&p[0],1) == 1; 355 | } else if(fb == 0xdb) { 356 | b &= s->readBytes(&p[3],1) == 1; 357 | b &= s->readBytes(&p[2],1) == 1; 358 | b &= s->readBytes(&p[1],1) == 1; 359 | b &= s->readBytes(&p[0],1) == 1; 360 | } else { 361 | return false; 362 | } 363 | if (!b) { 364 | read_size = 0; 365 | } 366 | *str_size = read_size; 367 | return b; 368 | } 369 | 370 | bool msgpck_read_buffer(Stream * s, uint8_t * buf, uint32_t size) { 371 | size_t count = s->readBytes(buf, size); 372 | return count == size; 373 | } 374 | 375 | bool msgpck_read_buffer(Stream * s, Print * p, uint32_t size) { 376 | size_t bufSize = 15; 377 | char buf[bufSize]; 378 | size_t length = 0; 379 | size_t count = 0; 380 | do 381 | { 382 | count = size - length; 383 | if (count > bufSize) 384 | { 385 | count = bufSize; 386 | } 387 | count = s->readBytes(buf, count); 388 | if (count > 0) { 389 | p->write(buf, count); 390 | length += count; 391 | } 392 | } while (size > length && count > 0); 393 | return length == size; 394 | } 395 | 396 | bool msgpck_read_buffer_human(Stream * s, Print * p, uint32_t size) { 397 | size_t bufSize = 15; 398 | char buf[bufSize]; 399 | size_t length = 0; 400 | size_t count = 0; 401 | do 402 | { 403 | count = size - length; 404 | if (count > bufSize) 405 | { 406 | count = bufSize; 407 | } 408 | count = s->readBytes(buf, count); 409 | if (count > 0) { 410 | for (size_t i = 0; i < count; i++) { 411 | p->write(" 0x"); 412 | p->print(buf[i], HEX); 413 | } 414 | length += count; 415 | } 416 | } while (size > length && count > 0); 417 | return length == size; 418 | } 419 | 420 | bool msgpck_read_string(Stream * s, Print * p) { 421 | uint32_t str_size; 422 | bool b = msgpck_read_string_length(s, &str_size); 423 | if (!b) { 424 | return false; 425 | } 426 | return msgpck_read_buffer(s, p, str_size); 427 | } 428 | 429 | bool msgpck_read_string(Stream * s, char * str, uint32_t max_size, uint32_t *str_size) { 430 | bool b = msgpck_read_string_length(s, str_size); 431 | if (!b || *str_size >= max_size) { 432 | return false; 433 | } 434 | 435 | b = msgpck_read_buffer(s, (uint8_t*)str, *str_size); 436 | if (!b) { 437 | *str = 0; 438 | } else { 439 | str[*str_size] = 0; 440 | } 441 | return b; 442 | } 443 | 444 | bool msgpck_read_string(Stream * s, char * str, uint32_t max_size) { 445 | uint32_t read_size; 446 | return msgpck_read_string(s, str, max_size, &read_size); 447 | } 448 | 449 | bool msgpck_read_bin_length(Stream * s, uint32_t *bin_size) { 450 | uint8_t fb; 451 | bool b = true; 452 | uint32_t read_size = 0; 453 | uint8_t * p = (uint8_t *) &read_size; 454 | if(s->readBytes(&fb,1) != 1) { 455 | return false; 456 | } 457 | 458 | if(fb == 0xc4) { 459 | b &= s->readBytes(&p[0],1) == 1; 460 | } else if(fb == 0xc5) { 461 | b &= s->readBytes(&p[1],1) == 1; 462 | b &= s->readBytes(&p[0],1) == 1; 463 | } else if(fb == 0xc6) { 464 | b &= s->readBytes(&p[3],1) == 1; 465 | b &= s->readBytes(&p[2],1) == 1; 466 | b &= s->readBytes(&p[1],1) == 1; 467 | b &= s->readBytes(&p[0],1) == 1; 468 | } else { 469 | return false; 470 | } 471 | 472 | if (!b) { 473 | *bin_size = read_size; 474 | } 475 | 476 | return b; 477 | } 478 | 479 | bool msgpck_read_bin(Stream * s, byte * bin, uint32_t max_size, uint32_t *bin_size) { 480 | bool b = msgpck_read_bin_length(s, bin_size); 481 | if (!b || *bin_size > max_size) { 482 | return false; 483 | } 484 | return msgpck_read_buffer(s, bin, *bin_size); 485 | } 486 | 487 | bool msgpck_read_bin(Stream * s, Print * p) { 488 | uint32_t bin_size; 489 | bool b = msgpck_read_bin_length(s, &bin_size); 490 | if (!b) { 491 | return false; 492 | } 493 | return msgpck_read_buffer(s, p, bin_size); 494 | } 495 | 496 | bool msgpck_read_bin_human(Stream * s, Print * p) { 497 | uint32_t bin_size; 498 | bool b = msgpck_read_bin_length(s, &bin_size); 499 | if (!b) { 500 | return false; 501 | } 502 | return msgpck_read_buffer_human(s, p, bin_size); 503 | } 504 | 505 | bool msgpck_read_bin(Stream * s, byte * bin, uint32_t max_size) { 506 | uint32_t read_size; 507 | return msgpck_read_bin(s, bin, max_size, &read_size); 508 | } 509 | 510 | bool msgpck_read_array_size(Stream * s, uint32_t * array_size) { 511 | uint8_t fb; 512 | bool b = true; 513 | uint8_t * p = (uint8_t *) array_size; 514 | if(s->readBytes(&fb,1) == 1) { 515 | if((fb >> 4) == 0x09) { 516 | *array_size = fb & 0x0f; 517 | } else if(fb == 0xdc) { 518 | *array_size = 0; 519 | b &= s->readBytes(&p[1],1) == 1; 520 | b &= s->readBytes(&p[0],1) == 1; 521 | return b; 522 | } else if(fb == 0xdd) { 523 | *array_size = 0; 524 | b &= s->readBytes(&p[3],1) == 1; 525 | b &= s->readBytes(&p[2],1) == 1; 526 | b &= s->readBytes(&p[1],1) == 1; 527 | b &= s->readBytes(&p[0],1) == 1; 528 | } else { 529 | return false; 530 | } 531 | return b; 532 | } 533 | return false; 534 | } 535 | 536 | bool msgpck_read_map_size(Stream * s, uint32_t * map_size) { 537 | uint8_t fb; 538 | bool b = true; 539 | uint8_t * p = (uint8_t *) map_size; 540 | if(s->readBytes(&fb,1) == 1) { 541 | if((fb >> 4) == 0x08) { 542 | *map_size = fb & 0x0f; 543 | } else if(fb == 0xde) { 544 | *map_size = 0; 545 | b &= s->readBytes(&p[1],1) == 1; 546 | b &= s->readBytes(&p[0],1) == 1; 547 | } else if(fb == 0xdf) { 548 | *map_size = 0; 549 | b &= s->readBytes(&p[3],1) == 1; 550 | b &= s->readBytes(&p[2],1) == 1; 551 | b &= s->readBytes(&p[1],1) == 1; 552 | b &= s->readBytes(&p[0],1) == 1; 553 | } else { 554 | return false; 555 | } 556 | return b; 557 | } 558 | return false; 559 | } 560 | 561 | void msgpck_write_nil(Print * s) { 562 | s->write(0xc0); 563 | } 564 | 565 | void msgpck_write_bool(Print * s, bool b) { 566 | b ? s->write(0xc3) : s->write(0xc2); 567 | } 568 | 569 | void msgpck_write_integer(Print * s, uint8_t u) { 570 | if(u < 128) { 571 | s->write(u); 572 | } else { 573 | s->write(0xcc); 574 | s->write(u); 575 | } 576 | } 577 | 578 | void msgpck_write_integer(Print * s, uint16_t u) { 579 | if(u < 256) { 580 | msgpck_write_integer(s, (uint8_t) u); 581 | } else { 582 | s->write(0xcd); 583 | s->write(u >> 8); 584 | s->write(u & 0xff); 585 | } 586 | } 587 | 588 | void msgpck_write_integer(Print * s, uint32_t u) { 589 | if(u < 65536) { 590 | msgpck_write_integer(s, (uint16_t) u); 591 | } else { 592 | s->write(0xce); 593 | s->write(u >> 24); 594 | s->write(u >> 16); 595 | s->write(u >> 8); 596 | s->write(u & 0xff); 597 | } 598 | } 599 | 600 | void msgpck_write_integer(Print * s, uint64_t u) { 601 | if(u < 4294967296) { 602 | msgpck_write_integer(s, (uint32_t) u); 603 | } else { 604 | s->write(0xcd); 605 | s->write((uint8_t)(u >> 56)); 606 | s->write((uint8_t)(u >> 48)); 607 | s->write((uint8_t)(u >> 40)); 608 | s->write((uint8_t)(u >> 32)); 609 | s->write((uint8_t)(u >> 24)); 610 | s->write((uint8_t)(u >> 16)); 611 | s->write((uint8_t)(u >> 8)); 612 | s->write((uint8_t)(u & 0xff)); 613 | } 614 | } 615 | 616 | void msgpck_write_integer(Print * s, int8_t i) { 617 | if((i < -32) || (i > 127)) { 618 | s->write(0xd0); 619 | s->write(i); 620 | } else { 621 | s->write(i); 622 | } 623 | } 624 | 625 | void msgpck_write_integer(Print * s, int16_t i) { 626 | if(i > 0) { 627 | msgpck_write_integer(s, (uint16_t) i); 628 | } else if(i < -127) { 629 | s->write(0xd1); 630 | s->write(i >> 8); 631 | s->write(i & 0xff); 632 | } else { 633 | msgpck_write_integer(s, (int8_t) i); 634 | } 635 | } 636 | 637 | void msgpck_write_integer(Print * s, int32_t i) { 638 | if(i > 0) { 639 | msgpck_write_integer(s, (uint32_t) i); 640 | } else if(i < -32768) { 641 | s->write(0xd2); 642 | s->write((i >> 24)& 0xff); 643 | s->write((i >> 16)& 0xff); 644 | s->write((i >> 8)& 0xff); 645 | s->write(i & 0xff); 646 | } else { 647 | msgpck_write_integer(s, (int16_t) i); 648 | } 649 | } 650 | 651 | void msgpck_write_integer(Print * s, int64_t i) { 652 | if(i > 0) { 653 | msgpck_write_integer(s, (uint64_t) i); 654 | } else if(i < -2147483647) { 655 | s->write(0xd3); 656 | s->write((uint8_t)(i >> 56)); 657 | s->write((uint8_t)(i >> 48)); 658 | s->write((uint8_t)(i >> 40)); 659 | s->write((uint8_t)(i >> 32)); 660 | s->write((uint8_t)(i >> 24)); 661 | s->write((uint8_t)(i >> 16)); 662 | s->write((uint8_t)(i >> 8)); 663 | s->write((uint8_t)(i & 0xff)); 664 | } else { 665 | msgpck_write_integer(s, (int32_t) i); 666 | } 667 | } 668 | 669 | void msgpck_write_float(Print *s, float f) { 670 | union float_to_byte { 671 | float f; 672 | byte b[4]; 673 | } f2b; 674 | f2b.f = f; 675 | s->write(0xca); 676 | s->write(f2b.b[3]); 677 | s->write(f2b.b[2]); 678 | s->write(f2b.b[1]); 679 | s->write(f2b.b[0]); 680 | } 681 | 682 | void msgpck_write_string(Print * s, char * str, uint32_t str_size) { 683 | if(str_size > 65535) { 684 | s->write(0xdb); 685 | s->write((str_size >> 24) & 0xff); 686 | s->write((str_size >> 16) & 0xff); 687 | s->write((str_size >> 8) & 0xff); 688 | s->write(str_size & 0xff); 689 | } else if(str_size > 255) { 690 | s->write(0xda); 691 | s->write(str_size >> 8); 692 | s->write(str_size & 0xff); 693 | } else if (str_size > 31) { 694 | s->write(0xd9); 695 | s->write(str_size & 0xff); 696 | } else { 697 | s->write(0xa0 + str_size); 698 | } 699 | uint32_t i; 700 | for(i=0;iwrite(str[i]); 702 | } 703 | } 704 | 705 | void msgpck_write_string(Print * s, String str) { 706 | char buf[str.length()+1]; 707 | str.toCharArray(buf, str.length()+1); 708 | msgpck_write_string(s, buf, str.length()); 709 | } 710 | 711 | void msgpck_write_bin(Print * s, byte * b, uint32_t bin_size) { 712 | if(bin_size > 65535) { 713 | s->write(0xc6); 714 | s->write((bin_size >> 24) & 0xff); 715 | s->write((bin_size >> 16) & 0xff); 716 | s->write((bin_size >> 8) & 0xff); 717 | s->write(bin_size & 0xff); 718 | } else if(bin_size > 255) { 719 | s->write(0xc5); 720 | s->write((bin_size >> 8) & 0xff); 721 | s->write(bin_size & 0xff); 722 | } else { 723 | s->write(0xc4); 724 | s->write(bin_size & 0xff); 725 | } 726 | uint32_t i; 727 | for(i=0;iwrite(b[i]); 729 | } 730 | } 731 | 732 | void msgpck_write_array_header(Print * s, uint32_t ar_size) { 733 | if(ar_size > 65535) { 734 | s->write(0xdd); 735 | s->write(ar_size >> 24); 736 | s->write(ar_size >> 16); 737 | s->write(ar_size >> 8); 738 | s->write(ar_size & 0xff); 739 | } else if (ar_size > 15) { 740 | s->write(0xdc); 741 | s->write(ar_size >> 8); 742 | s->write(ar_size & 0xff); 743 | } else { 744 | s->write(0x90 + ar_size); 745 | } 746 | } 747 | 748 | void msgpck_write_map_header(Print * s, uint32_t map_size) { 749 | if(map_size > 65535) { 750 | s->write(0xde); 751 | s->write(map_size >> 24); 752 | s->write(map_size >> 16); 753 | s->write(map_size >> 8); 754 | s->write(map_size & 0xff); 755 | } else if (map_size > 15) { 756 | s->write(0xdf); 757 | s->write(map_size >> 8); 758 | s->write(map_size & 0xff); 759 | } else { 760 | s->write(0x80 + map_size); 761 | } 762 | } 763 | 764 | void msgpck_to_json(Print * output, Stream * input) { 765 | uint8_t i; 766 | if(msgpck_map_next(input)) { 767 | uint32_t map_size; 768 | msgpck_read_map_size(input, &map_size); 769 | output->print("{"); 770 | for(i = 0; i < map_size; i++) { 771 | if(i != 0) 772 | output->print(", "); 773 | output->print("\""); 774 | msgpck_read_string(input, output); 775 | output->print("\": "); 776 | msgpck_to_json(output, input); 777 | } 778 | output->print("}"); 779 | } else if(msgpck_array_next(input)) { 780 | uint32_t array_size; 781 | msgpck_read_array_size(input, &array_size); 782 | output->print("["); 783 | for(i = 0; i < array_size; i++) { 784 | if(i != 0) 785 | output->print(", "); 786 | msgpck_to_json(output, input); 787 | } 788 | output->print("]"); 789 | } else if (msgpck_nil_next(input)) { 790 | msgpck_read_nil(input); 791 | output->print("nil"); 792 | } else if(msgpck_bool_next(input)) { 793 | bool b; 794 | msgpck_read_bool(input, &b); 795 | if(b) { 796 | output->print("true"); 797 | } else { 798 | output->print("false"); 799 | } 800 | } else if(msgpck_integer_next(input)) { 801 | if(msgpck_signed_next(input)) { 802 | int32_t i = 0; 803 | msgpck_read_integer(input, (uint8_t *) &i, 4); 804 | output->print(i); 805 | } else { 806 | uint32_t u = 0; 807 | msgpck_read_integer(input, (uint8_t *) &u, 4); 808 | output->print(u); 809 | } 810 | } else if(msgpck_float_next(input)) { 811 | float f; 812 | msgpck_read_float(input, &f); 813 | output->print(f); 814 | } else if(msgpck_string_next(input)) { 815 | output->print("\""); 816 | msgpck_read_string(input, output); 817 | output->print("\""); 818 | } else if(msgpck_bin_next(input)) { 819 | output->print("'"); 820 | msgpck_read_bin_human(input, output); 821 | output->print("'"); 822 | } 823 | } 824 | 825 | 826 | -------------------------------------------------------------------------------- /msgpck.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2014 SINTEF 3 | * 4 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3, 29 June 2007; 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.gnu.org/licenses/lgpl-3.0.txt 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef heads_msgpck_h 18 | #define heads_msgpck_h 19 | 20 | #include "Arduino.h" 21 | 22 | // ************************** Look up *****************************/ 23 | 24 | /** 25 | * Function: msgpck_what_next 26 | * Description: Look at Stream s's buffer and return the type of the first data in it. 27 | * 28 | * Parameter: Stream * s : input stream. 29 | * 30 | * return: type among: 31 | * - msgpck_empty 0xff 32 | * - msgpck_nil 0xc0 33 | * - msgpck_bool 0xc2 34 | * - msgpck_uint 0xcc 35 | * - msgpck_sint 0xd0 36 | * - msgpck_float 0xca 37 | * - msgpck_string 0xd9 38 | * - msgpck_bin 0xc4 39 | * - msgpck_ext 0xc7 40 | * - msgpck_array 0xdc 41 | * - msgpck_map 0xde 42 | * - msgpck_unknown 0x00 43 | * 44 | */ 45 | uint8_t msgpck_what_next(Stream * s); 46 | 47 | 48 | /** 49 | * Function: msgpck_nil_next 50 | * Description: Look at Stream s's buffer and return the type of the first data in it. 51 | * 52 | * Parameter: Stream * s : input stream. 53 | * 54 | * return: true if next data is nil, false if not 55 | * 56 | */ 57 | bool msgpck_nil_next(Stream * s); 58 | 59 | /** 60 | * Function: msgpck_bool_next 61 | * Description: Look at Stream s's buffer and return the type of the first data in it. 62 | * 63 | * Parameter: Stream * s : input stream. 64 | * 65 | * return: true if next data is a bool, false if not 66 | * 67 | */ 68 | bool msgpck_bool_next(Stream * s); 69 | 70 | /** 71 | * Function: msgpck_integer_next 72 | * Description: Look at Stream s's buffer and return the type of the first data in it. 73 | * 74 | * Parameter: Stream * s : input stream. 75 | * 76 | * return: true if next data is an integer (signed or not), false if not 77 | * 78 | */ 79 | bool msgpck_integer_next(Stream * s); 80 | 81 | /** 82 | * Function: msgpck_signed_next 83 | * Description: Look at Stream s's buffer and return the type of the first data in it. 84 | * 85 | * Parameter: Stream * s : input stream. 86 | * 87 | * return: true if next data is a signed integer, false if not 88 | * 89 | */ 90 | bool msgpck_signed_next(Stream * s); 91 | 92 | /** 93 | * Function: msgpck_float_next 94 | * Description: Look at Stream s's buffer and return the type of the first data in it. 95 | * 96 | * Parameter: Stream * s : input stream. 97 | * 98 | * return: true if next data is a float (on 4 bytes), false if not 99 | * 100 | */ 101 | bool msgpck_float_next(Stream * s); 102 | 103 | /** 104 | * Function: msgpck_string_next 105 | * Description: Look at Stream s's buffer and return the type of the first data in it. 106 | * 107 | * Parameter: Stream * s : input stream. 108 | * 109 | * return: true if next data is a String, false if not 110 | * 111 | */ 112 | bool msgpck_string_next(Stream * s); 113 | 114 | /** 115 | * Function: msgpck_bin_next 116 | * Description: Look at Stream s's buffer and return the type of the first data in it. 117 | * 118 | * Parameter: Stream * s : input stream. 119 | * 120 | * return: true if next data is a binary format, false if not 121 | * 122 | */ 123 | bool msgpck_bin_next(Stream * s); 124 | 125 | /** 126 | * Function: msgpck_array_next 127 | * Description: Look at Stream s's buffer and return the type of the first data in it. 128 | * 129 | * Parameter: Stream * s : input stream. 130 | * 131 | * return: true if next data is an array, false if not 132 | * 133 | */ 134 | bool msgpck_array_next(Stream * s); 135 | 136 | /** 137 | * Function: msgpck_map_next 138 | * Description: Look at Stream s's buffer and return the type of the first data in it. 139 | * 140 | * Parameter: Stream * s : input stream. 141 | * 142 | * return: true if next data is a map, false if not 143 | * 144 | */ 145 | bool msgpck_map_next(Stream * s); 146 | 147 | 148 | // ************************** Readers *****************************/ 149 | 150 | /** 151 | * Function: msgpck_read_nil 152 | * Description: Read the first data of Stream s's buffer if it is a nil. 153 | * 154 | * Parameter: Stream * s : input stream. 155 | * 156 | * return: true if next data has been read correctly, false if not 157 | * 158 | */ 159 | bool msgpck_read_nil(Stream * s); 160 | 161 | /** 162 | * Function: msgpck_read_bool 163 | * Description: Read the first data of Stream s's buffer if it is a bool. 164 | * 165 | * Parameter: Stream * s : input stream. 166 | * bool * b: pointer to the read value. 167 | * 168 | * return: true if next data has been read correctly, false if not 169 | * 170 | */ 171 | bool msgpck_read_bool(Stream * s, bool *b); 172 | 173 | /** 174 | * Function: msgpck_read_integer 175 | * Description: Read the first data of Stream s's buffer if it is an integer. 176 | * 177 | * Parameter: Stream * s : input stream. 178 | * byte * b: pointer to the read value. 179 | * uint8_t max_size: max size in byte of the expected value. 180 | * 181 | * return: true if next data has been read correctly, false if not 182 | * 183 | */ 184 | bool msgpck_read_integer(Stream * s, byte *b, uint8_t max_size); 185 | 186 | /** 187 | * Function: msgpck_read_float 188 | * Description: Read the first data of Stream s's buffer if it is a float. 189 | * 190 | * Parameter: Stream * s : input stream. 191 | * float * f: pointer to the read value. 192 | * 193 | * return: true if next data has been read correctly, false if not 194 | * 195 | */ 196 | bool msgpck_read_float(Stream * s, float *f); 197 | 198 | /** 199 | * Function: msgpck_read_string 200 | * Description: Read the first data of Stream s's buffer if it is a string. 201 | * 202 | * Parameter: Stream * s : input stream. 203 | * char * str: pointer to the read value. 204 | * uint32_t max_size: max size in byte of the expected value. 205 | * uint32_t *str_size: pointer to the actual size of the read string 206 | * 207 | * return: true if next data has been read correctly, false if not 208 | * 209 | */ 210 | bool msgpck_read_string(Stream * s, char * str, uint32_t max_size, uint32_t *str_size); 211 | 212 | /** 213 | * Function: msgpck_read_string 214 | * Description: Read the first data of Stream s's buffer if it is a string. 215 | * 216 | * Parameter: Stream * s : input stream. 217 | * Print * : output device 218 | * 219 | * return: true if next data has been read correctly, false if not 220 | * 221 | */ 222 | bool msgpck_read_string(Stream * s, Print * p); 223 | 224 | /** 225 | * Function: msgpck_read_string 226 | * Description: Read the first data of Stream s's buffer if it is a string. 227 | * 228 | * Parameter: Stream * s : input stream. 229 | * char * str: pointer to the read value. 230 | * uint32_t max_size: max size in byte of the expected value. 231 | * 232 | * return: true if next data has been read correctly, false if not 233 | * 234 | */ 235 | bool msgpck_read_string(Stream * s, char * str, uint32_t max_size); 236 | 237 | /** 238 | * Function: msgpck_read_bin 239 | * Description: Read the first data of Stream s's buffer if it is a bin. 240 | * 241 | * Parameter: Stream * s : input stream. 242 | * byte * bin: pointer to the read value. 243 | * uint32_t max_size: max size in byte of the expected value. 244 | * uint32_t *str_size: pointer to the actual size of the read bin 245 | * 246 | * return: true if next data has been read correctly, false if not 247 | * 248 | */ 249 | bool msgpck_read_bin(Stream * s, byte * bin, uint32_t max_size, uint32_t *bin_size); 250 | 251 | /** 252 | * Function: msgpck_read_bin 253 | * Description: Read the first data of Stream s's buffer if it is a bin. 254 | * 255 | * Parameter: Stream * s : input stream. 256 | * byte * bin: pointer to the read value. 257 | * uint32_t max_size: max size in byte of the expected value. 258 | * 259 | * return: true if next data has been read correctly, false if not 260 | * 261 | */ 262 | bool msgpck_read_bin(Stream * s, byte * bin, uint32_t max_size); 263 | 264 | /** 265 | * Function: msgpck_read_bin 266 | * Description: Read the first data of Stream s's buffer if it is a bin. 267 | * 268 | * Parameter: Stream * s : input stream. 269 | * Print * s : output device. 270 | * 271 | * return: true if next data has been read correctly, false if not 272 | * 273 | */ 274 | bool msgpck_read_bin(Stream * s, Print * p); 275 | 276 | /** 277 | * Function: msgpck_read_bin_human 278 | * Description: Read the first data of Stream s's buffer if it is a bin. 279 | * Data are formatted into a string where each bytes are prefixed with 280 | * 0x... 281 | * 282 | * Parameter: Stream * s : input stream. 283 | * Print * s : output device. 284 | * 285 | * return: true if next data has been read correctly, false if not 286 | * 287 | */ 288 | bool msgpck_read_bin_human(Stream * s, Print * p); 289 | 290 | /** 291 | * Function: msgpck_read_array_size 292 | * Description: Read the header of the incoming array. 293 | * 294 | * Parameter: Stream * s : input stream. 295 | * uint32_t * array_size: pointer to the read size of the incoming array 296 | * 297 | * return: true if next data has been read correctly, false if not 298 | * 299 | */ 300 | bool msgpck_read_array_size(Stream * s, uint32_t * array_size); 301 | 302 | /** 303 | * Function: msgpck_read_map_size 304 | * Description: Read the header of the incoming map. 305 | * 306 | * Parameter: Stream * s : input stream. 307 | * uint32_t * map_size: pointer to the read size of the incoming map 308 | * 309 | * Warning: map_size will contain the number of pair (key, element) 310 | * 311 | * return: true if next data has been read correctly, false if not 312 | * 313 | */ 314 | bool msgpck_read_map_size(Stream * s, uint32_t * map_size); 315 | 316 | 317 | // ************************** Writers *****************************/ 318 | 319 | /** 320 | * Function: msgpck_write_nil 321 | * Description: Write nil on the output stream 322 | * 323 | * Parameter: Print * s : output stream. 324 | * 325 | */ 326 | void msgpck_write_nil(Print * s); 327 | 328 | /** 329 | * Function: msgpck_write_bool 330 | * Description: Write a bool data on the output stream 331 | * 332 | * Parameter: Print * s : output stream. 333 | * bool b: bool value to write 334 | * 335 | */ 336 | void msgpck_write_bool(Print * s, bool b); 337 | 338 | /** 339 | * Function: msgpck_write_integer 340 | * Description: Write an integer data on the output stream 341 | * 342 | * Parameter: Print * s : output stream. 343 | * uint8_t u: integer value to write 344 | * 345 | */ 346 | void msgpck_write_integer(Print * s, uint8_t u); 347 | 348 | /** 349 | * Function: msgpck_write_integer 350 | * Description: Write an integer data on the output stream 351 | * 352 | * Parameter: Print * s : output stream. 353 | * uint16_t u: integer value to write 354 | * 355 | */ 356 | void msgpck_write_integer(Print * s, uint16_t u); 357 | 358 | /** 359 | * Function: msgpck_write_integer 360 | * Description: Write an integer data on the output stream 361 | * 362 | * Parameter: Print * s : output stream. 363 | * uint32_t u: integer value to write 364 | * 365 | */ 366 | void msgpck_write_integer(Print * s, uint32_t u); 367 | 368 | /** 369 | * Function: msgpck_write_integer 370 | * Description: Write an integer data on the output stream 371 | * 372 | * Parameter: Print * s : output stream. 373 | * uint64_t u: integer value to write 374 | * 375 | */ 376 | void msgpck_write_integer(Print * s, uint64_t u); 377 | 378 | /** 379 | * Function: msgpck_write_integer 380 | * Description: Write an integer data on the output stream 381 | * 382 | * Parameter: Print * s : output stream. 383 | * int8_t i: integer value to write 384 | * 385 | */ 386 | void msgpck_write_integer(Print * s, int8_t i); 387 | 388 | /** 389 | * Function: msgpck_write_integer 390 | * Description: Write an integer data on the output stream 391 | * 392 | * Parameter: Print * s : output stream. 393 | * int16_t i: integer value to write 394 | * 395 | */ 396 | void msgpck_write_integer(Print * s, int16_t i); 397 | 398 | /** 399 | * Function: msgpck_write_integer 400 | * Description: Write an integer data on the output stream 401 | * 402 | * Parameter: Print * s : output stream. 403 | * int32_t i: integer value to write 404 | * 405 | */ 406 | void msgpck_write_integer(Print * s, int32_t i); 407 | 408 | /** 409 | * Function: msgpck_write_integer 410 | * Description: Write an integer data on the output stream 411 | * 412 | * Parameter: Print * s : output stream. 413 | * int64_t i: integer value to write 414 | * 415 | */ 416 | void msgpck_write_integer(Print * s, int64_t i); 417 | 418 | /** 419 | * Function: msgpck_write_float 420 | * Description: Write a float data on the output stream 421 | * 422 | * Parameter: Print * s : output stream. 423 | * float f: float value to write 424 | * 425 | */ 426 | void msgpck_write_float(Print *s, float f); 427 | 428 | /** 429 | * Function: msgpck_write_string 430 | * Description: Write string on the output stream 431 | * 432 | * Parameter: Print * s : output stream. 433 | * char * str: a string to write 434 | * uint32_t str_size: size of the string to write 435 | * 436 | */ 437 | void msgpck_write_string(Print * s, char * str, uint32_t str_size); 438 | 439 | /** 440 | * Function: msgpck_write_string 441 | * Description: Write a string on the output stream 442 | * 443 | * Parameter: Print * s : output stream. 444 | * String str: string to write 445 | * 446 | */ 447 | void msgpck_write_string(Print * s, String str); 448 | 449 | /** 450 | * Function: msgpck_write_bin 451 | * Description: Write a bin data on the output stream 452 | * 453 | * Parameter: Print * s : output stream. 454 | * byte * b: bin to write 455 | * uint32_t bin_size: size of the bin to write 456 | * 457 | */ 458 | void msgpck_write_bin(Print * s, byte * b, uint32_t bin_size); 459 | 460 | /** 461 | * Function: msgpck_write_array_header 462 | * Description: Write the header of an array on the output stream 463 | * 464 | * Parameter: Print * s : output stream. 465 | * uint32_t ar_size: numder of element in the array 466 | * 467 | */ 468 | void msgpck_write_array_header(Print * s, uint32_t ar_size); 469 | 470 | /** 471 | * Function: msgpck_write_map_header 472 | * Description: Write the header of a map on the output stream 473 | * 474 | * Parameter: Print * s : output stream. 475 | * uint32_t ar_size: numder of pair (key, element) in the map 476 | * 477 | */ 478 | void msgpck_write_map_header(Print * s, uint32_t map_size); 479 | 480 | /** 481 | * Function: msgpck_to_json 482 | * Description: read messagepack data on the input and write json on the ouput 483 | * 484 | * Parameter: Print * output : output stream. 485 | * Stream * input : input stream. 486 | * 487 | */ 488 | void msgpck_to_json(Print * output, Stream * input); 489 | 490 | #endif 491 | --------------------------------------------------------------------------------