int main (){ cout << boolalpha; // constructor Dict<string,long> d; // add d.add("bill", 10); d.add("rich", 20); // output cout << d << endl << endl; //copy Dict<string,long> d2(d); cout << d2 << endl << endl; // add to existing key d2.add("bill", 100); // copy working? cout << d << endl << endl; cout << d2 << endl << endl; cout << "CHECK THIS ^^" << endl; // exists cout << "Exists bill:"<<d.exists("bill")<<endl; cout << "Exists john:"<<d.exists("john")<<endl; // get_value cout << "Value of bill:"<<d.get_value("bill")<<endl; // get_value throws on bad key try{ d.get_value("john"); } catch (range_error &e){ cout << "bad get_value "<<e.what()<<endl; } // make the array grow d.add("fred", 30); d.add("bob", 40); d.add("irving", 50); d.add("john",60); cout << endl; cout << d << endl<<endl; // assignment Dict<string,long> d3; d3 = d; // erase d.erase("bob"); // assignment working? cout << d << endl<<endl; cout << d3 << endl<<endl; cout << "D2: " << endl; cout << d2 << endl; }
// ***************************************************************************** FilterBy &FilterBy::op(const std::string &logicOperator, const std::string &path, const std::string &relation, const xmlrpc_c::value &value) { // ------------------------------------------------------------------- // The new simple condition Dict newCondition = Dict("path", path) .add("relation", relation); // The value has to be converted to an array List valueList; if (value.type() == xmlrpc_c::value::TYPE_ARRAY) { fromXmlrpcValue(value, valueList); } else { valueList.append(value); } newCondition.add("values", valueList); // ------------------------------------------------------------------- // Add the new simple condition to the conditions list List conditions; if (!m_filters.empty()) { // The Original m_filters map now becomes a condition conditions.append(m_filters); } conditions.append(newCondition); // ------------------------------------------------------------------- // Update the filters m_filters.clear(); m_filters.add("logical_operator", logicOperator) .add("conditions", conditions); return *this; }
// ***************************************************************************** EntityPtrs Shotgun::entityFactoryFind(const std::string &entityType, Dict &findMap, const int limit) { EntityPtrs entities; // Find the registered functions for the given type of class. ClassRegistry::iterator foundRegistryIter = m_classRegistry.find(entityType); if (foundRegistryIter == m_classRegistry.end()) { throw SgEntityNotRegisteredError(entityType); } // The set of registered functions RegistryFuncs registryFuncs = (*foundRegistryIter).second; // ------------------------------------------------------------------------ // If the given findMap already has a "return_fields", merge its contents // with the poupulated default return Fields of the given entity type. // Shotgun will ignore the duplicated fields when it returns the search result. // To update the findMap's "return_fields", erase it first since the // xmlrpc_c::value type can't be reassigned once it's been instantiated. // ------------------------------------------------------------------------ // Populate the default return fields and add the extra return fields // before passing them to the findMap List returnFields = (*(registryFuncs.defaultReturnFieldsFunc))(); try { // Check to see if the findMap has "return_fields" already returnFields.extend(findMap.value<List>("return_fields")); findMap.erase("return_fields"); } catch (SgDictKeyNotFoundError) { // Do nothing } findMap.add("return_fields", returnFields); // If the findMap already has a "type" field, override it with the // given entityType to ensure that the type will not conflict with // the factory function. if (findMap.find("type")) { findMap.erase("type"); } findMap.add("type", entityType); // Find the shotgun entities by the findMap List xmlrpcFindResult = Entity::findSGEntities(this, findMap, limit); // Create entity class object. for (size_t i = 0; i < xmlrpcFindResult.size(); i++) { entities.push_back((*(registryFuncs.factoryFunc))(this, xmlrpcFindResult[i])); } return entities; }
int test1() { int sfd = createAndBind( "12345" ); if( sfd == -1 ) { return -1; } FreeHelper fh_sfd( [&](){ close( sfd ); } ); // 确保回收 sfd int rtv = listen( sfd, SOMAXCONN ); // 系统设置的 /proc/sys/net/core/somaxconn 也是一层限制, 有文章建议设为 1024 if( rtv == -1 ) // http://www.hackbase.com/tech/2008-06-18/41054.html { std::cout << "listen error.\n"; return -1; } int efd = epoll_create( _maxEvents ); if( efd == -1 ) { std::cout << "epoll_create1 error.\n"; return -1; } FreeHelper fh_efd( [&](){ close( efd ); } ); // 确保回收 efd epoll_event e; e.data.fd = sfd; e.events = EPOLLIN | EPOLLET; rtv = epoll_ctl( efd, EPOLL_CTL_ADD, sfd, &e ); if( rtv == -1 ) { std::cout << "epoll_ctl error.\n"; return -1; } auto es = (epoll_event*)calloc( _maxEvents, sizeof(e) ); FreeHelper fh_es( [&](){ free( es ); } ); Dict<int, Binary*> tokens; FreeHelper fh_tokens( [&]() { for( int i = 0; i < tokens._nodes._len; ++i ) { close( tokens._nodes[ i ]->_key ); delete tokens._nodes[ i ]->_value; } } ); while( true ) { int n = epoll_wait( efd, es, _maxEvents, 0 ); // -1 if( n == -1 ) { std::cout << "epoll_wait error.\n"; // if( errno == EINTR ) // 当前不确定这个错误要不要无视 return -1; } for( int i = 0; i < n; ++i ) { auto &ce = es[ i ]; if( ( ce.events & EPOLLERR ) || ( ce.events & EPOLLHUP ) || !( ce.events & EPOLLIN ) ) { std::cout << "epoll error.\n"; continue; } else if( sfd == ce.data.fd ) { while( true ) { sockaddr sa; auto salen = (socklen_t)sizeof(sa); int ifd = accept( sfd, &sa, &salen ); if( ifd == -1 ) { if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) ) { break; // 执行到这里的时候已经处理完所有连接请求,跳出 } else { std::cout << "accept error.\n"; } break; } char hbuf[ NI_MAXHOST ], sbuf[ NI_MAXSERV ]; // 这段代码是取创建的连接的客户端地址信息 rtv = getnameinfo( &sa, salen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV ); if( rtv == 0 ) { std::cout << "accepted. in_fd = " << ifd << ", host = " << hbuf << ", port = " << sbuf << "\n"; } rtv = makeNonBlocking( ifd ); if( rtv == -1 ) { close( ifd ); return -1; } e.data.fd = ifd; e.events = EPOLLIN | EPOLLET; rtv = epoll_ctl( efd, EPOLL_CTL_ADD, ifd, &e ); if( rtv == -1 ) { std::cout << "epoll_ctl error.\n"; close( ifd ); return -1; } std::cout << "tokens.add( ifd : " << ifd << " ).\n"; tokens.add( ifd, new Binary() ); } continue; } else { auto ifd = ce.data.fd; Binary* bin; if( !tokens.tryGet( ifd, bin ) ) { std::cout << "cannot get ifd: " << ifd << " from tokens.\n"; continue; } bool done = false; // 有数据未读,必须读光( edge triggered mode ) do { bin->ensure( 4096 ); rtv = recv( ifd, bin->_buf + bin->_len, 4096, 0 ); if( rtv == -1 ) { if( errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK ) { break; } std::cout << "read error.\n"; done = true; break; } else if( rtv == 0 ) // 0 长度表示连接已断开 { done = true; break; } bin->_len += rtv; } while( rtv == 4096 ); // 按某文章的说法,读到的字节数小于 buf 长,就表明已经读完了 if( !done ) // 顺利读完数据到此 { LabBegin: // 这里使用 readIdx 来存上一次的扫描点 for( ; bin->_readIdx < bin->_len; ++bin->_readIdx ) { if( bin->_buf[ bin->_readIdx ] == '\n' ) { ++bin->_readIdx; // 跳过空格 if( bin->_buf[ 0 ] == '`' ) // 退出 { return 0; } else if( bin->_buf[ 0 ] == ' ' ) // 广播 { for( int i = 0; i < tokens._nodes._len; ++i ) { auto cifd = tokens._nodes[ i ]->_key; if( cifd == ifd ) continue; rtv = write( cifd, bin->_buf, bin->_readIdx ); if( rtv == -1 ) { close( cifd ); Binary* bin; if( !tokens.tryRemove( cifd, bin ) ) { std::cout << "cannot remove cifd: " << cifd << " from tokens.\n"; } else { delete bin; } } } } rtv = send( ifd, bin->_buf, bin->_readIdx, 0 ); // 回发收到的数据 \n 截止 if( rtv == -1 ) { std::cout << "write error.\n"; done = true; break; } memmove( bin->_buf, bin->_buf + bin->_readIdx, bin->_len - bin->_readIdx ); bin->_len = bin->_len - bin->_readIdx; bin->_readIdx = 0; if( bin->_len ) goto LabBegin; break; } } } if( done ) // 出问题需要关闭 ifd { std::cout << "closed. ce.data.fd = " << ifd << "\n"; close( ifd ); Binary* bin; if( !tokens.tryRemove( ifd, bin ) ) { std::cout << "cannot remove ifd: " << ifd << " from tokens.\n"; } else { delete bin; } } } } // todo: logic code here usleep( 1 ); } return 0; }
void AutoUpdaterImpl::step() { if(!req) { ret(); return; } if(!req->done()) return; ret(); if(req->getsize()) { Stringtable st(req->getbuf(), req->getsize()); char last_mod[64] = ""; enum { STATUS, HEADER, REPLY, } state = STATUS; Dict reply; for(int i = 0; i < st.size(); ++i) { const char* str = st.get(i); switch(state) { case STATUS: if(strncmp(str, "HTTP/", 5) != 0) { msgbox("update: Invalid HTTP response\n"); return; } while(str && *str != '\0' && *str != ' ' && *str != '\t') ++str; while(str && *str != '\0' && (*str == ' ' || *str == '\t')) ++str; if(strncmp(str, "200", 3) == 0) msgbox("HTTP status is OK\n"); else if(strncmp(str, "304", 3) == 0) { msgbox("update: version file not modified\n"); config.info3.last_update = time(NULL); config.write(); return; } else { msgbox("update: HTTP status isn't 200 or 304: %s\n", str); return; } state = HEADER; break; case HEADER: if(*str == '\0') { state = REPLY; continue; } // Take note of the Last-Modified header. if(strncasecmp(str, "Last-Modified:", 14) == 0) { while(str && *str != '\0' && *str != ' ' && *str != '\t') ++str; while(str && *str != '\0' && (*str == ' ' || *str == '\t')) ++str; snprintf(last_mod, sizeof(last_mod), "%s", str); msgbox("update: Last-Modified: %s\n", last_mod); } break; case REPLY: msgbox("update: reply: %s\n", str); reply.add(str); break; }; } const char* val = reply.find("qserv"); if(val) snprintf(config.info3.default_game_server_address, sizeof(config.info3.default_game_server_address), "%s", val); if(reply.find_sub("version")) { const char* version_key = "unstable"; if(VERSION_MINOR % 2 == 0) version_key = "stable"; val = reply.find_sub("version")->find(version_key); if(val) { int s = sizeof(config.info3.latest_version); strncpy(config.info3.latest_version, val, s); config.info3.latest_version[s-1] = 0; } } if(*last_mod) snprintf(config.info3.last_modified, sizeof(config.info3.last_modified), "%s", last_mod); config.info3.last_update = time(NULL); config.write(); msgbox("update: done\n"); } else msgbox("update: failed\n"); }
// Tests the basic functionality TEST(Dict, DictTest) { //Create a new dictionary Dict dict; //Create some values to add to the dictionary const int apple = 1; const int orange = 2; const int melon = 3; const Float pi = 3.14; VectorFloat buf(3); buf[0] = 1; buf[1] = 2; buf[2] = 3; int expectedSize = 0; //Check the size, it should be zero EXPECT_TRUE( dict.getSize() == expectedSize ); //Add some key-value pairs to the dictionary EXPECT_TRUE( dict.add( "apple", apple ) ); EXPECT_TRUE( dict.getSize() == ++expectedSize ); EXPECT_TRUE( dict.add( "orange", orange ) ); EXPECT_TRUE( dict.getSize() == ++expectedSize ); EXPECT_TRUE( dict.add( "melon", melon ) ); EXPECT_TRUE( dict.getSize() == ++expectedSize ); EXPECT_TRUE( dict.add( "pi", pi ) ); EXPECT_TRUE( dict.getSize() == ++expectedSize ); EXPECT_TRUE( dict.add( "pi", pi ) ); //Add it twice, the first value will be overwritten EXPECT_TRUE( dict.getSize() == expectedSize ); EXPECT_FALSE( dict.add( "pi", pi, false ) ); //Try and add it, but disable overwrites EXPECT_TRUE( dict.getSize() == expectedSize ); EXPECT_TRUE( dict.add( "buf", buf ) ); EXPECT_TRUE( dict.getSize() == ++expectedSize ); //Remove some values EXPECT_TRUE( dict.remove( "orange" ) ); EXPECT_TRUE( dict.getSize() == --expectedSize ); EXPECT_FALSE( dict.remove( "orange" ) ); //Try and remove the value a second time EXPECT_TRUE( dict.getSize() == expectedSize ); EXPECT_FALSE( dict.remove( "pear" ) ); //Try and remove a value that does not exist EXPECT_TRUE( dict.getSize() == expectedSize ); //Test some keys exist EXPECT_TRUE( dict.exists( "apple" ) ); EXPECT_TRUE( dict.exists( "pi" ) ); EXPECT_FALSE( dict.exists( "orange" ) ); //Test the getter EXPECT_EQ( dict.get< int >( "apple" ), apple ); EXPECT_EQ( dict.get< Float >( "pi" ), pi ); //Test the reference update int &v = dict.get< int >( "apple" ); v++; EXPECT_EQ( dict.get< int >( "apple" ), apple+1 ); //Test the vector VectorFloat vec = dict.get< VectorFloat >( "buf" ); EXPECT_TRUE( buf.getSize() == vec.getSize() ); for(UINT i=0; i<buf.getSize(); i++){ EXPECT_TRUE( buf[i] == vec[i] ); } //Test the keys Vector< std::string > keys = dict.getKeys(); EXPECT_EQ( keys.getSize(), dict.getSize() ); //Test the setter EXPECT_TRUE( dict.set( "pi", 3.14159 ) ); EXPECT_FALSE( dict.set( "foo", 3.14159 ) ); //This wil fail, as foo does not exist in the dictionary //Test the () operator int x = 0; EXPECT_TRUE( dict("melon", x) ); EXPECT_EQ( x, melon ); //This should return false EXPECT_FALSE( dict("pear", x) ); //Test the copy constructor Dict d2( dict ); EXPECT_EQ( dict.getSize(), d2.getSize() ); EXPECT_EQ( dict.getSize(), expectedSize ); //The values should match EXPECT_TRUE( dict.get< int >( "apple" ) == d2.get< int >( "apple" ) ); //Change something in the original dict, test that d2 has not changed EXPECT_TRUE( dict.set( "apple", 5 ) ); //The values should now not match EXPECT_FALSE( dict.get< int >( "apple" ) == d2.get< int >( "apple" ) ); //Clear all the values EXPECT_TRUE( dict.clear() ); EXPECT_TRUE( dict.getSize() == 0 ); }
/** * add a word to dictionary */ void addWord(Dict &d, const string &key, const string &value){ word w = {key, value}; if (!d.add(w)) cout << "Add failed.\n"; d.printDict(); }