Class document

Synopsis

#include <include/sajson.h>

class document

Description

Represents the result of a JSON parse: either is_valid() and the document contains a root value or parse error information is available.

Note that the document holds a strong reference to any memory allocated: any mutable copy of the input text and any memory allocated for the AST data structure. Thus, the document must not be deallocated while any value is in use.

Mentioned in

Methods

document overload
get_error_columnIf not is_valid(), returns the one-based column number where the parse failed.
get_error_lineIf not is_valid(), returns the one-based line number where the parse failed.
get_error_message_as_cstringIf not is_valid(), returns a null-terminated C string indicating why the parse failed.
get_error_message_as_stringIf not is_valid(), returns a std::string indicating why the parse failed.
get_rootIf is_valid(), returns the document's root value.
is_validReturns true if the document was parsed successfully

Source

Lines 815-971 in include/sajson.h.

class document {
public:
    document()
        : document{ mutable_string_view{}, 0, 0, ERROR_UNINITIALIZED, 0 } {}

    document(document&& rhs)
        : input(rhs.input)
        , structure(std::move(rhs.structure))
        , root_tag(rhs.root_tag)
        , root(rhs.root)
        , error_line(rhs.error_line)
        , error_column(rhs.error_column)
        , error_code(rhs.error_code)
        , error_arg(rhs.error_arg) {
        // Yikes... but strcpy is okay here because formatted_error is
        // guaranteed to be null-terminated.
        strcpy(formatted_error_message, rhs.formatted_error_message);
        // should rhs's fields be zeroed too?
    }

    /**
     * Returns true if the document was parsed successfully.
     * If true, call get_root() to access the document's root value.
     * If false, call get_error_line(), get_error_column(), and
     * get_error_message_as_cstring() to see why the parse failed.
     */
    bool is_valid() const {
        return root_tag == tag::array || root_tag == tag::object;
    }

    /// If is_valid(), returns the document's root \ref value.
    value get_root() const { return value(root_tag, root, input.get_data()); }

    /// If not is_valid(), returns the one-based line number where the parse
    /// failed.
    size_t get_error_line() const { return error_line; }

    /// If not is_valid(), returns the one-based column number where the parse
    /// failed.
    size_t get_error_column() const { return error_column; }

#ifndef SAJSON_NO_STD_STRING
    /// If not is_valid(), returns a std::string indicating why the parse
    /// failed.
    std::string get_error_message_as_string() const {
        return formatted_error_message;
    }
#endif

    /// If not is_valid(), returns a null-terminated C string indicating why the
    /// parse failed.
    const char* get_error_message_as_cstring() const {
        return formatted_error_message;
    }

    /// \cond INTERNAL

    // WARNING: Internal function which is subject to change
    error _internal_get_error_code() const { return error_code; }

    // WARNING: Internal function which is subject to change
    int _internal_get_error_argument() const { return error_arg; }

    // WARNING: Internal function which is subject to change
    const char* _internal_get_error_text() const {
        return internal::get_error_text(error_code);
    }

    // WARNING: Internal function exposed only for high-performance language
    // bindings.
    internal::tag _internal_get_root_tag() const { return root_tag; }

    // WARNING: Internal function exposed only for high-performance language
    // bindings.
    const size_t* _internal_get_root() const { return root; }

    // WARNING: Internal function exposed only for high-performance language
    // bindings.
    const mutable_string_view& _internal_get_input() const { return input; }

    /// \endcond

private:
    using tag = internal::tag;

    document(const document&) = delete;
    void operator=(const document&) = delete;

    explicit document(
        const mutable_string_view& input_,
        internal::ownership&& structure_,
        tag root_tag_,
        const size_t* root_)
        : input(input_)
        , structure(std::move(structure_))
        , root_tag(root_tag_)
        , root(root_)
        , error_line(0)
        , error_column(0)
        , error_code(ERROR_NO_ERROR)
        , error_arg(0) {
        formatted_error_message[0] = 0;
    }

    explicit document(
        const mutable_string_view& input_,
        size_t error_line_,
        size_t error_column_,
        const error error_code_,
        int error_arg_)
        : input(input_)
        , structure(0)
        , root_tag(tag::null)
        , root(0)
        , error_line(error_line_)
        , error_column(error_column_)
        , error_code(error_code_)
        , error_arg(error_arg_) {
        formatted_error_message[ERROR_BUFFER_LENGTH - 1] = 0;
        int written = has_significant_error_arg()
            ? SAJSON_snprintf(
                  formatted_error_message,
                  ERROR_BUFFER_LENGTH - 1,
                  "%s: %d",
                  _internal_get_error_text(),
                  error_arg)
            : SAJSON_snprintf(
                  formatted_error_message,
                  ERROR_BUFFER_LENGTH - 1,
                  "%s",
                  _internal_get_error_text());
        (void)written;
        assert(written >= 0 && written < ERROR_BUFFER_LENGTH);
    }

    bool has_significant_error_arg() const {
        return error_code == ERROR_ILLEGAL_CODEPOINT;
    }

    mutable_string_view input;
    internal::ownership structure;
    const tag root_tag;
    const size_t* const root;
    const size_t error_line;
    const size_t error_column;
    const error error_code;
    const int error_arg;

    enum { ERROR_BUFFER_LENGTH = 128 };
    char formatted_error_message[ERROR_BUFFER_LENGTH];

    template <typename AllocationStrategy, typename StringType>
    friend document
    parse(const AllocationStrategy& strategy, const StringType& string);
    template <typename Allocator>
    friend class parser;
};





Add Discussion as Guest

Log in