//Grab character, with appropriate error handling char Item_factory::char_from_json(Item_tag new_id, Item_tag index, picojson::value::object value_map){ std::string symbol = string_from_json(new_id, index, value_map); if(symbol == ""){ std::cerr << "Item "<< new_id << " attribute " << "was skipped, empty string not allowed." << std::endl; return 'X'; } return symbol[0]; }
//Grab color, with appropriate error handling nc_color Item_factory::color_from_json(Item_tag new_id, Item_tag index, picojson::value::object value_map){ std::string new_color = string_from_json(new_id, index, value_map); if("red"==new_color){ return c_red; } else if("blue"==new_color){ return c_blue; } else if("green"==new_color){ return c_green; } else { std::cerr << "Item "<< new_id << " attribute name was skipped, not a color. Color is required." << std::endl; return c_white; } }
uint8_t test_string_from_json ( ) { uint8_t json[] = "{ \"foo\": { \"bar\": \"whee\" }, \"grr\": [1, 2, 3], \"baz\": \"2.0\" }"; uint8_t *parts = (uint8_t *) "foo.bar"; uint8_t *parts2 = (uint8_t *) "baz"; uint8_t *buf; JsonContext *ctx; ctx = create_json_context(); buf = string_from_json(ctx, json, parts); check(strcmp((char *) buf, "whee") == 0, "string_from_json returns correct value for nested keys"); free(buf); buf = string_from_json(ctx, json, parts2); check(strcmp((char *) buf, "2.0") == 0, "string_from_json returns correct value for normal keys"); free(buf); check((string_from_json(ctx, json, (uint8_t *) "whee") == NULL), "string_from_json returns NULL for unknown keys"); check((ctx->error == 3), "and error is set to 3"); destroy_json_context(ctx); done(); }
// Load values from this data file into m_templates // TODO: Consider appropriate location for this code. Is this really where it belongs? // At the very least, it seems the json blah_from methods could be used elsewhere void Item_factory::load_item_templates_from(const std::string file_name){ std::ifstream data_file; picojson::value input_value; data_file.open(file_name.c_str()); data_file >> input_value; data_file.close(); //Handle any obvious errors on file load std::string err = picojson::get_last_error(); if (! err.empty()) { std::cerr << "In JSON file \"" << file_name << "\"" << data_file << ":" << err << std::endl; exit(1); } if (! input_value.is<picojson::array>()) { std::cerr << file_name << " is not an array of item_templates" << std::endl; exit(2); } //Crawl through and extract the items const picojson::array& all_items = input_value.get<picojson::array>(); for (picojson::array::const_iterator entry = all_items.begin(); entry != all_items.end(); ++entry) { if( !(entry->is<picojson::object>()) ){ std::cerr << "Invalid item definition, entry not a JSON object" << std::endl; } else{ const picojson::value::object& entry_body = entry->get<picojson::object>(); // The one element we absolutely require for an item definition is an id picojson::value::object::const_iterator key_pair = entry_body.find("id"); if( key_pair == entry_body.end() || !(key_pair->second.is<std::string>()) ){ std::cerr << "Item definition skipped, no id found or id was malformed." << std::endl; } else { Item_tag new_id = key_pair->second.get<std::string>(); // If everything works out, add the item to the group list... // unless a similar item is already there if(m_templates.find(new_id) != m_templates.end()){ std::cerr << "Item definition skipped, id " << new_id << " already exists." << std::endl; } else { itype* new_item_template = new itype(); new_item_template->id = new_id; m_templates[new_id] = new_item_template; // And then proceed to assign the correct field new_item_template->rarity = int_from_json(new_id, "rarity", entry_body); new_item_template->name = string_from_json(new_id, "name", entry_body); new_item_template->sym = char_from_json(new_id, "symbol", entry_body); new_item_template->color = color_from_json(new_id, "color", entry_body); new_item_template->description = string_from_json(new_id, "description", entry_body); new_item_template->m1 = material_from_json(new_id, "material", entry_body, 0); new_item_template->m2 = material_from_json(new_id, "material", entry_body, 1); new_item_template->volume = int_from_json(new_id, "volume", entry_body); new_item_template->weight = int_from_json(new_id, "weight", entry_body); new_item_template->melee_dam = int_from_json(new_id, "damage", entry_body); new_item_template->melee_cut = int_from_json(new_id, "cutting", entry_body); new_item_template->m_to_hit = int_from_json(new_id, "to_hit", entry_body); } } } } }