sexpostream.cxx
Go to the documentation of this file.00001 #include <cstring>
00002
00003
00004
00005 #include "sexpostream.h"
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 sexp::ostream::ostream(std::streambuf* sb)
00037 : std::ostream(sb)
00038 {
00039 curAtomFlags = IOFlags::NONE;
00040 state = 0;
00041
00042 SetState(INIT);
00043 indentAmnt = 0;
00044 indentStep = 2;
00045 }
00046
00047
00048 sexp::ostream::~ostream()
00049 {
00050 }
00051
00052
00053
00054 template <>
00055 void
00056 sexp::ostream::Atom(int xflags, const char* const & val)
00057 {
00058 using namespace IOFlags;
00059
00060
00061 BegAtom(xflags);
00062 const char* outstr = (val) ? val : "";
00063 if (IsFlag(xflags, A_DQUOTE)) {
00064 EscapeString(outstr);
00065 }
00066 else {
00067 (*this) << outstr;
00068 }
00069 EndAtom();
00070 }
00071
00072
00073 void
00074 sexp::ostream::BegAtom(int xflags)
00075 {
00076 using namespace IOFlags;
00077
00078
00079 if (!IsStateQClear()) {
00080 SetStateError();
00081 throw Exception("BegAtom: Cannot begin atom!");
00082 }
00083
00084
00085 int flags = 0;
00086 if (slistStack.size() != 0) {
00087 int& f = slistStack.front();
00088 flags = f;
00089 SetFlag(f, L_NONEMPTY);
00090 }
00091
00092
00093 AddSpaceIfNecessary(flags);
00094 if (IsFlag(xflags, A_SQUOTE) || IsFlag(flags, A_SQUOTE)) {
00095 (*this) << "'";
00096 }
00097 if (IsFlag(xflags, A_DQUOTE) || IsFlag(flags, A_DQUOTE)) {
00098 (*this) << '"';
00099 }
00100 if (IsFlag(xflags, A_OCT) || IsFlag(flags, A_OCT)) {
00101 (*this) << std::oct << "0";
00102 }
00103 if (IsFlag(xflags, A_HEX) || IsFlag(flags, A_HEX)) {
00104 (*this) << std::hex << "0x";
00105 }
00106
00107 curAtomFlags = xflags;
00108
00109
00110 if (IsState(INIT)) { SetState(DEFAULT); }
00111 SetStateQ(ATOM_OPEN);
00112 SetAction(BEG_ATOM);
00113 }
00114
00115
00116 void
00117 sexp::ostream::EndAtom()
00118 {
00119 using namespace IOFlags;
00120
00121
00122 if (!IsStateQ(ATOM_OPEN)) {
00123 SetStateError();
00124 throw Exception("EndAtom: No currently open atom!");
00125 }
00126
00127
00128 int flags = 0;
00129 if (slistStack.size() != 0) {
00130 flags = slistStack.front();
00131 }
00132
00133
00134 if (IsFlag(curAtomFlags, A_DQUOTE) || IsFlag(flags, A_DQUOTE)) {
00135 (*this) << '"';
00136 }
00137 if (IsFlag(curAtomFlags, A_OCT) || IsFlag(flags, A_OCT) ||
00138 IsFlag(curAtomFlags, A_HEX) || IsFlag(flags, A_HEX)) {
00139 (*this) << std::dec;
00140 }
00141
00142 curAtomFlags = IOFlags::NONE;
00143 ResetStateQ(ATOM_OPEN);
00144 SetAction(END_ATOM);
00145 }
00146
00147
00148 void
00149 sexp::ostream::BegList(int xflags)
00150 throw (sexp::ostream::Exception)
00151 {
00152 using namespace IOFlags;
00153
00154
00155 if (!IsStateQClear()) {
00156 SetStateError();
00157 throw Exception("BegList: Cannot begin list!");
00158 }
00159
00160
00161 int flags = 0;
00162 if (slistStack.size() != 0) {
00163 int& f = slistStack.front();
00164 flags = f;
00165 SetFlag(f, L_NONEMPTY);
00166 }
00167
00168
00169 AddSpaceIfNecessary(flags);
00170
00171 (*this) << '(';
00172 IndentIncr();
00173
00174 slistStack.push_front(xflags);
00175 SetState(LIST_OPEN);
00176 SetAction(BEG_LIST);
00177 }
00178
00179
00180 void
00181 sexp::ostream::EndList()
00182 {
00183 using namespace IOFlags;
00184
00185
00186 if (!IsState(LIST_OPEN)) {
00187 SetStateError();
00188 throw Exception("EndList: Cannot end list!");
00189 }
00190
00191 int& flags = slistStack.front();
00192
00193 IndentDecr();
00194 (*this) << ")";
00195
00196
00197
00198
00199 slistStack.pop_front();
00200 if (slistStack.size() == 0) {
00201 SetState(DEFAULT);
00202 }
00203 else {
00204 SetState(LIST_OPEN);
00205 }
00206 SetAction(END_LIST);
00207 }
00208
00209
00210 void
00211 sexp::ostream::Quote()
00212 {
00213
00214 if (!IsStateQClear()) {
00215 SetStateError();
00216 throw Exception("Quote: Cannot quote!");
00217 }
00218
00219
00220 int flags = 0;
00221 if (slistStack.size() != 0) {
00222 flags = slistStack.front();
00223 }
00224
00225 AddSpaceIfNecessary(flags);
00226
00227 (*this) << "'";
00228
00229
00230 if (IsState(INIT)) { SetState(DEFAULT); }
00231 SetAction(QUOTE);
00232 }
00233
00234
00235
00236
00237 void
00238 sexp::ostream::BegComment()
00239 {
00240
00241 if (IsStateQ(COMMENT)) {
00242 SetStateError();
00243 throw Exception("BegComment: Already within a comment!");
00244 }
00245
00246 (*this) << ";; ";
00247
00248 SetStateQ(COMMENT);
00249 SetAction(BEG_COMMENT);
00250 }
00251
00252
00253 void
00254 sexp::ostream::EndComment()
00255 {
00256
00257 if (!IsStateQ(COMMENT)) {
00258 SetStateError();
00259 throw Exception("EndComment: Not within a comment!");
00260 }
00261
00262 SetAction(END_COMMENT);
00263 EndLine();
00264 ResetStateQ(COMMENT);
00265 }
00266
00267
00268 void
00269 sexp::ostream::Comment(const char* str)
00270 {
00271
00272
00273 BegComment();
00274 (*this) << str;
00275 EndComment();
00276 }
00277
00278
00279
00280
00281 void
00282 sexp::ostream::EscapeString(const char* str)
00283 {
00284 for (int i = 0; i < strlen(str); ++i) {
00285 char c = str[i];
00286 if (c == '\\' || c == '"') {
00287 (*this) << '\\';
00288 }
00289 (*this) << c;
00290 }
00291 }
00292
00293
00294
00295
00296 void
00297 sexp::ostream::EndLine()
00298 {
00299 (*this) << "\n";
00300 SetAction(END_LINE);
00301 Indent();
00302 }
00303
00304
00305 void
00306 sexp::ostream::Indent()
00307 {
00308 for (int i = 0; i < indentAmnt; ++i) {
00309 (*this) << ' ';
00310 }
00311 SetAction(INDENT);
00312 }
00313
00314
00315
00316 void
00317 sexp::ostream::AddSpaceIfNecessary(int flags)
00318 {
00319 using namespace IOFlags;
00320
00321
00322 if (WasAction(QUOTE) || WasAction(END_LINE) || WasAction(INDENT)) {
00323 return;
00324 }
00325
00326 if (IsFlag(flags, L_NONEMPTY)) {
00327 (*this) << ' ';
00328 }
00329 }