Skip to main content

Squirrel Data Serialization

Learn What Data Types Can And Can’t Be Serialized

Many parts of the imp API store or transmit data in a serialized form. For instance, this applies to:

Most Squirrel data types can be serialized, but not all. The rules about what data is serializable, and thus what data can be used in the above situations, are as follows:

  • Any data of type null, boolean, integer or float is serializable.
  • A blob is serializable.
  • A safe string, which is one that is encoded in Ascii or UTF-8 and contains no embedded NUL ("\0") characters, is serializable.
  • Other strings are still serializable, but get serialized as blobs.
  • Any array containing only serializable data types is also serializable.
  • Any table of key-value pairs is serializable provided all the keys are safe strings.

These rules can be applied recursively, so an array of arrays of integers is also serializable. The restriction on tables only applies to the keys, not the values: values can be anything, including ‘unsafe’ strings, which are serialized as blobs and must be dealt with accordingly.

Conversely, the following Squirrel items are not serializable:

  • All functions.
  • All classes and class instances, except for instances of blob.
  • Any table entry whose key isn’t a safe string.

When attempting to serialize a table or array which contains some serializable elements and some non-serializable ones, the non-serializable ones are dropped without raising an error.

JSON Is A Blob-free Zone

In a few places, the restrictions are tighter, among them:

In these situations, no blobs are allowed, and thus no strings other than safe strings.

server.save() Does Not Like NaN, +inf and -inf

Currently, server.save() does not play well with NaN (Not a Number), +inf and -inf values, as defined by IEEE 754, the 2008-updated standard schema for storing floating-point numbers. Should you attempt to store such undefined or unrepresentable values, they will be converted to null by server.save(). If your application needs to preserve these values across device or server restarts, you should save them in the form of serializable tokens which when read back at a later time can be used to trigger the correct assignment of the undefined values.

Examples

This code won’t work because the key contains a NUL string, ie. it is ‘unsafe’:

nv <- { "\x00\x01": "\x80\x80" };   // don't do this

However, this code is fine:

nv <- {"calibration" : "\x00\x01\x80\x80"};

Note, though, that the value in this slot, because it is an unsafe string, will be serialized as a blob. When the data is loaded back from the nv table, the value delivered in return for the key calibration will be a blob, not a string.