#include "common.h" #include "NetMessage.h" #include NMString::NMString(): text(0) { } NMString::NMString(const NMString &other) { int len = strlen(other.text) + 1; text = new char[len + 1]; mir_snprintf(text, len, "%s", other.text); } NMString::NMString(char *t) { int len = strlen(t) + 1; text = new char[len + 1]; mir_snprintf(text, len, "%s", t); } const bool NMString::operator<(const NMString &other) const { return strcmp(text, other.text) < 0; } const bool NMString::operator==(const NMString &other) const { return strcmp(text, other.text) == 0; } NMString &NMString::operator=(const NMString &other) { if(text) delete[] text; int len = strlen(other.text) + 1; text = new char[len + 1]; mir_snprintf(text, len, "%s", other.text); return *this; } NMString::~NMString() { delete[] text; } NetMessage::NetMessage(): Map() { } NetMessage::~NetMessage() { } //static char *NetMessage::unescape_inplace(char *val) { int read_pos = 0, write_pos = 0, len = strlen(val); while(read_pos < len) { if(val[read_pos] == '/' && read_pos + 1 < len) { read_pos++; if(val[read_pos] == '1') val[write_pos++] = '/'; else if(val[read_pos] == '2') val[write_pos++] = '\\'; else val[write_pos++] = '?'; read_pos++; } else { val[write_pos++] = val[read_pos++]; } } val[write_pos] = 0; return val; } int NetMessage::parse(char *data, int size) { int pos = 0; bool finished = false; char *key, *value; int start, end = 0; while(end < size && !finished) { start = end + 1; end = start; while(end < size && data[end] != '\\') end++; if(end < size) { data[end] = 0; key = &data[start]; start = end + 1; end = start; while(end < size && data[end] != '\\') end++; if(end < size) { data[end] = 0; value = &data[start]; } else value = 0; } else { key = value = 0; } if(key && strcmp(key, "final") == 0) finished = true; else if(key && value) put(NMString(key), NMString(value)); } return pos; } bool NetMessage::get_string(char *key, char *buff, int buffsize) { NMString val; if(get(NMString(key), val)) { mir_snprintf(buff, buffsize, "%s", val.text); unescape_inplace(buff); return true; } return false; } bool NetMessage::get_data(char *key, char *buff, int *size) { NMString val; if(get(NMString(key), val)) { NETLIBBASE64 nbd = {0}; nbd.pszEncoded = val.text; nbd.cchEncoded = strlen(nbd.pszEncoded); nbd.pbDecoded = (BYTE *)buff; nbd.cbDecoded = *size; //*size = Netlib_GetBase64DecodedBufferSize(nbd.cchEncoded); CallService(MS_NETLIB_BASE64DECODE, 0, (LPARAM)&nbd); *size = nbd.cbDecoded; return true; } return false; } int NetMessage::get_int(char *key) { NMString val; if(get(NMString(key), val)) { return atoi(val.text); } return 0; } ClientNetMessage::ClientNetMessage(): LinkedList< KeyValue >() { } ClientNetMessage::~ClientNetMessage() { } void ClientNetMessage::add_string(char *key, char *buff) { char *temp = escape(buff); KeyValue dat = KeyValue(NMString(key), NMString(temp)); delete temp; add(dat); } void ClientNetMessage::add_data(char *key, char *data, int size) { int len = Netlib_GetBase64EncodedBufferSize(size); char *buff = new char[len]; NETLIBBASE64 nbd = {0}; nbd.pszEncoded = buff; nbd.cchEncoded = len; nbd.pbDecoded = (BYTE *)data; nbd.cbDecoded = size; //*size = Netlib_GetBase64DecodedBufferSize(nbd.cchEncoded); CallService(MS_NETLIB_BASE64ENCODE, 0, (LPARAM)&nbd); KeyValue dat = KeyValue(NMString(key), NMString(buff)); add(dat); } void ClientNetMessage::add_int(char *key, int i) { char buff[254]; KeyValue dat(NMString(key), NMString(_itoa(i, buff, 10))); add(dat); } //static char *ClientNetMessage::escape(char *val) { int len = strlen(val); char *buff = new char[len * 2 + 1]; int read_pos = 0, write_pos = 0; while(read_pos < len) { if(val[read_pos] == '/') { buff[write_pos++] = '/'; buff[write_pos++] = '1'; read_pos++; } else if(val[read_pos] == '\\') { buff[write_pos++] = '/'; buff[write_pos++] = '2'; read_pos++; } else { buff[write_pos++] = val[read_pos++]; } } buff[write_pos] = 0; return buff; } int ClientNetMessage::make_packet(char *buff, int size) { int pos = 0, key_len, val_len, len; for(Iterator i = start(); i.has_val() && pos < size; i.next()) { KeyValue v = i.val(); key_len = strlen(v.first.text); val_len = strlen(v.second.text); len = key_len + val_len + 2; if(size - pos - len > 0) mir_snprintf(buff + pos, size - pos, "\\%s\\%s", v.first.text, v.second.text); pos += len; } if(size - pos > 7) { mir_snprintf(buff + pos, size - pos, "\\final\\"); pos += 7; } return pos; }