pw_json#

Simple, efficient C++ JSON serialization

Stable C++17

Use pw::JsonBuilder to serialize JSON to a buffer. It’s simple, safe, and efficient.

  pw::JsonBuffer<256> json_buffer;
  pw::JsonObject& object = json_buffer.StartObject();
  object.Add("tagline", "Easy, efficient JSON serialization!")
      .Add("simple", is_simple)
      .Add("safe", safety_percentage)
      .Add("dynamic allocation", false);

  pw::NestedJsonArray nested_array = object.AddNestedArray("features");
  for (const std::string_view feature : features) {
    nested_array.Append(feature);
  }

The above code produces JSON equivalent to the following:

{
  "tagline": "Easy, efficient JSON serialization!",
  "simple": true,
  "safe": 100,
  "dynamic allocation": false,
  "features": ["values", "arrays", "objects", "nesting!"]
}

JsonBuilder#

The pw_json module provides utilities for interacting with JSON. JSON is a structured data format that supports strings, integers, floating point numbers, booleans, null, arrays, and objects (key-value pairs).

pw::JsonBuilder is a simple, efficient utility for serializing JSON to a fixed-sized buffer. It works directly with the JSON wire format. It does not support manipulation of previously serialized data.

All JsonBuilder functions are constexpr, so may be used in constexpr and constinit statements.

Example

  // Declare a JsonBuffer (JsonBuilder with included buffer) and start a JSON
  // object in it.
  pw::JsonBuffer<128> json_buffer;
  pw::JsonObject& json = json_buffer.StartObject();

  const char* name = "Crag";
  constexpr const char* kOccupationKey = "job";

  // Add key-value pairs to a JSON object.
  json.Add("name", name).Add(kOccupationKey, "hacker");

  // Add an array as the value in a key-value pair.
  pw::NestedJsonArray nested_array = json.AddNestedArray("skills");

  // Append items to an array.
  nested_array.Append(20).Append(1).Append(1).Append(1);

  // Check that everything fit in the JSON buffer.
  PW_ASSERT(json.ok());

  // Compare the contents of the JSON to a std::string_view.
  PW_ASSERT(std::string_view(json) ==
            R"({"name": "Crag", "job": "hacker", "skills": [20, 1, 1, 1]})");

  // Add an object as the value in a key-value pair.
  pw::NestedJsonObject nested_object = json.AddNestedObject("items");

  // Declare another JsonArray, and add it as nested value.
  pw::JsonBuffer<10> inner_buffer;
  inner_buffer.StartArray().Append(nullptr);
  nested_object.Add("misc", inner_buffer);

  // Add a value that is too large for the JsonBuffer.
  json.Add("way too big!", huge_string_that_wont_fit);

  // Adding the last entry failed, but the JSON is still valid.
  PW_ASSERT(json.status().IsResourceExhausted());

  PW_ASSERT(std::string_view(json) ==
            R"({"name": "Crag", "job": "hacker", "skills": [20, 1, 1, 1],)"
            R"( "items": {"misc": [null]}})");

API Reference#

class NestedJsonArray#

A JsonArray nested inside an object or array. Only provides functions for appending values to the nested array.

A NestedJsonArray is immediately invalidated if the enclosing JSON is updated. Attempting to append to the nested array is an error.

Public Functions

template<typename T>
constexpr NestedJsonArray &Append(const T &value)#

Appends to the nested array.

constexpr NestedJsonArray AppendNestedArray()#

Appends a new nested array to this nested array.

constexpr NestedJsonObject AppendNestedObject()#

Appends a new nested object to this nested array.

class NestedJsonObject#

A JsonObject nested inside an array or object. Only provides functions for adding key-value pairs to the nested object.

A NestedJsonObject is immediately invalidated if the enclosing JSON is updated. Attempting to add to the nested object fails an assertion.

Public Functions

template<typename T>
constexpr NestedJsonObject &Add(std::string_view key, const T &value)#

Adds a key-value pair to the nested object.

constexpr NestedJsonArray AddNestedArray(std::string_view key)#

Adds a nested array to the nested object.

constexpr NestedJsonObject AddNestedObject(std::string_view key)#

Adds a nested object to the nested object.

class JsonValue#

Stores a simple JSON value: a string, integer, float, boolean, or null. Provides a Set() function as well as the common functions for accessing the serialized data (see documentation for JsonBuilder).

Subclassed by pw::JsonBuilder

Public Functions

template<typename T>
constexpr Status Set(const T &value)#

Sets the JSON value to a boolean, number, string, or null. Sets and returns the status. If a Set call fails, the value is set to null.

It is an error to call Set() on a JsonValue if StartArray or StartObject was called on the JsonBuilder. Setting the JsonValue to a JSON object or array is also an error.

