SAVED EN CANONICAL
---
title: "Reading JSON"
documentId: "yyjson:01-guide/03-reading-json.md"
order: 3
licenseSource: "yyjson-fixed"
toc: {"maxLevel": 6}
documentContext: [{"kind": "source", "html": "<p>yyjson 0.13.0, fixed commit 6447536015f3d600f3d65323b10976103b337ca7. By YaoYuan and yyjson contributors. <a href=\"https://github.com/ibireme/yyjson/blob/6447536015f3d600f3d65323b10976103b337ca7/doc/API.md#L76-L514\">Fixed official original</a>. <a href=\"/docs/yyjson/notices/LICENSE.txt\">Original MIT notice</a>.</p><p>Libxによる非公式編集・日本語訳です。固定Markdown7資料とSVG7図を保持し、利用ガイド16ページが日本語訳の対象です。更新履歴・原著Performance TODO・原MIT通知は英語原文参照です。Libxの運用方針に基づき、意味のまとまった節分割・見出し・内部参照・静的な図の配置を調整しています。</p>"}, {"kind": "editorial", "html": "<p>原著のPerformance.mdはTODOのみで未執筆です。READMEの性能図表と2020年のレポートは固定原文のまま提供し、原著の制限・注意書きも保持しています。生成Doxygenの全シンボル一覧、第三者テーマ、対話型ベンチマークや構造図の編集ファイルは収録せず、<a href=\"https://ibireme.github.io/yyjson/doc/doxygen/html/\">公式文書</a>と原稿中の参照リンクで補います。原文の技術監査やサンプルプログラムの実行は行っていません。</p>"}]
---
# Reading JSON
The library provides 5 functions for reading JSON.<br/>
Each function accepts an input of UTF-8 data or a file,<br/>
returns a document if successful or `NULL` if it fails.

## Read JSON from string
The `dat` should be a UTF-8 string, null-terminator is not required.<br/>
The `len` is the byte length of `dat`.<br/>
The `flg` is reader flag, pass 0 if you don't need it, see `reader flag` for details.<br/>
Returns `NULL` if `dat` is NULL or `len` is 0.

```c
yyjson_doc *yyjson_read(const char *dat, 
                        size_t len, 
                        yyjson_read_flag flg);
```
Sample code:

```c
const char *str = "[1,2,3,4]";
yyjson_doc *doc = yyjson_read(str, strlen(str), 0);
if (doc) {...}
yyjson_doc_free(doc);
```

## Read JSON from file

The `path` is the JSON file path. This should be a null-terminated string using the system's native encoding.<br/>
The `flg` is reader flag, pass 0 if you don't need it, see `reader flag` for details.<br/>
The `alc` is memory allocator, pass NULL if you don't need it, see `memory allocator` for details.<br/>
The `err` is a pointer to receive error message, pass NULL if you don't need it.<br/>
Returns `NULL` if `path` is NULL or invalid.

```c
yyjson_doc *yyjson_read_file(const char *path,
                             yyjson_read_flag flg,
                             const yyjson_alc *alc,
                             yyjson_read_err *err);
```

Sample code:

```c
yyjson_doc *doc = yyjson_read_file("/tmp/test.json", 0, NULL, NULL);
if (doc) {...}
yyjson_doc_free(doc);
```

## Read JSON from file pointer

The `fp` is file pointer. The data will be read from the current position of the FILE to the end.<br/>
The `flg` is reader flag, pass 0 if you don't need it, see `reader flag` for details.<br/>
The `alc` is memory allocator, pass NULL if you don't need it, see `memory allocator` for details.<br/>
The `err` is a pointer to receive error message, pass NULL if you don't need it.<br/>
Returns `NULL` if `fp` is NULL or invalid.

```c
yyjson_doc *yyjson_read_fp(FILE *fp,
                           yyjson_read_flag flg,
                           const yyjson_alc *alc,
                           yyjson_read_err *err);
```

Sample code:

```c
FILE *fp = fdopen(fd, "rb"); // POSIX file descriptor (fd)
yyjson_doc *doc = yyjson_read_fp(fp, 0, NULL, NULL);
if (fp) fclose(fp);
if (doc) {...}
yyjson_doc_free(doc);
```

## Read JSON with options
The `dat` should be a UTF-8 string, you can pass a const string if you don't use `YYJSON_READ_INSITU` flag.<br/>
The `len` is the `dat`'s length in bytes.<br/>
The `flg` is reader flag, pass 0 if you don't need it, see `reader flag` for details.<br/>
The `alc` is memory allocator, pass NULL if you don't need it, see `memory allocator` for details.<br/>
The `err` is a pointer to receive error message, pass NULL if you don't need it.<br/>

```c
yyjson_doc *yyjson_read_opts(char *dat, 
                             size_t len, 
                             yyjson_read_flag flg,
                             const yyjson_alc *alc, 
                             yyjson_read_err *err);
```

Sample code:

```c
const char *dat = your_file.bytes;
size_t len = your_file.size;

yyjson_read_flag flg = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_INF_AND_NAN;
yyjson_doc *doc = yyjson_read_opts((char *)dat, len, flg, NULL, NULL);

if (doc) {...}

yyjson_doc_free(doc);
```

## Read JSON incrementally

Reading a very large JSON document can freeze the program for a short while. If
this is not acceptable, incremental reading can be used.

Incremental reading is recommended only for large documents and only when the
program needs to be responsive. Incremental reading is slightly slower than
`yyjson_read()` and `yyjson_read_opts()`.

Note: The incremental JSON reader only supports standard JSON.
Flags for non-standard features (e.g. comments, trailing commas) are ignored.

To read a large JSON document incrementally:

1. Call `yyjson_incr_new()` to create the state for incremental reading.
2. Call `yyjson_incr_read()` repeatedly.
3. Call `yyjson_incr_free()` to free the state.

### Create the state for incremental reading

The `buf` should be a UTF-8 string, null-terminator is not required.
You can pass a const string if you don't use the `YYJSON_READ_INSITU` flag.<br/>
The `buf_len` is the length of `buf` in bytes.
The `flg` is reader flag. Pass 0 if you don't need it. See reader flag for details.
The `alc` is memory allocator, pass NULL if you don't need it. See `memory allocator` for details.<br/>

The function returns a new state, or NULL if memory allocation fails.

```c
yyjson_incr_state *yyjson_incr_new(char *buf, size_t buf_len, yyjson_read_flag flg, const yyjson_alc *alc);
```

### Perform incremental read

Performs incremental read of up to `len` bytes.

The `state` for incremental reading is created using `yyjson_incr_new()`.<br/>
The `len` is the maximum number of bytes to read, counting from the start of the JSON data.<br/>
The `err` is a pointer to receive the error information. Required.<br/>

The function returns a document object when the reading is complete and NULL otherwise.
If `err->code` is set to `YYJSON_READ_ERROR_MORE`, it indicates that parsing is not yet complete.
Then, increase `len` by some kilobytes and call this function again.
Continue increasing `len` until `len == buf_len` (the total length of the input buffer) or until an error other than `YYJSON_READ_ERROR_MORE` is returned.

Note: Parsing in very small increments is not efficient.
An increment of several kilobytes or megabytes is recommended.

```c
yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len, yyjson_read_err *err);
```

### Free the state used for incremental reading

Free the `state` created by `yyjson_incr_new()`.

```c
void yyjson_incr_free(yyjson_incr_state *state);
```

### Sample code

```c
const char *dat = your_file.bytes;
size_t len = your_file.size;

yyjson_read_flag flg = YYJSON_READ_NOFLAG;
yyjson_incr_state *state = yyjson_incr_new(dat, len, flg, NULL);
yyjson_doc *doc;
yyjson_read_err err;
size_t read_so_far = 0;
do {
    read_so_far += 100000;
    if (read_so_far > len)
        read_so_far = len;
    doc = yyjson_incr_read(state, read_so_far, &err);
    if (err.code != YYJSON_READ_ERROR_MORE)
        break;
} while (read_so_far < len);
yyjson_incr_free(state);

if (doc != NULL) { ... }

yyjson_doc_free(doc);
```

## Reader error handling

When reading JSON fails, and you need error information, you can pass a `yyjson_read_err` pointer to the `yyjson_read_xxx()` functions to receive the error details.

Sample code:
```c
char *dat = ...;
size_t dat_len = ...;
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_opts(dat, dat_len, 0, NULL, &err);

if (!doc) {
    printf("read error: %s, code: %u at byte position: %lu\n", 
            err.msg, err.code, err.pos);
    // printed:
    // read error: trailing comma is not allowed, code: 7, at byte position: 40
}

yyjson_doc_free(doc);
```

The `pos` in the error information indicates the byte position where the error occurred. If you need the line and column number of the error, you can use the `yyjson_locate_pos()` function. Note that `line` and `column` start from 1, while `character` starts from 0. All values are calculated based on Unicode characters to ensure compatibility with various text editors.

Sample code:
```c
char *dat = ...;
size_t dat_len = ...;
yyjson_read_err err = ...;

size_t line, col, chr;
if (yyjson_locate_pos(dat, dat_len, err.pos, &line, &col, &chr)) {
    printf("error at line: %lu, column: %lu, character index: %lu\n",
           line, col, chr);
    // printed:
    // error at line: 3, column: 5, character index: 32
}
```

The complete list of error codes (`yyjson_read_code`):

| Code | Name | Description |
|------|------|-------------|
| 0 | `YYJSON_READ_SUCCESS` | Success, no error. |
| 1 | `YYJSON_READ_ERROR_INVALID_PARAMETER` | Invalid parameter, such as NULL input string or 0 input length. |
| 2 | `YYJSON_READ_ERROR_MEMORY_ALLOCATION` | Memory allocation failure. |
| 3 | `YYJSON_READ_ERROR_EMPTY_CONTENT` | Input JSON string is empty. |
| 4 | `YYJSON_READ_ERROR_UNEXPECTED_CONTENT` | Unexpected content after document end, such as `[123]abc`. |
| 5 | `YYJSON_READ_ERROR_UNEXPECTED_END` | Unexpected end of input; the parsed part is valid, such as `[123`. |
| 6 | `YYJSON_READ_ERROR_UNEXPECTED_CHARACTER` | Unexpected character inside the document, such as `[abc]`. |
| 7 | `YYJSON_READ_ERROR_JSON_STRUCTURE` | Invalid JSON structure, such as `[1,]`. |
| 8 | `YYJSON_READ_ERROR_INVALID_COMMENT` | Invalid comment (deprecated, mapped to `UNEXPECTED_END`). |
| 9 | `YYJSON_READ_ERROR_INVALID_NUMBER` | Invalid number, such as `123.e12` or `000`. |
| 10 | `YYJSON_READ_ERROR_INVALID_STRING` | Invalid string, such as an invalid escape sequence. |
| 11 | `YYJSON_READ_ERROR_LITERAL` | Invalid JSON literal, such as `truu`. |
| 12 | `YYJSON_READ_ERROR_FILE_OPEN` | Failed to open a file. |
| 13 | `YYJSON_READ_ERROR_FILE_READ` | Failed to read a file. |
| 14 | `YYJSON_READ_ERROR_MORE` | Incomplete input during incremental parsing; state is preserved for continuation. |
| 15 | `YYJSON_READ_ERROR_DEPTH` | Nesting depth exceeded `YYJSON_READER_DEPTH_LIMIT`. |

## Reader flag
The library provides a set of flags for JSON reader.<br/>

You can use a single flag, or combine multiple flags with bitwise `|` operator.<br/>

Non-standard flags (such as `YYJSON_READ_JSON5`) have no performance impact when reading standard JSON input.

### **YYJSON_READ_NOFLAG = 0**

This is the default flag for JSON reader (RFC-8259 or ECMA-404 compliant):

- Read positive integer as `uint64_t`.
- Read negative integer as `int64_t`.
- Read floating-point number as `double` with correct rounding.
- Read integer which cannot fit in `uint64_t` or `int64_t` as `double`.
- Report error if double number is infinity.
- Report error if string contains invalid UTF-8 character or BOM.
- Report error on trailing commas, comments, `Inf` and `NaN` literals.

### **YYJSON_READ_INSITU**
Read the input data in-situ.<br/>

This option allows the reader to modify and use the input data to store string values, which can slightly improve reading speed. However, the caller must ensure that the input data is held until the document is freed. The input data must be padded with at least `YYJSON_PADDING_SIZE` bytes. For example: `[1,2]` should be `[1,2]\0\0\0\0`, input length should be 5.

Sample code:

```c
size_t dat_len = ...;
char *buf = malloc(dat_len + YYJSON_PADDING_SIZE); // create a buffer larger than (len + 4)
read_from_socket(buf, ...);
memset(buf + dat_len, 0, YYJSON_PADDING_SIZE); // set 4-byte padding after data

yyjson_doc *doc = yyjson_read_opts(buf, dat_len, YYJSON_READ_INSITU, NULL, NULL);
if (doc) {...}
yyjson_doc_free(doc);
free(buf); // the input data should be freed after the document.
```

### **YYJSON_READ_STOP_WHEN_DONE**
Stop parsing when reaching the end of a JSON document instead of issuing an error if there's additional content after it.<br/>

This option is useful for parsing small pieces of JSON within larger data, such as [NDJSON](https://en.wikipedia.org/wiki/JSON_streaming).<br/>

Sample code:

```c
// Single file with multiple JSON, such as:
// [1,2,3] [4,5,6] {"a":"b"}

size_t file_size = ...;
char *dat = malloc(file_size + YYJSON_PADDING_SIZE);
your_read_file(dat, file);
memset(dat + file_size, 0, YYJSON_PADDING_SIZE); // add padding
    
char *hdr = dat;
char *end = dat + file_size;
yyjson_read_flag flg = YYJSON_READ_INSITU | YYJSON_READ_STOP_WHEN_DONE;

while (true) {
    yyjson_doc *doc = yyjson_read_opts(hdr, end - hdr, flg, NULL, NULL);
    if (!doc) break;
    your_doc_process(doc);
    hdr += yyjson_doc_get_read_size(doc); // move to next position
    yyjson_doc_free(doc);
}
free(dat);
```

### **YYJSON_READ_ALLOW_TRAILING_COMMAS**
Allow a single trailing comma at the end of an object or array (non-standard), for example:

```
{
    "a": 1,
    "b": 2,
}

[
    "a",
    "b",
]
```

### **YYJSON_READ_ALLOW_COMMENTS**
Allow C-style single-line and multi-line comments (non-standard), for example:

```
{
    "name": "Harry", // single-line comment
    "id": /* multi-line comment */ 123
}
```

### **YYJSON_READ_ALLOW_INF_AND_NAN**
Allow nan/inf number or case-insensitive literal (non-standard), for example:

```
{
    "large": 123e999,
    "nan1": NaN,
    "nan2": nan,
    "inf1": Inf,
    "inf2": -Infinity
}
```

### **YYJSON_READ_NUMBER_AS_RAW**
Read all numbers as raw strings without parsing.

This flag is useful if you want to handle number parsing yourself.
You can use the following functions to extract raw strings:
```c
bool yyjson_is_raw(const yyjson_val *val);
const char *yyjson_get_raw(const yyjson_val *val);
size_t yyjson_get_len(const yyjson_val *val);
```

### **YYJSON_READ_BIGNUM_AS_RAW**
Read big numbers as raw strings.

This flag is useful if you want to parse these big numbers yourself.
These big numbers include integers that cannot be represented by `int64_t` and `uint64_t`, and floating-point numbers that cannot be represented by finite `double`.

Note that this flag will be overridden by `YYJSON_READ_NUMBER_AS_RAW` flag.

### **YYJSON_READ_ALLOW_INVALID_UNICODE**
Allow reading invalid unicode when parsing string values (non-standard),
for example:
```
"\x80xyz"
"\xF0\x81\x81\x81"
```
This flag permits invalid characters to appear in the string values, but it still reports errors for invalid escape sequences. It does not impact the performance of correctly encoded strings.

***Warning***: when using this option, be aware that strings within JSON values may contain incorrect encoding, so you need to handle these strings carefully to avoid security risks.

### **YYJSON_READ_ALLOW_BOM**
Allow UTF-8 BOM and skip it before parsing if any (non-standard).

### **YYJSON_READ_ALLOW_EXT_NUMBER**
Allow extended number formats (non-standard):
- Hexadecimal numbers, such as `0x7B`.
- Numbers with leading or trailing decimal point, such as `.123`, `123.`.
- Numbers with a leading plus sign, such as `+123`.

### **YYJSON_READ_ALLOW_EXT_ESCAPE**
Allow extended escape sequences in strings (non-standard):
- Additional escapes: `\a`, `\e`, `\v`, ``\'``, `\?`, `\0`.
- Hex escapes: `\xNN`, such as `\x7B`.
- Line continuation: backslash followed by line terminator sequences.
- Unknown escape: if backslash is followed by an unsupported character,
    the backslash will be removed and the character will be kept as-is.
    However, `\1`-`\9` will still trigger an error.

### **YYJSON_READ_ALLOW_EXT_WHITESPACE**
Allow extended whitespace characters (non-standard):
- Vertical tab `\v` and form feed `\f`.
- Line separator `\u2028` and paragraph separator `\u2029`.
- Non-breaking space `\xA0`.
- Byte order mark: `\uFEFF`.
- Other Unicode characters in the Zs (Separator, space) category.

### **YYJSON_READ_ALLOW_SINGLE_QUOTED_STR**
Allow strings enclosed in single quotes (non-standard), such as ``'ab'``.

### **YYJSON_READ_ALLOW_UNQUOTED_KEY**
Allow object keys without quotes (non-standard), such as `{a:1,b:2}`.
This extends the ECMAScript IdentifierName rule by allowing any
non-whitespace character with code point above `U+007F`.

### **YYJSON_READ_JSON5**
Allow JSON5 format, see: https://json5.org.

This flag supports all JSON5 features with some additional extensions:
- Accepts more escape sequences than JSON5 (e.g. `\a`, `\e`).
- Unquoted keys are not limited to ECMAScript IdentifierName.
- Allow case-insensitive `NaN`, `Inf` and `Infinity` literals.

For example:
```json
{
    /* JSON5 example */
    id: 123,
    name: 'Harry',
    color: 0x66CCFF,
    min: .001,
    max: Inf,
    data: '\x00\xAA\xFF',
}
```

---------------

SAVED JA BODY
<a id="reading-json"></a>
# JSONの読み込み

ライブラリは、JSONを読み込む5つの関数を提供しています。<br/>
各関数はUTF-8データまたはファイルを入力として受け取り、<br/>
成功するとドキュメントを返し、失敗すると`NULL`を返します。

<a id="read-json-from-string"></a>
## 文字列からJSONを読み込む

`dat`はUTF-8文字列である必要があります。NUL終端は不要です。<br/>
`len`は`dat`のバイト長です。<br/>
`flg`は読み込みフラグです。不要なら0を渡します。詳細は読み込みフラグを参照してください。<br/>
`dat`がNULLまたは`len`が0の場合、`NULL`を返します。

```c
yyjson_doc *yyjson_read(const char *dat, 
                        size_t len, 
                        yyjson_read_flag flg);
```

サンプルコード：

```c
const char *str = "[1,2,3,4]";
yyjson_doc *doc = yyjson_read(str, strlen(str), 0);
if (doc) {...}
yyjson_doc_free(doc);
```


<a id="read-json-from-file"></a>
## ファイルからJSONを読み込む

`path`はJSONファイルのパスです。システム固有の文字エンコーディングによるNUL終端文字列である必要があります。<br/>
`flg`は読み込みフラグです。不要なら0を渡します。詳細は読み込みフラグを参照してください。<br/>
`alc`はメモリアロケーターです。不要ならNULLを渡します。詳細はメモリアロケーターを参照してください。<br/>
`err`はエラーメッセージを受け取るためのポインターです。不要ならNULLを渡します。<br/>
`path`がNULLまたは無効な場合、`NULL`を返します。

```c
yyjson_doc *yyjson_read_file(const char *path,
                             yyjson_read_flag flg,
                             const yyjson_alc *alc,
                             yyjson_read_err *err);
```


サンプルコード：

```c
yyjson_doc *doc = yyjson_read_file("/tmp/test.json", 0, NULL, NULL);
if (doc) {...}
yyjson_doc_free(doc);
```


<a id="read-json-from-file-pointer"></a>
## ファイルポインターからJSONを読み込む

`fp`はファイルポインターです。FILEの現在位置から末尾までデータを読み込みます。<br/>
`flg`は読み込みフラグです。不要なら0を渡します。詳細は読み込みフラグを参照してください。<br/>
`alc`はメモリアロケーターです。不要ならNULLを渡します。詳細はメモリアロケーターを参照してください。<br/>
`err`はエラーメッセージを受け取るためのポインターです。不要ならNULLを渡します。<br/>
`fp`がNULLまたは無効な場合、`NULL`を返します。

```c
yyjson_doc *yyjson_read_fp(FILE *fp,
                           yyjson_read_flag flg,
                           const yyjson_alc *alc,
                           yyjson_read_err *err);
```


サンプルコード：

```c
FILE *fp = fdopen(fd, "rb"); // POSIX file descriptor (fd)
yyjson_doc *doc = yyjson_read_fp(fp, 0, NULL, NULL);
if (fp) fclose(fp);
if (doc) {...}
yyjson_doc_free(doc);
```


<a id="read-json-with-options"></a>
## オプションを指定してJSONを読み込む

`dat`はUTF-8文字列である必要があります。`YYJSON_READ_INSITU`フラグを使わない場合は、const文字列を渡せます。<br/>
`len`は`dat`のバイト長です。<br/>
`flg`は読み込みフラグです。不要なら0を渡します。詳細は読み込みフラグを参照してください。<br/>
`alc`はメモリアロケーターです。不要ならNULLを渡します。詳細はメモリアロケーターを参照してください。<br/>
`err`はエラーメッセージを受け取るためのポインターです。不要ならNULLを渡します。<br/>

```c
yyjson_doc *yyjson_read_opts(char *dat, 
                             size_t len, 
                             yyjson_read_flag flg,
                             const yyjson_alc *alc, 
                             yyjson_read_err *err);
```


サンプルコード：

```c
const char *dat = your_file.bytes;
size_t len = your_file.size;

yyjson_read_flag flg = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_INF_AND_NAN;
yyjson_doc *doc = yyjson_read_opts((char *)dat, len, flg, NULL, NULL);

if (doc) {...}

yyjson_doc_free(doc);
```


<a id="read-json-incrementally"></a>
## JSONを増分的に読み込む

非常に大きなJSONドキュメントを読み込むと、プログラムがしばらく停止することがあります。これが許容できない場合、増分読み込みを使えます。

増分読み込みを推奨するのは、大きなドキュメントで、プログラムの応答性を保つ必要がある場合だけです。増分読み込みは`yyjson_read()`や`yyjson_read_opts()`よりも少し遅くなります。

注：増分JSONリーダーは標準JSONにのみ対応します。
非標準の機能（コメントや末尾のカンマなど）のフラグは無視されます。

大きなJSONドキュメントを増分的に読み込む手順は次のとおりです。

1. `yyjson_incr_new()`を呼び出して、増分読み込みの状態を作ります。
2. `yyjson_incr_read()`を繰り返し呼び出します。
3. `yyjson_incr_free()`を呼び出して、状態を解放します。

<a id="create-the-state-for-incremental-reading"></a>
### 増分読み込みの状態を作る

`buf`はUTF-8文字列である必要があります。NUL終端は不要です。
`YYJSON_READ_INSITU`フラグを使わない場合は、const文字列を渡せます。<br/>
`buf_len`は`buf`のバイト長です。
`flg`は読み込みフラグです。不要なら0を渡します。詳細は読み込みフラグを参照してください。
`alc`はメモリアロケーターです。不要ならNULLを渡します。詳細はメモリアロケーターを参照してください。<br/>

この関数は新しい状態を返します。メモリの確保に失敗した場合はNULLを返します。

```c
yyjson_incr_state *yyjson_incr_new(char *buf, size_t buf_len, yyjson_read_flag flg, const yyjson_alc *alc);
```


<a id="perform-incremental-read"></a>
### 増分読み込みを行う

`len`バイトまでの増分読み込みを行います。

増分読み込み用の`state`は、`yyjson_incr_new()`で作成します。<br/>
`len`は読み込むバイト数の上限で、JSONデータの先頭から数えます。<br/>
`err`はエラー情報を受け取るためのポインターです。必須です。<br/>

この関数は、読み込みが完了するとドキュメントオブジェクトを返し、それ以外の場合はNULLを返します。
`err->code`に`YYJSON_READ_ERROR_MORE`が設定された場合、解析がまだ完了していないことを示します。
その場合は`len`を数キロバイト増やし、この関数を再度呼び出します。
`len == buf_len`（入力バッファーの全長）になるか、`YYJSON_READ_ERROR_MORE`以外のエラーが返るまで、`len`を増やし続けます。

注：非常に小さな増分で解析するのは非効率です。
数キロバイトまたは数メガバイトずつ増やすことを推奨します。

```c
yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len, yyjson_read_err *err);
```


<a id="free-the-state-used-for-incremental-reading"></a>
### 増分読み込みに使った状態を解放する

`yyjson_incr_new()`で作成した`state`を解放します。

```c
void yyjson_incr_free(yyjson_incr_state *state);
```


<a id="sample-code"></a>
### サンプルコード

```c
const char *dat = your_file.bytes;
size_t len = your_file.size;

yyjson_read_flag flg = YYJSON_READ_NOFLAG;
yyjson_incr_state *state = yyjson_incr_new(dat, len, flg, NULL);
yyjson_doc *doc;
yyjson_read_err err;
size_t read_so_far = 0;
do {
    read_so_far += 100000;
    if (read_so_far > len)
        read_so_far = len;
    doc = yyjson_incr_read(state, read_so_far, &err);
    if (err.code != YYJSON_READ_ERROR_MORE)
        break;
} while (read_so_far < len);
yyjson_incr_free(state);

if (doc != NULL) { ... }

yyjson_doc_free(doc);
```


<a id="reader-error-handling"></a>
## 読み込みエラーの処理

JSONの読み込みが失敗し、エラー情報が必要な場合は、`yyjson_read_xxx()`関数に`yyjson_read_err`のポインターを渡して詳細を受け取れます。

サンプルコード：

```c
char *dat = ...;
size_t dat_len = ...;
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_opts(dat, dat_len, 0, NULL, &err);

if (!doc) {
    printf("read error: %s, code: %u at byte position: %lu\n", 
            err.msg, err.code, err.pos);
    // printed:
    // read error: trailing comma is not allowed, code: 7, at byte position: 40
}

yyjson_doc_free(doc);
```


エラー情報の`pos`は、エラーが発生したバイト位置を示します。エラーの行番号と列番号が必要な場合は、`yyjson_locate_pos()`を使えます。`line`と`column`は1から、`character`は0から始まることに注意してください。各値は、さまざまなテキストエディターと互換性を保つため、Unicode文字に基づいて計算されます。

サンプルコード：

```c
char *dat = ...;
size_t dat_len = ...;
yyjson_read_err err = ...;

size_t line, col, chr;
if (yyjson_locate_pos(dat, dat_len, err.pos, &line, &col, &chr)) {
    printf("error at line: %lu, column: %lu, character index: %lu\n",
           line, col, chr);
    // printed:
    // error at line: 3, column: 5, character index: 32
}
```


エラーコード（`yyjson_read_code`）の完全な一覧：

|コード|名前|説明|
|---|---|---|
|0|`YYJSON_READ_SUCCESS`|成功。エラーなし。|
|1|`YYJSON_READ_ERROR_INVALID_PARAMETER`|NULLの入力文字列や入力長0など、無効な引数。|
|2|`YYJSON_READ_ERROR_MEMORY_ALLOCATION`|メモリ確保の失敗。|
|3|`YYJSON_READ_ERROR_EMPTY_CONTENT`|入力JSON文字列が空。|
|4|`YYJSON_READ_ERROR_UNEXPECTED_CONTENT`|`[123]abc`のように、ドキュメント末尾の後に予期しない内容がある。|
|5|`YYJSON_READ_ERROR_UNEXPECTED_END`|入力が予期せず終了した。`[123`のように、解析済みの部分は有効。|
|6|`YYJSON_READ_ERROR_UNEXPECTED_CHARACTER`|`[abc]`のように、ドキュメント内に予期しない文字がある。|
|7|`YYJSON_READ_ERROR_JSON_STRUCTURE`|`[1,]`のように、JSON構造が無効。|
|8|`YYJSON_READ_ERROR_INVALID_COMMENT`|無効なコメント（非推奨。`UNEXPECTED_END`に対応付けられる）。|
|9|`YYJSON_READ_ERROR_INVALID_NUMBER`|`123.e12`や`000`のように、数値が無効。|
|10|`YYJSON_READ_ERROR_INVALID_STRING`|無効なエスケープシーケンスなど、文字列が無効。|
|11|`YYJSON_READ_ERROR_LITERAL`|`truu`のように、JSONリテラルが無効。|
|12|`YYJSON_READ_ERROR_FILE_OPEN`|ファイルを開けなかった。|
|13|`YYJSON_READ_ERROR_FILE_READ`|ファイルを読み込めなかった。|
|14|`YYJSON_READ_ERROR_MORE`|増分解析中に入力が未完了。状態は継続用に保持される。|
|15|`YYJSON_READ_ERROR_DEPTH`|ネストの深さが`YYJSON_READER_DEPTH_LIMIT`を超えた。|

<a id="reader-flag"></a>
## 読み込みフラグ

ライブラリは、JSONリーダー用のフラグを用意しています。<br/>
フラグを単独で使うことも、ビット単位の`|`演算子で複数のフラグを組み合わせることもできます。<br/>

非標準のフラグ（`YYJSON_READ_JSON5`など）は、標準JSONの入力を読み込む際の性能に影響しません。

### **YYJSON_READ_NOFLAG = 0**

JSONリーダーの既定のフラグです（RFC-8259またはECMA-404に準拠）。

- 正の整数を`uint64_t`として読み込みます。
- 負の整数を`int64_t`として読み込みます。
- 浮動小数点数を正しく丸めて`double`として読み込みます。
- `uint64_t`や`int64_t`に収まらない整数を`double`として読み込みます。
- doubleの数値が無限大の場合はエラーを報告します。
- 文字列に無効なUTF-8文字やBOMがある場合はエラーを報告します。
- 末尾のカンマ、コメント、`Inf`および`NaN`リテラルについてエラーを報告します。

### **YYJSON_READ_INSITU**

入力データをその場所で読み込みます。<br/>

このオプションでは、リーダーが入力データを変更し、文字列の値を格納するために使用できるため、読み込み速度が少し向上することがあります。ただし、呼び出し側は、ドキュメントを解放するまで入力データを保持しなければなりません。入力データの末尾には、少なくとも`YYJSON_PADDING_SIZE`バイトのパディングが必要です。たとえば、`[1,2]`は`[1,2]\0\0\0\0`とし、入力長は5にします。

サンプルコード：

```c
size_t dat_len = ...;
char *buf = malloc(dat_len + YYJSON_PADDING_SIZE); // create a buffer larger than (len + 4)
read_from_socket(buf, ...);
memset(buf + dat_len, 0, YYJSON_PADDING_SIZE); // set 4-byte padding after data

yyjson_doc *doc = yyjson_read_opts(buf, dat_len, YYJSON_READ_INSITU, NULL, NULL);
if (doc) {...}
yyjson_doc_free(doc);
free(buf); // the input data should be freed after the document.
```


### **YYJSON_READ_STOP_WHEN_DONE**

JSONドキュメントの末尾に達すると解析を停止し、その後に追加の内容があってもエラーにしません。<br/>

このオプションは、[NDJSON](https://en.wikipedia.org/wiki/JSON_streaming)のように、大きなデータの中に含まれる小さなJSON片を解析する場合に役立ちます。<br/>

サンプルコード：

```c
// Single file with multiple JSON, such as:
// [1,2,3] [4,5,6] {"a":"b"}

size_t file_size = ...;
char *dat = malloc(file_size + YYJSON_PADDING_SIZE);
your_read_file(dat, file);
memset(dat + file_size, 0, YYJSON_PADDING_SIZE); // add padding
    
char *hdr = dat;
char *end = dat + file_size;
yyjson_read_flag flg = YYJSON_READ_INSITU | YYJSON_READ_STOP_WHEN_DONE;

while (true) {
    yyjson_doc *doc = yyjson_read_opts(hdr, end - hdr, flg, NULL, NULL);
    if (!doc) break;
    your_doc_process(doc);
    hdr += yyjson_doc_get_read_size(doc); // move to next position
    yyjson_doc_free(doc);
}
free(dat);
```


### **YYJSON_READ_ALLOW_TRAILING_COMMAS**

オブジェクトや配列の末尾にカンマを1つ置くことを許可します（非標準）。例：

```
{
    "a": 1,
    "b": 2,
}

[
    "a",
    "b",
]
```


### **YYJSON_READ_ALLOW_COMMENTS**

C形式の単一行コメントと複数行コメントを許可します（非標準）。例：

```
{
    "name": "Harry", // single-line comment
    "id": /* multi-line comment */ 123
}
```


### **YYJSON_READ_ALLOW_INF_AND_NAN**

nan/infの数値、または大文字と小文字を区別しないリテラルを許可します（非標準）。例：

```
{
    "large": 123e999,
    "nan1": NaN,
    "nan2": nan,
    "inf1": Inf,
    "inf2": -Infinity
}
```


### **YYJSON_READ_NUMBER_AS_RAW**

数値をすべて解析せず、未加工の文字列として読み込みます。

数値の解析を自分で処理する場合に便利なフラグです。
次の関数で未加工の文字列を取り出せます。

```c
bool yyjson_is_raw(const yyjson_val *val);
const char *yyjson_get_raw(const yyjson_val *val);
size_t yyjson_get_len(const yyjson_val *val);
```


### **YYJSON_READ_BIGNUM_AS_RAW**

大きな数値を未加工の文字列として読み込みます。

これらの大きな数値を自分で解析する場合に便利なフラグです。
対象には、`int64_t`や`uint64_t`で表せない整数と、有限の`double`で表せない浮動小数点数が含まれます。

このフラグは`YYJSON_READ_NUMBER_AS_RAW`フラグで上書きされることに注意してください。

### **YYJSON_READ_ALLOW_INVALID_UNICODE**

文字列の値を解析する際に、無効なUnicodeの読み込みを許可します（非標準）。例：

```
"\x80xyz"
"\xF0\x81\x81\x81"
```

このフラグは、文字列の値に無効な文字が含まれることを許可しますが、無効なエスケープシーケンスについては引き続きエラーを報告します。正しくエンコードされた文字列の処理性能には影響しません。

***警告***：このオプションを使うと、JSON値の文字列に誤ったエンコーディングが含まれることがあります。セキュリティー上のリスクを避けるため、それらの文字列を慎重に扱う必要があります。

### **YYJSON_READ_ALLOW_BOM**

UTF-8のBOMを許可し、存在する場合は解析前に読み飛ばします（非標準）。

### **YYJSON_READ_ALLOW_EXT_NUMBER**

拡張数値形式を許可します（非標準）。

- `0x7B`のような16進数。
- `.123`や`123.`のように、小数点で始まる数値または小数点で終わる数値。
- `+123`のように、先頭にプラス記号が付いた数値。

### **YYJSON_READ_ALLOW_EXT_ESCAPE**

文字列中の拡張エスケープシーケンスを許可します（非標準）。

- 追加のエスケープ：`\a`、`\e`、`\v`、``\'``、`\?`、`\0`。
- `\x7B`のような、`\xNN`形式の16進エスケープ。
- 行の継続：バックスラッシュに続く行終端シーケンス。
- 未知のエスケープ：バックスラッシュの後が未対応の文字の場合、バックスラッシュを除去し、文字自体はそのまま保持します。ただし、`\1`〜`\9`は引き続きエラーになります。

### **YYJSON_READ_ALLOW_EXT_WHITESPACE**

拡張された空白文字を許可します（非標準）。

- 垂直タブ`\v`とフォームフィード`\f`。
- 行区切り`\u2028`と段落区切り`\u2029`。
- 改行しない空白`\xA0`。
- バイトオーダーマーク：`\uFEFF`。
- UnicodeのZs（Separator, space）分類に含まれるその他の文字。

### **YYJSON_READ_ALLOW_SINGLE_QUOTED_STR**

``'ab'``のように、単一引用符で囲まれた文字列を許可します（非標準）。

### **YYJSON_READ_ALLOW_UNQUOTED_KEY**

`{a:1,b:2}`のように、引用符で囲まれていないオブジェクトのキーを許可します（非標準）。
これはECMAScriptのIdentifierName規則を拡張し、コードポイントが`U+007F`より大きい、空白以外の任意の文字を許可するものです。

### **YYJSON_READ_JSON5**

JSON5形式を許可します。参照：https://json5.org。

このフラグは、JSON5の全機能に加え、次の拡張に対応します。

- JSON5よりも多くのエスケープシーケンスを受け付けます（`\a`、`\e`など）。
- 引用符で囲まれていないキーをECMAScriptのIdentifierNameに限定しません。
- `NaN`、`Inf`、`Infinity`リテラルについて、大文字と小文字を区別しません。

例：

```json
{
    /* JSON5 example */
    id: 123,
    name: 'Harry',
    color: 0x66CCFF,
    min: .001,
    max: Inf,
    data: '\x00\xAA\xFF',
}
```


---------------
