JSONlib:
Filter:
JSONlib/Classes (extension) | Files | Utilities | External Control

JSONlib
ExtensionExtension

A JSON en- and decoder

Description

Encode SuperCollider objects to the JSON format and decode them from the JSON format.

Quickstart

Encoding

Decoding

Also see *new and the examples.

What is JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.1

JSON is a common exchange format in the internet as Browsers provide a JavaScript runtime and JSON is the native exchange format for JavaScript objects. This led to wide adaption as it is a fixed standard with a variety of use cases. The network communication abilties of SuperCollider are restricted to OSC Communication which can only transfer Arrays but no nested dictionaries. But by using a JSON string we can transfer nested key-value pairs (see Transfer nested objects via OSC).

For more information consult https://www.json.org/

Yet another JSON parser?

But isn't there alreday a built in method called String: -parseJSON? Yes, but String: -parseJSON implementation

An encoder simply needs to translate the SuperCollider data types to the set of JSON data types. As there are far more SuperCollider data types than JSON data types we rely on some implicit and explicit conversions. Consult the source code on what kind of implicit conversions are made. These defaults can be overwritten and extended by providing a customEncoder or customDecoder (see JSONlib: *new).

The type conversion issue is a bit more difficult as it is not possible for us to recover the original types from the JSON explicitly. Was "42" always a string or was it an Integer once that got converted by String: -parseJSON from an Integer to a String? - so we decided to use implicit assignment of an appropriate class (also known as type casting in other programming languages) if the string matches a JSON representation other than String. The only exception here is null, see below.

If you do not want to make use of the implicit casting simply use the built in String: -parseJSON.

Consider the JSON {"number": 42}

Representing null in SuperCollider

null is a special value in JSON which represents the intentional absence of any object value.2 .

SuperColliders equivalent would be object nil, check Nil for more information. Yet it is not as easy as that because we can not store nil as a value in a Dictionary as this is the sclang syntax to delete a key-value pair within a dictionary because nil represents the return value for an empty slot and put(key, nil) is equivalent to removing the object at key.

To overcome this constraint we wrap nil into a Ref (shortcut is using the backtick, so `nil) wherever we encounter a null value in the JSON string.

The same applies if we decode null from JSON string

See https://github.com/musikinformatik/JSONlib/issues/7 and https://github.com/musikinformatik/JSONlib/issues/5 for discussion.

Class Methods

.new

Arguments:

postWarnings

If true a warning will be posted if an implicit conversion to a Object: -asCompileString occurs as a fallback because JSON has only a limited set of data types.

useEvent

If true it will return a Event instead of a Dictionary which is what String: -parseJSON uses

customEncoder

Using a custom encoder allows to specify the encoding of an abitrary object into its JSON representation. To introduce a custom encoding (e.g. Point or Function) simply provide a function which accepts the object as a first argument and return a non-nil value if it a custom representation should be used. Otherwise, it will be encoded as usual.

Example

A custom encoder which converts a Point into an array for the JSON representation.

WARNING: You need to take care of any escaping on String or any recursion due to using nested objects or arrays.
customDecoder

Allows to specify the decoding of a string by providing a function which takes as an argument every value within the return object of String: -parseJSON which includes String, Array, Dictionary and Nil. If this function returns a non-nil value we will use this in the returned sclang object.

Example

A (naive) custom decoder which converts the string "point#x#y" to a Point. Consider using regular expressions via e.g. String: -matchRegexp for more reliable implementation.

.convertToSC

Encodes a given JSON string to a Event, Dictionary or Array.

Arguments:

json

JSON String or Symbol one wants to parse. Keep in mind that when using a String any " needs to be escaped with \" (so at least every key needs this) and on a Symbol ' needs to be escaped with \'. If you have copied a JSON from elsewhere either save it as a file and use *parseFile or use the console of your browser by simply wrapping the JSON into backticks (e.g. `{"my": "json"}`). The returned string will contain the all necessary string escapes for SuperCollider."

customDecoder

See *new

useEvent

See *new

postWarnings

See *new

.parseFile

Parses a .json file in its SuperCollider object representation via *convertToSC

Arguments:

filePath

Path to the JSON file.

customDecoder

See *new

useEvent

See *new

postWarnings

See *new

.convertToJSON

Decodes a Event, Dictionary or Array into its JSON string representation.

Arguments:

object

The object one wants a JSON representation of.

customEncoder

See *new

postWarnings

See *new

Instance Methods

.postWarnings

See *new

.customEncoder

See *new

.useEvent

See *new

.customDecoder

See *new

Examples

Convert an Event to a JSON string

Convert a Dictionary to a JSON string

Convert a JSON string to an Event

See *convertToSC on advice how to handle escaping of JSON strings.

Save to file

See File for further details.

Using null

See also Representing null in SuperCollider and Ref

Encoding

Decoding

Consider the JSON {"nothing": null}

Use custom en/decoders to store functions

WARNING: Executing arbitrary functions from JSON files can be a security risk. Trust your sources or verify the content before executing any functions.

Useful if you want to exchange functions and data via network (see below)

Transfer nested objects via OSC

JSON allows to distribute and receive nested objects via OSC by distributing it as a String in an OSC message.