DEADSOFTWARE

Properly detect locale's charset
[odcread.git] / odcread.cc
index 858028e6babf5e252ede8ade0c0f71d2946ceb4e..891ea990102ba11cd63da7e952d66b4c2a3c379f 100644 (file)
@@ -9,6 +9,13 @@
 #include <textmodel.h>
 #include <visitor.h>
 
+// Character encoding conversions
+#include <langinfo.h> // determine the current charset
+#include <locale.h> // locale support
+#include <iconv.h> // charset conversions
+#include <errno.h> // error codes
+#include <string.h> // string descriptions of error codes
+
 namespace odc {
        class Context {
                public:
@@ -80,14 +87,64 @@ namespace odc {
                virtual void foldRight() {
                        terminateContext();
                }
+               char *getCharSet() {
+                       return nl_langinfo(CODESET);
+               }
                virtual void textShortPiece(const ShortPiece *piece) {
-                       std::string text = piece->getText();
-                       d_context.top()->addPiece(text);
+                       iconv_t conv = iconv_open(getCharSet(), "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) {
-                       throw "Long Piece not handled";
-                       //std::string text = piece->getText();
-                       //d_context.top()->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(getCharSet(), "UCS-2");
+                       if (conv == (iconv_t)-1) {
+                               std::string str("iconv initialization error: ");
+                               str += strerror(errno);
+                               throw str.c_str();
+                       }
+                       size_t bytesIn = piece->size() + 2;
+                       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);
                }
        };
 
@@ -112,6 +169,10 @@ 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;