summaryrefslogtreecommitdiff
path: root/MySpace/NetMessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MySpace/NetMessage.cpp')
-rw-r--r--MySpace/NetMessage.cpp369
1 files changed, 288 insertions, 81 deletions
diff --git a/MySpace/NetMessage.cpp b/MySpace/NetMessage.cpp
index a43ce85..b158654 100644
--- a/MySpace/NetMessage.cpp
+++ b/MySpace/NetMessage.cpp
@@ -2,19 +2,19 @@
#include "NetMessage.h"
#include <cstdlib>
-NMString::NMString(): text(0) {
+NMString::NMString(): text(0), len(0) {
}
NMString::NMString(const NMString &other) {
- int len = strlen(other.text) + 1;
+ len = strlen(other.text);
text = new char[len + 1];
- mir_snprintf(text, len, "%s", other.text);
+ mir_snprintf(text, len + 1, "%s", other.text);
}
NMString::NMString(char *t) {
- int len = strlen(t) + 1;
+ len = strlen(t);
text = new char[len + 1];
- mir_snprintf(text, len, "%s", t);
+ mir_snprintf(text, len + 1, "%s", t);
}
const bool NMString::operator<(const NMString &other) const {
@@ -25,12 +25,18 @@ const bool NMString::operator==(const NMString &other) const {
return strcmp(text, other.text) == 0;
}
-NMString &NMString::operator=(const NMString &other) {
- if(text) delete[] text;
+const bool NMString::operator==(const char *str) const {
+ return strcmp(text, str) == 0;
+}
- int len = strlen(other.text) + 1;
- text = new char[len + 1];
- mir_snprintf(text, len, "%s", other.text);
+NMString &NMString::operator=(const NMString &other) {
+ int olen = strlen(other.text);
+ if(olen > len) {
+ if(text) delete[] text;
+ len = olen;
+ text = new char[len + 1];
+ }
+ mir_snprintf(text, len + 1, "%s", other.text);
return *this;
}
@@ -39,6 +45,147 @@ NMString::~NMString() {
delete[] text;
}
+StringList::StringList(char *sep): LinkedList<NMString>(), seperators(sep) {
+}
+
+StringList::~StringList() {
+}
+
+int StringList::parse(char *data, int size) {
+ int i = 0, tl, pos = 0;
+ bool first = true;
+ while(pos < size) {
+ tl = strcspn(data + pos, seperators);
+ if(first && tl == 0) {
+ first = false;
+ pos += 1;
+ } else {
+ if(pos + tl < size) {
+ *(data + pos + tl) = 0;
+ add(NMString(unescape_inplace(data + pos)));
+ i++;
+ }
+ pos += tl + 1;
+ }
+ }
+ return i;
+}
+
+bool StringList::get_string(int index, char *buff, int buffsize) {
+ int i = 0;
+ ListNode<NMString> *n = head;
+ while(n && i < index) {
+ if(i == index) break;
+ n = n->next;
+ i++;
+ }
+ if(n) {
+ strncpy(buff, n->val.text, buffsize);
+ return true;
+ }
+ return false;
+}
+
+int StringList::get_int(int index) {
+ int i = 0;
+ ListNode<NMString> *n = head;
+ while(n && i < index) {
+ if(i == index) break;
+ n = n->next;
+ i++;
+ }
+ if(n) {
+ return atoi(n->val.text);
+ }
+ return 0;
+}
+
+void StringList::add_string(char *buff) {
+ add(NMString(buff));
+}
+
+void StringList::add_int(int i) {
+ char buff[128];
+ _itoa(i, buff, 10);
+ add(NMString(buff));
+}
+
+int StringList::make_body(char *buff, int size, bool sep_at_start) {
+ int len = 0;
+ bool first = true;
+ char *val;
+ for(LinkedList<NMString>::Iterator i = start(); i.has_val() && len < size; i.next()) {
+ NMString &val = i.val();
+ if(first && sep_at_start == false) {
+ first = false;
+ } else {
+ if(len < size) buff[len++] = seperators[0];
+ if(len < size) buff[len] = 0;
+ }
+ char *temp = escape(val.text);
+ strncat(buff, temp, size - len);
+ len += strlen(temp);
+ delete[] temp;
+ }
+ if(len < size) buff[len] = 0;
+ return len;
+}
+
+char *StringList::escape(char *val) {
+ int len = strlen(val);
+ char *buff = new char[len + 1];
+ strncpy(buff, val, strlen(val));
+ return buff;
+}
+
+char *StringList::unescape_inplace(char *val) {
+ return val;
+}
+
+PipedStringList::PipedStringList(): StringList() {
+}
+
+PipedStringList::~PipedStringList() {
+}
+
+char *PipedStringList::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++] = '3';
+ read_pos++;
+ } else {
+ buff[write_pos++] = val[read_pos++];
+ }
+ }
+ buff[write_pos] = 0;
+ return buff;
+}
+
+char *PipedStringList::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) {
+ if(val[read_pos + 1] == '3') {
+ read_pos += 2;
+ val[write_pos++] = '|';
+ } else {
+ val[write_pos++] = val[read_pos++];
+ val[write_pos++] = val[read_pos++];
+ }
+ } else {
+ val[write_pos++] = val[read_pos++];
+ }
+ }
+ val[write_pos] = 0;
+
+ return val;
+}
+
+
Dictionary::Dictionary(): LinkedList< KeyValue >() {
}
@@ -46,36 +193,28 @@ Dictionary::~Dictionary() {
}
int Dictionary::parse(char *data, int size) {
- int pos = 0;
+ int i = 0, tl, il, pos = 0;
+ bool first = true;
char *key, *value;
- int start, end = 0;
- while(end < size) {
- start = end;
- 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] != '\x1c' && data[end] != 0) end++;
- if(end <= size) {
- data[end] = 0;
- value = &data[start];
- end++;
- } else
- value = 0;
+ while(pos < size) {
+ tl = strcspn(data + pos, "\x1c");
+ if(first && tl == 0) {
+ first = false;
+ pos += 1;
} else {
- key = value = 0;
- }
+ *(data + pos + tl) = 0;
- if(key && value) {
+ il = strcspn(data + pos, "=");
+ *(data + pos + il) = 0;
+ key = unescape_inplace(data + pos);
+ value = unescape_inplace(data + pos + il + 1);
KeyValue kv = KeyValue(NMString(key), NMString(value));
add(kv);
+ pos += tl + 1;
+
}
}
- return pos;
+ return i;
}
bool Dictionary::get_string(char *key, char *buff, int buffsize) {
@@ -114,27 +253,96 @@ void Dictionary::add_int(char *key, int i) {
int Dictionary::make_body(char *buff, int size) {
int pos = 0, key_len, val_len, len;
+ char *ekey, *eval;
bool first = true;
for(Iterator i = start(); i.has_val() && pos < size; i.next()) {
- KeyValue v = i.val();
+ KeyValue &v = i.val();
- key_len = strlen(v.first.text);
- val_len = strlen(v.second.text);
+ ekey = escape(v.first.text);
+ eval = escape(v.second.text);
+ key_len = strlen(ekey);
+ val_len = strlen(eval);
len = key_len + val_len + 2;
if(size - pos - len > 0) {
if(first) {
- mir_snprintf(buff + pos, size - pos, "%s=%s", v.first.text, v.second.text);
+ mir_snprintf(buff + pos, size - pos, "%s=%s", ekey, eval);
first = false;
} else
- mir_snprintf(buff + pos, size - pos, "\x1c%s=%s", v.first.text, v.second.text);
+ mir_snprintf(buff + pos, size - pos, "\x1c%s=%s", ekey, eval);
+ pos += len;
}
- pos += len;
+ delete[] ekey;
+ delete[] eval;
}
return pos;
}
+char *Dictionary::escape(char *val) {
+ int len = strlen(val);
+ char *buff = new char[len * 6 + 1];
+ int read_pos = 0, write_pos = 0;
+ while(read_pos < len) {
+ if(val[read_pos] == '\'') {
+ buff[write_pos++] = '&';
+ buff[write_pos++] = '#';
+ buff[write_pos++] = '3';
+ buff[write_pos++] = '9';
+ buff[write_pos++] = ';';
+ read_pos++;
+ } else if(val[read_pos] == '`') {
+ buff[write_pos++] = '&';
+ buff[write_pos++] = '#';
+ buff[write_pos++] = '3';
+ buff[write_pos++] = '9';
+ buff[write_pos++] = ';';
+ read_pos++;
+ } else if(val[read_pos] == '#') {
+ buff[write_pos++] = '&';
+ buff[write_pos++] = '#';
+ buff[write_pos++] = '0';
+ buff[write_pos++] = '3';
+ buff[write_pos++] = '5';
+ buff[write_pos++] = ';';
+ read_pos++;
+ } else if(val[read_pos] == '\"') {
+ buff[write_pos++] = '&';
+ buff[write_pos++] = 'q';
+ buff[write_pos++] = 'u';
+ buff[write_pos++] = 'o';
+ buff[write_pos++] = 't';
+ buff[write_pos++] = ';';
+ read_pos++;
+ } else {
+ buff[write_pos++] = val[read_pos++];
+ }
+ }
+ buff[write_pos] = 0;
+ return buff;
+}
+
+char *Dictionary::unescape_inplace(char *val) {
+ int read_pos = 0, write_pos = 0, len = strlen(val);
+ while(read_pos < len) {
+ if(read_pos + 5 < len && strncmp(&val[read_pos], "&#39;", 5) == 0) {
+ read_pos += 5;
+ val[write_pos++] = '\'';
+ } else if(read_pos + 6 < len && strncmp(&val[read_pos], "&#035;", 6) == 0) {
+ read_pos += 6;
+ val[write_pos++] = '#';
+ } else if(read_pos + 6 < len && strncmp(&val[read_pos], "&quot;", 6) == 0) {
+ read_pos += 6;
+ val[write_pos++] = '\"';
+ } else {
+ val[write_pos++] = val[read_pos++];
+ }
+ }
+ val[write_pos] = 0;
+
+ return val;
+}
+
NetMessage::NetMessage(): Map<NMString, NMString>() {
}
@@ -147,11 +355,13 @@ 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++;
+ if(val[read_pos + 1] == '1') val[write_pos++] = '/';
+ else if(val[read_pos + 1] == '2') val[write_pos++] = '\\';
+ else {
+ val[write_pos++] = val[read_pos];
+ val[write_pos++] = val[read_pos + 1];
+ }
+ read_pos+= 2;
} else {
val[write_pos++] = val[read_pos++];
}
@@ -162,39 +372,17 @@ char *NetMessage::unescape_inplace(char *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;
- if(strcmp(key, "final") != 0) {
- end = start;
- while(end < size && data[end] != '\\') end++;
- if(end < size) {
- data[end] = 0;
- value = &data[start];
- } else
- value = 0;
- } else
- value = 0;
- } else {
- key = value = 0;
+ StringList sl("\\");
+ sl.parse(data, size);
+ for(StringList::Iterator i = sl.start(); i.has_val(); i.next()) {
+ NMString &key = i.val();
+ i.next();
+ if(i.has_val()) {
+ NMString &val = i.val();
+ put(key, val);
}
-
- if(key && strcmp(key, "final") == 0)
- finished = true;
- else if(key && value)
- put(NMString(key), NMString(value));
}
- return pos;
+ return this->size();
}
bool NetMessage::get_string(char *key, char *buff, int buffsize) {
@@ -242,6 +430,14 @@ Dictionary NetMessage::get_dict(char *key) {
return d;
}
+PipedStringList NetMessage::get_list(char *key) {
+ PipedStringList l;
+ char t[4096];
+ if(get_string(key, t, 4096)) {
+ l.parse(t, strlen(t));
+ }
+ return l;
+}
ClientNetMessage::ClientNetMessage(): Dictionary() {
}
@@ -259,7 +455,6 @@ bool ClientNetMessage::add_data(char *key, char *data, int size) {
nbd.pbDecoded = (BYTE *)data;
nbd.cbDecoded = size;
- //*size = Netlib_GetBase64DecodedBufferSize(nbd.cchEncoded);
if(CallService(MS_NETLIB_BASE64ENCODE, 0, (LPARAM)&nbd)) {
KeyValue dat = KeyValue(NMString(key), NMString(buff));
add(dat);
@@ -274,14 +469,23 @@ bool ClientNetMessage::add_data(char *key, char *data, int size) {
void ClientNetMessage::add_string(char *key, char *buff) {
char *temp = escape(buff);
KeyValue dat = KeyValue(NMString(key), NMString(temp));
- delete temp;
+ delete[] temp;
add(dat);
}
void ClientNetMessage::add_dict(char *key, Dictionary &d) {
char t[4096];
if(d.make_body(t, 4096)) {
- add_string(key, t);
+ KeyValue dat = KeyValue(NMString(key), NMString(t));
+ add(dat);
+ }
+}
+
+void ClientNetMessage::add_list(char *key, PipedStringList &list) {
+ char t[4096];
+ if(list.make_body(t, 4096)) {
+ KeyValue dat = KeyValue(NMString(key), NMString(t));
+ add(dat);
}
}
@@ -316,14 +520,17 @@ int ClientNetMessage::make_packet(char *buff, int size) {
val_len = strlen(v.second.text);
len = key_len + val_len + 2;
- if(size - pos - len > 0)
+ if(size - pos - len > 0) {
mir_snprintf(buff + pos, size - pos, "\\%s\\%s", v.first.text, v.second.text);
- pos += len;
+ pos += len;
+ } else
+ return -1;
}
if(size - pos > 7) {
mir_snprintf(buff + pos, size - pos, "\\final\\");
pos += 7;
+ return pos;
}
- return pos;
+ return -1;
}