jansson 1.0.0 clib Data Formats

Battle-tested C JSON library with a clean API, reference-counted memory management, strict type checking, and full UTF-8 support. The go-to JSON engine for native PascalAI.

ppm install jansson

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:

CLib package — requires libjansson-dev

Ubuntu / Debian: sudo apt install libjansson-dev  |  Fedora: sudo dnf install jansson-devel

jansson vs other JSON libraries

LibraryStrengthsWeaknesses
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:

ConstantValueMeaning
jstObject0JSON object {}
jstArray1JSON array []
jstString2JSON string
jstInteger364-bit signed integer
jstReal4IEEE 754 double
jstTrue5Boolean true
jstFalse6Boolean false
jstNull7JSON null

TJSError

Returned by ParseStringEx on failure:

FieldTypeDescription
TextstringHuman-readable error message
SourcestringSource label (e.g. filename or <string>)
LineInteger1-based line number where parsing failed
ColumnInteger1-based column number
PositionIntegerByte offset from start of input

TJSEncodeFlags

Passed to DumpsEx to control serialization output:

FieldTypeDescription
CompactBooleanOmit all non-essential whitespace
EnsureASCIIBooleanEscape non-ASCII characters as \uXXXX
SortKeysBooleanSort object keys alphabetically
IndentIntegerSpaces per indent level (0 = compact)

API Reference

Parse

fn
ParseString(const JSON: string): TJSValue
Parse a JSON string. Returns 0 on error.
fn
ParseFile(const Path: string): TJSValue
Parse a JSON file from disk. Returns 0 on error.
fn
ParseStringEx(const JSON: string; out Err: TJSError): TJSValue
Parse and populate TJSError with line/column info on failure.

Serialize

fn
Dumps(V: TJSValue): string
Serialize to compact JSON string.
fn
DumpsPretty(V: TJSValue; Indent: Integer): string
Serialize with pretty-printing. Indent = spaces per level (e.g. 2 or 4).
fn
DumpsEx(V: TJSValue; const Flags: TJSEncodeFlags): string
Serialize with full flag control (compact, ASCII escaping, sorted keys).
proc
DumpFile(V: TJSValue; const Path: string; Indent: Integer)
Write serialized JSON directly to a file.

Type Checking

fn
GetType(V: TJSValue): TJSType
Return the TJSType enum value for a JSON value.
fn
IsObject / IsArray / IsString(V: TJSValue): Boolean
Type predicates for the three structural types.
fn
IsInteger / IsReal / IsNumber(V: TJSValue): Boolean
IsNumber returns true for both integer and real values.
fn
IsTrue / IsFalse / IsBool / IsNull(V: TJSValue): Boolean
IsBool returns true for either true or false JSON values.

Create Values

fn
NewObject: TJSValue  |  NewArray: TJSValue
Create an empty JSON object or array.
fn
NewString(const S: string): TJSValue
Create a JSON string value.
fn
NewInteger(V: Int64): TJSValue
Create a JSON integer value.
fn
NewReal(V: Double): TJSValue
Create a JSON real (double) value.
fn
NewBool(V: Boolean): TJSValue  |  NewNull: TJSValue
Create a JSON boolean or null value.

Extract Values

fn
GetString(V: TJSValue): string
Extract string content. V must be a string value.
fn
GetInteger(V: TJSValue): Int64
Extract integer. V must be an integer value.
fn
GetReal(V: TJSValue): Double
Extract real. V must be a real value.
fn
GetNumber(V: TJSValue): Double
Extract numeric value coerced to Double; works for both integer and real.
fn
GetBool(V: TJSValue): Boolean
Extract boolean. V must be a true or false value.

Object Operations

fn
ObjGet(Obj: TJSValue; const Key: string): TJSValue
Get a field by key. Returns 0 if the key does not exist.
proc
ObjSet(Obj: TJSValue; const Key: string; Val: TJSValue)
Set (or replace) a field. Steals the reference to Val.
proc
ObjDelete(Obj: TJSValue; const Key: string)
Remove a field by key. No-op if key does not exist.
fn
ObjHas(Obj: TJSValue; const Key: string): Boolean
Return true if the key exists in the object.
fn
ObjKeys(Obj: TJSValue): array of string
Return all object keys as a string array.
fn
ObjSize(Obj: TJSValue): Integer
Number of fields in the object.
proc
ObjMerge(Obj, Other: TJSValue)
Shallow-merge Other into Obj. Existing keys are overwritten.

Array Operations

fn
ArrGet(Arr: TJSValue; Index: Integer): TJSValue
Get element at index. Returns 0 if out of bounds.
proc
ArrAppend(Arr: TJSValue; Val: TJSValue)
Append an element. Steals the reference to Val.
proc
ArrInsert(Arr: TJSValue; Index: Integer; Val: TJSValue)
Insert element before the given index.
proc
ArrRemove(Arr: TJSValue; Index: Integer)
Remove element at index, shifting subsequent elements down.
fn
ArrSize(Arr: TJSValue): Integer
Number of elements in the array.
proc
ArrClear(Arr: TJSValue)
Remove all elements from the array.

Path Access

Dot-notation paths traverse nested objects and arrays. Use integer segments to index into arrays: 'users.0.name', 'config.db.host'.

fn
PathGet(Root: TJSValue; const Path: string): TJSValue
Traverse path and return the value. Returns 0 if any segment is missing.
fn
PathGetStr(Root: TJSValue; const Path: string): string
Convenience: traverse path and extract string value.
fn
PathGetInt(Root: TJSValue; const Path: string): Int64
Convenience: traverse path and extract integer value.

Memory Management

proc
IncRef(V: TJSValue)
Increment the reference count of V (keep alive across scope).
proc
DecRef(V: TJSValue)
Decrement reference count. When it reaches zero the entire subtree is freed.
fn
DeepCopy(V: TJSValue): TJSValue
Return an independent deep copy of V with reference count 1.

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.
Memory management note

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

$ ppm install jansson
Requires: libjansson-dev

Package Info

Version1.0.0
Typeclib
C Librarylibjansson
LicenseMIT
Authorgustavo

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