/* */ #ifndef D_GENERIC_PARSER_H #define D_GENERIC_PARSER_H #include "common.h" #include "SharedHandle.h" #include "a2io.h" #include "util.h" namespace aria2 { template class GenericParser { public: GenericParser() : parser_(&psm_) {} ~GenericParser() {} typedef typename ParserStateMachine::ResultType ResultType; typedef ParserStateMachine ParserStateMachineType; // Parses |size| bytes of data |data| and returns the number of // bytes processed. On error, one of the negative error codes is // returned. ssize_t parseUpdate(const char* data, size_t size) { return parser_.parseUpdate(data, size); } // Parses |size| bytes of data |data| and returns result. On error, // null value is returned. On success, the |error| will be the // number of bytes processed (>= 0). On error, it will be one of the // negative error code. This function also resets underlying parser // facility and make it ready to reuse. ResultType parseFinal(const char* data, size_t size, ssize_t& error) { ResultType res; error = parser_.parseFinal(data, size); if(error < 0) { res = ParserStateMachine::noResult(); } else { res = psm_.getResult(); } parser_.reset(); return res; } private: ParserStateMachine psm_; Parser parser_; }; template typename Parser::ResultType parseFile(Parser& parser, const std::string& filename) { int fd; // TODO Overrode a2open(const char*,..) and a2open(const std::wstring&,..) while((fd = a2open(utf8ToWChar(filename).c_str(), O_BINARY | O_RDONLY, OPEN_MODE)) == -1 && errno != EINTR); if(fd == -1) { return Parser::ParserStateMachineType::noResult(); } auto_delete_r fdDeleter(fd, close); char buf[4096]; ssize_t nread; ssize_t nproc; while((nread = read(fd, buf, sizeof(buf))) > 0) { nproc = parser.parseUpdate(buf, nread); if(nproc < 0) { break; } } return parser.parseFinal(0, 0, nproc); } } // namespace aria2 #endif // D_GENERIC_PARSER_H