# Module json

This module implements a simple high performance JSON parser. JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write (unlike XML). It is easy for machines to parse and generate. JSON is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999.

Usage example:

    let
      small_json = """{"test": 1.3, "key2": true}"""
      jobj = parseJson(small_json)
    assert (jobj.kind == JObject)
    echo($jobj["test"].fnum)
    echo($jobj["key2"].bval)

Results in:

    1.3000000000000000e+00
    true

# Imports

hashes, strutils, lexbase, streams, unicode

# Types

    TJsonEventKind = enum
      jsonError,                  ## an error ocurred during parsing
      jsonEof,                    ## end of file reached
      jsonString,                 ## a string literal
      jsonInt,                    ## an integer literal
      jsonFloat,                  ## a float literal
      jsonTrue,                   ## the value ``true``
      jsonFalse,                  ## the value ``false``
      jsonNull,                   ## the value ``null``
      jsonObjectStart,            ## start of an object: the ``{`` token
      jsonObjectEnd,              ## end of an object: the ``}`` token
      jsonArrayStart,             ## start of an array: the ``[`` token
      jsonArrayEnd                ## start of an array: the ``]`` token

  enumeration of all events that may occur when parsing

    TJsonError = enum
      errNone,                    ## no error
      errInvalidToken,            ## invalid token
      errStringExpected,          ## string expected
      errColonExpected,           ## ``:`` expected
      errCommaExpected,           ## ``,`` expected
      errBracketRiExpected,       ## ``]`` expected
      errCurlyRiExpected,         ## ``}`` expected
      errQuoteExpected,           ## ``"`` or ``'`` expected
      errEOC_Expected,            ## ``*/`` expected
      errEofExpected,             ## EOF expected
      errExprExpected             ## expr expected

  enumeration that lists all errors that can occur

    TJsonParser = object of TBaseLexer
      a: string
      tok: TTokKind
      kind: TJsonEventKind
      err: TJsonError
      state: seq[TParserState]
      filename: string

  the parser object.

    TJsonNodeKind = enum
      JNull, JBool, JInt, JFloat, JString, JObject, JArray

  possible JSON node types

    PJsonNode = ref TJsonNode

  JSON node

    TJsonNode = object
      case kind*: TJsonNodeKind
      of JString:
          str*: string

      of JInt:
          num*: BiggestInt

      of JFloat:
          fnum*: float

      of JBool:
          bval*: bool

      of JNull:
          nil

      of JObject:
          fields*: seq[tuple[key: string, val: PJsonNode]]

      of JArray:
          elems*: seq[PJsonNode]

    EJsonParsingError = object of EInvalidValue

  is raised for a JSON error

