What is Jansson?
Jansson is a mature C library for encoding, decoding, and manipulating JSON data. Unlike purpose-built scripting-language parsers, Jansson has been in production for over a decade and is trusted by major open-source projects including curl, Keepalived, Suricata, and NetworkManager.
Key properties that make it the right choice for PascalAI:
- ✓ Clean API — intuitive, symmetrical function names for every JSON operation
- ✓ Reference counting — automatic memory management; no manual tree walks
- ✓ Full UTF-8 support — handles any Unicode payload without extra configuration
- ✓ Strict type checking — distinguishes integers from reals, true/false from null
- ✓ Thread-safe — no global mutable state; safe to use from concurrent agents
- ✓ Battle-tested — in production use since 2009, zero external dependencies
Ubuntu / Debian: sudo apt install libjansson-dev | Fedora: sudo dnf install jansson-devel
jansson vs other JSON libraries
| Library | Strengths | Weaknesses |
|---|---|---|
| jansson | Battle-tested, clean symmetrical API, ref-counting, strict types, thread-safe | Slightly slower than yyjson on micro-benchmarks |
| cJSON | Very small footprint, easy to embed | Weaker error handling, no ref-counting, less strict types |
| yyjson | Fastest parser available, SIMD-optimized | Newer, smaller ecosystem, immutable-by-default API is verbose |
| json-c | Similar broad scope, also ref-counted | Messier API conventions, less consistent naming |
Types
Jansson exposes four types to PascalAI programs:
TJSValue
An opaque handle (Integer) representing a reference-counted JSON value. All parse, create, and manipulation functions return or accept a TJSValue. A value of 0 indicates nil / parse error.
TJSType
Enumeration returned by GetType:
| Constant | Value | Meaning |
|---|---|---|
| jstObject | 0 | JSON object {} |
| jstArray | 1 | JSON array [] |
| jstString | 2 | JSON string |
| jstInteger | 3 | 64-bit signed integer |
| jstReal | 4 | IEEE 754 double |
| jstTrue | 5 | Boolean true |
| jstFalse | 6 | Boolean false |
| jstNull | 7 | JSON null |
TJSError
Returned by ParseStringEx on failure:
| Field | Type | Description |
|---|---|---|
| Text | string | Human-readable error message |
| Source | string | Source label (e.g. filename or <string>) |
| Line | Integer | 1-based line number where parsing failed |
| Column | Integer | 1-based column number |
| Position | Integer | Byte offset from start of input |
TJSEncodeFlags
Passed to DumpsEx to control serialization output:
| Field | Type | Description |
|---|---|---|
| Compact | Boolean | Omit all non-essential whitespace |
| EnsureASCII | Boolean | Escape non-ASCII characters as \uXXXX |
| SortKeys | Boolean | Sort object keys alphabetically |
| Indent | Integer | Spaces per indent level (0 = compact) |
API Reference
Parse
Serialize
Type Checking
Create Values
Extract Values
Object Operations
Array Operations
Path Access
Dot-notation paths traverse nested objects and arrays. Use integer segments to index into arrays: 'users.0.name', 'config.db.host'.
Memory Management
Code Example
uses jansson;
var
Root, Users, User: TJSValue;
JSON: string;
begin
{ Build a JSON document from scratch }
Root := NewObject;
ObjSet(Root, 'app', NewString('MyApp'));
ObjSet(Root, 'version', NewInteger(2));
Users := NewArray;
User := NewObject;
ObjSet(User, 'name', NewString('Alice'));
ObjSet(User, 'age', NewInteger(30));
ArrAppend(Users, User); { User ref stolen by ArrAppend }
ObjSet(Root, 'users', Users); { Users ref stolen by ObjSet }
JSON := DumpsPretty(Root, 2);
WriteLn(JSON);
{ Path access on parsed data }
Root := ParseString('{"users":[{"name":"Bob","score":9.5}]}');
WriteLn(PathGetStr(Root, 'users.0.name')); { Bob }
WriteLn(PathGet(Root, 'users.0.score') <> 0); { true }
{ Always DecRef the root when done }
DecRef(Root);
end.
Error Handling
var
V: TJSValue;
Err: TJSError;
begin
V := ParseStringEx('{"broken": }', Err);
if V = 0 then
WriteLn('Parse error at line ', Err.Line, ' col ', Err.Column,
': ', Err.Text)
else
DecRef(V);
end.
Jansson uses reference counting. ObjSet and ArrAppend steal the
reference of the value passed in — do not call DecRef on child values after handing
them to a container. Call DecRef(Root) once when the entire document is no longer needed;
all nested values are freed automatically as the reference cascade reaches zero.
Install
libjansson-devPackage Info
Used By
- • curl (HTTP client)
- • Suricata (IDS/IPS)
- • NetworkManager
- • Keepalived (HA)
Functions
- ParseString / ParseFile
- ParseStringEx
- Dumps / DumpsPretty
- DumpsEx / DumpFile
- GetType
- IsObject / IsArray
- IsString / IsInteger
- IsReal / IsBool / IsNull
- IsNumber / IsTrue / IsFalse
- NewObject / NewArray
- NewString / NewInteger
- NewReal / NewBool / NewNull
- GetString / GetInteger
- GetReal / GetNumber / GetBool
- ObjGet / ObjSet
- ObjDelete / ObjHas
- ObjKeys / ObjSize / ObjMerge
- ArrGet / ArrAppend
- ArrInsert / ArrRemove
- ArrSize / ArrClear
- PathGet / PathGetStr
- PathGetInt
- IncRef / DecRef
- DeepCopy
- JanssonVersion
See Also
- json-parser (pure PAI)
- yaml (YAML support)
- toml (TOML support)
- msgpack (binary)
- curl (HTTP + JSON)