jsmn is a minimalistic and high-performance JSON parser written in C, particularly suitable for use in resource-constrained embedded environments. Its design goal is to maintain a very small code size and memory footprint while not relying on any external libraries.
The table below summarizes the main features of jsmn for quick reference:
| Feature Category | Details |
|---|---|
| Code and Dependencies | Approximately 200 lines of code, with no library dependencies (not even libc), highly portable |
| Memory and Performance | No dynamic memory allocation, fast parsing speed, minimal memory overhead |
| API Design | Extremely simple API, with only two main functions |
| Compatibility | Compatible with C89, high code portability |
🛠️ Installation and Project Integration
Getting the Source Code
The source code for jsmn is hosted on GitHub, and you can clone the repository directly:
git clone https://github.com/zserge/jsmn.git
Compilation and Integration
Compiling jsmn is very straightforward. After entering the source directory, you can compile it using the make command. The project directory mainly contains the following files:
jsmn.c: The main implementation file of the library.jsmn.h: Contains function declarations and necessary macro definitions.demo.c: Example code demonstrating basic usage.
To integrate jsmn into your project, you typically only need to:
- Add
#include "jsmn.h"in your source code. - Compile and link
jsmn.cduring the build, for example:
gcc -o your_program your_program.c jsmn/jsmn.c -Ijsmn
💻 Core Usage and Code Example
When jsmn parses JSON, it breaks the string into a series of tokens. Each token corresponds to a data segment in the JSON, recording its starting position, ending position, and type in the string.
Basic Usage Flow
The following example demonstrates the basic steps for using jsmn to parse JSON:
#include <stdio.h>
#include <string.h>
#include "jsmn.h" // Include jsmn header file
// A helper function to compare the content of tokens in the JSON string with a given string
static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
return 0;
}
return -1;
}
int main() {
// 1. Define the JSON string to be parsed
const char *json_string = "{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000}";
jsmn_parser p; // Declare parser object
jsmntok_t t[128]; // Pre-allocate a token array (token pool)
jsmn_init(&p); // Initialize parser
// 2. Execute parsing
int num_tokens = jsmn_parse(&p, json_string, strlen(json_string), t, sizeof(t)/sizeof(t[0]));
if (num_tokens < 0) {
printf("Parsing failed, error code: %d\n", num_tokens);
return 1;
}
// 3. Loop through all tokens to extract needed data
for (int i = 1; i < num_tokens; i++) {
if (jsoneq(json_string, &t[i], "user") == 0) {
// Use the position information in the token to directly print the segment from the original JSON string
printf("- user: %.*s\n", t[i+1].end - t[i+1].start, json_string + t[i+1].start);
i++; // Skip the next token, as it is the value of the current key
} else if (jsoneq(json_string, &t[i], "uid") == 0) {
printf("- UID: %.*s\n", t[i+1].end - t[i+1].start, json_string + t[i+1].start);
i++;
}
}
return 0;
}
💡 Advanced Applications and Considerations
- Handling Large JSON Data: For large JSON data, you can adjust the size of the token pool to ensure there is enough space to accommodate all tokens.
- Configuring Compilation Options:
jsmnprovides several compilation options, such asJSMN_STRICTfor enabling stricter JSON syntax checks, which can be defined at compile time using the-Dflag.
🔄 Comparison with Other Libraries
jsmn and cJSON are both commonly used JSON parsing libraries in C, but they differ in their positioning and implementation:
| Feature | jsmn | cJSON |
|---|---|---|
| Design Philosophy | Minimalism, only performs token parsing | Feature-rich, builds a complete DOM tree |
| Memory Management | No dynamic memory allocation, user must pre-allocate token pool | Uses dynamic memory allocation, must be manually freed |
| Code Size | Extremely small code footprint | Relatively larger |
| Use Cases | Extremely resource-constrained embedded systems | Relatively resource-rich scenarios requiring convenient operations |
In simple terms, jsmn provides you with raw materials (tokens) that you need to process yourself; whereas cJSON provides pre-processed parts. When choosing, if your system resources are very tight and primarily focused on JSON parsing rather than construction, jsmn is the better choice.