void CMsnADLPayload::ToString(CMsnClient* client, acl::string& out, const std::list<CMembership*>& memberShips) { std::list<MSN_DOMAIN*> domains; acl::string buf; // 遍历所有的联系人成员 std::list<CMembership*>::const_iterator cit = memberShips.begin(); for (; cit != memberShips.end(); cit++) { const CMembership* memberShip = *cit; const std::list<Member*>& members = memberShip->GetMembers(); std::list<Member*>::const_iterator cit2 = members.begin(); for (; cit2 != members.end(); cit2++) AddToDomain(domains, *cit2); } buf = "<ml l='1'>"; std::list<MSN_DOMAIN*>::const_iterator cit2 = domains.begin(); for (; cit2 != domains.end(); cit2++) { AddXmlNode(buf, *cit2); if (buf.length() >= 4096) { buf << "</ml>"; out << "ADL " << client->Sid() << " " << (int) buf.length() << "\r\n"; out.append(buf); buf = "<ml l='1'>"; } } //buf.format_append("<d n='live.com'><c n='support.service' t='32'>" // "<s l='2' n='IM' /><s l='2' n='PE' /></c></d>"); //buf.format_append("<d n='live.com'><c n='support.service' l='2' t='1'/></d>"); buf << "</ml>"; out << "ADL " << client->Sid() << " " << (int) buf.length() << "\r\n"; out.append(buf); ClearDomain(domains); }
bool mem_cache::get(const acl::string& key, acl::string& buf, unsigned short* flags) { bool has_tried = false; buf.clear(); m_line.format("get %s\r\n", key.c_str()); AGAIN: if (open() == false) return (false); if (m_conn->write(m_line) < 0) { close(); if (m_retry && !has_tried) { has_tried = true; goto AGAIN; } m_ebuf.format("write get(%s) error", key.c_str()); return (false); } // 读取服务器响应行 if (m_conn->gets(m_line) == false) { close(); if (m_retry && !has_tried) { has_tried = true; goto AGAIN; } m_ebuf.format("reply for get(%s) error", key.c_str()); return (false); } else if (m_line == "END") { m_ebuf.format("not found"); return (false); } else if (error_happen(m_line.c_str())) { close(); return (false); } // VALUE {key} {flags} {bytes}\r\n ACL_ARGV* tokens = acl_argv_split(m_line.c_str(), " \t"); if (tokens->argc < 4 || strcasecmp(tokens->argv[0], "VALUE") != 0) { close(); m_ebuf.format("server error for get(%s)", key.c_str()); acl_argv_free(tokens); return (false); } if (flags) *flags = (unsigned short) atoi(tokens->argv[2]); int len = atoi(tokens->argv[3]); if (len < 0) { close(); m_ebuf.format("value's len < 0"); acl_argv_free(tokens); return (false); } else if (len == 0) { acl_argv_free(tokens); return (true); } acl_argv_free(tokens); // 得需要保证足够的空间能容纳读取的数据,该种方式 // 可能会造成数据量非常大时的缓冲区溢出! char tmp[4096]; int n; while (true) { n = sizeof(tmp); if (n > len) n = len; if ((n = m_conn->read(tmp, n, false)) < 0) { close(); m_ebuf.format("read data for get cmd error"); return (false); } buf.append(tmp, n); len -= n; if (len <= 0) break; } // 读取数据尾部的 "\r\n" if (m_conn->gets(m_line) == false) { close(); m_ebuf.format("read data's delimiter error"); return (false); } // 读取 "END\r\n" if (m_conn->gets(m_line) == false || m_line != "END") { close(); m_ebuf.format("END flag not found"); return (false); } return (true); }