diff options
Diffstat (limited to 'src/tafreader.cpp')
-rw-r--r-- | src/tafreader.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/tafreader.cpp b/src/tafreader.cpp new file mode 100644 index 0000000..db465e9 --- /dev/null +++ b/src/tafreader.cpp | |||
@@ -0,0 +1,155 @@ | |||
1 | #include "bu/tafreader.h" | ||
2 | #include "bu/exceptions.h" | ||
3 | #include "bu/fstring.h" | ||
4 | |||
5 | using namespace Bu; | ||
6 | |||
7 | Bu::TafReader::TafReader( Bu::Stream &sIn ) : | ||
8 | c( 0 ), | ||
9 | sIn( sIn ) | ||
10 | { | ||
11 | next(); next(); | ||
12 | } | ||
13 | |||
14 | Bu::TafReader::~TafReader() | ||
15 | { | ||
16 | |||
17 | } | ||
18 | |||
19 | Bu::TafGroup *Bu::TafReader::readGroup() | ||
20 | { | ||
21 | ws(); | ||
22 | if( c != '{' ) | ||
23 | throw TafException("Expected '{'"); | ||
24 | next(); | ||
25 | ws(); | ||
26 | FString sName = readStr(); | ||
27 | TafGroup *pGroup = new TafGroup( sName ); | ||
28 | next(); | ||
29 | //printf("Node[%s]:\n", sName.getStr() ); | ||
30 | |||
31 | groupContent( pGroup ); | ||
32 | |||
33 | if( c != '}' ) | ||
34 | throw TafException("Expected '}'"); | ||
35 | |||
36 | next(); | ||
37 | |||
38 | return pGroup; | ||
39 | } | ||
40 | |||
41 | void Bu::TafReader::groupContent( Bu::TafGroup *pGroup ) | ||
42 | { | ||
43 | for(;;) | ||
44 | { | ||
45 | ws(); | ||
46 | if( c == '{' ) | ||
47 | pGroup->addChild( readGroup() ); | ||
48 | else if( c == '}' ) | ||
49 | return; | ||
50 | else if( c == '/' && la == '*' ) | ||
51 | pGroup->addChild( readComment() ); | ||
52 | else | ||
53 | pGroup->addChild( readProperty() ); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | Bu::TafProperty *Bu::TafReader::readProperty() | ||
58 | { | ||
59 | FString sName = readStr(); | ||
60 | ws(); | ||
61 | if( c != '=' ) | ||
62 | { | ||
63 | //printf(" %s (true)\n", sName.getStr() ); | ||
64 | return new Bu::TafProperty( sName, "" ); | ||
65 | } | ||
66 | next(); | ||
67 | FString sValue = readStr(); | ||
68 | return new Bu::TafProperty( sName, sValue ); | ||
69 | //printf(" %s = %s\n", sName.getStr(), sValue.getStr() ); | ||
70 | } | ||
71 | |||
72 | Bu::TafComment *Bu::TafReader::readComment() | ||
73 | { | ||
74 | next(); | ||
75 | FString sCmnt; | ||
76 | for(;;) | ||
77 | { | ||
78 | next(); | ||
79 | if( c == '*' && la == '/' ) | ||
80 | break; | ||
81 | sCmnt += c; | ||
82 | } | ||
83 | |||
84 | return new TafComment( sCmnt ); | ||
85 | } | ||
86 | |||
87 | Bu::FString Bu::TafReader::readStr() | ||
88 | { | ||
89 | ws(); | ||
90 | FString s; | ||
91 | if( c == '"' ) | ||
92 | { | ||
93 | next(); | ||
94 | for(;;) | ||
95 | { | ||
96 | if( c == '\\' ) | ||
97 | { | ||
98 | next(); | ||
99 | if( c == 'x' ) | ||
100 | { | ||
101 | char code[3]={'\0','\0','\0'}; | ||
102 | next(); | ||
103 | code[0] = c; | ||
104 | next(); | ||
105 | code[1] = c; | ||
106 | c = (unsigned char)strtol( code, NULL, 16 ); | ||
107 | } | ||
108 | else if( c == '"' ) | ||
109 | c = '"'; | ||
110 | else | ||
111 | throw TafException("Invalid escape sequence."); | ||
112 | } | ||
113 | else if( c == '"' ) | ||
114 | break; | ||
115 | s += c; | ||
116 | next(); | ||
117 | } | ||
118 | next(); | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | for(;;) | ||
123 | { | ||
124 | if( isws() || c == '}' || c == '{' || c == ':' || c == '=' ) | ||
125 | break; | ||
126 | s += c; | ||
127 | next(); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return s; | ||
132 | } | ||
133 | |||
134 | void Bu::TafReader::ws() | ||
135 | { | ||
136 | for(;;) | ||
137 | { | ||
138 | if( !isws() ) | ||
139 | return; | ||
140 | |||
141 | next(); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | bool Bu::TafReader::isws() | ||
146 | { | ||
147 | return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); | ||
148 | } | ||
149 | |||
150 | void Bu::TafReader::next() | ||
151 | { | ||
152 | c = la; | ||
153 | sIn.read( &la, 1 ); | ||
154 | } | ||
155 | |||