Returns:

Code

Description

OK

The value serialized successfully.

RESOURCE_EXHAUSTED

There is insufficient buffer space to serialize.

class JsonArray#

Stores a JSON array: a sequence of values. Provides functions for adding items to the array, as well as the common functions for accessing the serialized data (see documentation for JsonBuilder).

Subclassed by pw::JsonBuilder

Public Functions

template<typename T>
constexpr JsonArray &Append(const T &value)#

Adds a value to the JSON array. Updates the status.

It is an error to call Append() if the underlying JsonBuilder is no longer an array.

constexpr NestedJsonArray AppendNestedArray()#

Appends a nested array to this array.

constexpr NestedJsonObject AppendNestedObject()#

Appends a nested object to this array.

template<typename Iterable>
constexpr JsonArray &Extend(const Iterable &iterable)#

Appends all elements from an iterable container. If there is an error, changes are reverted.

template<typename T, size_t kSize>
constexpr JsonArray &Extend(const T (&iterable)[kSize])#

Appends all elements from an iterable container. If there is an error, changes are reverted.

class JsonObject#

Stores a JSON object: a sequence of key-value pairs. Provides functions for adding entries to the object, as well as the common functions for accessing the serialized data (see documentation for JsonBuilder).

Subclassed by pw::JsonBuilder

Public Functions

template<typename T>
constexpr JsonObject &Add(std::string_view key, const T &value)#

Adds a key-value pair to the JSON object. Updates the status.

It is an error to call Add() if the underlying JsonBuilder is no longer an object.

Returns:

Code

Description

OK

The value was appended successfully.

RESOURCE_EXHAUSTED

Insufficient buffer space to serialize.

class JsonBuilder : private pw::JsonValue, private pw::JsonArray, private pw::JsonObject#

JsonBuilder is used to create arbitrary JSON. Contains a JSON value, which may be an object or array. Arrays and objects may contain other values, objects, or arrays.

Subclassed by pw::JsonBuffer< kMaxSize >

Public Functions

inline constexpr JsonBuilder(span<char> buffer)#

Initializes to the value null. buffer.size() must be at least 5.

inline constexpr JsonBuilder(char *buffer, size_t buffer_size)#

Initializes to the value null. buffer_size must be at least 5.

inline constexpr bool IsValue() const#

True if the top-level JSON entity is a simple value (not array or object).

inline constexpr bool IsArray() const#

True if the top-level JSON entity is an array.

inline constexpr bool IsObject() const#

True if the top-level JSON entity is an object.

inline constexpr operator std::string_view() const#

JsonBuilder converts to std::string_view.

inline constexpr const char *data() const#

Pointer to the serialized JSON, which is always a null-terminated string.

inline constexpr size_t size() const#

The current size of the JSON string, excluding the null terminator.

inline constexpr size_t max_size() const#

The maximum size of the JSON string, excluding the null terminator.

inline constexpr bool ok() const#

True if.

status() is OK ; no errors have occurred.

inline constexpr Status status() const#

Returns the JsonBuilder’s status, which reflects the first error that occurred while updating the JSON. After an update fails, the non-OK status remains until it is reset with clear, clear_status, or SetValue.

Returns:

Code

Description

OK

All previous updates have succeeded.

RESOURCE_EXHAUSTED

An update did not fit in the buffer.

inline constexpr Status last_status() const#

Returns the status from the most recent change to the JSON. This is set with each JSON update and may be OK while status() is not.

inline constexpr void clear()#

Sets the JSON null and clears the status.

inline constexpr void clear_status()#

Resets status() and last_status().

template<typename T>
constexpr Status SetValue(const T &value)#

Clears the JSON and sets it to a single JSON value (see JsonValue::Set).

inline constexpr JsonValue &StartValue()#

Sets the JSON to null and returns a JsonValue reference to this JsonBuilder.

inline constexpr JsonArray &StartArray()#

Clears the JSON and sets it to an empty array ([]). Returns a JsonArray reference to this JsonBuilder. For example:

builder.StartArray()
    .Append("item1")
    .Append(2)
    .Extend({"3", "4", "5"});
inline constexpr JsonObject &StartObject()#

Clears the JSON and sets it to an empty object ({}). Returns a JsonObject reference to this JsonBuilder. For example:

JsonBuffer<128> builder;
JsonObject& object = builder.StartObject()
    .Add("key1", 1)
    .Add("key2", "val2");
object.Add("another", "entry");

Public Static Functions

static inline constexpr size_t MinBufferSize()#

JsonBuilder requires at least 5 characters in its buffer.

template<size_t kMaxSize>
class JsonBuffer : public pw::JsonBuilder#

A JsonBuilder with an integrated buffer. The buffer will be sized to fit kMaxSize characters.