Skip to content

Commit 93b637b

Browse files
committed
extensive revision: parse for re-use of keys, tostring using enumerators
1 parent b6478b6 commit 93b637b

File tree

6 files changed

+1026
-537
lines changed

6 files changed

+1026
-537
lines changed

CHANGELOG.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
v1.1.0
2+
### ATTENTION!!! breaking change: ###
3+
- JSON function: use '{' key suffix to start embedded document (instead of value '[')
4+
- IJSONDocument.ToString re-done using IJSONEnumerator
5+
- IJSONDocWithReUse to fix re-using pre-allocated keys
6+
7+
v1.0.5
8+
- IJSONDocument.Delete
9+
110
v1.0.4
211
- JsonEnum: return 'empty' enumerator on nil/Null
312

@@ -15,4 +24,4 @@ v1.0.1
1524
- IJSONEnumerator
1625
- IJSONDocArrayBuilder
1726

18-
v1.0.0
27+
v1.0.0

README.md

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,61 +6,108 @@ _jsonDoc_ started out as _bsonDoc.pas_ and `IBSONDocument` in the [TMongoWire](h
66

77
### JSON
88

9+
To create a new `IJSONDocument` instance:
10+
911
function JSON: IJSONDocument; overload;
1012

11-
Use this function to create a new `IJSONDocument` instance.
13+
To create and populate a new `IJSONDocument` instance:
1214

1315
function JSON(const x: array of OleVariant): IJSONDocument; overload;
1416

15-
Convert a variant array into an `IJSONDocument` instance. Pass a list of key/value-pairs, use value `[` to start an embedded document, and key `]` to close it.
17+
Pass a list of alternately keys and values, suffix the key with `{` to start an embedded document, and use key `}` to close it. E.g.: with
18+
19+
d:=JSON(['a',1,'b{','x','foo','}','c{','x','bar','}','d',VarArrayOf([JSON(['x','hello']),JSON(['y','world'])]),'e',true]);
20+
21+
`d.ToString` will return `{"a":1,"b":{"x":"foo"},"c":{"x":"bar"},"d":[{"x":"hello"},{"x":"world"}],"e":true}`.
22+
23+
Convert a variant into an IJSONDocument reference.
1624

1725
function JSON(x: OleVariant): IJSONDocument; overload;
1826

19-
Use this overload to convert an OleVariant into an `IJSONDocument` reference:
27+
Depending on the value of the argument:
2028

2129
* string types are parsed into a new `IJSONDocument` instance,
2230
* Null (or empty or unassigned) returns `nil`,
2331
* in all other cases the variant is probed for a reference to an `IJSONDocument` instace.
2432

2533
### IJSONDocument
2634

27-
function Parse(const JSONData: WideString): IJSONDocument; safecall;
35+
Merge a string with JSON data into the `IJSONDocument` instance, existing keys will get their values overwritten (see `Clear` below).
2836

29-
Convert a string with JSON data into the `IJSONDocument` instance.
30-
31-
function ToString: WideString; safecall;
37+
function Parse(const JSONData: WideString): IJSONDocument;
3238

3339
Convert the data in the `IJSONDocument` instance into a JSON string.
3440

35-
function ToVarArray:OleVariant; safecall;
41+
function ToString: WideString;
42+
43+
Convert the data in the `IJSONDocument` instance into a Variant array of dimensions [0.._n_,0..1], where [_i_,0] holds keys and [_i_,1] holds values.
44+
45+
function ToVarArray:OleVariant;
3646

37-
Convert the data in the `IJSONDocument` instance into a Variant array.
47+
Clear the values of the `IJSONDocument`, but keep the list of keys.
3848

39-
procedure Clear; safecall;
49+
procedure Clear;
4050

41-
Clear the values of the `IJSONDocument`, but keep the list of keys. When processing a sequence of JSON documents with a similar set of keys (and keys of embedded documents), performance can be gained by avoiding the de- and re-allocation of memory to store the keys (and the Variant record for their values).
51+
When processing a sequence of JSON documents with a similar set of keys (and keys of embedded documents), performance can be gained by avoiding the de- and re-allocation of memory to store the keys (and the Variant record for their values). (See also `IJSONDocArrayBuilder` below).
52+
53+
Retrieve a value by key. This is the default property, so you can access the keys of a `IJSONDocument` by index notation (e.g.: `d['id']`).
4254

4355
property Item[const Key: WideString]: OleVariant; default;
4456

45-
Get or set the value for a key. Notice this is the default property, so you can access the keys of a `IJSONDocument` by index notation (e.g.: `d['id']`)
57+
## Remarks
58+
59+
**Attention:** the default `IJSONDocument` implementation: `TJSONDocument` is **not** thread-safe. Please use proper locking and synchronisation methods to ensure only one thread accesses an instance at one time, or use `jsonTS.pas`.
60+
61+
### JSONEnum
62+
63+
Create an `IJSONEnumerator` instance for a `IJSONDocument` reference.
64+
65+
function JSONEnum(x: IJSONDocument): IJSONEnumerator; overload;
66+
function JSONEnum(const x: OleVariant): IJSONEnumerator; overload;
4667

4768
### IJSONEnumerator
4869

49-
Use the `JSONEnum` function to create an `IJSONEnumerator` instance for a `IJSONDocument` reference.
70+
Check wether the enumerator is past the end of the set of keys of the document.
5071

5172
function EOF: boolean;
5273

53-
Checks wether the enumerator is past the end of the set. Use `EOF` on a new enumerator for skipping the iteration on an empty set.
74+
Move the iterator to the next item in the set. Moves the iterator to the first item on the first call. Returns false when moved past the end of the set.
5475

5576
function Next: boolean;
5677

57-
Moves the iterator to the next item in the set. Moves the iterator to the first item on the first call. Returns false when moved past the end of the set.
78+
Returns the key or value of the current item in the set.
5879

5980
function Key: WideString;
6081
function Value: OleVariant;
6182

6283
Returns the key or value of the current item in the set.
6384

64-
## Remarks
85+
### JSONDocArray
86+
87+
Use an `IJSONDocArrayBuilder` instance to store a set of similar JSON documents. JSON is converted to and from strings internally to save on memory usage. Use `LoadItem` with a single `IJSONDocument` instance to re-use keys and save on memory allocation. Pre-load a parent `IJSONDocument` with an `IJSONDocArrayBuilder` instance to postpone some of the parsing of the children documents.
88+
89+
function JSONDocArray: IJSONDocArrayBuilder; overload;
90+
function JSONDocArray(const Items:array of IJSONDocument): IJSONDocArrayBuilder; overload;
91+
92+
### IJSONDocArrayBuilder
93+
94+
Append a document to the array.
95+
96+
function Add(Doc: IJSONDocument): integer;
97+
function AddJSON(const Data: WideString): integer;
98+
99+
Retrieve a document using an existing `IJSONDocument` instance, possibly re-using allocated keys.
100+
101+
procedure LoadItem(Index: integer; Doc: IJSONDocument);
102+
103+
Retrieve the number of documents in the array.
104+
105+
function Count: integer; stdcall;
106+
107+
Convert the data in the `IJSONDocArrayBuilder` instance into a JSON string.
108+
109+
function ToString: WideString; stdcall;
110+
111+
Retrieve a document by index, in a new `IJSONDocument` instance. This is the default property, so you can use index notation (e.g.: `a[3]`).
65112

66-
**Attention:** the default `IJSONDocument` implementation: `TJSONDocument` is **not** thread-safe. Please use proper locking and synchronisation methods to ensure only one thread accesses an instance at one time.
113+
property Item[Idx: integer]: IJSONDocument; default;

0 commit comments

Comments
 (0)