text:
#ifndef BOOST_PARSER_PARSER_FWD_HPP
#define BOOST_PARSER_PARSER_FWD_HPP

#include <boost/parser/config.hpp>
#include <boost/parser/error_handling_fwd.hpp>

#include <boost/any.hpp>

#include <cstdint>
#include <map>

namespace boost { namespace parser {

    /** A placeholder type used to represent the absence of information,
        value, etc., in `boost::parser`.  For instance, a parser with no
        global data will have a `globals_` data member whose type is `nope`.
        `nope` is designed to satisfy all requirements of any type that it
        might replace, where convenient.  For instance, it has an implicit
        conversion to `std::nullopt_t`, so that it be assigned to a
        `std::optional<T>`. */
    struct nope;

    namespace detail {
        enum class flags : unsigned int {
            gen_attrs = 1 << 0,
            use_skip = 1 << 1,
            trace = 1 << 2,
            in_apply_parser = 1 << 3
        };

        // Built-in tags for use with the context.
        struct val_tag;
        struct attr_tag;
        struct where_tag;
        struct begin_tag;
        struct end_tag;
        struct pass_tag;
        struct locals_tag;
        struct rule_params_tag;
        struct globals_tag;
        struct trace_indent_tag;
        struct error_handler_tag;
        struct callbacks_tag;
        struct symbol_table_tries_tag;

        using symbol_table_tries_t = std::map<void *, any, std::less<void *>>;

        template<typename Iter, typename Sentinel, typename ErrorHandler>
        inline auto make_context(
            Iter first,
            Sentinel last,
            bool & success,
            int & indent,
            ErrorHandler const & error_handler,
            nope &,
            symbol_table_tries_t & symbol_table_tries) noexcept;

        struct skip_skipper;
    }

    /** Repeats the application of another parser `p` of type `Parser`,
        optionally applying another parser `d` of type `DelimiterParser` in
        between each pair of applications of `p`.  The parse succeeds if `p`
        succeeds at least the minumum number of times, and `d` succeeds each
        time it is applied.  The attribute produced is a sequence of the type
        of attribute produced by `Parser`. */
    template<
        typename Parser,
        typename DelimiterParser = nope,
        typename MinType = int64_t,
        typename MaxType = int64_t>
    struct repeat_parser;

    /** Repeats the application of another parser `p` of type `Parser`, `[0,
        Inf)` times.  The parse always succeeds.  The attribute produced is a
        sequence of the type of attribute produced by `Parser`. */
    template<typename Parser>
    struct zero_plus_parser;

    /** Repeats the application of another parser `p` of type `Parser`, `[1,
        Inf)` times.  The parse succeeds iff `p` succeeds at least once.  The
        attribute produced is a sequence of the type of attribute produced by
        `Parser`. */
    template<typename Parser>
    struct one_plus_parser;

    /** Repeats the application of another parser `p` of type `Parser`, `[1,
        Inf)` times, applying a parser `d` of type `DelimiterParser` in
        between each pair of applications of `p`.  The parse succeeds iff `p`
        succeeds at least once, and `d` succeeds each time it is applied.  The
        attribute produced is a sequence of the type of attribute produced by
        `Parser`. */
    template<typename Parser, typename DelimiterParser>
    struct delimited_seq_parser;

    /** Repeats the application of another parser of type `Parser`, `[0, 1]`
        times.  The parse always succeeds.  The attribute produced is a
        `std::optional<T>`, where `T` is the type of attribute produced by
        `Parser`. */
    template<typename Parser>
    struct opt_parser;

    /** Applies each parser in `ParserTuple`, in order, stopping after the
        application of the first one that succeeds.  The parse succeeds iff
        one of the sub-parsers succeeds.  The attribute produced is a
        `std::variant` over the types of attribute produced by the parsers in
        `ParserTuple`. */
    template<typename ParserTuple>
    struct or_parser;

    /** Applies each parser in `ParserTuple`, in order.  The parse succeeds
        iff all of the sub-parsers succeeds.  The attribute produced is a
        `std::tuple` over the types of attribute produced by the parsers in
        `ParserTuple`.  The BacktrackingTuple template parameter is a
        `hana::tuple` of `hana::bool_` values.  The `i`th such value indicates
        whether backtracking is allowed if the `i`th parser fails. */
    template<typename ParserTuple, typename BacktrackingTuple>
    struct seq_parser;

    /** Applies the given parser `p` of type `Parser` and an invocable `a` of
        type `Action`.  `Action` shall model `semantic_action`, and `a` will
        only be invoked if `p` succeeds.  The parse succeeds iff `p` succeeds.
        Produces no attribute. */
    template<typename Parser, typename Action>
    struct action_parser;

    /** Applies the given parser `p` of type `Parser`.  This parser produces
        no attribute, and suppresses the production of any attributes that
        would otherwise be produced by `p`.  The parse succeeds iff `p`
        succeeds. */
    template<typename Parser>
    struct omit_parser;

    /** Applies the given parser `p` of type `Parser`; regardless of the
        attribute produced by `Parser`, this parser's attribute is equivalent
        to `_where(ctx)` within a semantic action on `p`.  The parse succeeds
        iff `p` succeeds. */
    template<typename Parser>
    struct raw_parser;

    /** Applies the given parser `p` of type `Parser`, disabling the current
        skipper in use, if any.  The parse succeeds iff `p` succeeds.  The
        attribute produced is the type of attribute produced by `Parser`. */
    template<typename Parser>
    struct lexeme_parser;

    /** Applies the given parser `p` of type `Parser`, using a parser of type
        `SkipParser` as the skipper.  The parse succeeds iff `p` succeeds.
        The attribute produced is the type of attribute produced by
        `Parser`. */
    template<typename Parser, typename SkipParser = nope>
    struct skip_parser;

    /** Applies the given parser `p` of type `Parser`, producing no attributes
        and consuming no input.  The parse succeeds iff `p` succeeds. */
    template<typename Parser, bool FailOnMatch>
    struct expect_parser;

    /** Matches one of a set S of possible inputs, each of which is associated
        with an attribute value of type `T`, forming a symbol table.  New
        elements and their associated attributes may be added to or removed
        from S dynamically, during parsing; any such changes are reverted at
        the end of parsing.  The parse succeeds iff an element of S is
        matched.  \see `symbols` */
    template<typename T>
    struct symbol_parser;

    /** Applies another parser `p`, associated with this parser via `TagType`.
        The attribute produced is `Attribute`.  Both a default-constructed
        object of type `LocalState`, and a default-constructed object of type
        `ParamsTuple`, are added to the parse context before the associated
        parser is applied.  The parse succeeds iff `p` succeeds.  If
        `UseCallbacks` is `true`, the attribute is produced via callback;
        otherwise, the attribute is produced as normal (as a return value, or
        as an out-param).  The rule may be constructed with a user-friendly
        name that will appear if the top-level parse is executed with
        `trace_mode == boost::parser::trace::on`. */
    template<
        bool UseCallbacks,
        typename TagType,
        typename Attribute,
        typename LocalState,
        typename ParamsTuple>
    struct rule_parser;

    /** Matches anything, and consumes no input.  If `Predicate` is anything
        other than `nope`, and `pred_(ctx)` evaluates to false, where `ctx` is
        the parser context, the parse fails. */
    template<typename Predicate>
    struct eps_parser;

    /** Matches only the end of input.  Produces no attribute. */
    struct eoi_parser;

    /** Matches anything, consumes no input, and produces an attribute of type
        `Attribute`. */
    template<typename Attribute>
    struct attr_parser;

