Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

JsonStream Pascal Implementation

Files

File Description
example Examples showing how to use the library
package Contains a Lazarus package file
test Automated tests
jsonstream.pas Contains the entire source code of the library.

How to use

To use JsonStream in your project, you can either copy jsonstream.pas into your project folder directly, or you can add the provided Lazarus package as a dependency.

This implementation was tested under FreePascal 3.2.2. If you are using a different compiler and have trouble getting the source code to build, please open an issue. Pull Requests are welcome.

Reference

TJsonString (type)

Alias for string.

TJsonFeature (enum)

Value Meaning
jsJson5 Enable JSON5 features.

TJsonFeatures (set)

Set of TJsonFeature.

TJsonState (enum)

Describes the state of a TJsonReader.

Value Meaning
jsError Parser encountered a syntax error
jsEOF End of the file has been reached
jsDict Current element is the beginning of a dict ({)
jsDictEnd Current element is the end of a dict (})
jsList Current element is the beginning of a list ([)
jsListEnd Current element is the end of a list (])
jsNumber Current element is a number
jsBoolean Current element is a boolean
jsNull Current element is a null value
jsString Current element is a string
jsKey Current element is the key of a dict entry

TJsonError (enum)

Gives additional information about an error.

Value Meaning
jeNoError = 0 There is no error
jeInvalidToken Got a character sequence that is not a valid JSON token.
jeInvalidNumber Token was recognized as a number, but does not conform to JSON syntax.
jeUnexpectedToken Token is a valid JSON token, but there is a syntax error.
jeTrailingComma A list or dict contains a trailing comma.
jeUnexpectedEOF End of file was unexpectedly encountered.
jeInvalidEscapeSequence There was an invalid escape sequence in a string, or a character that must be escaped was not escaped.
jeNestingTooDeep The maximum nesting limit set by the user was reached.

TJsonReader (class)

This class is used for parsing JSON markup.

constructor TJsonReader.Create(Stream: TStream; Features: TJsonFeatures=[]; MaxNestingDepth: integer=MaxInt)
Construct a TJsonReader object. The input will be read from Stream. Pass [jfJson5] as Features to create a JSON5 parser instead of a regular JSON parser. You can specify a maximum allowable nesting depth via MaxNestingDepth. If this depth is exceeded, the parser will abort.
function TJsonReader.Advance: TJsonState
Move to the next element and return the new parse state.
function TJsonReader.State: TJsonState
Return the current parse state.
function TJsonReader.Key(out K: TJsonString): Boolean;
Returns true iff the current element is a dict entry and stores its key in K. If true is returned, then the key is stored in K and the reader is automatically advanced to the corresponding value. If false is returned, the current element is either not a key or an error ocurred during decoding (such as an invalid escape sequence or premature end of file) and the contents of K are undefined. If an error occured, you may call Proceed() to ignore it and call Key() again.
function TJsonReader.KeyBuf(out Buf; BufSize: SizeInt): SizeInt;
This function is like Key, except that it does not return the full key, but only reads part of it. This is intended for situations where the key could be very large and it would not be efficient to allocate it in memory its entirety. The semantics are the same as the read() syscall on Unix: Up to BufSize bytes are read and stored in Buf.

