void ClassAdJsonUnParser:: Unparse( string &buffer, const Value &val ) { char tempBuf[512]; switch( val.GetType( ) ) { case Value::NULL_VALUE: buffer += "(null-value)"; break; case Value::STRING_VALUE: { string s; val.IsStringValue( s ); buffer += '"'; UnparseAuxEscapeString( buffer, s ); buffer += '"'; return; } case Value::INTEGER_VALUE: { long long i; val.IsIntegerValue( i ); sprintf( tempBuf, "%lld", i ); buffer += tempBuf; return; } case Value::REAL_VALUE: { double real; val.IsRealValue(real); if (real == 0.0) { // It might be positive or negative and it's // hard to tell. printf is good at telling though. // We also want to print it with as few // digits as possible, which is why we don't use the // case below. sprintf(tempBuf, "%.1f", real); buffer += tempBuf; } else if (classad_isnan(real)) { UnparseAuxQuoteExpr( buffer, "real(\"NaN\")" ); } else if (classad_isinf(real) == -1){ UnparseAuxQuoteExpr( buffer, "real(\"-INF\")" ); } else if (classad_isinf(real) == 1) { UnparseAuxQuoteExpr( buffer, "real(\"INF\")" ); } else { // Use the more user-friendly formatting of reals // that we use for old ClassAds format sprintf(tempBuf, "%.16G", real); // %G may print something that looks like an integer or exponent. // In that case, tack on a ".0" if (tempBuf[strcspn(tempBuf, ".Ee")] == '\0') { strcat(tempBuf, ".0"); } buffer += tempBuf; } return; } case Value::BOOLEAN_VALUE: { bool b; val.IsBooleanValue( b ); buffer += b ? "true" : "false"; return; } case Value::UNDEFINED_VALUE: { buffer += "null"; return; } case Value::ERROR_VALUE: { UnparseAuxQuoteExpr( buffer, "error" ); return; } case Value::ABSOLUTE_TIME_VALUE: { abstime_t asecs; string s; val.IsAbsoluteTimeValue(asecs); s += "absTime(\""; absTimeToString(asecs, s); s += "\")"; UnparseAuxQuoteExpr( buffer, s ); return; } case Value::RELATIVE_TIME_VALUE: { double rsecs; string s; val.IsRelativeTimeValue(rsecs); s += "relTime(\""; relTimeToString(rsecs, s); s += "\")"; UnparseAuxQuoteExpr( buffer, s ); return; } case Value::SCLASSAD_VALUE: case Value::CLASSAD_VALUE: { const ClassAd *ad = NULL; val.IsClassAdValue( ad ); Unparse( buffer, ad ); return; } case Value::SLIST_VALUE: case Value::LIST_VALUE: { const ExprList *el = NULL; val.IsListValue( el ); Unparse( buffer, el ); return; } default: break; } }
bool convertValueToRealValue(const Value value, Value &realValue) { bool could_convert; string buf; const char *start; const char *end; char *end_tmp; long long ivalue; time_t rtvalue; abstime_t atvalue; bool bvalue; double rvalue; Value::NumberFactor nf; switch(value.GetType()) { case Value::UNDEFINED_VALUE: realValue.SetUndefinedValue(); could_convert = false; break; case Value::ERROR_VALUE: case Value::CLASSAD_VALUE: case Value::LIST_VALUE: case Value::SLIST_VALUE: realValue.SetErrorValue(); could_convert = false; break; case Value::STRING_VALUE: could_convert = true; value.IsStringValue(buf); start = buf.c_str(); rvalue = strtod(start, &end_tmp); end = end_tmp; // On HPUX11, an input value of "INF" fails in // a strange way: end points beyond the null. if( classad_isinf(rvalue) && end > start+strlen(start) ) { end = start+strlen(start); } if (end == start && rvalue == 0.0) { // strtod() returned an error realValue.SetErrorValue(); could_convert = false; } switch (toupper( *end )) { case 'B': nf = Value::B_FACTOR; break; case 'K': nf = Value::K_FACTOR; break; case 'M': nf = Value::M_FACTOR; break; case 'G': nf = Value::G_FACTOR; break; case 'T': nf = Value::T_FACTOR; break; case '\0': nf = Value::NO_FACTOR; break; default: nf = Value::NO_FACTOR; break; } if (could_convert) { realValue.SetRealValue(rvalue*Value::ScaleFactor[nf]); } break; case Value::BOOLEAN_VALUE: value.IsBooleanValue(bvalue); realValue.SetRealValue(bvalue ? 1.0 : 0.0); could_convert = true; break; case Value::INTEGER_VALUE: value.IsIntegerValue(ivalue); realValue.SetRealValue((double)ivalue); could_convert = true; break; case Value::REAL_VALUE: realValue.CopyFrom(value); could_convert = true; break; case Value::ABSOLUTE_TIME_VALUE: value.IsAbsoluteTimeValue(atvalue); realValue.SetRealValue(atvalue.secs); could_convert = true; break; case Value::RELATIVE_TIME_VALUE: value.IsRelativeTimeValue(rtvalue); realValue.SetRealValue(rtvalue); could_convert = true; break; default: could_convert = false; // Make gcc's -Wuninitalized happy CLASSAD_EXCEPT( "Should not reach here" ); break; } return could_convert; }