Specification: Core | Import | Alternate Names | Symbols, Units, Currencies | Validation | Conditional Composition

JSON Structure

Logo

JSON Structure is a data structure definition language that enforces strict typing, modularity, and determinism.

View the Project on GitHub json-structure

JSON Structure C/C++ SDK

A portable, C99-compatible JSON Structure schema validator with modern C++11 bindings. Designed for embedded systems and cross-platform development.

Features

Installation

vcpkg

vcpkg install json-structure

# With regex support
vcpkg install json-structure[regex]

Then in your CMakeLists.txt:

find_package(json_structure CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE json_structure::json_structure)

Manual Build

Dependencies

Prerequisites

Build Steps

# Create build directory
mkdir build && cd build

# Configure (downloads cJSON automatically)
cmake .. -DCMAKE_BUILD_TYPE=Release

# Build
cmake --build .

# Run tests
ctest

CMake Options

Option Default Description
JS_BUILD_TESTS ON Build test suite
JS_BUILD_EXAMPLES ON Build example programs
JS_ENABLE_REGEX OFF Enable regex validation (requires PCRE2)
JS_FETCH_DEPENDENCIES ON Auto-fetch cJSON via FetchContent

Usage

C API

#include <json_structure/json_structure.h>

int main(void) {
    const char* schema = "{\"type\": \"string\", \"minLength\": 1}";
    const char* instance = "\"hello\"";
    
    js_result_t result;
    
    // Validate schema
    if (js_validate_schema(schema, &result)) {
        printf("Schema is valid\n");
    }
    js_result_cleanup(&result);
    
    // Validate instance
    if (js_validate_instance(instance, schema, &result)) {
        printf("Instance is valid\n");
    } else {
        for (size_t i = 0; i < result.error_count; i++) {
            printf("Error: %s\n", result.errors[i].message);
        }
    }
    js_result_cleanup(&result);
    
    return 0;
}

C++ API

#include <json_structure/json_structure.hpp>

int main() {
    using namespace json_structure;
    
    std::string schema = R"({"type": "string", "minLength": 1})";
    std::string instance = R"("hello")";
    
    // Validate schema
    auto schemaResult = validate_schema(schema);
    if (schemaResult) {
        std::cout << "Schema is valid" << std::endl;
    }
    
    // Validate instance
    auto instanceResult = validate_instance(instance, schema);
    if (instanceResult) {
        std::cout << "Instance is valid" << std::endl;
    } else {
        std::cout << "Errors: " << instanceResult.error_summary() << std::endl;
    }
    
    // Or use exceptions
    try {
        InstanceValidator validator;
        validator.validate_or_throw(instance, schema);
    } catch (const InstanceValidationException& e) {
        std::cerr << "Validation failed: " << e.what() << std::endl;
    }
    
    return 0;
}

Custom Allocator (Embedded Systems)

#include <json_structure/json_structure.h>

// Your custom allocator functions
static void* my_malloc(size_t size) { /* ... */ }
static void* my_realloc(void* ptr, size_t size) { /* ... */ }
static void my_free(void* ptr) { /* ... */ }

int main(void) {
    // Set custom allocator before any other calls
    js_allocator_t alloc = {
        .malloc_fn = my_malloc,
        .realloc_fn = my_realloc,
        .free_fn = my_free,
        .user_data = NULL
    };
    js_set_allocator(alloc);
    
    // Now all allocations use your functions
    // ...
    
    return 0;
}

Thread Safety

The JSON Structure C SDK is designed to be thread-safe for concurrent validation operations when used correctly:

Thread-Safe Operations

Usage Requirements

For thread-safe operation, follow these guidelines:

  1. Initialize once before threading:
    int main(void) {
        // Call js_init() once at program startup, before creating threads
        js_init();
           
        // Now safe to create threads that perform validation
        // ...
           
        return 0;
    }
    
  2. Do not change allocator during validation:
    // Set custom allocator BEFORE any validation operations
    js_init_with_allocator(my_allocator);
       
    // Do NOT call js_set_allocator() while validation is in progress
    
  3. Clean up after all threads complete:
    // Ensure all validation threads have finished
    // join_all_threads();
       
    // Then call cleanup once
    js_cleanup();
    

Thread-Safety Guarantees

Testing with ThreadSanitizer

To verify thread safety in your application, compile with ThreadSanitizer:

cmake .. -DCMAKE_C_FLAGS="-fsanitize=thread -g" -DCMAKE_CXX_FLAGS="-fsanitize=thread -g"
cmake --build .
ctest

API Reference

Core Types

Schema Validation

Instance Validation

Convenience Functions

Project Structure

c/
├── CMakeLists.txt          # Main build configuration
├── include/
│   └── json_structure/
│       ├── json_structure.h     # Main umbrella header (C)
│       ├── json_structure.hpp   # C++ bindings
│       ├── types.h              # Core type definitions
│       ├── error_codes.h        # Error enumerations
│       ├── schema_validator.h   # Schema validator API
│       └── instance_validator.h # Instance validator API
├── src/
│   ├── types.c                 # Type implementations
│   ├── error_codes.c           # Error string functions
│   ├── schema_validator.c      # Schema validation logic
│   ├── instance_validator.c    # Instance validation logic
│   └── json_source_locator.c   # Source location tracking
├── tests/
│   ├── main.c                  # Test runner
│   ├── test_types.c
│   ├── test_schema_validator.c
│   └── test_instance_validator.c
└── examples/
    ├── validate_schema.c       # C example
    └── validate_schema.cpp     # C++ example

License

MIT License. See LICENSE for details.

Contributing

See CONTRIBUTING.md for contribution guidelines.