/** * Reads engine info from a JsonObject. */ void vpart_info::load_engine( cata::optional<vpslot_engine> &eptr, JsonObject &jo, const itype_id &fuel_type ) { vpslot_engine e_info; if( eptr ) { e_info = *eptr; } assign( jo, "backfire_threshold", e_info.backfire_threshold ); assign( jo, "backfire_freq", e_info.backfire_freq ); assign( jo, "noise_factor", e_info.noise_factor ); assign( jo, "damaged_power_factor", e_info.damaged_power_factor ); assign( jo, "m2c", e_info.m2c ); assign( jo, "muscle_power_factor", e_info.muscle_power_factor ); auto excludes = jo.get_array( "exclusions" ); if( !excludes.empty() ) { e_info.exclusions.clear(); while( excludes.has_more() ) { e_info.exclusions.push_back( excludes.next_string() ); } } auto fuel_opts = jo.get_array( "fuel_options" ); if( !fuel_opts.empty() ) { e_info.fuel_opts.clear(); while( fuel_opts.has_more() ) { e_info.fuel_opts.push_back( itype_id( fuel_opts.next_string() ) ); } } else if( e_info.fuel_opts.empty() && fuel_type != itype_id( "null" ) ) { e_info.fuel_opts.push_back( fuel_type ); } eptr = e_info; assert( eptr ); }
inline bool move_next_leaf() { if (has_more() && current_node().is_leaf) skip_subtree(); while (has_more() && !current_node().is_leaf) expand(); return has_more(); }
static char * read_expression (struct parsebuf *p) { int start; int end; skip_whitespace (p); if (peek_char (p) == '"') { /* Read as a quoted string. The quotation marks are not included in the expression value. */ /* Skip opening quotation mark. */ read_char (p); start = p->pos; while (has_more (p) && peek_char (p) != '"') read_char (p); end = p->pos; /* Skip the terminating quotation mark. */ read_char (p); } else if (peek_char (p) == '(') { /* Read as a parenthesized string -- for tuples/coordinates. */ /* The parentheses are included in the expression value. */ int c; start = p->pos; do { c = read_char (p); } while (c != -1 && c != ')'); end = p->pos; } else if (has_more (p)) { /* Read as a single word -- for numeric values or words without whitespace. */ start = p->pos; while (has_more (p) && ! is_whitespace (peek_char (p))) read_char (p); end = p->pos; } else { /* The end of the theme file has been reached. */ grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file", p->filename, p->line_num, p->col_num); return 0; } return grub_new_substring (p->buf, start, end); }
void fault::load_fault( JsonObject &jo ) { fault f; f.id_ = fault_id( jo.get_string( "id" ) ); f.name_ = _( jo.get_string( "name" ) ); f.description_ = _( jo.get_string( "description" ) ); f.time_ = jo.get_int( "time" ); auto sk = jo.get_array( "skills" ); while( sk.has_more() ) { auto cur = sk.next_array(); f.skills_.emplace( skill_id( cur.get_string( 0 ) ), cur.size() >= 2 ? cur.get_int( 1 ) : 1 ); } if( jo.has_string( "requirements" ) ) { f.requirements_ = requirement_id( jo.get_string( "requirements" ) ); } else { auto req = jo.get_object( "requirements" ); const requirement_id req_id( std::string( "inline_fault_" ) + f.id_.str() ); requirement_data::load_requirement( req, req_id ); f.requirements_ = req_id; } if( faults_all.find( f.id_ ) != faults_all.end() ) { jo.throw_error( "parsed fault overwrites existing definition", "id" ); } else { faults_all[ f.id_ ] = f; } }
int relay_raw(zmq::socket_t& src, zmq::socket_t& dst, bool check_first_part) { int relayed = 0; for ( bool more = check_first_part ? has_more(src) : true; more; ++relayed) { zmq::message_t cur_part; src.recv(&cur_part); more = has_more(src); int flag = more ? ZMQ_SNDMORE : 0; send_msg(dst, cur_part, flag); } return relayed; }
bool JsonArray::test_object() { if (!has_more()) { return false; } jsin->seek(positions[index]); return jsin->test_object(); }
void Sink::relay_from( zmq::socket_t& relay_src, ReceiveObserver* receive_observer) throw (ZmqErrorType) { for (bool more = has_more(relay_src); more; ) { Part cur_part; recv_msg(relay_src, cur_part.msg()); more = has_more(relay_src); if (receive_observer) { receive_observer->on_receive_part(cur_part.msg(), more); } send_owned(cur_part); } }
void GTokenizer::advance(size_t n) { while(n > 0 && has_more()) { get(); n--; } }
static int peek_char (struct parsebuf *p) { if (has_more (p)) return p->buf[p->pos]; else return -1; }
bool socket_t::recv(message_pack_t &msg_pack, int flags) { do { message_part_t msg(new zmq::message_t); if(!m_socket.recv(msg.get(), flags)) return false; msg_pack.push_tail(std::move(msg)); } while (has_more()); return true; }
void GTokenizer::skipTo(GCharSet& delimeters) { while(has_more()) { char c = peek(); if(delimeters.find(c)) break; c = get(); } }
TransportInterface::Status ServerSession::LocalServerConnection::end_decoding(CommandInitiator* thread) { if (has_more()) { m_session->add_ready(this); thread->fork(); } else { m_session->add_waiting(this); } return OK; }
void GTokenizer::expect(const char* szString) { while(*szString != '\0' && has_more()) { char c = get(); if(c != *szString) throw Ex("Expected \"", szString, "\" on line ", to_str(m_line), ", col ", to_str(col())); szString++; } if(*szString != '\0') throw Ex("Expected \", szString, \". Reached end-of-file instead."); }
void quality::load( JsonObject &jo, const std::string & ) { mandatory( jo, was_loaded, "name", name, translated_string_reader ); JsonArray arr = jo.get_array( "usages" ); while( arr.has_more() ) { auto lvl = arr.next_array(); auto funcs = lvl.get_array( 1 ); while( funcs.has_more() ) { usages.emplace_back( lvl.get_int( 0 ), funcs.next_string() ); } } }
void Sink::relay_from( zmq::socket_t& relay_src, OccupationAccumulator acc) throw (ZmqErrorType) { while (has_more(relay_src)) { MsgPtr cur_part(new zmq::message_t); recv_msg(relay_src, *cur_part); size_t sz = cur_part->size(); acc(sz); send_owned(cur_part.release()); } }
static void parse_vp_reqs( JsonObject &obj, const std::string &id, const std::string &key, std::vector<std::pair<requirement_id, int>> &reqs, std::map<skill_id, int> &skills, int &moves ) { if( !obj.has_object( key ) ) { return; } auto src = obj.get_object( key ); auto sk = src.get_array( "skills" ); if( !sk.empty() ) { skills.clear(); } while( sk.has_more() ) { auto cur = sk.next_array(); skills.emplace( skill_id( cur.get_string( 0 ) ), cur.size() >= 2 ? cur.get_int( 1 ) : 1 ); } assign( src, "time", moves ); if( src.has_string( "using" ) ) { reqs = { { requirement_id( src.get_string( "using" ) ), 1 } }; } else if( src.has_array( "using" ) ) { auto arr = src.get_array( "using" ); while( arr.has_more() ) { auto cur = arr.next_array(); reqs.emplace_back( requirement_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); } } else { const requirement_id req_id( string_format( "inline_%s_%s", key.c_str(), id.c_str() ) ); requirement_data::load_requirement( src, req_id ); reqs = { { req_id, 1 } }; } }
char* GTokenizer::nextUntil(GCharSet& delimeters, size_t minLen) { m_pBufPos = m_pBufStart; while(has_more()) { char c = peek(); if(delimeters.find(c)) break; c = get(); bufferChar(c); } if((size_t)(m_pBufPos - m_pBufStart) < minLen) throw Ex("On line ", to_str(m_line), ", col ", to_str(col()), ", expected a token of at least size ", to_str(minLen), ", but got only ", to_str(m_pBufPos - m_pBufStart)); return nullTerminate(); }
char* GTokenizer::nextWhile(GCharSet& set, size_t minLen) { m_pBufPos = m_pBufStart; while(has_more()) { char c = peek(); if(!set.find(c)) break; c = get(); bufferChar(c); } if((size_t)(m_pBufPos - m_pBufStart) < minLen) throw Ex("Unexpected token on line ", to_str(m_line), ", col ", to_str(col())); return nullTerminate(); }
char* GTokenizer::nextUntilNotEscaped(char escapeChar, GCharSet& delimeters) { m_pBufPos = m_pBufStart; char cCur = '\0'; while(has_more()) { char c = peek(); if(delimeters.find(c) && cCur != escapeChar) break; c = get(); bufferChar(c); cCur = c; } return nullTerminate(); }
void material_type::load( JsonObject &jsobj ) { mandatory( jsobj, was_loaded, "name", _name, translated_string_reader ); mandatory( jsobj, was_loaded, "bash_resist", _bash_resist ); mandatory( jsobj, was_loaded, "cut_resist", _cut_resist ); mandatory( jsobj, was_loaded, "acid_resist", _acid_resist ); mandatory( jsobj, was_loaded, "elec_resist", _elec_resist ); mandatory( jsobj, was_loaded, "fire_resist", _fire_resist ); mandatory( jsobj, was_loaded, "chip_resist", _chip_resist ); mandatory( jsobj, was_loaded, "density", _density ); optional( jsobj, was_loaded, "salvaged_into", _salvaged_into, "null" ); optional( jsobj, was_loaded, "repaired_with", _repaired_with, "null" ); optional( jsobj, was_loaded, "edible", _edible, false ); optional( jsobj, was_loaded, "soft", _soft, false ); auto arr = jsobj.get_array( "vitamins" ); while( arr.has_more() ) { auto pair = arr.next_array(); _vitamins.emplace( vitamin_id( pair.get_string( 0 ) ), pair.get_float( 1 ) ); } mandatory( jsobj, was_loaded, "bash_dmg_verb", _bash_dmg_verb, translated_string_reader ); mandatory( jsobj, was_loaded, "cut_dmg_verb", _cut_dmg_verb, translated_string_reader ); JsonArray jsarr = jsobj.get_array( "dmg_adj" ); while( jsarr.has_more() ) { _dmg_adj.push_back( _( jsarr.next_string().c_str() ) ); } JsonArray burn_data_array = jsobj.get_array( "burn_data" ); for( size_t intensity = 0; intensity < MAX_FIELD_DENSITY; intensity++ ) { if( burn_data_array.has_more() ) { JsonObject brn = burn_data_array.next_object(); _burn_data[ intensity ] = load_mat_burn_data( brn ); } else { // If not specified, supply default bool flammable = _fire_resist <= ( int )intensity; mat_burn_data mbd; if( flammable ) { mbd.burn = 1; } _burn_data[ intensity ] = mbd; } } }
/* * ZAP request handling loop. */ static void zap_handler(void *handler) { for (;;) { char *version, *sequence, *domain, *address, *identity, *mechanism; /* Receive request. */ if(!(version = s_tryrecv(handler))) break; sequence = s_recvmore(handler); domain = s_recvmore(handler); address = s_recvmore(handler); identity = s_recvmore(handler); mechanism = s_recvmore(handler); assert(!has_more(handler)); assert(!strcmp(version, "1.0")); assert(!strcmp(mechanism, "NULL")); printf("ZAP REQUEST %s %s %s %s %s %s\n", version, sequence, domain, address, identity, mechanism); /* Send reply. */ s_sendmore(handler, version); s_sendmore(handler, sequence); if(!strcmp(domain, "test")) { s_sendmore(handler, "200"); s_sendmore(handler, "OK"); s_sendmore(handler, "anonymous"); printf("ZAP REPLY 1.0 %s 200 OK anonymous\n", sequence); } else { s_sendmore(handler, "500"); s_sendmore(handler, "Denied"); s_sendmore(handler, ""); printf("ZAP REPLY 1.0 %s 200 Denied\n", sequence); } s_send(handler, ""); /* Cleanup. */ free(version); free(sequence); free(domain); free(address); free(identity); free(mechanism); } zmq_close(handler); }
static int read_char (struct parsebuf *p) { if (has_more (p)) { char c; c = p->buf[p->pos++]; if (c == '\n') { p->line_num++; p->col_num = 1; } else { p->col_num++; } return c; } else return -1; }
void XRouting::receive_routing(zmq::socket_t& sock) throw (MessageFormatError, ZmqErrorType) { if (size_) { return; } for (int i = 0; ; ++i) { Part* const part = next(); if (!part) { std::ostringstream ss; ss << "Receiving multipart message: reading route info failed: " << "part " << (i+1) << " cannot be allocated."; throw MessageFormatError(ss.str()); } recv_msg(sock, part->msg()); ZMQMESSAGE_LOG_STREAM << "Received X route: " << part->msg().size() << "bytes;" << ZMQMESSAGE_LOG_TERM; if (part->msg().size() == 0) { break; } if (!has_more(sock)) { std::ostringstream ss; ss << "Receiving multipart message: reading route info failed: " << "part " << (i+1) << " has nothing after it. " << "Routing info doesn't end with null message"; throw MessageFormatError(ss.str()); } } }
void fault::load_fault( JsonObject &jo ) { fault f; f.id_ = fault_id( jo.get_string( "id" ) ); f.name_ = _( jo.get_string( "name" ).c_str() ); f.description_ = _( jo.get_string( "description" ).c_str() ); auto sk = jo.get_array( "skills" ); while( sk.has_more() ) { auto cur = sk.next_array(); f.skills_.emplace( skill_id( cur.get_string( 0 ) ) , cur.size() >= 2 ? cur.get_int( 1 ) : 1 ); } auto req = jo.get_object( "requirements" ); f.requirements_.load( req ); if( faults_all.find( f.id_ ) != faults_all.end() ) { jo.throw_error( "parsed fault overwrites existing definition", "id" ); } else { faults_all[ f.id_ ] = f; DebugLog( D_INFO, DC_ALL ) << "Loaded fault: " << f.name_; } }
void recipe::load( JsonObject &jo, const std::string &src ) { bool strict = src == "dda"; abstract = jo.has_string( "abstract" ); if( abstract ) { ident_ = recipe_id( jo.get_string( "abstract" ) ); } else { result_ = jo.get_string( "result" ); ident_ = recipe_id( result_ ); } assign( jo, "time", time, strict, 0 ); assign( jo, "difficulty", difficulty, strict, 0, MAX_SKILL ); assign( jo, "flags", flags ); // automatically set contained if we specify as container assign( jo, "contained", contained, strict ); contained |= assign( jo, "container", container, strict ); if( jo.has_array( "batch_time_factors" ) ) { auto batch = jo.get_array( "batch_time_factors" ); batch_rscale = batch.get_int( 0 ) / 100.0; batch_rsize = batch.get_int( 1 ); } assign( jo, "charges", charges ); assign( jo, "result_mult", result_mult ); assign( jo, "skill_used", skill_used, strict ); if( jo.has_member( "skills_required" ) ) { auto sk = jo.get_array( "skills_required" ); required_skills.clear(); if( sk.empty() ) { // clear all requirements } else if( sk.has_array( 0 ) ) { // multiple requirements while( sk.has_more() ) { auto arr = sk.next_array(); required_skills[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } else { // single requirement required_skills[skill_id( sk.get_string( 0 ) )] = sk.get_int( 1 ); } } // simplified autolearn sets requirements equal to required skills at finalization if( jo.has_bool( "autolearn" ) ) { assign( jo, "autolearn", autolearn ); } else if( jo.has_array( "autolearn" ) ) { autolearn = true; auto sk = jo.get_array( "autolearn" ); while( sk.has_more() ) { auto arr = sk.next_array(); autolearn_requirements[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } if( jo.has_member( "decomp_learn" ) ) { learn_by_disassembly.clear(); if( jo.has_int( "decomp_learn" ) ) { if( !skill_used ) { jo.throw_error( "decomp_learn specified with no skill_used" ); } assign( jo, "decomp_learn", learn_by_disassembly[skill_used] ); } else if( jo.has_array( "decomp_learn" ) ) { auto sk = jo.get_array( "decomp_learn" ); while( sk.has_more() ) { auto arr = sk.next_array(); learn_by_disassembly[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } } if( jo.has_member( "book_learn" ) ) { auto bk = jo.get_array( "book_learn" ); booksets.clear(); while( bk.has_more() ) { auto arr = bk.next_array(); booksets.emplace( arr.get_string( 0 ), arr.size() > 1 ? arr.get_int( 1 ) : -1 ); } } // recipes not specifying any external requirements inherit from their parent recipe (if any) if( jo.has_string( "using" ) ) { reqs_external = { { requirement_id( jo.get_string( "using" ) ), 1 } }; } else if( jo.has_array( "using" ) ) { auto arr = jo.get_array( "using" ); reqs_external.clear(); while( arr.has_more() ) { auto cur = arr.next_array(); reqs_external.emplace_back( requirement_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); } } const std::string type = jo.get_string( "type" ); if( type == "recipe" ) { if( jo.has_string( "id_suffix" ) ) { if( abstract ) { jo.throw_error( "abstract recipe cannot specify id_suffix", "id_suffix" ); } ident_ = recipe_id( ident_.str() + "_" + jo.get_string( "id_suffix" ) ); } assign( jo, "category", category, strict ); assign( jo, "subcategory", subcategory, strict ); assign( jo, "reversible", reversible, strict ); if( jo.has_member( "byproducts" ) ) { auto bp = jo.get_array( "byproducts" ); byproducts.clear(); while( bp.has_more() ) { auto arr = bp.next_array(); byproducts[ arr.get_string( 0 ) ] += arr.size() == 2 ? arr.get_int( 1 ) : 1; } } } else if( type == "uncraft" ) { reversible = true; } else { jo.throw_error( "unknown recipe type", "type" ); } // inline requirements are always replaced (cannot be inherited) const auto req_id = string_format( "inline_%s_%s", type.c_str(), ident_.c_str() ); requirement_data::load_requirement( jo, req_id ); reqs_internal = { { requirement_id( req_id ), 1 } }; }
/* * Assure that socket has more data before receiving and returning a string. */ static char *s_recvmore(void *socket) { assert(has_more(socket)); return s_recv(socket); }
/** * Reads in a vehicle part from a JsonObject. */ void vpart_info::load( JsonObject &jo, const std::string &src ) { vpart_info def; if( jo.has_string( "copy-from" ) ) { auto const base = vpart_info_all.find( vpart_id( jo.get_string( "copy-from" ) ) ); auto const ab = abstract_parts.find( vpart_id( jo.get_string( "copy-from" ) ) ); if( base != vpart_info_all.end() ) { def = base->second; } else if( ab != abstract_parts.end() ) { def = ab->second; } else { deferred.emplace_back( jo.str(), src ); return; } } if( jo.has_string( "abstract" ) ) { def.id = vpart_id( jo.get_string( "abstract" ) ); } else { def.id = vpart_id( jo.get_string( "id" ) ); } assign( jo, "name", def.name_ ); assign( jo, "item", def.item ); assign( jo, "location", def.location ); assign( jo, "durability", def.durability ); assign( jo, "damage_modifier", def.dmg_mod ); assign( jo, "power", def.power ); assign( jo, "epower", def.epower ); assign( jo, "fuel_type", def.fuel_type ); assign( jo, "default_ammo", def.default_ammo ); assign( jo, "folded_volume", def.folded_volume ); assign( jo, "size", def.size ); assign( jo, "difficulty", def.difficulty ); assign( jo, "bonus", def.bonus ); assign( jo, "flags", def.flags ); if( jo.has_member( "requirements" ) ) { auto reqs = jo.get_object( "requirements" ); parse_vp_reqs( reqs, def.id.str(), "install", def.install_reqs, def.install_skills, def.install_moves ); parse_vp_reqs( reqs, def.id.str(), "removal", def.removal_reqs, def.removal_skills, def.removal_moves ); parse_vp_reqs( reqs, def.id.str(), "repair", def.repair_reqs, def.repair_skills, def.repair_moves ); def.legacy = false; } if( jo.has_member( "symbol" ) ) { def.sym = jo.get_string( "symbol" )[ 0 ]; } if( jo.has_member( "broken_symbol" ) ) { def.sym_broken = jo.get_string( "broken_symbol" )[ 0 ]; } if( jo.has_member( "color" ) ) { def.color = color_from_string( jo.get_string( "color" ) ); } if( jo.has_member( "broken_color" ) ) { def.color_broken = color_from_string( jo.get_string( "broken_color" ) ); } if( jo.has_member( "breaks_into" ) ) { JsonIn& stream = *jo.get_raw( "breaks_into" ); def.breaks_into_group = item_group::load_item_group( stream, "collection" ); } auto qual = jo.get_array( "qualities" ); if( !qual.empty() ) { def.qualities.clear(); while( qual.has_more() ) { auto pair = qual.next_array(); def.qualities[ quality_id( pair.get_string( 0 ) ) ] = pair.get_int( 1 ); } } if( jo.has_member( "damage_reduction" ) ) { JsonObject dred = jo.get_object( "damage_reduction" ); def.damage_reduction = load_damage_array( dred ); } else { def.damage_reduction.fill( 0.0f ); } if( jo.has_string( "abstract" ) ) { abstract_parts[def.id] = def; } else { vpart_info_all[def.id] = def; } }
void recipe_dictionary::load( JsonObject &jo, const std::string &src, bool uncraft ) { bool strict = src == "core"; recipe r; // defer entries dependent upon as-yet unparsed definitions if( jo.has_string( "copy-from" ) ) { auto base = jo.get_string( "copy-from" ); if( uncraft ) { if( !recipe_dict.uncraft.count( base ) ) { deferred.emplace_back( jo.str(), src ); return; } r = recipe_dict.uncraft[ base ]; } else { if( !recipe_dict.recipes.count( base ) ) { deferred.emplace_back( jo.str(), src ); return; } r = recipe_dict.recipes[ base ]; } } if( jo.has_string( "abstract" ) ) { r.ident_ = jo.get_string( "abstract" ); r.abstract = true; } else { r.ident_ = r.result = jo.get_string( "result" ); r.abstract = false; } if( !uncraft ) { if( jo.has_string( "id_suffix" ) ) { if( r.abstract ) { jo.throw_error( "abstract recipe cannot specify id_suffix", "id_suffix" ); } r.ident_ += "_" + jo.get_string( "id_suffix" ); } assign( jo, "category", r.category, strict ); assign( jo, "subcategory", r.subcategory, strict ); assign( jo, "reversible", r.reversible, strict ); } else { r.reversible = true; } assign( jo, "time", r.time, strict, 0 ); assign( jo, "difficulty", r.difficulty, strict, 0, MAX_SKILL ); assign( jo, "flags", r.flags ); // automatically set contained if we specify as container assign( jo, "contained", r.contained, strict ); r.contained |= assign( jo, "container", r.container, strict ); if( jo.has_array( "batch_time_factors" ) ) { auto batch = jo.get_array( "batch_time_factors" ); r.batch_rscale = batch.get_int( 0 ) / 100.0; r.batch_rsize = batch.get_int( 1 ); } assign( jo, "charges", r.charges ); assign( jo, "result_mult", r.result_mult ); assign( jo, "skill_used", r.skill_used, strict ); if( jo.has_member( "skills_required" ) ) { auto sk = jo.get_array( "skills_required" ); r.required_skills.clear(); if( sk.empty() ) { // clear all requirements } else if( sk.has_array( 0 ) ) { // multiple requirements while( sk.has_more() ) { auto arr = sk.next_array(); r.required_skills[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } else { // single requirement r.required_skills[skill_id( sk.get_string( 0 ) )] = sk.get_int( 1 ); } } // simplified autolearn sets requirements equal to required skills at finalization if( jo.has_bool( "autolearn" ) ) { assign( jo, "autolearn", r.autolearn ); } else if( jo.has_array( "autolearn" ) ) { r.autolearn = true; auto sk = jo.get_array( "autolearn" ); while( sk.has_more() ) { auto arr = sk.next_array(); r.autolearn_requirements[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } if( jo.has_member( "decomp_learn" ) ) { r.learn_by_disassembly.clear(); if( jo.has_int( "decomp_learn" ) ) { if( !r.skill_used ) { jo.throw_error( "decomp_learn specified with no skill_used" ); } assign( jo, "decomp_learn", r.learn_by_disassembly[r.skill_used] ); } else if( jo.has_array( "decomp_learn" ) ) { auto sk = jo.get_array( "decomp_learn" ); while( sk.has_more() ) { auto arr = sk.next_array(); r.learn_by_disassembly[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } } if( !uncraft && jo.has_member( "byproducts" ) ) { auto bp = jo.get_array( "byproducts" ); r.byproducts.clear(); while( bp.has_more() ) { auto arr = bp.next_array(); r.byproducts[ arr.get_string( 0 ) ] += arr.size() == 2 ? arr.get_int( 1 ) : 1; } } if( jo.has_member( "book_learn" ) ) { auto bk = jo.get_array( "book_learn" ); r.booksets.clear(); while( bk.has_more() ) { auto arr = bk.next_array(); r.booksets.emplace( arr.get_string( 0 ), arr.get_int( 1 ) ); } } // recipes not specifying any external requirements inherit from their parent recipe (if any) if( jo.has_string( "using" ) ) { r.reqs_external = { { requirement_id( jo.get_string( "using" ) ), 1 } }; } else if( jo.has_array( "using" ) ) { auto arr = jo.get_array( "using" ); r.reqs_external.clear(); while( arr.has_more() ) { auto cur = arr.next_array(); r.reqs_external.emplace_back( requirement_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); } } // inline requirements are always replaced (cannot be inherited) auto req_id = string_format( "inline_%s_%s", uncraft ? "uncraft" : "recipe", r.ident_.c_str() ); requirement_data::load_requirement( jo, req_id ); r.reqs_internal = { { requirement_id( req_id ), 1 } }; if( uncraft ) { recipe_dict.uncraft[ r.ident_ ] = r; } else { recipe_dict.recipes[ r.ident_ ] = r; } }
char* GTokenizer::nextArg(GCharSet& delimiters, char escapeChar) { m_pBufPos = m_pBufStart; char c = peek(); if(c == '"') { bufferChar('"'); advance(1); GCharSet cs("\"\n"); while(has_more()) { char c2 = peek(); if(cs.find(c2)) break; c2 = get(); bufferChar(c2); } if(peek() != '"') throw Ex("Expected matching double-quotes on line ", to_str(m_line), ", col ", to_str(col())); bufferChar('"'); advance(1); while(!delimiters.find(peek())) advance(1); return nullTerminate(); } else if(c == '\'') { bufferChar('\''); advance(1); GCharSet cs("'\n"); while(has_more()) { char c2 = peek(); if(cs.find(c2)) break; c2 = get(); bufferChar(c2); } if(peek() != '\'') throw Ex("Expected a matching single-quote on line ", to_str(m_line), ", col ", to_str(col())); bufferChar('\''); advance(1); while(!delimiters.find(peek())) advance(1); return nullTerminate(); } bool inEscapeMode = false; while(has_more()) { char c2 = peek(); if(inEscapeMode) { if(c2 == '\n') { throw Ex("Error: '", to_str(escapeChar), "' character used as " "last character on a line to attempt to extend string over " "two lines on line" , to_str(m_line), ", col ", to_str(col()) ); } c2 = get(); bufferChar(c2); inEscapeMode = false; } else { if(c2 == '\n' || delimiters.find(c2)){ break; } c2 = get(); if(c2 == escapeChar) { inEscapeMode = true; } else { bufferChar(c2); } } } return nullTerminate(); }
int main(int, char**) { setup_test_environment(); void* context = zmq_ctx_new (); void* sockets [2]; int rc = 0; sockets [SERVER] = zmq_socket (context, ZMQ_STREAM); rc = zmq_bind (sockets [SERVER], "tcp://0.0.0.0:6666"); assert (rc == 0); sockets [CLIENT] = zmq_socket (context, ZMQ_STREAM); rc = zmq_connect (sockets [CLIENT], "tcp://localhost:6666"); assert (rc == 0); // wait for connect notification // Server: Grab the 1st frame (peer identity). zmq_msg_t peer_frame; rc = zmq_msg_init (&peer_frame); assert (rc == 0); rc = zmq_msg_recv (&peer_frame, sockets [SERVER], 0); assert (rc != -1); assert(zmq_msg_size (&peer_frame) > 0); assert (has_more (sockets [SERVER])); // Server: Grab the 2nd frame (actual payload). zmq_msg_t data_frame; rc = zmq_msg_init (&data_frame); assert (rc == 0); rc = zmq_msg_recv (&data_frame, sockets [SERVER], 0); assert (rc != -1); assert(zmq_msg_size (&data_frame) == 0); // Client: Grab the 1st frame (peer identity). rc = zmq_msg_init (&peer_frame); assert (rc == 0); rc = zmq_msg_recv (&peer_frame, sockets [CLIENT], 0); assert (rc != -1); assert(zmq_msg_size (&peer_frame) > 0); assert (has_more (sockets [CLIENT])); // Client: Grab the 2nd frame (actual payload). rc = zmq_msg_init (&data_frame); assert (rc == 0); rc = zmq_msg_recv (&data_frame, sockets [CLIENT], 0); assert (rc != -1); assert(zmq_msg_size (&data_frame) == 0); // Send initial message. char blob_data [256]; size_t blob_size = sizeof(blob_data); rc = zmq_getsockopt (sockets [CLIENT], ZMQ_IDENTITY, blob_data, &blob_size); assert (rc != -1); assert(blob_size > 0); zmq_msg_t msg; rc = zmq_msg_init_size (&msg, blob_size); assert (rc == 0); memcpy (zmq_msg_data (&msg), blob_data, blob_size); rc = zmq_msg_send (&msg, sockets [dialog [0].turn], ZMQ_SNDMORE); assert (rc != -1); rc = zmq_msg_close (&msg); assert (rc == 0); rc = zmq_msg_init_size (&msg, strlen(dialog [0].text)); assert (rc == 0); memcpy (zmq_msg_data (&msg), dialog [0].text, strlen(dialog [0].text)); rc = zmq_msg_send (&msg, sockets [dialog [0].turn], ZMQ_SNDMORE); assert (rc != -1); rc = zmq_msg_close (&msg); assert (rc == 0); // TODO: make sure this loop doesn't loop forever if something is wrong // with the test (or the implementation). int step = 0; while (step < steps) { // Wait until something happens. zmq_pollitem_t items [] = { { sockets [SERVER], 0, ZMQ_POLLIN, 0 }, { sockets [CLIENT], 0, ZMQ_POLLIN, 0 }, }; int rc = zmq_poll (items, 2, 100); assert (rc >= 0); // Check for data received by the server. if (items [SERVER].revents & ZMQ_POLLIN) { assert (dialog [step].turn == CLIENT); // Grab the 1st frame (peer identity). zmq_msg_t peer_frame; rc = zmq_msg_init (&peer_frame); assert (rc == 0); rc = zmq_msg_recv (&peer_frame, sockets [SERVER], 0); assert (rc != -1); assert(zmq_msg_size (&peer_frame) > 0); assert (has_more (sockets [SERVER])); // Grab the 2nd frame (actual payload). zmq_msg_t data_frame; rc = zmq_msg_init (&data_frame); assert (rc == 0); rc = zmq_msg_recv (&data_frame, sockets [SERVER], 0); assert (rc != -1); // Make sure payload matches what we expect. const char * const data = (const char*)zmq_msg_data (&data_frame); const int size = zmq_msg_size (&data_frame); // 0-length frame is a disconnection notification. The server // should receive it as the last step in the dialogue. if (size == 0) { ++step; assert (step == steps); } else { assert ((size_t) size == strlen (dialog [step].text)); int cmp = memcmp (dialog [step].text, data, size); assert (cmp == 0); ++step; assert (step < steps); // Prepare the response. rc = zmq_msg_close (&data_frame); assert (rc == 0); rc = zmq_msg_init_size (&data_frame, strlen (dialog [step].text)); assert (rc == 0); memcpy (zmq_msg_data (&data_frame), dialog [step].text, zmq_msg_size (&data_frame)); // Send the response. rc = zmq_msg_send (&peer_frame, sockets [SERVER], ZMQ_SNDMORE); assert (rc != -1); rc = zmq_msg_send (&data_frame, sockets [SERVER], ZMQ_SNDMORE); assert (rc != -1); } // Release resources. rc = zmq_msg_close (&peer_frame); assert (rc == 0); rc = zmq_msg_close (&data_frame); assert (rc == 0); } // Check for data received by the client. if (items [CLIENT].revents & ZMQ_POLLIN) { assert (dialog [step].turn == SERVER); // Grab the 1st frame (peer identity). zmq_msg_t peer_frame; rc = zmq_msg_init (&peer_frame); assert (rc == 0); rc = zmq_msg_recv (&peer_frame, sockets [CLIENT], 0); assert (rc != -1); assert(zmq_msg_size (&peer_frame) > 0); assert (has_more (sockets [CLIENT])); // Grab the 2nd frame (actual payload). zmq_msg_t data_frame; rc = zmq_msg_init (&data_frame); assert (rc == 0); rc = zmq_msg_recv (&data_frame, sockets [CLIENT], 0); assert (rc != -1); assert(zmq_msg_size (&data_frame) > 0); // Make sure payload matches what we expect. const char * const data = (const char*)zmq_msg_data (&data_frame); const int size = zmq_msg_size (&data_frame); assert ((size_t)size == strlen(dialog [step].text)); int cmp = memcmp(dialog [step].text, data, size); assert (cmp == 0); ++step; // Prepare the response (next line in the dialog). assert (step < steps); rc = zmq_msg_close (&data_frame); assert (rc == 0); rc = zmq_msg_init_size (&data_frame, strlen (dialog [step].text)); assert (rc == 0); memcpy (zmq_msg_data (&data_frame), dialog [step].text, zmq_msg_size (&data_frame)); // Send the response. rc = zmq_msg_send (&peer_frame, sockets [CLIENT], ZMQ_SNDMORE); assert (rc != -1); rc = zmq_msg_send (&data_frame, sockets [CLIENT], ZMQ_SNDMORE); assert (rc != -1); // Release resources. rc = zmq_msg_close (&peer_frame); assert (rc == 0); rc = zmq_msg_close (&data_frame); assert (rc == 0); } } assert (step == steps); rc = zmq_close (sockets [CLIENT]); assert (rc == 0); rc = zmq_close (sockets [SERVER]); assert (rc == 0); rc = zmq_ctx_term (context); assert (rc == 0); return 0; }