std::size_t HeaderParser::advance(std::streambuf& sb) { std::size_t ret = 0; while (sb.in_avail() > 0) { ++ret; if (parse(sb.sbumpc())) return ret; } return ret; }
virtual int_type underflow() { // Return current character. if ( gptr() == &_oneChar ) return traits_type::to_int_type(_oneChar); // Get another character from the archive stream, if available. if ( _curPos==_numChars ) return traits_type::eof(); _curPos += 1; int_type next_value = _streambuf->sbumpc(); if ( !traits_type::eq_int_type(next_value,traits_type::eof()) ) { setg(&_oneChar, &_oneChar, (&_oneChar)+1); _oneChar = traits_type::to_char_type(next_value); } return next_value; }
bool Responder::advance(std::streambuf& in) { std::streambuf::int_type chi; while ((chi = in.sgetc()) != std::streambuf::traits_type::eof()) { char ch = std::streambuf::traits_type::to_char_type(chi); switch (_state) { case state_0: log_debug("new rpc request"); if (ch == '\xc0') _state = state_method; else if (ch == '\xc3') _state = state_domain; else throw std::runtime_error("domain or method name expected"); in.sbumpc(); break; case state_domain: if (ch == '\0') { log_info_if(!_domain.empty(), "rpc method domain \"" << _domain << '"'); _state = state_method; } else _domain += ch; in.sbumpc(); break; case state_method: if (ch == '\0') { log_info("rpc method \"" << _methodName << '"'); _proc = _serviceRegistry.getProcedure(_domain.empty() ? _methodName : _domain + '\0' + _methodName); if (_proc) { _args = _proc->beginCall(); _state = state_params; } else { _failed = true; _errorMessage = "unknown method \"" + _methodName + '"'; _state = state_params_skip; } _methodName.clear(); _domain.clear(); } else _methodName += ch; in.sbumpc(); break; case state_params: if (ch == '\xff') { if (_args && *_args) { _failed = true; _errorMessage = "argument expected"; } in.sbumpc(); return true; } else { if (_args == 0 || *_args == 0) { _failed = true; _errorMessage = "too many arguments"; _state = state_params_skip; } else { _deserializer.begin(false); _state = state_param; } } break; case state_params_skip: if (ch == '\xff') { in.sbumpc(); return true; } else { _deserializer.skip(); _state = state_param_skip; } break; case state_param: if (_deserializer.advance(in)) { try { (*_args)->fixup(_deserializer.si()); ++_args; _state = state_params; } catch (const std::exception& e) { _failed = true; _errorMessage = e.what(); _state = state_params_skip; } } break; case state_param_skip: if (_deserializer.advance(in)) _state = state_params_skip; break; } } return false; }
virtual int uflow() override { ASSERT(_streambuf); return _streambuf->sbumpc(); }