Skip to content

JSON de-serialization "library" optimized for high speed, low resource usage on 8/32-bit microcontrollers

Notifications You must be signed in to change notification settings

sylt-collab/SYLT-JSON

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SYLT-JSON

LOW-LEVEL JSON PARSING/TOKENIZER LIBRARY

And some other funky character conversion stuff, like Base-64 and Latin-1 to/from UTF-8

Resource optimized for small 8-bit and 32-bit microcontrollers

Authors:

  • D. Taylor 2018 (gmail: senseitg)

License:

  • Ask and thou shalt receive

Features:

  • Parses and validates JSON very fast
  • Fully compliant and well tested against https://github.com/nst/JSONTestSuite
  • No dynamic memory allocation
  • Delivers tokens via callback
  • Handles JSON in RAM as well as streaming JSON
  • Designed for UTF-8

Options (*.h):

  • Configurable max nesting depth
  • Configurable standards-breaking optimizations
  • Configurable data sizes for number representation

Resource requirements:

  • Minimal memory requirements (not even 32 bytes of RAM)
  • Minimal stack use (non-recursive, few local variables)
  • Minimal program space (lean, compact code)
  • No heap use

Notes:

  • Designed for high speed, low footprint - not a rich feature set.

Caveats:

  • No UTF-8 error checking - strings delivered as is
  • No UTF-16
  • Requires C99 to compile (-std=c99 for GCC)

Performance:

  • Pretty darn good. You do the comparisons!

WhatDoesItDo™:

It takes JSON data in RAM:

char json[] = "{\"JSON\":\"We haz it\"}";
result = json_parse(json, strlen(json), print_json, NULL);

Or it takes a stream of JSON data:

char jsbuf[32]; // String extraction buffer
json_parser_ctx ctx = json_stream(jsbuf, sizeof(jsbuf), print_json, NULL);
while(!your_stream_eof()) {
  result = json_octet(&ctx, your_stream_read());
  if(result) break;
}

And delivers the contents to a custom callback function (example):

uint8_t print_json(uint32_t depth, uint8_t type, void * value, void * user) {
  uint8_t n;
  for(n = 0; n < depth; n++) printf("  ");
  switch(type) {
    case JSON_OBJECT:     printf("{"); break;
    case JSON_OBJECT_END: printf("}"); break;
    case JSON_ARRAY:      printf("["); break;
    case JSON_ARRAY_END:  printf("]"); break;
		case JSON_KEY:        printf("\"%s\" : ", json_to_string(value));
    case JSON_STRING:     printf("\"%s\"", json_to_string(value)); break;
    case JSON_NUMBER:     printf("%0.10g", json_to_double(value)); break;
    default:              printf("%s", json_const_str(type));
  }
  printf("\n");
  return JSON_OK;
}

Thus, converting this JSON string:

[null, -1.23000456789e+2, false, "Sing ♪ a \u266B song", {"var" : [0.0, 1.500, 2, {}]}]

Into this result (printed by the callback example as shown above):

[
  null
  -123.0004567
  false
  "Sing ♪ a ♫ song"
  {
    "var" : [
      0
      1.5
      2
      {
      }
    ]
  }
]

Of course, the callback function can be anything you desire.
I mostly use it to parse configuration files by implementing a small state machine that extracts all fields of interest.

About

JSON de-serialization "library" optimized for high speed, low resource usage on 8/32-bit microcontrollers

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages