File-Raw-JSON

 view release on metacpan or  search on metacpan

yyjson.c  view on Meta::CPAN

        return_err(0, INVALID_PARAMETER, "input data is NULL");
    }
    if (unlikely(!len)) {
        return_err(0, INVALID_PARAMETER, "input length is 0");
    }
    
    /* add 4-byte zero padding for input data if necessary */
    if (has_read_flag(INSITU)) {
        hdr = (u8 *)dat;
        end = (u8 *)dat + len;
        cur = (u8 *)dat;
    } else {
        if (unlikely(len >= USIZE_MAX - YYJSON_PADDING_SIZE)) {
            return_err(0, MEMORY_ALLOCATION, "memory allocation failed");
        }
        hdr = (u8 *)alc.malloc(alc.ctx, len + YYJSON_PADDING_SIZE);
        if (unlikely(!hdr)) {
            return_err(0, MEMORY_ALLOCATION, "memory allocation failed");
        }
        end = hdr + len;
        cur = hdr;
        memcpy(hdr, dat, len);
        memset(end, 0, YYJSON_PADDING_SIZE);
    }
    
    /* skip empty contents before json document */
    if (unlikely(char_is_space_or_comment(*cur))) {
        if (has_read_flag(ALLOW_COMMENTS)) {
            if (!skip_spaces_and_comments(&cur)) {
                return_err(cur - hdr, INVALID_COMMENT,
                           "unclosed multiline comment");
            }
        } else {
            if (likely(char_is_space(*cur))) {
                while (char_is_space(*++cur));
            }
        }
        if (unlikely(cur >= end)) {
            return_err(0, EMPTY_CONTENT, "input data is empty");
        }
    }
    
    /* read json document */
    if (likely(char_is_container(*cur))) {
        if (char_is_space(cur[1]) && char_is_space(cur[2])) {
            doc = read_root_pretty(hdr, cur, end, alc, flg, err);
        } else {
            doc = read_root_minify(hdr, cur, end, alc, flg, err);
        }
    } else {
        doc = read_root_single(hdr, cur, end, alc, flg, err);
    }
    
    /* check result */
    if (likely(doc)) {
        memset(err, 0, sizeof(yyjson_read_err));
    } else {
        /* RFC 8259: JSON text MUST be encoded using UTF-8 */
        if (err->pos == 0 && err->code != YYJSON_READ_ERROR_MEMORY_ALLOCATION) {
            if ((hdr[0] == 0xEF && hdr[1] == 0xBB && hdr[2] == 0xBF)) {
                err->msg = "byte order mark (BOM) is not supported";
            } else if (len >= 4 &&
                       ((hdr[0] == 0x00 && hdr[1] == 0x00 &&
                         hdr[2] == 0xFE && hdr[3] == 0xFF) ||
                        (hdr[0] == 0xFF && hdr[1] == 0xFE &&
                         hdr[2] == 0x00 && hdr[3] == 0x00))) {
                err->msg = "UTF-32 encoding is not supported";
            } else if (len >= 2 &&
                       ((hdr[0] == 0xFE && hdr[1] == 0xFF) ||
                        (hdr[0] == 0xFF && hdr[1] == 0xFE))) {
                err->msg = "UTF-16 encoding is not supported";
            }
        }
        if (!has_read_flag(INSITU)) alc.free(alc.ctx, (void *)hdr);
    }
    return doc;
    
#undef return_err
}

yyjson_doc *yyjson_read_file(const char *path,
                             yyjson_read_flag flg,
                             const yyjson_alc *alc_ptr,
                             yyjson_read_err *err) {
#define return_err(_code, _msg) do { \
    err->pos = 0; \
    err->msg = _msg; \
    err->code = YYJSON_READ_ERROR_##_code; \
    return NULL; \
} while (false)
    
    yyjson_read_err dummy_err;
    yyjson_doc *doc;
    FILE *file;
    
    if (!err) err = &dummy_err;
    if (unlikely(!path)) return_err(INVALID_PARAMETER, "input path is NULL");
    
    file = fopen_readonly(path);
    if (unlikely(!file)) return_err(FILE_OPEN, "file opening failed");
    
    doc = yyjson_read_fp(file, flg, alc_ptr, err);
    fclose(file);
    return doc;
    
#undef return_err
}

yyjson_doc *yyjson_read_fp(FILE *file,
                           yyjson_read_flag flg,
                           const yyjson_alc *alc_ptr,
                           yyjson_read_err *err) {
#define return_err(_code, _msg) do { \
    err->pos = 0; \
    err->msg = _msg; \
    err->code = YYJSON_READ_ERROR_##_code; \
    if (buf) alc.free(alc.ctx, buf); \
    return NULL; \
} while (false)
    
    yyjson_read_err dummy_err;



( run in 0.915 second using v1.01-cache-2.11-cpan-9581c071862 )