12 // Character encoding conversions
13 #include <langinfo.h> // determine the current charset
14 #include <locale.h> // locale support
15 #include <iconv.h> // charset conversions
16 #include <errno.h> // error codes
17 #include <string.h> // string descriptions of error codes
22 virtual void addPiece(std::string
&piece
) = 0;
23 virtual std::string
getPlainText() const = 0;
25 class PartContext
: public Context
{
29 virtual void addPiece(std::string
&piece
) {
32 virtual std::string
getPlainText() const {
36 class FoldContext
: public Context
{
39 bool d_haveFirst
; // flag that first part has been set
40 std::string d_firstPart
;
41 std::string d_remainder
;
43 FoldContext(bool collapsed
) : d_collapsed(collapsed
), d_haveFirst(false) {}
44 virtual void addPiece(std::string
&piece
) {
52 virtual std::string
getPlainText() const {
54 return std::string("##=>") + d_remainder
+ "\n" + d_firstPart
+"##<=";
56 return std::string("##=>") + d_firstPart
+ "\n" + d_remainder
+"##<=";
61 class MyVisitor
: public Visitor
{
63 std::stack
<Context
*> d_context
;
65 void terminateContext() {
66 Context
*c
= d_context
.top();
68 if (d_context
.empty()) {
69 std::cout
<< c
->getPlainText() << std::endl
;
71 std::string text
= c
->getPlainText();
72 d_context
.top()->addPiece(text
);
78 virtual void partStart() {
79 d_context
.push(new PartContext());
81 virtual void partEnd() {
84 virtual void foldLeft(bool collapsed
) {
85 d_context
.push(new FoldContext(collapsed
));
87 virtual void foldRight() {
91 return nl_langinfo(CODESET
);
93 virtual void textShortPiece(const ShortPiece
*piece
) {
94 iconv_t conv
= iconv_open(getCharSet(), "ISO-8859-1");
95 if (conv
== (iconv_t
)-1) {
96 std::string
str("iconv initialization error: ");
97 str
+= strerror(errno
);
100 size_t bytesIn
= piece
->size() + 1;
101 SHORTCHAR
*in
= piece
->getBuffer();
102 size_t bytesOut
= bytesIn
; // FIXME probably not safe.
103 char *out
= new char[bytesIn
];
105 size_t rval
= iconv(conv
, &in
, &bytesIn
, &outPtr
, &bytesOut
);
106 if (rval
== (size_t)-1) {
107 std::string
str("iconv error: ");
108 str
+= strerror(errno
);
112 std::string
str(out
);
113 for (std::string::iterator it
= str
.begin(); it
< str
.end(); ++it
) {
114 if (*it
== '\r') *it
= '\n';
116 d_context
.top()->addPiece(str
);
118 virtual void textLongPiece(const LongPiece
*piece
) {
120 char *out = (char*)piece->getBuffer();
121 std::string str(out);
122 d_context.top()->addPiece(str);
124 //d_convLong = iconv_open(setlocale(LC_CTYPE, 0), "UCS-2");
125 iconv_t conv
= iconv_open(getCharSet(), "UCS-2");
126 if (conv
== (iconv_t
)-1) {
127 std::string
str("iconv initialization error: ");
128 str
+= strerror(errno
);
131 size_t bytesIn
= piece
->size() + 2;
132 char *in
= (char*)piece
->getBuffer();
133 size_t bytesOut
= bytesIn
; // FIXME probably not safe.
134 char *out
= new char[bytesIn
];
136 size_t rval
= iconv(conv
, &in
, &bytesIn
, &outPtr
, &bytesOut
);
137 if (rval
== (size_t)-1) {
138 std::string
str("iconv error: ");
139 str
+= strerror(errno
);
143 std::string
str(out
);
144 for (std::string::iterator it
= str
.begin(); it
< str
.end(); ++it
) {
145 if (*it
== '\r') *it
= '\n';
147 d_context
.top()->addPiece(str
);
151 Store
* importDocument(std::istream
&is
) {
152 const INTEGER docTag
= 0x6F4F4443;
153 const INTEGER docVersion
= 0;
155 INTEGER tag
= r
.readInt();
157 INTEGER version
= r
.readInt();
158 if (version
!= docVersion
) {
161 Store
*s
= r
.readStore();
168 int main(int argc
, char *argv
[]) {
173 // Set the locale according to the terminal's environment
174 setlocale(LC_ALL
, "");
176 std::ifstream
in(argv
[1], std::ios::in
| std::ios::binary
);
180 s
= odc::importDocument(in
);
182 std::cerr
<< "Exception in parsing file: BlackBox trap no. " << trap
<< std::endl
;
184 } catch (const char * exception
) {
185 std::cerr
<< "Exception in parsing file: " << exception
<< std::endl
;
188 // std::cout << s->toPlainText() << std::endl;
189 // std::cout << std::endl << std::endl;
192 odc::MyVisitor visitor
;
194 } catch (const char * exception
) {
195 std::cerr
<< "Exception in processing document: " << exception
<< std::endl
;
198 // std::cout << s->toString() << std::endl;
199 // std::cout << in.tellg() << " " << in.eof() << std::endl;
201 // odc::TypePath path;
202 // odc::ContainerModel(0).getTypePath(&path);
203 // std::cout << path.toString() << std::endl;