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_util.h"
00036
00037 #include "util/date.h"
00038 #include "util/parsing.h"
00039
00040 #include "common/wave_ex.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049 static const hash_value_t *
00050 getSingleValue
00051 (
00052 IN const Datahash * h,
00053 IN const char * key,
00054 IN eDatahash_Flag flag,
00055 IN eHashDataType type
00056 )
00057 {
00058 ASSERT(h, "null");
00059 ASSERT(key, "null");
00060 ASSERT(eHashDataType_Invalid != type, "Bad type");
00061
00062 int nValues = h->count(key);
00063 if (!nValues && (eDatahash_Optional & flag))
00064 return NULL;
00065 ASSERT_THROW(1 == nValues,
00066 "Expected exactly 1 value for key='" << key << "', found " <<
00067 nValues << " instead");
00068
00069 Datahash::iterator_t i;
00070 h->getIterator(key, i);
00071 const hash_value_t * phv = h->getNextElementUnsafe(i);
00072 ASSERT_THROW(phv, "No value found for key='" << key << "'");
00073 ASSERT_THROW(type == phv->type,
00074 "value at key='" << key << "' is not the proper type "
00075 << "(string vs hash)");
00076 return phv;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 const char *
00088 getString
00089 (
00090 IN const Datahash * h,
00091 IN const char * key,
00092 IN eDatahash_Flag flag
00093 )
00094 {
00095 ASSERT(h, "null");
00096 ASSERT(key, "null");
00097
00098 const hash_value_t * phv =
00099 getSingleValue(h, key, flag, eHashDataType_String);
00100 if (!phv) {
00101 return NULL;
00102 }
00103 return phv->text.c_str();
00104 }
00105
00106
00107
00108 const char *
00109 getOptionalString
00110 (
00111 IN const Datahash * h,
00112 IN const char * key,
00113 IN const char * default_value
00114 )
00115 {
00116 ASSERT(h, "null");
00117 ASSERT(key, "null");
00118
00119
00120 const char * val = getString(h, key, eDatahash_Optional);
00121 return val ? val : default_value;
00122 }
00123
00124
00125
00126 long
00127 getLong
00128 (
00129 IN const Datahash * h,
00130 IN const char * key
00131 )
00132 {
00133 ASSERT(h, "null");
00134 ASSERT(key, "null");
00135
00136 return atol(getString(h, key));
00137 }
00138
00139
00140
00141 long
00142 getOptionalLong
00143 (
00144 IN const Datahash * h,
00145 IN const char * key,
00146 IN long default_value
00147 )
00148 {
00149 ASSERT(h, "null");
00150 ASSERT(key, "null");
00151
00152 const char * val = getString(h, key, eDatahash_Optional);
00153 if (!val)
00154 return default_value;
00155 return atol(val);
00156 }
00157
00158
00159
00160 double
00161 getDouble
00162 (
00163 IN const Datahash * h,
00164 IN const char * key
00165 )
00166 {
00167 ASSERT(h, "null");
00168 ASSERT(key, "null");
00169
00170 return atof(getString(h, key));
00171 }
00172
00173
00174
00175 bool
00176 getBooleanValueFromString
00177 (
00178 IN const char * v
00179 )
00180 {
00181 ASSERT(v, "null");
00182
00183 if (!strcasecmp(v, "true") ||
00184 !strcasecmp(v, "t") ||
00185 !strcasecmp(v, "1") ||
00186 !strcasecmp(v, "yes")) {
00187
00188 return true;
00189 }
00190 if (!strcasecmp(v, "false") ||
00191 !strcasecmp(v, "f") ||
00192 !strcasecmp(v, "0") ||
00193 !strcasecmp(v, "no")) {
00194 return false;
00195 }
00196
00197
00198 {
00199 WAVE_EX(wex);
00200 wex << "Cannot determine true or false from value: " << v;
00201 }
00202
00203 return false;
00204 }
00205
00206
00207
00208 bool
00209 getBoolean
00210 (
00211 IN const Datahash * h,
00212 IN const char * key
00213 )
00214 {
00215 ASSERT(h, "null");
00216 ASSERT(key, "null");
00217
00218 return getBooleanValueFromString(getString(h, key));
00219 }
00220
00221
00222
00223 smart_ptr<Datahash>
00224 getSubhash
00225 (
00226 IN const Datahash * h,
00227 IN const char * key,
00228 IN eDatahash_Flag flag
00229 )
00230 {
00231 ASSERT(h, "null");
00232 ASSERT(key, "null");
00233
00234 const hash_value_t * phv =
00235 getSingleValue(h, key, flag, eHashDataType_Hash);
00236 if (!phv) {
00237 return NULL;
00238 }
00239 return phv->hash;
00240 }
00241
00242
00243
00244 void
00245 setTimestampAsDateString
00246 (
00247 IN Datahash * h,
00248 IN const char * key_name,
00249 IN long timestamp
00250 )
00251 {
00252 ASSERT(h, "null");
00253 ASSERT(key_name, "null");
00254
00255 std::string display;
00256 getDateStringFromNetTime(timestamp, display);
00257
00258 setValue(h, key_name, display);
00259 }
00260
00261
00262
00263 long
00264 getTimestampFromDateString
00265 (
00266 IN const Datahash * h,
00267 IN const char * key
00268 )
00269 {
00270 ASSERT(h, "null");
00271 ASSERT(key, "null");
00272
00273 std::string display = getString(h, key);
00274 return getNetTimeFromDateString(display.c_str());
00275 }
00276
00277
00278
00279 smart_ptr<Datahash>
00280 getHashFromColonString
00281 (
00282 IN const char * s
00283 )
00284 {
00285 ASSERT(s, "null");
00286
00287 smart_ptr<Datahash> hash = new Datahash;
00288 ASSERT(hash, "Failed to create empty datahash");
00289
00290
00291
00292
00293 eParseBehavior behavior = (eParseBehavior)
00294 (eParse_RespectQuotes);
00295
00296 while (*s) {
00297 std::string token;
00298 s = getNextTokenFromString(s, token, behavior);
00299 if ("" == token) {
00300 break;
00301 }
00302
00303 int i = token.find(':', 0);
00304 if ((int) std::string::npos == i) {
00305
00306 DPRINTF("Warning: malformed token: '%s'",
00307 token.c_str());
00308 continue;
00309 }
00310
00311 std::string key = token.substr(0, i);
00312 std::string value = token.substr(i + 1);
00313
00314
00315
00316
00317 hash->insert(key, value);
00318 }
00319
00320 return hash;
00321 }
00322
00323
00324
00325 void
00326 getStringValues
00327 (
00328 IN const Datahash * hash,
00329 IN const char * key,
00330 OUT VecString& vec
00331 )
00332 {
00333 ASSERT(hash, "null");
00334 ASSERT(key, "null");
00335 vec.clear();
00336
00337 Datahash::iterator_t i;
00338 hash->getIterator(key, i);
00339 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00340 if (eHashDataType_String != phv->type)
00341 continue;
00342
00343 vec.push_back(phv->text);
00344 }
00345 }
00346
00347