filters

rtfimport_tokenizer.cpp
1/*
2 This file is part of the KDE project
3 Copyright (C) 2001 Ewald Snel <ewald@rambo.its.tudelft.nl>
4 Copyright (C) 2001 Tomasz Grobelny <grotk@poczta.onet.pl>
5 Copyright (C) 2005 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11*/
12
13#include <kdebug.h>
14
15#include "rtfimport_tokenizer.h"
16
17
18RTFTokenizer::RTFTokenizer()
19{
20 tokenText.resize( 4113 );
21 fileBuffer.resize( 4096 );
22 infile = 0L;
23}
24
29void RTFTokenizer::open( TQFile *in )
30{
31 fileBufferPtr = 0L;
32 fileBufferEnd = 0L;
33 infile = in;
34 type = RTFTokenizer::PlainText;
35}
36
37int RTFTokenizer::nextChar()
38{
39 if ( fileBufferPtr == fileBufferEnd ) {
40 int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
41 fileBufferPtr = ( uchar* ) fileBuffer.data();
42 fileBufferEnd = fileBufferPtr;
43
44 if ( n <= 0 )
45 return -1;
46
47 fileBufferEnd = fileBufferPtr + n;
48 }
49 return *fileBufferPtr++;
50}
51
52
57{
58 int ch;
59 value=0;
60 if (!infile)
61 return;
62
63 do {
64 int n = nextChar();
65
66 if ( n <= 0 ) {
67 ch = '}';
68 break;
69 }
70
71 ch = n;
72 }
73 while (ch == '\n' || ch == '\r' && ch != 0);
74
75 // Skip one byte for prepend '@' to destinations
76 text = (tokenText.data() + 1);
77 hasParam = false;
78
79 uchar *_text = (uchar *)text;
80
81
82 if (ch == '{')
83 type = RTFTokenizer::OpenGroup;
84 else if (ch == '}')
85 type = RTFTokenizer::CloseGroup;
86 else if (ch == '\\')
87 {
88 type = RTFTokenizer::ControlWord;
89
90 int n = nextChar();
91
92 if ( n <= 0 ) {
93 // Return CloseGroup on EOF
94 type = RTFTokenizer::CloseGroup;
95 return;
96 }
97 ch = n;
98
99 // Type is either control word or control symbol
100 if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
101 {
102 int v = 0;
103
104 // Read alphabetic string (command)
105 while (_text < ( uchar* )tokenText.data()+tokenText.size()-3 &&
106 ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) )
107 {
108 *_text++ = ch;
109
110 int n = nextChar();
111 if ( n <= 0 ) {
112 ch = ' ';
113 break;
114 }
115 ch = n;
116 }
117
118 // Read numeric parameter (param)
119 bool isneg = (ch == '-');
120
121 if (isneg) {
122 int n = nextChar();
123 if ( n <= 0 ) {
124 type = RTFTokenizer::CloseGroup;
125 return;
126 }
127 ch = n;
128 }
129
130 while (ch >= '0' && ch <= '9') {
131 v = (10 * v) + ch - '0';
132 hasParam = true;
133
134 int n = nextChar();
135
136 if ( n <= 0 )
137 n = ' ';
138 ch = n;
139 }
140 value = isneg ? -v : v;
141
142 // If delimiter is a space, it's part of the control word
143 if (ch != ' ')
144 {
145 --fileBufferPtr;
146 }
147
148 *_text = 0; // Just put an end of string for the test, it can then be over-written again
149 if ( !memcmp( tokenText.data()+1, "bin", 4 ) )
150 { // We have \bin, so we need to read the bytes
151 kdDebug(30515) << "Token:" << tokenText << endl;
152 if (value > 0)
153 {
154 kdDebug(30515) << "\\bin" << value << endl;
155 type = RTFTokenizer::BinaryData;
156 binaryData.resize(value);
157 for (int i=0; i<value; i++)
158 {
159 int n = nextChar();
160 if ( n <= 0 ) {
161 type = RTFTokenizer::CloseGroup;
162 break;
163 }
164
165 binaryData[i] = n;
166 }
167 }
168 }
169
170 }
171 else if (ch=='\'')
172 {
173 // Got hex value, for example \'2d
174
175 type = RTFTokenizer::ControlWord;
176 *_text++ = ch;
177
178 for(int i=0;i<2;i++)
179 {
180 int n = nextChar();
181
182 if ( n <= 0 ) {
183 if ( i == 0 ) {
184 type = RTFTokenizer::CloseGroup;
185 return;
186 } else {
187 ch = ' ';
188 break;
189 }
190 }
191
192 ch = n;
193
194 hasParam = true;
195 value<<=4;
196 value=value|((ch + ((ch & 16) ? 0 : 9)) & 0xf);
197 }
198 }
199 else
200 {
201 type = RTFTokenizer::ControlWord;
202 *_text++ = ch;
203 }
204 }
205 else
206 {
207 type = RTFTokenizer::PlainText;
208
209 // Everything until next backslash, opener or closer
210 while ( ch != '\\' && ch != '{' && ch != '}' && ch != '\n' &&
211 ch != '\r')
212 {
213 *_text++ = ch;
214 if(fileBufferPtr >= fileBufferEnd)
215 break;
216 ch = *fileBufferPtr++;
217 }
218 if(fileBufferPtr < fileBufferEnd)
219 --fileBufferPtr; // give back the last char
220 }
221 *_text++ = 0;
222
223}
void open(TQFile *in)
Open tokenizer from file.
void next()
Reads the next token.
TQByteArray binaryData
Binary data (of \bin keyword).
char * text
plain text or control word/symbol
int value
numeric parameter
bool hasParam
token has a (numeric) parameter