# Procs

    proc open(my: var TJsonParser; input: PStream; filename: string) {.
        raises: [E_Base], tags: [FReadIO].}

  initializes the parser with an input stream. Filename is only used for nice error messages.

    proc close(my: var TJsonParser) {.inline, raises: [E_Base], tags: [].}

  closes the parser my and its associated input stream.

    proc str(my: TJsonParser): string {.inline, raises: [], tags: [].}

  returns the character data for the events: `jsonInt`, `jsonFloat`, `jsonString`

    proc getInt(my: TJsonParser): BiggestInt {.inline, raises: [EInvalidValue],
        tags: [].}

  returns the number for the event: `jsonInt`

    proc getFloat(my: TJsonParser): float {.inline, raises: [EInvalidValue],
                                            tags: [].}

  returns the number for the event: `jsonFloat`

    proc kind(my: TJsonParser): TJsonEventKind {.inline, raises: [], tags: [].}

  returns the current event type for the JSON parser

    proc getColumn(my: TJsonParser): int {.inline, raises: [], tags: [].}

  get the current column the parser has arrived at.

    proc getLine(my: TJsonParser): int {.inline, raises: [], tags: [].}

  get the current line the parser has arrived at.

    proc getFilename(my: TJsonParser): string {.inline, raises: [], tags: [].}

  get the filename of the file that the parser processes.

    proc errorMsg(my: TJsonParser): string {.raises: [EInvalidValue], tags: [].}

  returns a helpful error message for the event `jsonError`

    proc errorMsgExpected(my: TJsonParser; e: string): string {.
        raises: [EInvalidValue], tags: [].}

  returns an error message "e expected" in the same format as the other error messages

    proc next(my: var TJsonParser) {.raises: [E_Base], tags: [FReadIO].}

  retrieves the first/next event. This controls the parser.

    proc raiseParseErr(p: TJsonParser; msg: string) {.noinline, noreturn,
        raises: [EJsonParsingError, EInvalidValue], tags: [].}

  raises an EJsonParsingError exception.

    proc newJString(s: string): PJsonNode {.raises: [], tags: [].}

  Creates a new JString PJsonNode.

    proc newJInt(n: BiggestInt): PJsonNode {.raises: [], tags: [].}

  Creates a new JInt PJsonNode.

    proc newJFloat(n: float): PJsonNode {.raises: [], tags: [].}

  Creates a new JFloat PJsonNode.

    proc newJBool(b: bool): PJsonNode {.raises: [], tags: [].}

  Creates a new JBool PJsonNode.

    proc newJNull(): PJsonNode {.raises: [], tags: [].}

  Creates a new JNull PJsonNode.

    proc newJObject(): PJsonNode {.raises: [], tags: [].}

  Creates a new JObject PJsonNode

    proc newJArray(): PJsonNode {.raises: [], tags: [].}

  Creates a new JArray PJsonNode

    proc `%`(s: string): PJsonNode {.raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JString PJsonNode.

    proc `%`(n: BiggestInt): PJsonNode {.raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JInt PJsonNode.

    proc `%`(n: float): PJsonNode {.raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JFloat PJsonNode.

    proc `%`(b: bool): PJsonNode {.raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JBool PJsonNode.

    proc `%`(keyVals: openarray[tuple[key: string, val: PJsonNode]]): PJsonNode {.
        raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JObject PJsonNode

    proc `%`(elements: openarray[PJsonNode]): PJsonNode {.raises: [], tags: [].}

  Generic constructor for JSON data. Creates a new JArray PJsonNode

    proc len(n: PJsonNode): int {.raises: [], tags: [].}

  If n is a JArray, it returns the number of elements. If n is a JObject, it returns the number of pairs. Else it returns 0.

    proc `[]`(node: PJsonNode; name: string): PJsonNode {.raises: [], tags: [].}

  Gets a field from a JObject. Returns nil if the key is not found.

    proc `[]`(node: PJsonNode; index: int): PJsonNode {.raises: [], tags: [].}

  Gets the node at index in an Array.

    proc existsKey(node: PJsonNode; key: string): bool {.raises: [], tags: [].}

  Checks if key exists in node.

    proc add(father, child: PJsonNode) {.raises: [], tags: [].}

  Adds child to a JArray node father.

    proc add(obj: PJsonNode; key: string; val: PJsonNode) {.raises: [], tags: [].}

  Adds `(key, val)` pair to the JObject node obj. For speed reasons no check for duplicate keys is performed! But `[]=` performs the check.

    proc `[]=`(obj: PJsonNode; key: string; val: PJsonNode) {.raises: [], tags: [].}

  Sets a field from a JObject. Performs a check for duplicate keys.

    proc delete(obj: PJsonNode; key: string) {.raises: [EInvalidIndex], tags: [].}

  Deletes `obj[key]` preserving the order of the other (key, value)-pairs.

    proc copy(p: PJsonNode): PJsonNode {.raises: [], tags: [].}

  Performs a deep copy of a.

    proc escapeJson(s: string): string {.raises: [], tags: [].}

  Converts a string s to its JSON representation.

    proc pretty(node: PJsonNode; indent = 2): string {.raises: [], tags: [].}

  Converts node to its JSON Representation, with indentation and on multiple lines.

    proc `$`(node: PJsonNode): string {.raises: [], tags: [].}

  Converts node to its JSON Representation on one line.

    proc parseJson(s: PStream; filename: string): PJsonNode {.
        raises: [E_Base, EInvalidValue, EJsonParsingError], tags: [FReadIO].}

  Parses from a stream s into a PJsonNode. filename is only needed for nice error messages.

    proc parseJson(buffer: string): PJsonNode {.
        raises: [E_Base, EInvalidValue, EJsonParsingError], tags: [FReadIO].}

  Parses JSON from buffer.

    proc parseFile(filename: string): PJsonNode {.
        raises: [EOutOfMemory, EIO, E_Base, EInvalidValue, EJsonParsingError],
        tags: [FReadIO].}

  Parses file into a PJsonNode.

# Iterators

    iterator items(node: PJsonNode): PJsonNode {.raises: [], tags: [].}

  Iterator for the items of node. node has to be a JArray.

    iterator pairs(node: PJsonNode): tuple[key: string, val: PJsonNode] {.
        raises: [], tags: [].}

  Iterator for the child elements of node. node has to be a JObject.

Generated: 2013-05-21 09:55:18 UTC