Return value:

  • > 0: The number of bytes actually read.
  • = 0: Indicates the end of the key.
  • < 0: An error occurred (invalid escape sequence or missing trailing ") or the value is not a key.

If an error occurred, you can call Proceed() to ignore it and try to continue reading.

function TJsonReader.Str(out S: TJsonString): Boolean;
Returns true iff the current element is a valid string value. If true is returned, then the decoded string value is stored in S. If false is returned, the current element is either not a string or an error occurred during decoding (such as an invalid escape sequence or premature end of file) and the contents of S are undefined. If an error occurred, you may call Proceed() to ignore it and call Str() again. This function only returns true once per element.
function TJsonReader.StrBuf(out Buf; BufSize: SizeInt): SizeInt;
This function is like Str, except that it does not return the full string, but only reads part of it. This is intended for situations where the string could be very large and it would not be efficient to allocate it in memory in its entirety. The semantics are the same as the read() syscall on Unix: Up to BufSize bytes are read and stored in Buf.

Return value:

  • > 0: The number of bytes actually read.
  • = 0: Indicates the end of the string.
  • < 0: An error occurred (invalid escape sequence or missing trailing ") or the value is not a string.

If an error occurred, you can call Proceed() to ignore it and try to continue reading.

function TJsonReader.Number(out Num: integer): Boolean; overload;
Returns true iff the current element is a number that can be exactly represented by an integer and returns its value in Num. This function only returns true once per element.
function TJsonReader.Number(out Num: int64): Boolean; overload;
Returns true iff the current element is a number that can be exactly represented by an int64 and returns its value in Num. This function only returns true once per element.
function TJsonReader.Number(out Num: uint64): Boolean; overload;
Returns true iff the current element is a number that can be exactly represented by an uint64 and returns its value in Num. This function only returns true once per element.
function TJsonReader.Number(out Num: double): Boolean; overload;
Returns true iff the current element is a number and returns its value in Num. If the number exceeds the representable precision or range of a double precision float, it will be rounded to the closest approximation. This function only returns true once per element.
function TJsonReader.Bool(out Bool: Boolean): Boolean;
Returns true iff the current element is a boolean and returns its value in bool. This function only returns true once per element.
function TJsonReader.Null: Boolean;
Returns true iff the current element is a null value. This function only returns true once per element.
function TJsonReader.Dict: Boolean;
Returns true iff the current element is a dict. If true is returned, then the next element will be the first child of the dict.
function TJsonReader.List: Boolean;
Returns true iff the current element is a list. If true is returned, then the next element will be the first child of the list.
function TJsonReader.Error: Boolean;
Returns true if the last operation resulted in an error. You can then check the LastError and LastErrorMessage functions to learn more about the error. You can call Proceed to try to recover from the error and continue parsing. Otherwise no further tokens will be consumed and all open elements will be closed.
function TJsonReader.Proceed: Boolean;
Proceed after a parse error. If this is not called after an error, parsing is aborted and no further tokens in the file will be processed.
function TJsonReader.LastError: TJsonError;
Return last error code. A return value of 0 means that there was no error. A return value other than 0 indicates that there was an error.
function TJsonReader.LastErrorMessage: TJsonString;
Return error message for last error.
function TJsonReader.LastErrorPosition: SizeInt;
Byte offset of the last error.

TJsonWriter (class)

This class is used for writing JSON output.

constructor TJsonWriter.Create(Stream: TStream; Features: TJsonFeatures=[]; PrettyPrint: Boolean=false; const Indentation: string=' ');
Construct a TJsonWriter object. Pass [jfJson5] as Features to enable JSON5 features. Pass true as PrettyPrint to produce formatted, human-readable output. Pretty-printed output is by default indented with two spaces. Pass a string to Indentation to change the characters used for indenting.
procedure TJsonWriter.Key(const K: TJsonString);
Append a key to the output. May only be used inside a dict. Must be followed by a value.
procedure TJsonWriter.KeyBuf(const Buf; BufSize: SizeInt);
Streaming equivalent of the Key() method. See StrBuf().
procedure TJsonWriter.Str(const S: TJsonString);
Append a string to the output.
procedure TJsonWriter.StrBuf(const Buf; BufSize: SizeInt);
Streaming equivalent of the Str() method. To indicate the end of the string, call once with BufSize set to 0.

Note: To write an empty string, you have to call the method twice:

StrBuf(..., 0); // Write 0 bytes
StrBuf(..., 0); // Signal end of string
procedure TJsonWriter.Number(Num: integer); overload;
procedure TJsonWriter.Number(Num: int64); overload;
procedure TJsonWriter.Number(Num: uint64); overload;
procedure TJsonWriter.Number(Num: double); overload;
Append a number to the output. Note: The values NaN and Infinity are only allowed in JSON5 mode.
procedure TJsonWriter.NumberHex(Num: uint64); overload;
Append a number in hexadecimal format, if possible. This requires jfJson5 to be included in Features. If jfJson5 is not included in Features, a decimal number will be written, instead.
procedure TJsonWriter.Bool(Bool: Boolean);
Append a boolean.
procedure TJsonWriter.Null;
Append a null value.
procedure TJsonWriter.Dict;
Begin writing a dict.
procedure TJsonWriter.DictEnd;
Stop writing a dict.
procedure TJsonWriter.List;
Begin writing a list.
procedure TJsonWriter.ListEnd;
Stop writing a list.