/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef XMLARCHIVE_HH_ #define XMLARCHIVE_HH_ #include #include #include #include #include #include "recordio.hh" XERCES_CPP_NAMESPACE_USE namespace hadoop { class Value { private: std::string type; std::string value; public: Value(const std::string& t) { type = t; } void addChars(const char* buf, unsigned int len) { value += std::string(buf, len); } const std::string& getType() const { return type; } const std::string& getValue() const { return value; } }; class MySAXHandler : public HandlerBase { private: std::vector& vlist; bool charsValid; public: MySAXHandler(std::vector& list) : vlist(list) {charsValid = false;} void startElement(const XMLCh* const name, AttributeList& attr); void endElement(const XMLCh* const name); void characters(const XMLCh* const buf, unsigned int len); }; class XmlIndex : public Index { private: std::vector& vlist; unsigned int& vidx; public: XmlIndex(std::vector& list, unsigned int& idx) : vlist(list), vidx(idx) {} bool done() { Value v = vlist[vidx]; return (v.getType() == "/array") ? true : false; } void incr() {} ~XmlIndex() {} }; class MyBinInputStream : public BinInputStream { private: InStream& stream; unsigned int pos; public: MyBinInputStream(InStream& s) : stream(s) { pos = 0; } virtual unsigned int curPos() const { return pos; } virtual unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead) { ssize_t nread = stream.read(toFill, maxToRead); if (nread < 0) { return 0; } else { pos += nread; return nread; } } }; class MyInputSource : public InputSource { private: InStream& stream; public: MyInputSource(InStream& s) : stream(s) { } virtual BinInputStream* makeStream() const { return new MyBinInputStream(stream); } virtual const XMLCh* getEncoding() const { return XMLString::transcode("UTF-8"); } virtual ~MyInputSource() {} }; class IXmlArchive : public IArchive { private: std::vector vlist; unsigned int vidx; MySAXHandler *docHandler; SAXParser *parser; MyInputSource* src; Value next() { Value v = vlist[vidx]; vidx++; return v; } public: IXmlArchive(InStream& _stream) { vidx = 0; try { XMLPlatformUtils::Initialize(); } catch (const XMLException& e) { throw new IOException("Unable to initialize XML Parser."); } parser = new SAXParser(); docHandler = new MySAXHandler(vlist); parser->setDocumentHandler(docHandler); src = new MyInputSource(_stream); try { parser->parse(*src); } catch (const XMLException& e) { throw new IOException("Unable to parse XML stream."); } catch (const SAXParseException& e) { throw new IOException("Unable to parse XML stream."); } delete parser; delete docHandler; } virtual void deserialize(int8_t& t, const char* tag); virtual void deserialize(bool& t, const char* tag); virtual void deserialize(int32_t& t, const char* tag); virtual void deserialize(int64_t& t, const char* tag); virtual void deserialize(float& t, const char* tag); virtual void deserialize(double& t, const char* tag); virtual void deserialize(std::string& t, const char* tag); virtual void deserialize(std::string& t, size_t& len, const char* tag); virtual void startRecord(Record& s, const char* tag); virtual void endRecord(Record& s, const char* tag); virtual Index* startVector(const char* tag); virtual void endVector(Index* idx, const char* tag); virtual Index* startMap(const char* tag); virtual void endMap(Index* idx, const char* tag); virtual ~IXmlArchive() { XMLPlatformUtils::Terminate(); } }; class OXmlArchive : public OArchive { private: OutStream& stream; std::vector cstack; void insideRecord(const char* tag) { printBeginEnvelope(tag); cstack.push_back("record"); } void outsideRecord(const char* tag) { std::string s = cstack.back(); cstack.pop_back(); if (s != "record") { throw new IOException("Error deserializing record."); } printEndEnvelope(tag); } void insideVector(const char* tag) { printBeginEnvelope(tag); cstack.push_back("vector"); } void outsideVector(const char* tag) { std::string s = cstack.back(); cstack.pop_back(); if (s != "vector") { throw new IOException("Error deserializing vector."); } printEndEnvelope(tag); } void insideMap(const char* tag) { printBeginEnvelope(tag); cstack.push_back("map"); } void outsideMap(const char* tag) { std::string s = cstack.back(); cstack.pop_back(); if (s != "map") { throw new IOException("Error deserializing map."); } printEndEnvelope(tag); } void p(const char* cstr) { stream.write(cstr, strlen(cstr)); } void printBeginEnvelope(const char* tag) { if (cstack.size() != 0) { std::string s = cstack.back(); if ("record" == s) { p("\n"); p(""); p(tag); p("\n"); p(""); } else if ("vector" == s) { p(""); } else if ("map" == s) { p(""); } } else { p(""); } } void printEndEnvelope(const char* tag) { if (cstack.size() != 0) { std::string s = cstack.back(); if ("record" == s) { p("\n"); p("\n"); } else if ("vector" == s) { p("\n"); } else if ("map" == s) { p("\n"); } } else { p("\n"); } } public: OXmlArchive(OutStream& _stream) : stream(_stream) {} virtual void serialize(int8_t t, const char* tag); virtual void serialize(bool t, const char* tag); virtual void serialize(int32_t t, const char* tag); virtual void serialize(int64_t t, const char* tag); virtual void serialize(float t, const char* tag); virtual void serialize(double t, const char* tag); virtual void serialize(const std::string& t, const char* tag); virtual void serialize(const std::string& t, size_t len, const char* tag); virtual void startRecord(const Record& s, const char* tag); virtual void endRecord(const Record& s, const char* tag); virtual void startVector(size_t len, const char* tag); virtual void endVector(size_t len, const char* tag); virtual void startMap(size_t len, const char* tag); virtual void endMap(size_t len, const char* tag); virtual ~OXmlArchive(); }; } #endif /*XMLARCHIVE_HH_*/