inline void ReadBSTRFromStream( std::basic_istream< CharT, CharTraitsT > &Istream, ATL::CComBSTR &Str ) { Str.Empty(); CharT Buff[256]; do { Istream.read( Buff, APL_ARRSIZE(Buff) ); ATL::CComBSTR TmpStr(Istream.gcount(), Buff); Str.Append(TmpStr); } while(Istream.gcount() == APL_ARRSIZE(Buff)); }
inline void ReadBSTRFromStream( std::basic_istream< WCHAR, CharTraitsT > &Istream, ATL::CComBSTR &Str ) { //Оптимизация исключающая временные объекты Str.Empty(); WCHAR Buff[256]; do { Istream.read( Buff, APL_ARRSIZE(Buff) ); Str.Append(Buff, Istream.gcount()); } while(Istream.gcount() == APL_ARRSIZE(Buff)); }
void read_next() { parser_.begin_parse(); while (!eof_ && !parser_.done()) { if (!(index_ < buffer_length_)) { if (!is_->eof()) { is_->read(buffer_.data(), buffer_capacity_); buffer_length_ = static_cast<size_t>(is_->gcount()); if (buffer_length_ == 0) { eof_ = true; } index_ = 0; } else { eof_ = true; } } if (!eof_) { parser_.parse(buffer_.data(),index_,buffer_length_); index_ = parser_.index(); } } parser_.end_parse(); }
void check_done() { while (!eof_) { if (!(index_ < buffer_length_)) { if (!is_->eof()) { is_->read(buffer_.data(), buffer_capacity_); buffer_length_ = static_cast<size_t>(is_->gcount()); if (buffer_length_ == 0) { eof_ = true; } index_ = 0; } else { eof_ = true; } } if (!eof_) { parser_.check_done(buffer_.data(),index_,buffer_length_); index_ = parser_.index(); } } }
std::streamsize ignore_line ( std::basic_istream<CharT>& in, bool always_discard = false ) { std::streamsize nread = 0; if ( always_discard || ( in.rdbuf()->sungetc() != std::char_traits<CharT>::eof() && in.get() != in.widen ( '\n' ) ) ) { // The stream is good, and we haven't // read a full line yet, so clear it out in.ignore ( std::numeric_limits<std::streamsize>::max(), in.widen ( '\n' ) ); nread = in.gcount(); } return nread; }
int Buffer::pushBytesFromStream(std::basic_istream<char>& istr, int cnt) { if (writeAvailable() < cnt) cnt = writeAvailable(); istr.read((char*)_tail, cnt); if (istr.eof()) { cnt = istr.gcount(); } else if (istr.fail()) { return -1; } _tail += cnt; return cnt; }
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 ¤t) { 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(); }