Beispiel #1
0
inline
std::basic_istream<CharType, CharTrait>&
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v)
{
  if (in.good())
  {
    int d = in.get();
    if (d == ' ')
    {
      T x;
      in >> x;
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
      v = boost::move(x);
#else
      v = x;
#endif
    }
Beispiel #2
0
	inline SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>&
	operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::rational<IntType>& rhs) {
		IntType n = IntType(0);
		IntType d = IntType(1);
		Elem c = 0;
		sprout::detail::io::ios_flags_saver saver(lhs);
		lhs >> n;
		c = lhs.get();
		if (c != Elem('/')) {
			lhs.clear(std::istream::badbit);
		}
		lhs >> std::noskipws;
		lhs >> d;
		if (lhs) {
			rhs.assign(n, d);
		}
		return lhs;
	}
Beispiel #3
0
        std::basic_istream<charT, Traits>&
        operator>>(std::basic_istream<charT, Traits>& in,
            token_matcher<charT, Traits, Allocator> matcher)
        {
            typename std::basic_string<charT, Traits, Allocator>::iterator
                i = matcher.token.begin(),
                end = matcher.token.end();
            typename std::basic_istream<charT, Traits>::char_type c;
            for (; i != end && in.get(c); ++i)
            {
                if (*i != c)
                {
                    in.clear(std::basic_ios<charT, Traits>::failbit);
                    break;
                }
            }

            return in;
        }
Beispiel #4
0
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, pcg128_t& value)
{
    typename std::basic_istream<CharT,Traits>::sentry s(in);

    if (!s)
         return in;

    constexpr auto BASE = pcg128_t(10ULL);
    pcg128_t current(0ULL);
    bool did_nothing = true;
    bool overflow = false;
    for(;;) {
        CharT wide_ch = in.get();
        if (!in.good())
            break;
        auto ch = in.narrow(wide_ch, '\0');
        if (ch < '0' || ch > '9') {
            in.unget();
            break;
        }
        did_nothing = false;
        pcg128_t digit(uint32_t(ch - '0'));
        pcg128_t timesbase = current*BASE;
        overflow = overflow || timesbase < current;
        current = timesbase + digit;
        overflow = overflow || current < digit;
    }

    if (did_nothing || overflow) {
        in.setstate(std::ios::failbit);
        if (overflow)
            current = ~pcg128_t(0ULL);
    }

    value = current;

    return in;
}
Beispiel #5
0
void parse(std::basic_istream<CharT> &src, HandlerT &handler)
{
    enum Action {
        Stay,
        Skip
    };
    const int eos = -1;
    typedef std::function<Action (int)> parser_t;
    parser_t rule, top, in_string, in_atom, in_comment,
        append_escaped, append_escaped_hex;
    stack<parser_t> ctx;
    unsigned level = 0;

    std::string data;
    int hex_byte;

    auto rule_use = [&](parser_t const &p) {
        data = "";
        data.reserve(256);
        rule = p;
    };

    auto rule_pop = [&]() {
        auto p = ctx.top();
        ctx.pop();
        rule = p;
    };

    auto rule_push = [&](parser_t const &after,
                         parser_t const &current) {
        ctx.push(after);
        rule = current;
    };

    top = [&](int c) -> Action {
        if (c == ')') {
            if (!level)
                throw Error(src, "Unexpected ')'");
            --level;
            handler.on_list_end();
        } else if (c == '(') {
            ++level;
            handler.on_list_begin();
        } else if (c == ';') {
            rule_use(in_comment);
        } else if (::isspace(c)) {
            // do nothing
        } else if (c == '"') {
            rule_use(in_string);
        } else if (c != eos) {
            rule_use(in_atom);
            return Stay;
        }
        return Skip;
    };

    in_comment = [&](int c) -> Action {
        if (c != '\n' && c != eos) {
            data += c;
        } else {
            handler.on_comment(std::move(data));
            rule_use(top);
        }
        return Skip;
    };

    auto in_hex = [&](int c) -> Action {
        if (c != eos) {
            int n = char2hex(c);
            if (n >= 0) {
                if (hex_byte < 0) {
                    hex_byte = (n << 4);
                    return Skip;
                }
                hex_byte |= n;
            }
        }
        rule_pop();
        return Stay;
    };

    append_escaped_hex = [&](int) -> Action {
        if (hex_byte < 0)
            throw Error(src, "Escaped hex is empty");

        data += static_cast<char>(hex_byte);
        rule_pop();
        return Stay;
    };

    auto process_hex = [&](parser_t const &after) -> Action {
        hex_byte = -1;
        rule_push(after, in_hex);
        return Skip;
    };

    append_escaped = [&](int c) -> Action {
        static const std::unordered_map<char, char>
        assoc{{'n', '\n'}, {'t', '\t'}, {'r', '\r'}, {'a', '\a'},
              {'b', '\b'}, {'v', '\v'}};

        if (c == eos)
            throw Error(src, "Expected escaped symbol, got EOS");

        if (c == 'x')
            return process_hex(append_escaped_hex);

        auto p = assoc.find(c);
        if (p != assoc.end()) {
            data += p->second;
        } else {
            data += c;
        }
        rule_pop();
        return Skip;
    };

    auto process_escaped = [&]() -> Action {
        rule_push(rule, append_escaped);
        return Skip;
    };

    in_atom = [&](int c) -> Action {
        static const std::string bound("()");
        if (bound.find(c) != std::string::npos || isspace(c) || c == eos) {
            handler.on_atom(std::move(data));
            rule_use(top);
            return Stay;
        } else if (c == '\\') {
            return process_escaped();
        } else {
            data += c;
        }
        return Skip;
    };

    in_string = [&](int c) -> Action {
        if (c == '"') {
            handler.on_string(std::move(data));
            rule_use(top);
        } else if (c == '\\') {
            return process_escaped();
        } else if (c == eos) {
            throw Error(src, "string is not limited, got EOS");
        } else {
            data += c;
        }
        return Skip;
    };

    rule_use(top);
    try {
        while (true) {
            CharT c = src.get();
            if (src.gcount() == 0) {
                rule(eos);
                break;
            }
            
            while (rule(c) == Stay) {}
        }
    } catch (Error const &e) {
        throw;
    } catch (std::exception const &e) {
        throw;
    }
    handler.on_eof();
}
Beispiel #6
0
    /**
     *  @brief Deserialize the string value from the specified input stream.
     *  @param __s  Reference to the input stream.
     */
    void
    load(std::basic_istream<CharT, Traits>& __s)
    {
        // Define the integer symbol representation placeholder.
        std::basic_stringstream<CharT, Traits> __i;

        // Define the input stream iterator of the provided stream to
        // be able to read the string length value symbol by symbol.
        auto __si = std::istream_iterator<CharT, CharT, Traits>(__s);

        // Define the output stream to as a buffer for the integer
        // value, which will be later converted.
        auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i);

        // Copy the symbols from the input stream to the integer
        // placeholder until the ":" delimiter value.
        auto __result = copy_until(__si, __ival,
            [&__s](const CharT& __ch) {

            // Additionally, check that we did not exceed the
            // length of the stream to prevent hangs.
            return !__s.eof() && __ch != basic_value_type::delimiter_token;
        }, basic_value_type::integer_length);

        if (*__result != basic_value_type::delimiter_token) {
            std::ostringstream __error;

            __error << "bencode::string::load the delimiter `:` "
                "expected, but `" << CharT(*__result) << "` found\n";
            throw encoding_error(__error.str());
        }

        // Save the length of the string.
        int64_t __count;
        __i >> __count;

        if (!__count && __i.str() != std::basic_string<
                CharT, Traits>(1, CharT('0'))) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "length is not a number\n";
            throw value_error(__error.str());
        }

        // Ensure that the string length is a non-negative value.
        if (__count < 0) {
            std::ostringstream __error;

            __error << "bencode::string::load the length of the string "
                "value must be a positive integer: `" << __count << "`\n";
            throw value_error(__error.str());
        }

        // Allocate the list of symbols of the specified string length.
        std::unique_ptr<CharT[]> __str(new CharT[__count+1]);

        // Read the string value into the symbol list.
        __s.get(__str.get(), std::streamsize(__count+1));
        auto __strval = string_type(__str.get());

        // Ensure that valid count of the symbols was extracted from
        // the provided input stream.
        if (int64_t(__strval.length()) != __count) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "decoded length is not equal to the real one: `" << __count
                << "` != `" << __strval.length() << "`\n";
            throw value_error(__error.str());
        }

        // Initialize the internal value with a new string.
        _M_value = __strval;
    }