summaryrefslogtreecommitdiff
path: root/src/stable/tafreader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/tafreader.cpp')
-rw-r--r--src/stable/tafreader.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/stable/tafreader.cpp b/src/stable/tafreader.cpp
new file mode 100644
index 0000000..6708c8c
--- /dev/null
+++ b/src/stable/tafreader.cpp
@@ -0,0 +1,252 @@
1/*
2 * Copyright (C) 2007-2011 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/taf.h"
9#include "bu/string.h"
10#include "bu/stream.h"
11
12#include <stdlib.h>
13
14using namespace Bu;
15
16Bu::TafReader::TafReader( Bu::Stream &sIn ) :
17 c( 0 ),
18 la( 0 ),
19 sIn( sIn ),
20 iLine( 1 ), iCol( -1 )
21{
22 next(); next();
23}
24
25Bu::TafReader::~TafReader()
26{
27
28}
29
30Bu::TafGroup *Bu::TafReader::readGroup()
31{
32 ws();
33 if( c != '{' )
34 throw TafException("%d:%d: Expected '{' got '%c'.", iLine, iCol, c );
35 next();
36 ws();
37 String sName = readStr();
38 TafGroup *pGroup = new TafGroup( sName );
39 try
40 {
41 ws();
42 if( c != ':' )
43 throw TafException("%d:%d: Expected ':' got '%c'.",
44 iLine, iCol, c );
45 next();
46 //printf("Node[%s]:\n", sName.getStr() );
47
48 groupContent( pGroup );
49
50 if( c != '}' )
51 throw TafException("%d:%d: Expected '}' got '%c'.",
52 iLine, iCol, c );
53
54 //next();
55
56 return pGroup;
57 }
58 catch(...)
59 {
60 delete pGroup;
61 throw;
62 }
63}
64
65void Bu::TafReader::groupContent( Bu::TafGroup *pGroup )
66{
67 for(;;)
68 {
69 ws();
70 if( c == '{' )
71 {
72 pGroup->addChild( readGroup() );
73 next();
74 }
75 else if( c == '}' )
76 return;
77 else if( c == '/' && la == '*' )
78 pGroup->addChild( readComment() );
79 else if( c == '/' && la == '/' )
80 pGroup->addChild( readComment( true ) );
81 else if( c == ':' )
82 throw TafException("%d:%d: Encountered stray ':' in taf stream.",
83 iLine, iCol );
84 else
85 pGroup->addChild( readProperty() );
86 }
87}
88
89Bu::TafProperty *Bu::TafReader::readProperty()
90{
91 String sName = readStr();
92 ws();
93 if( c != '=' )
94 {
95 //printf(" %s (true)\n", sName.getStr() );
96 return new Bu::TafProperty( "", sName );
97 }
98 next();
99 String sValue = readStr();
100 return new Bu::TafProperty( sName, sValue );
101 //printf(" %s = %s\n", sName.getStr(), sValue.getStr() );
102}
103
104Bu::TafComment *Bu::TafReader::readComment( bool bEOL )
105{
106 String sCmnt;
107 next();
108 if( bEOL )
109 {
110 for(;;)
111 {
112 next();
113 if( c == '\n' && la == '\r' )
114 {
115 next(); next();
116 break;
117 }
118 else if( c == '\n' || c == '\r' )
119 {
120 next();
121 break;
122 }
123 sCmnt += c;
124 }
125 }
126 else
127 {
128 for(;;)
129 {
130 next();
131 if( c == '*' && la == '/' )
132 {
133 next(); next();
134 break;
135 }
136 sCmnt += c;
137 }
138 }
139
140 return new TafComment( sCmnt, bEOL );
141}
142
143Bu::String Bu::TafReader::readStr()
144{
145 ws();
146 String s;
147 if( c == '"' )
148 {
149 next();
150 for(;;)
151 {
152 if( c == '\\' )
153 {
154 next();
155 if( c == 'x' )
156 {
157 char code[3]={'\0','\0','\0'};
158 next();
159 code[0] = c;
160 next();
161 code[1] = c;
162 c = (unsigned char)strtol( code, NULL, 16 );
163 }
164 else if( c == '"' )
165 c = '"';
166 else if( c == '\\' )
167 c = '\\';
168 else if( c == 'n' )
169 c = '\n';
170 else if( c == 't' )
171 c = '\t';
172 else
173 throw TafException("%d:%d: Invalid escape sequence '\\%c'.",
174 iLine, iCol, c );
175 }
176 else if( c == '"' )
177 break;
178 s += c;
179 next();
180 }
181 next();
182 }
183 else
184 {
185 for(;;)
186 {
187 if( isws() || c == '}' || c == '{' || c == ':' || c == '=' )
188 break;
189 s += c;
190 next();
191 }
192 }
193
194 return s;
195}
196
197void Bu::TafReader::ws()
198{
199 for(;;)
200 {
201 if( !isws() )
202 return;
203
204 next();
205 }
206}
207
208bool Bu::TafReader::isws()
209{
210 return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
211}
212
213void Bu::TafReader::next()
214{
215 if( c == '\n' )
216 {
217 iLine++;
218 iCol = 1;
219 }
220 else
221 iCol++;
222 if( c == '}' )
223 {
224 rawread( &c );
225 if( c != '}' )
226 rawread( &la );
227 }
228 else
229 {
230 c = la;
231 if( c != '}' )
232 rawread( &la );
233 }
234}
235
236void Bu::TafReader::rawread( char *c )
237{
238 if( sIn.read( c, 1 ) < 1 )
239 {
240 if( sIn.isEos() )
241 {
242 throw TafException("%d:%d: Premature end of stream.",
243 iLine, iCol, c );
244 }
245 else
246 {
247 throw TafException("%d:%d: No data read, but not end of stream?",
248 iLine, iCol, c );
249 }
250 }
251}
252