X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=odcread.cc;h=caa87e7713f0dc937cd24c717c54dbbc2add4160;hb=7a97d981de20c2e9e9fa27d06f5b2c69ea09de16;hp=4ba36802c058412591472bd9fb6c4af470c6a41f;hpb=d7f2452e20b04d1559b7bdd3aa49b6fbf7d0abaf;p=odcread.git diff --git a/odcread.cc b/odcread.cc index 4ba3680..caa87e7 100644 --- a/odcread.cc +++ b/odcread.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -8,6 +9,12 @@ #include #include +// Character encoding conversions +#include +#include +#include +#include + namespace odc { class Context { public: @@ -52,40 +59,90 @@ namespace odc { class MyVisitor : public Visitor { private: - std::vector d_context; + std::stack d_context; void terminateContext() { - Context *c = *(d_context.end() - 1); - d_context.erase(d_context.end() - 1); - if (d_context.size() == 0) { + Context *c = d_context.top(); + d_context.pop(); + if (d_context.empty()) { std::cout << c->getPlainText() << std::endl; } else { std::string text = c->getPlainText(); - (*(d_context.end() - 1))->addPiece(text); + d_context.top()->addPiece(text); } delete c; } public: virtual void partStart() { - d_context.push_back(new PartContext()); + d_context.push(new PartContext()); } virtual void partEnd() { terminateContext(); } virtual void foldLeft(bool collapsed) { - d_context.push_back(new FoldContext(collapsed)); + d_context.push(new FoldContext(collapsed)); } virtual void foldRight() { terminateContext(); } + char *getCharSet() { + return "UTF-8"; // FIXME setlocale(LC_CTYPE, 0) + processing + } virtual void textShortPiece(const ShortPiece *piece) { - std::string text = piece->getText(); - (*(d_context.end() - 1))->addPiece(text); + iconv_t conv = iconv_open("UTF-8", "ISO-8859-1"); + if (conv == (iconv_t)-1) { + std::string str("iconv initialization error: "); + str += strerror(errno); + throw str.c_str(); + } + size_t bytesIn = piece->size() + 1; + SHORTCHAR *in = piece->getBuffer(); + size_t bytesOut = bytesIn; // FIXME probably not safe. + char *out = new char[bytesIn]; + char *outPtr = out; + size_t rval = iconv(conv, &in, &bytesIn, &outPtr, &bytesOut); + if (rval == (size_t)-1) { + std::string str("iconv error: "); + str += strerror(errno); + throw str.c_str(); + } + iconv_close(conv); + std::string str(out); + for (std::string::iterator it = str.begin(); it < str.end(); ++it) { + if (*it == '\r') *it = '\n'; + } + d_context.top()->addPiece(str); } virtual void textLongPiece(const LongPiece *piece) { - std::string text = piece->getText(); - (*(d_context.end() - 1))->addPiece(text); + char *out = (char*)piece->getBuffer(); + std::string str(out); + d_context.top()->addPiece(str); + //d_convLong = iconv_open(setlocale(LC_CTYPE, 0), "UCS-2"); + /* + iconv_t conv = iconv_open("UTF-8", "UTF-8"); + if (conv == (iconv_t)-1) { + std::string str("iconv initialization error: "); + str += strerror(errno); + throw str.c_str(); + } + size_t bytesIn = piece->size() + 1; + char *in = (char*)piece->getBuffer(); + size_t bytesOut = bytesIn; // FIXME probably not safe. + char *out = new char[bytesIn]; + char *outPtr = out; + size_t rval = iconv(conv, &in, &bytesIn, &outPtr, &bytesOut); + if (rval == (size_t)-1) { + std::string str("iconv error: "); + str += strerror(errno); + throw str.c_str(); + } + iconv_close(conv); + std::string str(out); + for (std::string::iterator it = str.begin(); it < str.end(); ++it) { + if (*it == '\r') *it = '\n'; + } + d_context.top()->addPiece(str);*/ } }; @@ -110,13 +167,32 @@ int main(int argc, char *argv[]) { if (argc < 2) { return 1; } + + // Set the locale according to the terminal's environment + setlocale(LC_ALL, ""); + std::ifstream in(argv[1], std::ios::in | std::ios::binary); - odc::Store* s = odc::importDocument(in); + + odc::Store* s; + try { + s = odc::importDocument(in); + } catch (int trap) { + std::cerr << "Exception in parsing file: BlackBox trap no. " << trap << std::endl; + return 2; + } catch (const char * exception) { + std::cerr << "Exception in parsing file: " << exception << std::endl; + return 2; + } // std::cout << s->toPlainText() << std::endl; // std::cout << std::endl << std::endl; - odc::MyVisitor visitor; - s->accept(visitor); + try { + odc::MyVisitor visitor; + s->accept(visitor); + } catch (const char * exception) { + std::cerr << "Exception in processing document: " << exception << std::endl; + return 3; + } // std::cout << s->toString() << std::endl; // std::cout << in.tellg() << " " << in.eof() << std::endl;