################################################################################ # SUMMARY ################################################################################ The nosj data format is the latest and greatest way to serialize data such that it can be shared across arbitrary channels, languages, and applications. Although formats like JSON, XML, and protocol-buffers already exist, they do not subscribe to nosj's philosophy of "No one ever needs more than three data-types!". nosj was created for the purpose of allowing even the most complex data structures to be represented in an ascii-only format useful for all known situations usage. A nosj object consists of a root-level map containing zero or more key-value pairs (see map data-type). One of the core design-goals of nosj is to have all unmarshalled data types to be handled by almost any languages' built-in data types using only the languages built-in libraries for example (non-inclusive possibilities listed): - Java - nosj num == double or int - nosj simple-string == java.lang.String OR byte[] - nosj complex-string == java.lang.String OR byte[] - nosj map == java.util.HashMap - Python - nosj num == float or int - nosj simple-string == str OR bytes - nosj complex-string == str OR bytes - nosj map == dict - golang - nosj num == float64 or int - nosj simple-string == string OR byte[] - nosj complex-string == string OR byte[] - nosj map == map[string]{}interface ################################################################################ # DATA-TYPES ################################################################################ The nosj format consists of three data-types: maps, nums, and strings. Each is described in-depth below. # Data-Type: num A nosj num represents an integer value between positive-infinity and negative-infinity. A marshalled num consists of the value's two's complement representation (including the sign bit) in binary format as a sequence of ascii "1"s and "0"s. Examples: Marshalled nosj num: 1010 Numerical value: -6 Marshalled nosj num: 11110110 Numerical value: -10 # Data-Type: string A nosj string is a sequence of ascii bytes which can be used to represent arbitrary internal data such as ascii, unicode, or raw-binary. There are two distinct representations of a nosj string data-type as described below. ### Representation #1: Simple-Strings In the simple representation, the string is restricted to a set of commonly-used ascii characters which (according to our extensive market survey) are the most-liked by humans (i.e. upper and lowercase ascii letters, ascii digits, spaces (" " / 0x20), and tabs ("\t" / 0x09)). Simple-strings are followed by a trailing "s" which is NOT part of the data being encoded. Examples: Marshalled nosj simple-string: abcds String value: "abcd" Marshalled nosj simple-string: ef ghs String value: "ef gh" ### Representation #2: Complex-Strings In the complex representation, the string is percent-encoded in order to reuse pre-existing and well-tested libraries such as those used for encoding/decoding URLs. Where as simple-string may only represent a restricted set of characters, complex-strings can encode arbitrary bytes. While the marshalled-form can contain multiple percent-encoded bytes, it MUST include at least one (1) percent-encoded byte. Examples: Marshalled nosj complex-string: ab%2Ccd String value: "ab,cd" Marshalled nosj complex-string: ef%00gh String value: "efgh" # Data-Type: map A nosj map is a sequence of zero or more key-value pairs that take the form of "" similar to the conceptual hash-map data structure. A nosj map MUST start with the two character "BEGIN" sequence ("(<") and end with the two-character "END" sequence (">)"). Map keys MUST be an ascii-string consisting of one or more lowercase ascii letters ("a" through "z" / 0x61 through 0x7a ) only. Map values may be any of the three canonical nosj data-types (map, string or num) and there is no specification-bound on how many maps may be nested within each other. Though map values are not required to be unique, map keys MUST be unique within the current map (though they may be duplicated in maps at other levels of "nesting"). Examples: Marshalled nosj map: () Key-1: "x" Value-1: "abcd" (string) Marshalled nosj map: () Key-1: "x" Value-1: "abcd" (string) Key-2: "y" Value-2: -7 (num) Marshalled nosj map: ()>) Key-1: "x" Value-1: (map) Key-1-1: "y" Value-1-1: -8 (num) A properly formatted nosj map contains NO WHITESPACE characters (spaces, tabs, newlines / " ", "\t", "\n" / 0x20, 0x09, 0x0a) unless it is as part of one of the below special-cases: - Whitespace is part of a simple-string which is part of that string. - Valid: "()" - Whitespace is before or after the start/end of the map which should be ignored. - Valid: " ()" - Valid: "() " Examples of invalid whitespace: - "()" - "(< a:bs>)" - "()" ERRATA: 26Aug2024 - Fixed typo in example: "6" --> "-6"