void s_print_value(PullParser& data_parser){ const bnj_val& v = data_parser.GetValue(); unsigned type = bnj_val_type(&v); switch(type){ case BNJ_NUMERIC: /* If nonzero exponent, then float. */ if(v.exp_val){ double d; BNJ::Get(d, data_parser); printf("%lf", d); } else{ if(v.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND){ int d; BNJ::Get(d, data_parser); printf("%i", d); } else{ unsigned d; BNJ::Get(d, data_parser); printf("%u", d); } } break; case BNJ_STRING: /* TODO loop to get entire string value..for now just output fixed chars. */ { char buffer[1024]; data_parser.ChunkRead8(buffer, 1024); printf("%s", buffer); } break; case BNJ_SPECIAL: { static const char* special[BNJ_COUNT_SPC] = { "false", "true", "null", "NaN", "Infinity" }; unsigned idx = bnj_val_special(&v); if(BNJ_SPC_INFINITY == idx && (v.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND)){ printf("-Infinity"); } else{ printf("%s", special[idx]); } } break; default: throw PullParser::invalid_value("Expecting simple value!", data_parser); } }
unsigned BNJ::GetKey(char* dest, unsigned destlen, const PullParser& p){ const bnj_val& val = p.GetValue(); if(dest){ if(val.key_length > destlen) throw std::runtime_error("First key value overlong!"); return bnj_stpkeycpy(dest, &val, p.Buff()) - dest; } return 0; }
void BNJ::VerifyMap(const PullParser& p, unsigned key_enum){ if(key_enum != 0xFFFFFFFF){ const bnj_val& val = p.GetValue(); if(val.key_enum != key_enum) s_throw_key_error(p, key_enum); } if(p.GetState() != PullParser::ST_MAP) throw std::runtime_error("Value is not map!"); }
void BNJ::VerifyNull(const PullParser& p, unsigned key_enum){ const bnj_val& val = p.GetValue(); if(key_enum != 0xFFFFFFFF && val.key_enum != key_enum) s_throw_key_error(p, key_enum); if(bnj_val_type(&val) != BNJ_SPECIAL || val.significand_val != BNJ_SPC_NULL) { s_throw_type_error(p, BNJ_SPECIAL); } }
void BNJ::Get(unsigned& u, const PullParser& p, unsigned key_enum){ const bnj_val& val = p.GetValue(); if(key_enum != 0xFFFFFFFF && val.key_enum != key_enum) s_throw_key_error(p, key_enum); if(bnj_val_type(&val) != BNJ_NUMERIC) s_throw_type_error(p, BNJ_NUMERIC); if(val.exp_val) throw std::runtime_error("Non-integral numeric value!"); /* Check sign. */ if(val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND) throw std::runtime_error("Must be nonnegative!"); u = val.significand_val; }
void BNJ::Get(int& ret, const PullParser& p, unsigned key_enum){ const bnj_val& val = p.GetValue(); if(key_enum != 0xFFFFFFFF && val.key_enum != key_enum) s_throw_key_error(p, key_enum); if(bnj_val_type(&val) != BNJ_NUMERIC) s_throw_type_error(p, BNJ_NUMERIC); if(val.exp_val) throw std::runtime_error("Non-integral numeric value!"); if(val.significand_val > LONG_MAX) throw std::runtime_error("Out of range integer!"); ret = val.significand_val; if(val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND) ret = -ret; }
void BNJ::Get(bool& b, const PullParser& p, unsigned key_enum){ const bnj_val& val = p.GetValue(); if(key_enum != 0xFFFFFFFF && val.key_enum != key_enum) s_throw_key_error(p, key_enum); unsigned t = bnj_val_type(&val); if(BNJ_SPECIAL == t){ if(BNJ_SPC_FALSE == val.significand_val){ b = false; return; } else if(BNJ_SPC_TRUE == val.significand_val){ b = true; return; } } s_throw_type_error(p, BNJ_SPECIAL); }
void BNJ::Get(double& d, const PullParser& p, unsigned key_enum){ const bnj_val& val = p.GetValue(); if(key_enum != 0xFFFFFFFF && val.key_enum != key_enum) s_throw_key_error(p, key_enum); unsigned t = bnj_val_type(&val); if(BNJ_NUMERIC == t){ d = bnj_double(&val); } else if(BNJ_SPECIAL == t && val.significand_val > BNJ_SPC_NULL){ if(BNJ_SPC_NAN == t) d = NAN; else d = (val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND) ? -INFINITY: INFINITY; } else s_throw_type_error(p, BNJ_NUMERIC); }