00001
00002
00003
00004
00005
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 #include "datahash_text.h"
00036
00037 #include <fstream>
00038 #include <sstream>
00039
00040 #include "common/wave_ex.h"
00041
00042 #include "perf/perf.h"
00043
00044 #include "util/file.h"
00045 #include "util/parsing.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 static smart_ptr<Datahash>
00056 readHashFromStreamInternal
00057 (
00058 IO std::istream& stream
00059 )
00060 {
00061 smart_ptr<Datahash> root = new Datahash;
00062 ASSERT(root, "failed to create empty datahash");
00063
00064 eParseBehavior behave = eParse_StripComments;
00065
00066
00067 while (!stream.eof()) {
00068 std::string line = getNextLineFromStream(stream, behave);
00069
00070
00071 std::string key_name;
00072 const char * remain =
00073 getNextTokenFromString(line.c_str(), key_name, behave);
00074
00075
00076 if ("" == key_name) {
00077 continue;
00078 }
00079
00080
00081 if ("}" == key_name)
00082 break;
00083
00084
00085 while (*remain && isspace((byte_t) *remain)) {
00086 ++remain;
00087 }
00088
00089
00090 long N = strlen(remain);
00091 while (N > 0 && isspace((byte_t) remain[N - 1])) {
00092 --N;
00093 }
00094
00095 std::string value;
00096 for (long l = 0; l < N; ++l) {
00097 value += remain[l];
00098 }
00099
00100
00101
00102
00103 if (!strcmp("{", value.c_str())) {
00104
00105 smart_ptr<Datahash> hash =
00106 readHashFromStream(key_name.c_str(), stream);
00107 ASSERT(hash, "null value after reading subhash");
00108
00109
00110 root->insert(key_name, hash);
00111 } else {
00112
00113 root->insert(key_name, value);
00114 }
00115 }
00116
00117
00118 return root;
00119 }
00120
00121
00122
00123 static void
00124 newlineAndIndent
00125 (
00126 IO std::ostream& stream,
00127 IN int indent
00128 )
00129 throw()
00130 {
00131 ASSERT(indent >= 0, "bad indent value");
00132
00133 stream << "\n";
00134 for (int i = 0; i < indent; i++) {
00135 stream << "\t";
00136 }
00137 }
00138
00139
00140
00141 void
00142 writeHashToStreamInternal
00143 (
00144 IN const Datahash * hash,
00145 IO std::ostream& stream,
00146 IN int indent
00147 )
00148 {
00149 ASSERT(hash, "NULL hash");
00150 ASSERT(indent >= 0, "Bad indent value");
00151
00152
00153 Datahash::iterator_t i;
00154 hash->getIterator(i);
00155 std::string k;
00156 while (const hash_value_t * phv = hash->getNextElementUnsafe(i, k)) {
00157 ASSERT(phv, "null?");
00158 const char * key = k.c_str();
00159 ASSERT(key, "null");
00160
00161
00162 if (eHashDataType_String == phv->type) {
00163 newlineAndIndent(stream, indent);
00164 stream << key << "\t" << phv->text;
00165 } else {
00166
00167 newlineAndIndent(stream, indent);
00168 stream << key << " {";
00169 writeHashToStreamInternal(phv->hash, stream, indent + 1);
00170 newlineAndIndent(stream, indent);
00171 stream << "}\n";
00172 }
00173 }
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 smart_ptr<Datahash>
00185 readHashFromStream
00186 (
00187 IN const char * key_name,
00188 IO std::istream& stream
00189 )
00190 {
00191 perf::Timer timer("readHashFromStream");
00192 ASSERT(key_name, "null");
00193
00194 try {
00195 return readHashFromStreamInternal(stream);
00196 } catch (std::exception& e) {
00197 WAVE_EX(wex);
00198 wex << "Failed to read hash with key name: " << key_name;
00199 wex << "\n";
00200 wex << e.what();
00201 }
00202
00203 ASSERT(false, "should never get here");
00204 return NULL;
00205 }
00206
00207
00208
00209 smart_ptr<Datahash>
00210 readHashFromTextFile
00211 (
00212 IN const char * filename
00213 )
00214 {
00215 perf::Timer timer("readHashFromTextFile");
00216 ASSERT(filename, "NULL filename");
00217
00218
00219 std::ifstream stream(filename);
00220 if (!stream.good()) {
00221 WAVE_EX(wex);
00222 wex << "Failed to open file for reading: " << filename;
00223 }
00224
00225 try {
00226 return readHashFromStream("(root element)", stream);
00227 } catch (std::exception& e) {
00228 WAVE_EX(wex);
00229 wex << "Failure while reading from file: " << filename;
00230 wex << "\n";
00231 wex << e.what();
00232 }
00233
00234 ASSERT(false, "should never get here");
00235 return NULL;
00236 }
00237
00238
00239
00240 smart_ptr<Datahash>
00241 readHashFromString
00242 (
00243 IN const char * val
00244 )
00245 {
00246 ASSERT(val, "null");
00247
00248 std::istringstream iss(val);
00249 return readHashFromStream("root", iss);
00250 }
00251
00252
00253
00254 void
00255 writeHashToStream
00256 (
00257 IN const Datahash * hash,
00258 IO std::ostream& stream
00259 )
00260 {
00261 perf::Timer timer("writeHashToStream");
00262 ASSERT(hash, "null");
00263
00264 writeHashToStreamInternal(hash, stream, 0);
00265 }
00266
00267
00268
00269 void
00270 writeHashToTextFile
00271 (
00272 IN const Datahash * hash,
00273 IN const char * filename,
00274 IN const char * comment_at_top_of_file
00275 )
00276 {
00277 perf::Timer timer("writeHashToTextFile");
00278 ASSERT(hash, "NULL hash");
00279 ASSERT(filename, "NULL filename");
00280
00281
00282
00283 std::string tmpfile = filename;
00284 tmpfile += ".data.tmp";
00285
00286 {
00287
00288 std::ofstream stream(tmpfile.c_str());
00289 if (!stream.good()) {
00290 WAVE_EX(wex);
00291 wex << "Failed to open file for writing: " << tmpfile;
00292 }
00293
00294
00295 if (comment_at_top_of_file) {
00296 stream << comment_at_top_of_file << "\n";
00297 }
00298
00299
00300 writeHashToStreamInternal(hash, stream, 0);
00301
00302
00303 stream << "\n";
00304
00305 stream.flush();
00306 }
00307
00308
00309 if (rename(tmpfile.c_str(), filename)) {
00310 WAVE_EX(wex);
00311 wex << "Failed to rename from " << tmpfile << " to ";
00312 wex << filename;
00313 }
00314 }
00315
00316
00317
00318 void
00319 dumpHash
00320 (
00321 IN const char * title,
00322 IN const Datahash * hash
00323 )
00324 {
00325 ASSERT(title, "null");
00326 ASSERT(hash, "null");
00327
00328 std::ostringstream oss;
00329 writeHashToStream(hash, oss);
00330
00331 DPRINTF("HASH DUMP %s:\n%s", title, oss.str().c_str());
00332 }
00333