static void parseXMLSkipSpace(std::streambuf& buffer) { while(buffer.sgetc()==' ' || buffer.sgetc()=='\n' || buffer.sgetc()=='\r') { buffer.snextc(); } }
static std::string parseXMLIdentifier(std::streambuf& buffer) { std::stringstream identifier; { char c=buffer.sgetc(); if((c<'A' || c>'Z') && (c<'a' || c>'z')) { throw XMLParseException(); } buffer.snextc(); identifier<<c; } for(;;) { char c=buffer.sgetc(); if((c<'0' || c>'9') && (c<'A' || c>'Z') && (c<'a' || c>'z')) { break; } buffer.snextc(); identifier<<c; } return identifier.str(); }
XMLNode_SPtr parseXML(std::streambuf& buffer) { std::cout<<"Parse Start"<<std::endl; parseXMLSkipSpace(buffer); char c=buffer.sgetc(); if(c=='<') { buffer.snextc(); std::cout<<"Parse Node"<<std::endl; XMLNode_SPtr current=parseXMLNode(buffer); std::cout<<"Something"<<std::endl; return current; } std::cout<<"Nothing"<<std::endl; return XMLNode_SPtr(); }
static XMLNode_SPtr parseXMLNode(std::streambuf& buffer) { // 1. Read Symbol name parseXMLSkipSpace(buffer); std::string id=parseXMLIdentifier(buffer); std::cout<<"Parse Id:"<<id<<std::endl; std::list<XMLNode_SPtr> children; std::string text; parseXMLSkipSpace(buffer); for(;;) { char c=buffer.sgetc(); char c2=buffer.snextc(); if((c=='/') && (c2=='>')) { buffer.snextc(); goto completeNode; } if(c=='>') { goto parseText; } // TODO: Parse attribute } parseText: std::cout<<"Parse Text"<<std::endl; { std::stringstream textbuffer; parseXMLSkipSpace(buffer); for(;;) { char c=buffer.sgetc(); char c2=buffer.snextc(); if(c!='<') { textbuffer<<c; } else { if(c2=='/') { buffer.snextc(); break; } // TODO: There may be other cases. children.push_back(parseXMLNode(buffer)); } } text=textbuffer.str(); } { std::string::reverse_iterator trimpos=text.rbegin(); while((trimpos!=text.rend()) && (*trimpos==' ' || *trimpos=='\n' || *trimpos=='\r')) { trimpos++; } text.erase(trimpos.base(),text.end()); } std::cout<<"Parse end"<<std::endl; { std::string endidentifier=parseXMLIdentifier(buffer); if(endidentifier!=id) { throw XMLParseException(); } parseXMLSkipSpace(buffer); char c=buffer.sgetc(); if(c!='>') { throw XMLParseException(); } buffer.snextc(); } completeNode: std::cout<<"Complete"<<std::endl; // Complete...just build and return it. XMLNode_SPtr node(new XMLNode(id, children, text)); return node; }
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_type underflow() override { ASSERT(_streambuf); return _streambuf->sgetc(); }