Compare commits

..
Author SHA1 Message Date
Niels Lohmann 73db3b5fdb docs: name the macros that turn off FILE* locking and bulk scans
parse() and sax_parse() now say that the FILE* is locked unless
JSON_DISABLE_UNLOCKED_FILE_IO is defined to 1, and the input-source
table and the performance page name JSON_DISABLE_STREAM_BULK_SCAN and
JSON_DISABLE_UNLOCKED_FILE_IO with what each turns off.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-11-11 22:21:47 +01:00
6 changed files with 17 additions and 18 deletions

No files matched your search

+4 -8
View File
@@ -133,10 +133,10 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
ahead, so the stream is left exactly where it would be after reading one character at a time. With glibc ahead, so the stream is left exactly where it would be after reading one character at a time. With glibc
and the Apple C library, the characters the `#!cpp FILE` holds in its buffer are scanned in bulk like a stream's; and the Apple C library, the characters the `#!cpp FILE` holds in its buffer are scanned in bulk like a stream's;
elsewhere a `#!cpp FILE*` is read one character at a time. Where the C library has unlocked stdio functions, the elsewhere a `#!cpp FILE*` is read one character at a time. Where the C library has unlocked stdio functions, the
file is locked only once, so other threads that use the same `FILE` object wait until parsing is done. See file is locked only once, so other threads that use the same `FILE` object wait until parsing is done, unless
[input sources and performance](../../features/parsing/index.md#input-sources-and-performance), [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) is defined to `1`. See
[`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md), and [input sources and performance](../../features/parsing/index.md#input-sources-and-performance) and
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md). [`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md).
## Examples ## Examples
@@ -313,10 +313,6 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
it as end of input; planned to become the default in version 4.0.0. it as end of input; planned to become the default in version 4.0.0.
- Extended empty-input detection to also cover an `std::istream` without a stream buffer, and fixed a crash - Extended empty-input detection to also cover an `std::istream` without a stream buffer, and fixed a crash
(`std::terminate`) when parsing from an `std::istream` with `eofbit` in its exception mask, in version 3.13.0. (`std::terminate`) when parsing from an `std::istream` with `eofbit` in its exception mask, in version 3.13.0.
- Fixed the position that a [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) reports for an
unexpected number that is followed by a line feed in version 3.13.0: for the input `1`, line feed, `2`, line feed,
version 3.12.0 reported "line 2, column 0" and version 3.13.0 reports "line 2, column 1"; for `1 2` and a line feed,
the report was "line 1, column 0" and is now "line 1, column 3".
- Parsing from an `std::istream` scans the characters in its stream buffer in bulk in version 3.13.0 - Parsing from an `std::istream` scans the characters in its stream buffer in bulk in version 3.13.0
([`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md) restores reading one character at a ([`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md) restores reading one character at a
time). time).
+2 -2
View File
@@ -124,8 +124,8 @@ consumer `sax` has a super-linear complexity.
A UTF-8 byte order mark is silently ignored. A UTF-8 byte order mark is silently ignored.
When reading from a `#!c FILE*`, where the C library has unlocked stdio functions (see When reading from a `#!c FILE*` where the C library has unlocked stdio functions, the file is locked while it is parsed,
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md)), the file is locked while it is parsed. unless [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) is defined to `1`.
The lock is recursive, so the SAX handler may use the same file with stdio functions, but it must not wait for another The lock is recursive, so the SAX handler may use the same file with stdio functions, but it must not wait for another
thread that uses the same `FILE` object. thread that uses the same `FILE` object.
@@ -67,7 +67,3 @@ Constant.
## Version history ## Version history
- Added in version 3.12.0. - Added in version 3.12.0.
- Fixed in version 3.13.0: in version 3.12.0, the start position of a string that contains escape sequences (for
example `#!cpp "\n"` or `#!cpp "\u00e4"`) was too large, by the number of bytes the escape sequences add to the
source text. The position is now always that of the opening `"`. The "(bytes a-b)" range in the messages of
[`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) was wrong in the same way.
@@ -125,5 +125,3 @@ When the macro is not defined, the library will define it to its default value.
## Version history ## Version history
- Added in version 3.12.0. - Added in version 3.12.0.
- Fixed in version 3.13.0: in version 3.12.0, [`start_pos()`](../basic_json/start_pos.md) of a string that contains
escape sequences was too large; it is now the position of the opening `"`.
@@ -80,6 +80,12 @@ them faster than others:
| `#!cpp FILE*` | with glibc and the Apple C library, the characters the `FILE` holds in its buffer are scanned in bulk like a stream's; elsewhere one character at a time; where the C library has unlocked stdio functions, the file is locked once for the whole parse | | `#!cpp FILE*` | with glibc and the Apple C library, the characters the `FILE` holds in its buffer are scanned in bulk like a stream's; elsewhere one character at a time; where the C library has unlocked stdio functions, the file is locked once for the whole parse |
| other iterator ranges (e.g., `#!cpp std::list<char>`, `#!cpp std::istreambuf_iterator<char>`), wide strings | one character at a time | | other iterator ranges (e.g., `#!cpp std::list<char>`, `#!cpp std::istreambuf_iterator<char>`), wide strings | one character at a time |
Defining [`JSON_DISABLE_STREAM_BULK_SCAN`](../../api/macros/json_disable_stream_bulk_scan.md) to `1` turns off the bulk
scan of a stream buffer, so a `#!cpp std::istream` is read one character at a time. Defining
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../../api/macros/json_disable_unlocked_file_io.md) to `1` makes a `#!cpp FILE*` read
every character with `std::fgetc`, without locking the file for the whole parse and without the bulk scan of its buffer
(which `JSON_DISABLE_STREAM_BULK_SCAN` does not affect). Neither changes any result.
Input in one block of memory is read even faster with the default options (no Input in one block of memory is read even faster with the default options (no
[parser callback](../../api/basic_json/parser_callback_t.md), no comments, no trailing commas, and for `sax_parse()` [parser callback](../../api/basic_json/parser_callback_t.md), no comments, no trailing commas, and for `sax_parse()`
`strict = true`): `parse()`, `accept()`, and `sax_parse()` then read the grammar and the tokens in one loop over the `strict = true`): `parse()`, `accept()`, and `sax_parse()` then read the grammar and the tokens in one loop over the
+5 -2
View File
@@ -29,8 +29,11 @@ up. Nothing is read ahead, so the stream is left exactly where it would be after
[`operator>>`](../api/operator_gtgt.md) can still read several values from one stream. A stream buffer without a get [`operator>>`](../api/operator_gtgt.md) can still read several values from one stream. A stream buffer without a get
area is read one character at a time. Where the C library has unlocked stdio functions, a `#!cpp FILE*` is locked once area is read one character at a time. Where the C library has unlocked stdio functions, a `#!cpp FILE*` is locked once
per parse instead of once per character, and with glibc and the Apple C library, the characters in its buffer are per parse instead of once per character, and with glibc and the Apple C library, the characters in its buffer are
scanned in bulk as a stream's get area is. See scanned in bulk as a stream's get area is.
[input sources and performance](parsing/index.md#input-sources-and-performance) for the full table. Parsing from a [`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md) turns off the bulk scan of streams, and
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) both the single lock and the bulk scan
of a `#!cpp FILE*`. See [input sources and performance](parsing/index.md#input-sources-and-performance) for the full
table. Parsing from a
stream takes about 1.15 to 1.45 times as long as parsing an equivalent `#!cpp std::string`, which `parse()` reads with stream takes about 1.15 to 1.45 times as long as parsing an equivalent `#!cpp std::string`, which `parse()` reads with
a parser of its own (see there). a parser of its own (see there).