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>
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
14
#include "rtfimport_tokenizer.h"
17
RTFTokenizer::RTFTokenizer()
19
tokenText.resize( 4112 );
20
fileBuffer.resize( 4096 );
25
* Open tokenizer from file.
26
* @param in the input file
28
void RTFTokenizer::open( QFile *in )
36
* Reads the next token.
38
void RTFTokenizer::next()
47
if (fileBufferPtr == fileBufferEnd)
49
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
53
// Return CloseGroup on EOF
57
fileBufferPtr = (uchar *)fileBuffer.data();
58
fileBufferEnd = (fileBufferPtr + n);
60
ch = *fileBufferPtr++;
62
while (ch == '\n' || ch == '\r' && ch != 0);
64
// Skip one byte for prepend '@' to destinations
65
text = (tokenText.data() + 1);
68
uchar *_text = (uchar *)text;
71
type = RTFTokenizer::OpenGroup;
73
type = RTFTokenizer::CloseGroup;
76
type = RTFTokenizer::ControlWord;
78
if (fileBufferPtr == fileBufferEnd)
80
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
84
// Return CloseGroup on EOF
85
type = RTFTokenizer::CloseGroup;
88
fileBufferPtr = (uchar *)fileBuffer.data();
89
fileBufferEnd = (fileBufferPtr + n);
91
ch = *fileBufferPtr++;
93
// Type is either control word or control symbol
94
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
98
// Read alphabetic string (command)
99
while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
103
if (fileBufferPtr == fileBufferEnd)
105
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
112
fileBufferPtr = (uchar *)fileBuffer.data();
113
fileBufferEnd = (fileBufferPtr + n);
115
ch = *fileBufferPtr++;
118
// Read numeric parameter (param)
119
bool isneg = (ch == '-');
123
if (fileBufferPtr == fileBufferEnd)
125
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
129
// Return CloseGroup on EOF
130
type = RTFTokenizer::CloseGroup;
133
fileBufferPtr = (uchar *)fileBuffer.data();
134
fileBufferEnd = (fileBufferPtr + n);
136
ch = *fileBufferPtr++;
138
while (ch >= '0' && ch <= '9')
140
v = (10 * v) + ch - '0';
143
if (fileBufferPtr == fileBufferEnd)
145
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
152
fileBufferPtr = (uchar *)fileBuffer.data();
153
fileBufferEnd = (fileBufferPtr + n);
155
ch = *fileBufferPtr++;
157
value = isneg ? -v : v;
159
// If delimiter is a space, it's part of the control word
165
*_text = 0; // Just put an end of string for the test, it can then be over-written again
166
if ( !qstrncmp( tokenText.data()+1, "bin", 4 ) ) // Test the NULL too to avoid catching keywords starting with "bin"
167
{ // We have \bin, so we need to read the bytes
168
kdDebug(30515) << "Token:" << tokenText << endl;
171
kdDebug(30515) << "\\bin" << value << endl;
172
type = RTFTokenizer::BinaryData;
173
binaryData.resize(value);
174
for (int i=0; i<value; i++)
176
if (fileBufferPtr == fileBufferEnd)
178
const int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
182
kdError(30515) << "\\bin stream hit end of file." << endl;
183
type = RTFTokenizer::CloseGroup;
186
fileBufferPtr = (uchar *)fileBuffer.data();
187
fileBufferEnd = (fileBufferPtr + n);
189
binaryData[i]=*fileBufferPtr++;
194
kdError(30515) << "\\bin with negative value skipping" << endl;
201
type = RTFTokenizer::ControlWord;
203
if (fileBufferPtr == fileBufferEnd)
205
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
209
// Return CloseGroup on EOF
210
type = RTFTokenizer::CloseGroup;
213
fileBufferPtr = (uchar *)fileBuffer.data();
214
fileBufferEnd = (fileBufferPtr + n);
216
ch = *fileBufferPtr++;
221
value=value|((ch + ((ch & 16) ? 0 : 9)) & 0xf);
223
if (fileBufferPtr == fileBufferEnd)
225
int n = infile->readBlock( fileBuffer.data(), fileBuffer.size() );
232
fileBufferPtr = (uchar *)fileBuffer.data();
233
fileBufferEnd = (fileBufferPtr + n);
235
ch = *fileBufferPtr++;
241
type = RTFTokenizer::ControlWord;
247
type = RTFTokenizer::PlainText;
249
// Everything until next backslash, opener or closer
250
while ( ch != '\\' && ch != '{' && ch != '}' && ch != '\n' &&
251
ch != '\r' && fileBufferPtr <= fileBufferEnd )
254
ch = *fileBufferPtr++;
257
// Give back last char