Code Monkey home page Code Monkey logo

jsmn-find's Introduction

JSMN-FIND

jsmn-find is an ANSI C add-on for the minimalistic JSON tokenizer jsmn, it offers a familiar and zero-allocation design. Its serializer counterpart can be found at json-build.

Dependencies

  • jsmn - Minimalistic JSON parser

Included Dependencies

  • chash - Type-safe, stackful hashtable

Design

jsmn-find organizes jsmn's JSON tokens under a hashtable so that they can be searched for in linear time.

Usage

Download jsmn-find.h and the dependencies should be visible to your linker search path:

load (zero-allocation)

#include "jsmn.h"
#include "jsmn-find.h"

...
jsmn_parser parser;
jsmntok_t tokens[256];

jsmn_init(&parser);
r = jsmn_parse(&parser, json, strlen(json), tokens, 256);
if (r < 0) error();

// populate jsmnf_pairs with the jsmn tokens
jsmnf_loader loader;
jsmnf_pair pairs[256];

jsmnf_init(&loader);
r = jsmnf_load(&loader, json, tokens, parser.toknext, pairs, 256);
if (r < 0) error();

auto load (allocate memory for jsmn tokens and jsmnf pairs as necessary)

#include "jsmn.h"
#include "jsmn-find.h"

...
jsmn_parser parser;
jsmntok_t *toks = NULL;
unsigned num_tokens = 0;

jsmn_init(&parser);
r = jsmn_parse_auto(&parser, json, strlen(json), &toks, &num_tokens);
if (r <= 0) error();

// populate jsmnf_pairs with the jsmn tokens
jsmnf_loader loader;
jsmnf_pair *pairs = NULL;
unsigned num_pairs = 0;

jsmnf_init(&loader);
r = jsmnf_load_auto(&loader, json, toks, num_tokens, &pairs, &num_pairs);
if (r <= 0) error();

...
free(toks);
free(pairs);

find by key

jsmnf_pair *f;

// assume the JSON : { "foo": { "bar": [ true, null, null ] } }
if ((f = jsmnf_find(pairs, json, "foo", strlen("foo")))) {
    // Found: { "bar" : [ true, null, null ] }
    printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos);
    if ((f = jsmnf_find(f, json, "bar", 3))) {
        // Found: [ true, null, null ]
        printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos);
        if ((f = jsmn_find(f, json, "0", 1))) {
            // Found: true
            printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos);
        }
    }
}

index access for arrays

jsmnf_pair *f;

// assume the JSON : [ false, [ true ] ]
f = &pairs->fields[1];
printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos); // Found: [ true ]
f = &f->fields[0]; // get nested array
printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos); // Found: true

// looping over array
for (int i = 0; pairs->size; ++i) {
    f = &pairs->fields[i];
    printf("%.*s ", (int)f->v.len, json + f->v.pos);
}

find by path

// assume the JSON : [ false, false, [ false, [ { "b":true } ] ] ]
char *path[] = { "2", "1", "0", "b" }; // array keys are the same as its indexes
jsmnf_pair *f;

if ((f = jsmnf_find_path(pairs, json, path, sizeof(path) / sizeof *path))) {
    // Found: true
    printf("Found: %.*s\n", (int)f->v.len, json + f->v.pos);
}

jsmn-find is single-header and should be compatible with jsmn additional macros for more complex uses cases. #define JSMN_STATIC hides all jsmn-find API symbols by making them static. Also, if you want to include jsmn-find.h from multiple C files, to avoid duplication of symbols you may define JSMN_HEADER macro.

/* In every .c file that uses jsmn include only declarations: */
#define JSMN_HEADER
#include "jsmn.h"
#include "jsmn-find.h"

/* Additionally, create one jsmn-find.c file for jsmn-find implementation: */
#include "jsmn.h"
#include "jsmn-find.h"

API

  • jsmnf_init() - initialize a jsmnf_loader
  • jsmnf_load() - populate jsmnf_pair array with JSMN tokens
  • jsmnf_find() - locate a jsmnf_pair by its associated key
  • jsmnf_find_path() - locate a jsmnf_pair by its full key path

Misc

  • jsmn_parse_auto() - jsmn_parse() counterpart that allocates the necessary amount of tokens
  • jsmnf_load_auto() - jsmn_load() counterpart that allocates the necessary amount of pairs
  • jsmnf_unescape() - unescape a Unicode string

Other Info

This software is distributed under MIT license, so feel free to integrate it in your commercial products.

jsmn-find's People

Contributors

jdeokkim avatar lcsmuller avatar ratakor avatar tarbomb avatar thepedroo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

thepedroo

jsmn-find's Issues

Rewrite this lib as being a `jsmn` fork instead of an add-on

Describe the feature

There's not much to gain in making this library depend on jsmn.h to be used. It should be updated as a jsmn fork instead.

Acceptance criteria

  • Match jsmn codebase with this lib's syntax rules
  • Get rid of unneeded jsmn features
  • Rename this lib to json-lookup
  • (bonus) Can we get rid of chash dependency aswell? Is it viable?

Bug in memory allocation fix

Hi,

during my tests I found a bug in the fix for #20. I had issues with corruption of already declared tokens.

Memset in following code will start at wrong address
memset((tmp) + *(prev_size), 0, (new_size - *(prev_size)) * sizeof *(ptr));

I think correct code should looks like:
memset((tmp) + *(prev_size) * sizeof *(ptr), 0, (new_size - *(prev_size)) * sizeof *(ptr));

Test string: "{"status":"enabled","timestamp":"2023-08-24T07:59:03Z"}\n"
Fails with: JSMN_ERROR_INVAL, unmatched closing bracket

BR,
Diego

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.