    /** Matches a single code point.  If `AttributeType` is not `void`,
        `AttributeType` is the attribute type produced; otherwise, the
        attribute type is the decayed type of the matched code point.  The
        parse fails only if the parser is constructed with a specific set of
        expected code point values that does not include the matched code
        point `CP`. */
    template<typename Expected, typename AttributeType = void>
    struct char_parser;

    /** Maches a particular string, delimited by an iterator sentinel pair;
        produces no attribute. */
    template<typename StrIter, typename StrSentinel>
    struct string_parser;

    /** Maches an end-of-line in the input; produces no attribute.
        End-of-line is considered to be "\r\n", or any one of the line break
        code points from the Unicode Line Break Algorithm, described in
        https://unicode.org/reports/tr14. */
    struct eol_parser;

    /** Maches the strings "true" and "false", producing an attribute of
        `true` or `false`, respectively, and fails on any other input. */
    struct bool_parser;

    /** Matches an unsigned number of radix `Radix`, of at least `MinDigits`
        and at most `MaxDigits`, producing an attribute of type `T`.  Fails on
        any other input.  The parse will also fail if `Expected` is anything
        but `nope`, and the produced attribute is not equal to `expected_`.
        `Radix` must be in `[2, 36]`. */
    template<
        typename T,
        int Radix = 10,
        int MinDigits = 1,
        int MaxDigits = -1,
        typename Expected = nope>
    struct uint_parser;

    /** Matches a signed number of radix `Radix`, of at least `MinDigits` and
        at most `MaxDigits`, producing an attribute of type `T`.  Fails on any
        other input.  The parse will also fail if `Expected` is anything but
        `nope`, and the produced attribute is not equal to `expected_`.
        `Radix` must be one of `2`, `8`, `10`, or `16`. */
    template<
        typename T,
        int Radix = 10,
        int MinDigits = 1,
        int MaxDigits = -1,
        typename Expected = nope>
    struct int_parser;

    /** Matches a floating point number, producing an attribute of type
        `T`. */
    template<typename T>
    struct float_parser;

    /** Applies at most one of the parsers in `OrParser`.  If `switch_value_`
        matches one or more of the values in the parsers in `OrParser`, the
        first such parser is applied, and the success or failure and attribute
        of the parse are those of the applied parser.  Otherwise, the parse
        fails. */
    template<typename SwitchValue, typename OrParser = nope>
    struct switch_parser;

    /** A wrapper for a parser, with optional global state and optional error
        handler, that provides the interface that all parsers must have:
        `operator*()`, `operator>>()`, etc. */
    template<
        typename Parser,
        typename GlobalState = nope,
        typename ErrorHandler = default_error_handler>
    struct parser_interface;

}}

#endif

ext: hpp

max_stars_repo_name: tzlaine/yaml

max_issues_repo_name: tzlaine/yaml

max_forks_repo_name: tzlaine/yaml


text:
#include "spark_wiring_json.h"
#include "spark_wiring_print.h"

#include "tools/stream.h"
#include "tools/buffer.h"

#include <boost/variant.hpp>

#include <deque>
#include <string>
#include <cstdlib>

namespace {

using namespace spark;

class Checker {
public:
    Checker() {
    }

    explicit Checker(const JSONValue &val) {
        v_.push_back(val);
    }

    Checker& invalid() {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_INVALID);
        CHECK(v.isValid() == false);
        return *this;
    }

    Checker& null() {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_NULL);
        CHECK(v.isNull() == true);
        return *this;
    }

    Checker& boolean(bool val) {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_BOOL);
        CHECK(v.isBool() == true);
        CHECK(v.toBool() == val);
        return *this;
    }

    Checker& number(int val) {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_NUMBER);
        CHECK(v.isNumber());
        CHECK(v.toInt() == val);
        return *this;
    }

    Checker& number(double val) {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_NUMBER);
        CHECK(v.isNumber());
        CHECK(v.toDouble() == val);
        return *this;
    }

    Checker& string(const std::string &str) {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_STRING);
        CHECK(v.isString() == true);
        const JSONString s = v.toString();
        CHECK(std::string(s.data(), s.size()) == str);
        return *this;
    }

    Checker& beginArray() {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_ARRAY);
        CHECK(v.isArray() == true);
        v_.push_back(JSONArrayIterator(v));
        return *this;
    }

    Checker& endArray() {
        const Variant v = v_.back();
        if (v.which() != ARRAY) {
            FAIL("Unexpected checker state");
        }
        v_.pop_back();
        JSONArrayIterator it = boost::get<JSONArrayIterator>(v);
        REQUIRE(it.count() == 0);
        CHECK(it.next() == false);
        return *this;
    }

    Checker& beginObject() {
        const JSONValue v = value();
        REQUIRE(v.type() == JSON_TYPE_OBJECT);
        CHECK(v.isObject() == true);
        v_.push_back(JSONObjectIterator(v));
        return *this;
    }

    Checker& endObject() {
        const Variant v = v_.back();
        if (v.which() != OBJECT) {
            FAIL("Unexpected checker state");
        }
        v_.pop_back();
        JSONObjectIterator it = boost::get<JSONObjectIterator>(v);
        REQUIRE(it.count() == 0);
        CHECK(it.next() == false);
        return *this;
    }

    Checker& name(const std::string &str) {
        Variant &v = v_.back();
        if (v.which() != OBJECT) {
            FAIL("Unexpected checker state");
        }
        JSONObjectIterator it = boost::get<JSONObjectIterator>(v);
        const size_t n = it.count();
        REQUIRE(it.next() == true);
        CHECK(it.count() == n - 1);
        const JSONString s = it.name();
        CHECK(std::string(s.data(), s.size()) == str);
        v = it; // Update iterator
        return *this;
    }

private:
    enum Which {
        BLANK,
        VALUE,
        ARRAY,
        OBJECT
    };

    typedef boost::variant<boost::blank, JSONValue, JSONArrayIterator, JSONObjectIterator> Variant;

    std::deque<Variant> v_;

    JSONValue value() {
        if (v_.empty()) {
            FAIL("Unexpected checker state");
        }
        Variant &v = v_.back();
        switch (v.which()) {
        case VALUE: {
            return boost::get<JSONValue>(v);
        }
        case ARRAY: { // JSONArrayIterator
            JSONArrayIterator it = boost::get<JSONArrayIterator>(v);
            const size_t n = it.count();
            REQUIRE(it.next() == true);
            CHECK(it.count() == n - 1);
            v = it; // Update iterator
            return it.value();
        }
        case OBJECT: { // JSONObjectIterator
            const JSONObjectIterator it = boost::get<JSONObjectIterator>(v);
            return it.value();
        }
        default:
            FAIL("Unexpected checker state");
            return JSONValue();
        }
    }
};

inline JSONValue parse(const std::string &json) {
    return JSONValue::parseCopy(json.data(), json.size());
}

inline Checker check(const JSONValue &val) {
    return Checker(val);
}

inline Checker check(const char *json) {
    return Checker(parse(json));
}

} // namespace

namespace spark {

inline std::ostream& operator<<(std::ostream &strm, const JSONString &str) {
    return strm << '"' << str.data() << '"';
}

} // namespace spark

TEST_CASE("Parsing JSON") {
    SECTION("null") {
        check("null").null();
    }

    SECTION("bool") {
        check("true").boolean(true);
        check("false").boolean(false);
    }

    SECTION("number") {
        SECTION("int") {
            check("0").number(0);
            check("1").number(1);
            check("-1").number(-1);
            check("12345").number(12345);
            check("-12345").number(-12345);
            check("-2147483648").number((int)-2147483648); // INT_MIN
            check("2147483647").number((int)2147483647); // INT_MAX
        }
        SECTION("float") {
            check("0.0").number(0.0);
            check("1.0").number(1.0);
            check("-1.0").number(-1.0);
            check("0.5").number(0.5);
            check("-0.5").number(-0.5);
            check("3.1416").number(3.1416);
            check("-3.1416").number(-3.1416);
            check("1.17549e-38").number(1.17549e-38); // ~FLT_MIN
            check("3.40282e+38").number(3.40282e+38); // ~FLT_MAX
        }
    }

    SECTION("string") {
        check("\"\"").string(""); // Empty string
        check("\"abc\"").string("abc");
        check("\"a\"").string("a"); // Single character
        check("\"\\\"\"").string("\""); // Single escaped character
        check("\"\\\"\\/\\\\\\b\\f\\n\\r\\t\"").string("\"/\\\b\f\n\r\t"); // Named escaped characters
        check("\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\u000a\\u000b"
                "\\u000c\\u000d\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019"
                "\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\"").string(
                std::string("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15"
                        "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 32)); // Control characters
        check("\"\\u2014\"").string("\\u2014"); // Unicode characters are not processed
    }

    SECTION("array") {
        SECTION("empty") {
            check("[]").beginArray().endArray();
        }
        SECTION("single element") {
            check("[null]").beginArray()
                    .null()
                    .endArray();
        }
        SECTION("primitive elements") {
            check("[null,true,2,3.14,\"abcd\"]").beginArray()
                    .null()
                    .boolean(true)
                    .number(2)
                    .number(3.14)
                    .string("abcd")
                    .endArray();
        }
        SECTION("nested array") {
            check("[1.1,[2.1,2.2,2.3],1.3]").beginArray()
                    .number(1.1)
                    .beginArray()
                            .number(2.1)
                            .number(2.2)
                            .number(2.3)
                            .endArray()
                    .number(1.3)
                    .endArray();
        }
        SECTION("nested object") {
            check("[1.1,{\"2.1\":2.1,\"2.2\":2.2,\"2.3\":2.3},1.3]").beginArray()
                    .number(1.1)
                    .beginObject()
                            .name("2.1").number(2.1)
                            .name("2.2").number(2.2)
                            .name("2.3").number(2.3)
                            .endObject()
                    .number(1.3)
                    .endArray();
        }
        SECTION("deeply nested array") {
            Checker c = check("[[[[[[[[[[[]]]]]]]]]]]");
            c.beginArray();
            for (int i = 0; i < 10; ++i) {
                c.beginArray();
            }
            for (int i = 0; i < 10; ++i) {
                c.endArray();
            }
            c.endArray();
        }
    }

    SECTION("object") {
        SECTION("empty") {
            check("{}").beginObject().endObject();
        }
        SECTION("single element") {
            check("{\"null\":null}").beginObject()
                    .name("null").null()
                    .endObject();
        }
        SECTION("primitive elements") {
            check("{\"null\":null,\"bool\":true,\"int\":2,\"float\":3.14,\"string\":\"abcd\"}").beginObject()
                    .name("null").null()
                    .name("bool").boolean(true)
                    .name("int").number(2)
                    .name("float").number(3.14)
                    .name("string").string("abcd")
                    .endObject();
        }
        SECTION("nested object") {
            check("{\"1.1\":1.1,\"1.2\":{\"2.1\":2.1,\"2.2\":2.2,\"2.3\":2.3},\"1.3\":1.3}").beginObject()
                    .name("1.1").number(1.1)
                    .name("1.2").beginObject()
                            .name("2.1").number(2.1)
                            .name("2.2").number(2.2)
                            .name("2.3").number(2.3)
                            .endObject()
                    .name("1.3").number(1.3)
                    .endObject();
        }
        SECTION("nested array") {
            check("{\"1.1\":1.1,\"1.2\":[2.1,2.2,2.3],\"1.3\":1.3}").beginObject()
                    .name("1.1").number(1.1)
                    .name("1.2").beginArray()
                            .number(2.1)
                            .number(2.2)
                            .number(2.3)
                            .endArray()
                    .name("1.3").number(1.3)
                    .endObject();
        }
        SECTION("deeply nested object") {
            Checker c = check("{\"1\":{\"2\":{\"3\":{\"4\":{\"5\":{\"6\":{\"7\":{\"8\":{\"9\":{\"10\":{}}}}}}}}}}}");
            c.beginObject();
            for (int i = 1; i <= 10; ++i) {
                c.name(std::to_string(i)).beginObject();
            }
            for (int i = 1; i <= 10; ++i) {
                c.endObject();
            }
            c.endObject();
        }
    }

    SECTION("parsing errors") {
        check("").invalid(); // Empty source data
        check("[").invalid(); // Malformed array
        check("]").invalid();
        check("[1,").invalid();
        check("{").invalid(); // Malformed object
        check("}").invalid();
        check("{null").invalid();
        check("{false").invalid();
        check("{1").invalid();
        check("{\"1\"").invalid();
        check("{\"1\":").invalid();
        check("\"\\x\"").invalid(); // Unknown escaped character
        check("\"\\U0001\"").invalid(); // Uppercase 'U'
        check("\"\\u000x\"").invalid(); // Invalid hex value
        check("\"\\u001\"").invalid();
        check("\"\\u01\"").invalid();
        check("\"\\u\"").invalid();
    }
}

TEST_CASE("Writing JSON") {
    test::OutputStream data;
    JSONStreamWriter json(data);

    SECTION("null") {
        json.nullValue();
        check(data).equals("null");
    }

    SECTION("bool") {
        SECTION("true") {
            json.value(true);
            check(data).equals("true");
        }
        SECTION("false") {
            json.value(false);
            check(data).equals("false");
        }
    }

    SECTION("number") {
        SECTION("int") {
            SECTION("0") {
                json.value(0);
                check(data).equals("0");
            }
            SECTION("1") {
                json.value(1);
                check(data).equals("1");
            }
            SECTION("-1") {
                json.value(-1);
                check(data).equals("-1");
            }
            SECTION("12345") {
                json.value(12345);
                check(data).equals("12345");
            }
            SECTION("-12345") {
                json.value(-12345);
                check(data).equals("-12345");
            }
            SECTION("-2147483648") {
                json.value((int)-2147483648); // INT_MIN
                check(data).equals("-2147483648");
            }
            SECTION("2147483647") {
                json.value((int)2147483647); // INT_MAX
                check(data).equals("2147483647");
            }
        }
        SECTION("float") {
            SECTION("0.0") {
                json.value(0.0);
                check(data).equals("0");
            }
            SECTION("1.0") {
                json.value(1.0);
                check(data).equals("1");
            }
            SECTION("-1.0") {
                json.value(-1.0);
                check(data).equals("-1");
            }
            SECTION("0.5") {
                json.value(0.5);
                check(data).equals("0.5");
            }
            SECTION("-0.5") {
                json.value(-0.5);
                check(data).equals("-0.5");
            }
            SECTION("3.1416") {
                json.value(3.1416);
                check(data).equals("3.1416");
            }
            SECTION("-3.1416") {
                json.value(-3.1416);
                check(data).equals("-3.1416");
            }
            SECTION("1.17549e-38") {
                json.value(1.17549e-38); // ~FLT_MIN
                check(data).equals("1.17549e-38");
            }
            SECTION("3.40282e+38") {
                json.value(3.40282e+38); // ~FLT_MAX
                check(data).equals("3.40282e+38");
            }
        }
    }

    SECTION("string") {
        SECTION("empty") {
            json.value("");
            check(data).equals("\"\"");
        }
        SECTION("test string") {
            json.value("abc");
            check(data).equals("\"abc\"");
        }
        SECTION("single character") {
            json.value("a");
            check(data).equals("\"a\"");
        }
        SECTION("single escaped character") {
            json.value("\"");
            check(data).equals("\"\\\"\"");
        }
        SECTION("named escaped characters") {
            json.value("\"/\\\b\f\n\r\t");
            check(data).equals("\"\\\"/\\\\\\b\\f\\n\\r\\t\""); // '/' is never escaped
        }
        SECTION("control characters") {
            json.value("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16"
                    "\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 32);
            check(data).equals("\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e"
                    "\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c"
                    "\\u001d\\u001e\\u001f\"");
        }
    }

    SECTION("array") {
        SECTION("empty") {
            json.beginArray();
            json.endArray();
            check(data).equals("[]");
        }
        SECTION("single element") {
            json.beginArray();
            json.nullValue();
            json.endArray();
            check(data).equals("[null]");
        }
        SECTION("primitive elements") {
            json.beginArray();
            json.nullValue().value(true).value(2).value(3.14).value("abcd");
            json.endArray();
            check(data).equals("[null,true,2,3.14,\"abcd\"]");
        }
        SECTION("nested array") {
            json.beginArray();
            json.value(1.1);
            json.beginArray();
            json.value(2.1).value(2.2).value(2.3);
            json.endArray();
            json.value(1.3);
            json.endArray();
            check(data).equals("[1.1,[2.1,2.2,2.3],1.3]");
        }
        SECTION("nested object") {
            json.beginArray();
            json.value(1.1);
            json.beginObject();
            json.name("2.1").value(2.1);
            json.name("2.2").value(2.2);
            json.name("2.3").value(2.3);
            json.endObject();
            json.value(1.3);
            json.endArray();
            check(data).equals("[1.1,{\"2.1\":2.1,\"2.2\":2.2,\"2.3\":2.3},1.3]");
        }
        SECTION("deeply nested array") {
            json.beginArray();
            for (int i = 0; i < 10; ++i) {
                json.beginArray();
            }
            for (int i = 0; i < 10; ++i) {
                json.endArray();
            }
            json.endArray();
            check(data).equals("[[[[[[[[[[[]]]]]]]]]]]");
        }
    }

    SECTION("object") {
        SECTION("empty") {
            json.beginObject();
            json.endObject();
            check(data).equals("{}");
        }
        SECTION("single element") {
            json.beginObject();
            json.name("null").nullValue();
            json.endObject();
            check(data).equals("{\"null\":null}");
        }
        SECTION("primitive elements") {
            json.beginObject();
            json.name("null").nullValue();
            json.name("bool").value(true);
            json.name("int").value(2);
            json.name("float").value(3.14);
            json.name("string").value("abcd");
            json.endObject();
            check(data).equals("{\"null\":null,\"bool\":true,\"int\":2,\"float\":3.14,\"string\":\"abcd\"}");
        }
        SECTION("nested object") {
            json.beginObject();
            json.name("1.1").value(1.1);
            json.name("1.2").beginObject();
            json.name("2.1").value(2.1);
            json.name("2.2").value(2.2);
            json.name("2.3").value(2.3);
            json.endObject();
            json.name("1.3").value(1.3);
            json.endObject();
            check(data).equals("{\"1.1\":1.1,\"1.2\":{\"2.1\":2.1,\"2.2\":2.2,\"2.3\":2.3},\"1.3\":1.3}");
        }
        SECTION("nested array") {
            json.beginObject();
            json.name("1.1").value(1.1);
            json.name("1.2").beginArray();
            json.value(2.1).value(2.2).value(2.3);
            json.endArray();
            json.name("1.3").value(1.3);
            json.endObject();
            check(data).equals("{\"1.1\":1.1,\"1.2\":[2.1,2.2,2.3],\"1.3\":1.3}");
        }
        SECTION("deeply nested object") {
            json.beginObject();
            for (int i = 1; i <= 10; ++i) {
                json.name(std::to_string(i).c_str()).beginObject();
            }
            for (int i = 1; i <= 10; ++i) {
                json.endObject();
            }
            json.endObject();
            check(data).equals("{\"1\":{\"2\":{\"3\":{\"4\":{\"5\":{\"6\":{\"7\":{\"8\":{\"9\":{\"10\":{}}}}}}}}}}}");
        }
        SECTION("escaped name characters") {
            json.beginObject();
            json.name("a\tb\n").value("a\tb\n");
            json.endObject();
            check(data).equals("{\"a\\tb\\n\":\"a\\tb\\n\"}");
        }
    }
}

TEST_CASE("JSONValue") {
    SECTION("construction") {
        const JSONValue v; // Constructs invalid value
        check(v).invalid();
    }

    SECTION("type conversions") {
        SECTION("invalid") {
            const JSONValue v;
            check(v).invalid();
            CHECK(v.toBool() == false);
            CHECK(v.toInt() == 0);
            CHECK(v.toDouble() == 0.0);
            CHECK(v.toString() == "");
        }
        SECTION("null") {
            const JSONValue v = parse("null");
            check(v).null();
            CHECK(v.toBool() == false);
            CHECK(v.toInt() == 0);
            CHECK(v.toDouble() == 0.0);
            CHECK(v.toString() == "");
        }
        SECTION("bool") {
            SECTION("true") {
                const JSONValue v = parse("true");
                check(v).boolean(true);
                CHECK(v.toInt() == 1);
                CHECK(v.toDouble() == 1.0);
                CHECK(v.toString() == "true");
            }
            SECTION("false") {
                const JSONValue v = parse("false");
                check(v).boolean(false);
                CHECK(v.toInt() == 0);
                CHECK(v.toDouble() == 0.0);
                CHECK(v.toString() == "false");
            }
        }
        SECTION("number") {
            SECTION("int") {
                SECTION("0") {
                    const JSONValue v = parse("0");
                    check(v).number(0);
                    CHECK(v.toBool() == false);
                    CHECK(v.toDouble() == 0.0);
                    CHECK(v.toString() == "0");
                }
                SECTION("12345") {
                    const JSONValue v = parse("12345");
                    check(v).number(12345);
                    CHECK(v.toBool() == true);
                    CHECK(v.toDouble() == 12345.0);
                    CHECK(v.toString() == "12345");
                }
            }
            SECTION("float") {
                SECTION("0.0") {
                    const JSONValue v = parse("0.0");
                    check(v).number(0.0);
                    CHECK(v.toBool() == false);
                    CHECK(v.toInt() == 0);
                    CHECK(v.toString() == "0.0");
                }
                SECTION("3.1416") {
                    const JSONValue v = parse("3.1416");
                    check(v).number(3.1416);
                    CHECK(v.toBool() == true);
                    CHECK(v.toInt() == 3);
                    CHECK(v.toString() == "3.1416");
                }
                SECTION("1.0e+1") {
                    const JSONValue v = parse("1.0e+1");
                    check(v).number(1.0e+1);
                    CHECK(v.toBool() == true);
                    CHECK(v.toInt() == 1); // toInt() may produce incorrect results for floating point numbers
                    CHECK(v.toString() == "1.0e+1");
                }
            }
        }
        SECTION("string") {
            SECTION("empty") {
                const JSONValue v = parse("\"\"");
                check(v).string("");
                CHECK(v.toBool() == false);
                CHECK(v.toInt() == 0);
                CHECK(v.toDouble() == 0.0);
            }
            SECTION("abc") {
                const JSONValue v = parse("\"abc\"");
                check(v).string("abc");
                CHECK(v.toBool() == true); // Non-empty string which is not "false"
                CHECK(v.toInt() == 0);
                CHECK(v.toDouble() == 0.0);
            }
            SECTION("true") {
                const JSONValue v = parse("\"true\"");
                check(v).string("true");
                CHECK(v.toBool() == true);
                CHECK(v.toInt() == 0);
                CHECK(v.toDouble() == 0.0);
            }
            SECTION("false") {
                const JSONValue v = parse("\"false\"");
                check(v).string("false");
                CHECK(v.toBool() == false);
                CHECK(v.toInt() == 0);
                CHECK(v.toDouble() == 0.0);
            }
            SECTION("3.1416") {
                const JSONValue v = parse("\"3.1416\"");
                check(v).string("3.1416");
                CHECK(v.toBool() == true);
                CHECK(v.toInt() == 3);
                CHECK(v.toDouble() == 3.1416);
            }
            SECTION("1.0e+1") {
                const JSONValue v = parse("\"1.0e+1\"");
                check(v).string("1.0e+1");
                CHECK(v.toBool() == true);
                CHECK(v.toInt() == 1); // toInt() may produce incorrect results for floating point numbers
                CHECK(v.toDouble() == 1.0e+1);
            }
        }
        SECTION("array") {
            const JSONValue v = parse("[]");
            check(v).beginArray().endArray();
            CHECK(v.toBool() == false);
            CHECK(v.toInt() == 0);
            CHECK(v.toDouble() == 0.0);
            CHECK(v.toString() == "");
        }
        SECTION("object") {
            const JSONValue v = parse("{}");
            check(v).beginObject().endObject();
            CHECK(v.toBool() == false);
            CHECK(v.toInt() == 0);
            CHECK(v.toDouble() == 0.0);
            CHECK(v.toString() == "");
        }
    }

    SECTION("in-place processing vs copying") {
        SECTION("in-place processing") {
            char json[] = "\"abc\"";
            const JSONValue v = JSONValue::parse(json, sizeof(json));
            json[2] = 'B';
            check(v).string("aBc");
        }
        SECTION("copying") {
            char json[] = "\"abc\"";
            const JSONValue v = JSONValue::parseCopy(json, sizeof(json));
            json[2] = 'B';
            check(v).string("abc"); // Source data is not affected
        }
        SECTION("implicit copying") {
            char json[] = "1x";
            const JSONValue v = JSONValue::parse(json, 1); // No space for term. null
            check(v).number(1);
            const char *s = v.toString().data();
            CHECK(s[1] == '\0'); // JSONString::data() returns null-terminated string
            CHECK(json[1] == 'x');
        }
    }
}

TEST_CASE("JSONString") {
    SECTION("construction") {
        JSONString s1; // Constructs empty string
        CHECK(s1 == "");
        CHECK(s1.size() == 0);
        CHECK(s1.isEmpty() == true);
        JSONValue v;
        JSONString s2(v); // Constructing from invalid JSONValue
        CHECK(s2 == "");
        CHECK(s2.size() == 0);
        CHECK(s2.isEmpty() == true);
    }

    SECTION("comparison") {
        const JSONString s1(parse("\"\""));
        const JSONString s2(parse("\"abc\""));
        CHECK(s1 == JSONString()); // JSONString
        CHECK(s1 == s1);
        CHECK(s2 == s2);
        CHECK(s1 != s2);
        CHECK((s1 == "" && "" == s1)); // const char*
        CHECK((s1 != "abc" && "abc" != s1));
        CHECK((s2 == "abc" && "abc" == s2));
        CHECK((s2 != "abcd" && "abcd" != s2));
        CHECK((s1 == String() && String() == s1)); // String
        CHECK((s1 != String("abc") && String("abc") != s1));
        CHECK((s2 == String("abc") && String("abc") == s2));
        CHECK((s2 != String("abcd") && String("abcd") != s2));
    }

    SECTION("casting") {
        const JSONString s1(parse("\"\""));
        const JSONString s2(parse("\"abc\""));
        CHECK(strcmp((const char*)s1, "") == 0); // const char*
        CHECK(strcmp((const char*)s2, "abc") == 0);
        CHECK((String)s1 == String()); // String
        CHECK((String)s2 == String("abc"));
    }
}

TEST_CASE("JSONArrayIterator") {
    SECTION("construction") {
        JSONArrayIterator it1;
        check(it1.value()).invalid();
        CHECK(it1.count() == 0);
        CHECK(it1.next() == false);
        const JSONValue v;
        JSONArrayIterator it2(v); // Constructing from invalid JSONValue
        check(it2.value()).invalid();
        CHECK(it2.count() == 0);
        CHECK(it2.next() == false);
    }
}

TEST_CASE("JSONObjectIterator") {
    SECTION("construction") {
        JSONObjectIterator it1;
        CHECK(it1.name() == "");
        CHECK(it1.value().isValid() == false);
        CHECK(it1.count() == 0);
        CHECK(it1.next() == false);
        const JSONValue v;
        JSONObjectIterator it2(v); // Constructing from invalid JSONValue
        CHECK(it2.name() == "");
        CHECK(it2.value().isValid() == false);
        CHECK(it2.count() == 0);
        CHECK(it2.next() == false);
    }
}

TEST_CASE("JSONStreamWriter") {
    SECTION("construction") {
        test::OutputStream strm;
        JSONStreamWriter w(strm);
        CHECK(w.stream() == &strm);
        check(strm).isEmpty();
    }
}

TEST_CASE("JSONBufferWriter") {
    SECTION("construction") {
        test::Buffer buf; // Empty buffer
        JSONBufferWriter w((char*)buf, buf.size());
        CHECK(w.buffer() == (char*)buf);
        CHECK(w.bufferSize() == buf.size());
        CHECK(w.dataSize() == 0);
    }

    SECTION("exact buffer size") {
        test::Buffer buf(25); // 25 bytes
        JSONBufferWriter w((char*)buf, buf.size());
        w.beginArray().nullValue().value(true).value(2).value(3.14).value("abcd").endArray();
        CHECK(w.dataSize() == 25);
        check(buf).equals("[null,true,2,3.14,\"abcd\"]");
        CHECK(buf.isPaddingValid());
    }

    SECTION("too small buffer") {
        test::Buffer buf;
        JSONBufferWriter w((char*)buf, buf.size());
        w.beginArray().nullValue().value(true).value(2).value(3.14).value("abcd").endArray();
        CHECK(w.dataSize() == 25); // Size of the actual JSON data
        CHECK(buf.isPaddingValid());
    }
}

ext: cpp


text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file write_pla_from_cirkit_bdd.hpp
 *
 * @brief Functions to write a pla file from a  cirkit BDD.
 *
 * @author Arun Chandrasekharan
 */

#pragma once

#ifndef WRITE_PLA_FROM_CIRKIT_BDD
#define WRITE_PLA_FROM_CIRKIT_BDD

#include <core/properties.hpp>
#include <classical/dd/bdd.hpp>
#include <classical/dd/visit_solutions.hpp>

#include <fstream>
#include <iostream>

#include <boost/noncopyable.hpp>
#include <boost/filesystem/path.hpp>

namespace cirkit
{
void write_pla_from_cirkit_bdd (const std::vector<bdd> &fvec,
				const std::vector<std::string> &input_labels,
				const std::vector<std::string> &output_labels,
				std::ostream &os);

void write_pla_from_cirkit_bdd (const bdd &f,
				const std::vector<std::string> &input_labels,
				const std::vector<std::string> &output_labels,
				std::ostream &os);

} // namespace cirkit

#endif

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


text:
#pragma once

#include "Archive_Entry.hxx"
#include <archive.h>

#include <boost/filesystem.hpp>

#include <memory>

struct Archive_Writer
{
  std::unique_ptr<archive, int (*)(archive *)> ptr;
  Archive_Writer(const boost::filesystem::path &filename);
  ~Archive_Writer() { archive_write_close(ptr.get()); }
  Archive_Writer() = delete;

  void write_entry(const Archive_Entry &entry, std::istream &stream);
};

ext: hxx

max_stars_repo_name: ChrisPattison/sdpb

max_issues_repo_name: ChrisPattison/sdpb

max_forks_repo_name: ChrisPattison/sdpb


text:
// Boost Includes ==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

// Includes ====================================================================
#include <AxComponent.h>
#include <create_instance.h>

// Using =======================================================================
using namespace boost::python;

// Module ======================================================================
void Export_pyste_src_AxComponent()
{

    class_< AxComponent, boost::noncopyable >("AxComponent", init< IAAFComponentSP >())
        .def(init< IAAFComponent2SP >())
        .def("GetLength", &AxComponent::GetLength)
        .def("ExistsLength", &AxComponent::ExistsLength)
        .def("SetLength", &AxComponent::SetLength)
        .def("SetDataDef", &AxComponent::SetDataDef)
        .def("GetDataDef", &AxComponent::GetDataDef)
        .def("AppendKLVData", &AxComponent::AppendKLVData)
        .def("AppendComment", &AxComponent::AppendComment)
        .def("AppendAttribute", &AxComponent::AppendAttribute)
        .def("CountKLVData", &AxComponent::CountKLVData)
        .def("CountComments", &AxComponent::CountComments)
        .def("CountAttributes", &AxComponent::CountAttributes)
        .def("GetKLVData", &AxComponent::GetKLVData)
        .def("GetComments", &AxComponent::GetComments)
        .def("GetAttributes", &AxComponent::GetAttributes)
        .def("RemoveKLVData", &AxComponent::RemoveKLVData)
        .def("RemoveComment", &AxComponent::RemoveComment)
        .def("RemoveAttribute", &AxComponent::RemoveAttribute)
        .def("GetClassName", &AxObject::GetClassName)
        .def("GetDictionary", &AxObject::GetDictionary)
        .def("GetProperties", &AxObject::GetProperties)
        .def("GetDefinition", &AxObject::GetDefinition)
        .def("to_IAAFComponentSP", &AxComponent::operator IAAFComponentSP)
        .def("to_IAAFComponent2SP", &AxComponent::operator IAAFComponent2SP)
        .def("CreateInstance",create_instance<IAAFComponent,IAAFComponentSP, AxComponent> )
        .staticmethod("CreateInstance")
    ;

    class_< AxSegment, bases< AxComponent > , boost::noncopyable >("AxSegment", init< IAAFSegmentSP >())
        .def("to_IAAFSegmentSP", &AxSegment::operator IAAFSegmentSP)
        .def("CreateInstance",create_instance<IAAFSegment,IAAFSegmentSP, AxSegment> )
        .staticmethod("CreateInstance")
    ;

    class_< AxTransition, bases< AxComponent > , boost::noncopyable >("AxTransition", init< IAAFTransitionSP >())
        .def("Initialize", &AxTransition::Initialize)
        .def("GetCutPoint", &AxTransition::GetCutPoint)
        .def("SetCutPoint", &AxTransition::SetCutPoint)
        .def("GetOperationGroup", &AxTransition::GetOperationGroup)
        .def("SetOperationGroup", &AxTransition::SetOperationGroup)
        .def("to_IAAFTransitionSP", &AxTransition::operator IAAFTransitionSP)
        .def("CreateInstance",create_instance<IAAFTransition,IAAFTransitionSP, AxTransition> )
        .staticmethod("CreateInstance")
    ;

    class_< AxSequence, bases< AxSegment > , boost::noncopyable >("AxSequence", init< IAAFSequenceSP >())
        .def("Initialize", &AxSequence::Initialize)
        .def("AppendComponent", &AxSequence::AppendComponent)
        .def("PrependComponent", &AxSequence::PrependComponent)
        .def("GetComponents", &AxSequence::GetComponents)
        .def("GetComponentAt", &AxSequence::GetComponentAt)
        .def("InsertComponentAt", &AxSequence::InsertComponentAt)
        .def("RemoveComponentAt", &AxSequence::RemoveComponentAt)
        .def("CountComponents", &AxSequence::CountComponents)
        .def("CreateInstance",create_instance<IAAFSequence,IAAFSequenceSP, AxSequence> )
        .staticmethod("CreateInstance")
    ;

    class_< AxTimecode, bases< AxSegment > , boost::noncopyable >("AxTimecode", init< IAAFTimecodeSP >())
        .def("Initialize", &AxTimecode::Initialize)
        .def("GetTimecode", &AxTimecode::GetTimecode)
        .def("SetTimecode", &AxTimecode::SetTimecode)
        .def("CreateInstance",create_instance<IAAFTimecode,IAAFTimecodeSP, AxTimecode> )
        .staticmethod("CreateInstance")
    ;

    class_< AxFiller, bases< AxSegment > , boost::noncopyable >("AxFiller", init< IAAFFillerSP >())
        .def("Initialize", &AxFiller::Initialize)
        .def("CreateInstance",create_instance<IAAFFiller,IAAFFillerSP,  AxFiller> )
        .staticmethod("CreateInstance")
    ;

    class_< AxPulldown, bases< AxSegment > , boost::noncopyable >("AxPulldown", init< IAAFPulldownSP >())
        .def("GetInputSegment", &AxPulldown::GetInputSegment)
        .def("GetPulldownKind", &AxPulldown::GetPulldownKind)
        .def("GetPulldownDirection", &AxPulldown::GetPulldownDirection)
        .def("GetPhaseFrame", &AxPulldown::GetPhaseFrame)
        .def("SetInputSegment", &AxPulldown::SetInputSegment)
        .def("SetPulldownKind", &AxPulldown::SetPulldownKind)
        .def("SetPulldownDirection", &AxPulldown::SetPulldownDirection)
        .def("SetPhaseFrame", &AxPulldown::SetPhaseFrame)
        .def("to_IAAFPulldownSP", &AxPulldown::operator IAAFPulldownSP)
        .def("CreateInstance",create_instance<IAAFPulldown, IAAFPulldownSP, AxPulldown> )
        .staticmethod("CreateInstance")
    ;

    class_< AxSourceReference, bases< AxSegment > , boost::noncopyable >("AxSourceReference", init< IAAFSourceReferenceSP >())
        .def("GetSourceID", &AxSourceReference::GetSourceID)
        .def("SetSourceID", &AxSourceReference::SetSourceID)
        .def("GetSourceMobSlotID", &AxSourceReference::GetSourceMobSlotID)
        .def("SetSourceMobSlotID", &AxSourceReference::SetSourceMobSlotID)
        .def("to_IAAFSourceReferenceSP", &AxSourceReference::operator IAAFSourceReferenceSP)
        .def("CreateInstance",create_instance<IAAFSourceReference,IAAFSourceReferenceSP, AxSourceReference> )
        .staticmethod("CreateInstance")
    ;

    class_< AxSourceClip, bases< AxSourceReference > , boost::noncopyable >("AxSourceClip", init< IAAFSourceClipSP >())
        .def("Initialize", &AxSourceClip::Initialize)
        .def("SetSourceReference", &AxSourceClip::SetSourceReference)
        .def("GetSourceReference", &AxSourceClip::GetSourceReference)
        .def("ResolveRef", &AxSourceClip::ResolveRef)
        .def("to_IAAFSourceClipSP", &AxSourceClip::operator IAAFSourceClipSP)
        .def("CreateInstance",create_instance<IAAFSourceClip, IAAFSourceClipSP, AxSourceClip> )
        .staticmethod("CreateInstance")
    ;

    class_< AxOperationGroup, bases< AxSegment > , boost::noncopyable >("AxOperationGroup", init< IAAFOperationGroupSP >())
        .def("Initialize", &AxOperationGroup::Initialize)
        .def("AppendInputSegment", &AxOperationGroup::AppendInputSegment)
        .def("PrependInputSegment", &AxOperationGroup::PrependInputSegment)
        .def("InsertInputSegmentAt", &AxOperationGroup::InsertInputSegmentAt)
        .def("GetInputSegmentAt", &AxOperationGroup::GetInputSegmentAt)
        .def("RemoveInputSegmentAt", &AxOperationGroup::RemoveInputSegmentAt)
        .def("CountSourceSegments", &AxOperationGroup::CountSourceSegments)
        .def("GetOperationDef", &AxOperationGroup::GetOperationDef)
        .def("SetOperationDef", &AxOperationGroup::SetOperationDef)
        .def("GetRender", &AxOperationGroup::GetRender)
        .def("SetRender", &AxOperationGroup::SetRender)
        .def("IsATimeWarp", &AxOperationGroup::IsATimeWarp)
        .def("IsValidTranOperation", &AxOperationGroup::IsValidTranOperation)
        .def("GetBypassOverride", &AxOperationGroup::GetBypassOverride)
        .def("SetBypassOverride", &AxOperationGroup::SetBypassOverride)
        .def("CountParameters", &AxOperationGroup::CountParameters)
        .def("AddParameter", &AxOperationGroup::AddParameter)
        .def("GetParameters", &AxOperationGroup::GetParameters)
        .def("LookupParameter", &AxOperationGroup::LookupParameter)
        .def("to_IAAFOperationGroupSP", &AxOperationGroup::operator IAAFOperationGroupSP)
        .def("CreateInstance",create_instance<IAAFOperationGroup, IAAFOperationGroupSP, AxOperationGroup> )
        .staticmethod("CreateInstance")
    ;

    class_< AxNestedScope, bases< AxSegment > , boost::noncopyable >("AxNestedScope", init< IAAFNestedScopeSP >())
        .def("AppendSegment", &AxNestedScope::AppendSegment)
        .def("PrependSegment", &AxNestedScope::PrependSegment)
        .def("InsertSegmentAt", &AxNestedScope::InsertSegmentAt)
        .def("RemoveSegmentAt", &AxNestedScope::RemoveSegmentAt)
        .def("CountSegments", &AxNestedScope::CountSegments)
        .def("GetSegmentAt", &AxNestedScope::GetSegmentAt)
        .def("GetSegments", &AxNestedScope::GetSegments)
        .def("to_IAAFNestedScopeSP", &AxNestedScope::operator IAAFNestedScopeSP)
        .def("CreateInstance",create_instance<IAAFNestedScope, IAAFNestedScopeSP, AxNestedScope> )
        .staticmethod("CreateInstance")
    ;

    class_< AxScopeReference, bases< AxSegment > , boost::noncopyable >("AxScopeReference", init< IAAFScopeReferenceSP >())
        .def("Initialize", &AxScopeReference::Initialize)
        .def("GetRelativeScope", &AxScopeReference::GetRelativeScope)
        .def("GetRelativeSlot", &AxScopeReference::GetRelativeSlot)
        .def("to_IAAFScopeReferenceSP", &AxScopeReference::operator IAAFScopeReferenceSP)
        .def("CreateInstance",create_instance<IAAFScopeReference, IAAFScopeReferenceSP, AxScopeReference> )
        .staticmethod("CreateInstance")
    ;

    class_< AxEssenceGroup, bases< AxSegment > , boost::noncopyable >("AxEssenceGroup", init< IAAFEssenceGroupSP >())
        .def("GetStillFrame", &AxEssenceGroup::GetStillFrame)
        .def("CountChoices", &AxEssenceGroup::CountChoices)
        .def("GetChoiceAt", &AxEssenceGroup::GetChoiceAt)
        .def("to_IAAFEssenceGroupSP", &AxEssenceGroup::operator IAAFEssenceGroupSP)
        .def("CreateInstance",create_instance<IAAFEssenceGroup, IAAFEssenceGroupSP, AxEssenceGroup> )
        .staticmethod("CreateInstance")
    ;

    class_< AxSelector, bases< AxSegment > , boost::noncopyable >("AxSelector", init< IAAFSelectorSP >())
        .def("GetSelectedSegment", &AxSelector::GetSelectedSegment)
        .def("EnumAlternateSegments", &AxSelector::EnumAlternateSegments)
        .def("to_IAAFSelectorSP", &AxSelector::operator IAAFSelectorSP)
        .def("CreateInstance",create_instance<IAAFSelector, IAAFSelectorSP, AxSelector> )
        .staticmethod("CreateInstance")
    ;

    class_< AxEdgecode, bases< AxSegment > , boost::noncopyable >("AxEdgecode", init< IAAFEdgecodeSP >())
        .def("Initialize", &AxEdgecode::Initialize)
        .def("GetEdgecode", &AxEdgecode::GetEdgecode)
        .def("to_IAAFEdgecodeSP", &AxEdgecode::operator IAAFEdgecodeSP)
        .def("CreateInstance",create_instance<IAAFEdgecode, IAAFEdgecodeSP, AxEdgecode> )
        .staticmethod("CreateInstance")
    ;

    class_< AxEvent, bases< AxSegment > , boost::noncopyable >("AxEvent", init< IAAFEventSP >())
        .def("GetPosition", &AxEvent::GetPosition)
        .def("SetPosition", &AxEvent::SetPosition)
        .def("SetComment", &AxEvent::SetComment)
        .def("GetComment", &AxEvent::GetComment)
        .def("CreateInstance",create_instance<IAAFEvent,IAAFEventSP, AxEvent> )
        .staticmethod("CreateInstance")
    ;

    class_< AxCommentMarker, bases< AxEvent > , boost::noncopyable >("AxCommentMarker", init< IAAFCommentMarkerSP >())
        .def("GetAnnotation", &AxCommentMarker::GetAnnotation)
        .def("SetAnnotation", &AxCommentMarker::SetAnnotation)
        .def("CreateInstance",create_instance<IAAFCommentMarker,IAAFCommentMarkerSP, AxCommentMarker> )
        .staticmethod("CreateInstance")
    ;

    class_< AxGPITrigger, bases< AxEvent > , boost::noncopyable >("AxGPITrigger", init< IAAFGPITriggerSP >())
        .def("GetActiveState", &AxGPITrigger::GetActiveState)
        .def("SetActiveState", &AxGPITrigger::SetActiveState)
        .def("CreateInstance",create_instance<IAAFGPITrigger, IAAFGPITriggerSP, AxGPITrigger> )
        .staticmethod("CreateInstance")
    ;

    class_< AxTimecodeStream, bases< AxSegment > , boost::noncopyable >("AxTimecodeStream", init< IAAFTimecodeStreamSP >())
        .def("GetPositionTimecode", &AxTimecodeStream::GetPositionTimecode)
        .def("GetUserDataLength", &AxTimecodeStream::GetUserDataLength)
        .def("GetSampleRate", &AxTimecodeStream::GetSampleRate)
        .def("GetSourceType", &AxTimecodeStream::GetSourceType)
        .def("GetSampleSize", &AxTimecodeStream::GetSampleSize)
        .def("GetSourceBufLen", &AxTimecodeStream::GetSourceBufLen)
        .def("GetUserDataAtPosition", &AxTimecodeStream::GetUserDataAtPosition)
        .def("GetSource", &AxTimecodeStream::GetSource)
        .def("SetPositionTimecode", &AxTimecodeStream::SetPositionTimecode)
        .def("SetUserDataAtPosition", &AxTimecodeStream::SetUserDataAtPosition)
        .def("SetSampleRate", &AxTimecodeStream::SetSampleRate)
        .def("SetSourceType", &AxTimecodeStream::SetSourceType)
        .def("SetSource", &AxTimecodeStream::SetSource)
        .def("to_IAAFTimecodeStreamSP", &AxTimecodeStream::operator IAAFTimecodeStreamSP)
        .def("CreateInstance",create_instance<IAAFTimecodeStream,IAAFTimecodeStreamSP, AxTimecodeStream> )
        .staticmethod("CreateInstance")
    ;

    class_< AxTimecodeStream12M, bases< AxTimecodeStream > , boost::noncopyable >("AxTimecodeStream12M", init< IAAFTimecodeStream12MSP >())
        .def("to_IAAFTimecodeStream12MSP", &AxTimecodeStream12M::operator IAAFTimecodeStream12MSP)
        .def("CreateInstance",create_instance<IAAFTimecodeStream12M,IAAFTimecodeStream12MSP, AxTimecodeStream12M> )
        .staticmethod("CreateInstance")
    ;

    class_< AxDescriptiveMarker, bases< AxCommentMarker > , boost::noncopyable >("AxDescriptiveMarker", init< IAAFDescriptiveMarkerSP >())
        .def("Initialize", &AxDescriptiveMarker::Initialize)
        .def("GetDescribedSlotIDs", &AxDescriptiveMarker::GetDescribedSlotIDs)
        .def("GetDescriptiveFramework", &AxDescriptiveMarker::GetDescriptiveFramework)
        .def("SetDescribedSlotIDs", &AxDescriptiveMarker::SetDescribedSlotIDs)
        .def("SetDescriptiveFramework", &AxDescriptiveMarker::SetDescriptiveFramework)
        .def("to_IAAFDescriptiveMarkerSP", &AxDescriptiveMarker::operator IAAFDescriptiveMarkerSP)
        .def("CreateInstance",create_instance<IAAFDescriptiveMarker,IAAFDescriptiveMarkerSP, AxDescriptiveMarker> )
        .staticmethod("CreateInstance")
    ;
}

max_issues_repo_name: DIT-Tools/pyaaf


text:
/*
 * Copyright 2011-2013 Esrille Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "HTMLIFrameElementImp.h"

#include <boost/bind.hpp>

#include "one_at_a_time.hpp"

constexpr auto Intern = &one_at_a_time::hash<char16_t>;

#include "DocumentImp.h"
#include "EventImp.h"
#include "HTMLUtil.h"
#include "WindowProxy.h"

namespace org
{
namespace w3c
{
namespace dom
{
namespace bootstrap
{

HTMLIFrameElementImp::HTMLIFrameElementImp(DocumentImp* ownerDocument) :
    ObjectMixin(ownerDocument, u"iframe"),
    blurListener(boost::bind(&HTMLIFrameElementImp::handleBlur, this, _1, _2)),
    loadInProgess(false)
{
    tabIndex = 0;
    addEventListener(u"blur", blurListener, false, EventTargetImp::UseDefault);
}

HTMLIFrameElementImp::HTMLIFrameElementImp(const HTMLIFrameElementImp& org) :
    ObjectMixin(org),
    window(org.window),
    blurListener(boost::bind(&HTMLIFrameElementImp::handleBlur, this, _1, _2)),
    loadInProgess(false)
{
    tabIndex = org.tabIndex;
    addEventListener(u"blur", blurListener, false, EventTargetImp::UseDefault);
}

HTMLIFrameElementImp::~HTMLIFrameElementImp()
{
}

void HTMLIFrameElementImp::open(const std::u16string& url, unsigned flags)
{
    auto owner = getOwnerDocumentImp();
    if (!owner)
        return;
    if (owner->getReadyState() != u"complete") {
        loadInProgess = true;
        owner->incrementLoadEventDelayCount(url);
    }
    if (auto proxy = owner->getDefaultWindow()->createChildProxy(flags, std::static_pointer_cast<HTMLIFrameElementImp>(self()))) {
        window = proxy;
        proxy->open(url, u"_self");  // TODO: Check how location is created
    }  // TODO: else ...
}

void HTMLIFrameElementImp::notify(bool error)
{
    // The iframe load event steps
    auto event = std::make_shared<EventImp>();
    if (!error)
        event->initEvent(u"load", false, false);
    else
        event->initEvent(u"error", false, false);
    dispatchEvent(event);
    if (!loadInProgess)
        return;
    if (auto owner = getOwnerDocumentImp()) {
        owner->decrementLoadEventDelayCount(getSrc());
        loadInProgess = false;
    }
}

void HTMLIFrameElementImp::handleMutation(events::MutationEvent mutation)
{
    std::u16string value = mutation.getNewValue();
    css::CSSStyleDeclaration style(getStyle());

    switch (Intern(mutation.getAttrName().c_str())) {
    case Intern(u"src"):
        window.open(getSrc(), u"_self");
        break;
    // Styles
    case Intern(u"height"):
        if (mapToDimension(value))
            style.setProperty(u"height", value, u"non-css");
        break;
    case Intern(u"hspace"):
        if (mapToDimension(value)) {
            style.setProperty(u"margin-left", value, u"non-css");
            style.setProperty(u"margin-right", value, u"non-css");
        }
        break;
    case Intern(u"vspace"):
        if (mapToDimension(value)) {
            style.setProperty(u"margin-top", value, u"non-css");
            style.setProperty(u"margin-bottom", value, u"non-css");
        }
        break;
    case Intern(u"width"):
        if (mapToDimension(value))
            style.setProperty(u"width", value, u"non-css");
        break;
    default:
        HTMLElementImp::handleMutation(mutation);
        break;
    }
}

void HTMLIFrameElementImp::handleBlur(EventListenerImp* listener, events::Event event)
{
    if (auto imp = std::dynamic_pointer_cast<DocumentImp>(window.getDocument().self()))
        imp->setFocus(0);
}

//
// HTMLIFrameElement
//

std::u16string HTMLIFrameElementImp::getSrc()
{
    return getAttributeAsURL(u"src");
}

void HTMLIFrameElementImp::setSrc(const std::u16string& src)
{
    setAttribute(u"src", src);
}

std::u16string HTMLIFrameElementImp::getSrcdoc()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setSrcdoc(const std::u16string& srcdoc)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getName()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setName(const std::u16string& name)
{
    // TODO: implement me!
}

DOMSettableTokenList HTMLIFrameElementImp::getSandbox()
{
    // TODO: implement me!
    return nullptr;
}

void HTMLIFrameElementImp::setSandbox(const std::u16string& sandbox)
{
    // TODO: implement me!
}

bool HTMLIFrameElementImp::getSeamless()
{
    // TODO: implement me!
    return 0;
}

void HTMLIFrameElementImp::setSeamless(bool seamless)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getWidth()
{
    return getAttribute(u"width");
}

void HTMLIFrameElementImp::setWidth(const std::u16string& width)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getHeight()
{
    return getAttribute(u"height");
}

void HTMLIFrameElementImp::setHeight(const std::u16string& height)
{
    // TODO: implement me!
}

Document HTMLIFrameElementImp::getContentDocument()
{
    return window.getDocument();
}

html::Window HTMLIFrameElementImp::getContentWindow()
{
    return window;
}

std::u16string HTMLIFrameElementImp::getAlign()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setAlign(const std::u16string& align)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getFrameBorder()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setFrameBorder(const std::u16string& frameBorder)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getLongDesc()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setLongDesc(const std::u16string& longDesc)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getMarginHeight()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setMarginHeight(const std::u16string& marginHeight)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getMarginWidth()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setMarginWidth(const std::u16string& marginWidth)
{
    // TODO: implement me!
}

std::u16string HTMLIFrameElementImp::getScrolling()
{
    // TODO: implement me!
    return u"";
}

void HTMLIFrameElementImp::setScrolling(const std::u16string& scrolling)
{
    // TODO: implement me!
}

}
}
}
}

max_stars_repo_name: esrille/escudo

max_issues_repo_name: esrille/escudo

max_forks_repo_name: esrille/escudo