#include <iomanip>
#include <vector>
+SerializationError eof_ser_err("Attempted read past end of data");
+
+////
+//// BufReader
+////
+
+bool BufReader::getStringNoEx(std::string *val)
+{
+ u16 num_chars;
+ if (!getU16NoEx(&num_chars))
+ return false;
+
+ if (pos + num_chars > size) {
+ pos -= sizeof(num_chars);
+ return false;
+ }
+
+ val->assign((const char *)data + pos, num_chars);
+ pos += num_chars;
+
+ return true;
+}
+
+bool BufReader::getWideStringNoEx(std::wstring *val)
+{
+ u16 num_chars;
+ if (!getU16NoEx(&num_chars))
+ return false;
+
+ if (pos + num_chars * 2 > size) {
+ pos -= sizeof(num_chars);
+ return false;
+ }
+
+ for (size_t i = 0; i != num_chars; i++) {
+ val->push_back(readU16(data + pos));
+ pos += 2;
+ }
+
+ return true;
+}
+
+bool BufReader::getLongStringNoEx(std::string *val)
+{
+ u32 num_chars;
+ if (!getU32NoEx(&num_chars))
+ return false;
+
+ if (pos + num_chars > size) {
+ pos -= sizeof(num_chars);
+ return false;
+ }
+
+ val->assign((const char *)data + pos, num_chars);
+ pos += num_chars;
+
+ return true;
+}
+
+bool BufReader::getRawDataNoEx(void *val, size_t len)
+{
+ if (pos + len > size)
+ return false;
+
+ memcpy(val, data + pos, len);
+ pos += len;
+
+ return true;
+}
+
+
////
//// String
////
std::string s;
char buf[2];
- if (plain.size() > 65535)
+ if (plain.size() > STRING_MAX_LEN)
throw SerializationError("String too long for serializeString");
writeU16((u8 *)&buf[0], plain.size());
std::string s;
char buf[2];
- if (plain.size() > 65535)
- throw SerializationError("String too long for serializeString");
+ if (plain.size() > WIDE_STRING_MAX_LEN)
+ throw SerializationError("String too long for serializeWideString");
writeU16((u8 *)buf, plain.size());
s.append(buf, 2);
is.read(buf, 2);
if (is.gcount() != 2)
- throw SerializationError("deSerializeString: size not read");
+ throw SerializationError("deSerializeWideString: size not read");
u16 s_size = readU16((u8 *)buf);
if (s_size == 0)
{
char buf[4];
- if (plain.size() > LONG_STRING_MAX)
+ if (plain.size() > LONG_STRING_MAX_LEN)
throw SerializationError("String too long for serializeLongString");
writeU32((u8*)&buf[0], plain.size());
return s;
// We don't really want a remote attacker to force us to allocate 4GB...
- if (s_size > LONG_STRING_MAX) {
+ if (s_size > LONG_STRING_MAX_LEN) {
throw SerializationError("deSerializeLongString: "
"string too long: " + itos(s_size) + " bytes");
}
Buffer<char> buf2(s_size);
is.read(&buf2[0], s_size);
- if (is.gcount() != s_size)
- throw SerializationError("deSerializeString: couldn't read all chars");
+ if ((u32)is.gcount() != s_size)
+ throw SerializationError("deSerializeLongString: couldn't read all chars");
s.reserve(s_size);
s.append(&buf2[0], s_size);
return os.str();
}
+std::string serializeJsonStringIfNeeded(const std::string &s)
+{
+ for (size_t i = 0; i < s.size(); ++i) {
+ if (s[i] <= 0x1f || s[i] >= 0x7f || s[i] == ' ' || s[i] == '\"')
+ return serializeJsonString(s);
+ }
+ return s;
+}
+
+std::string deSerializeJsonStringIfNeeded(std::istream &is)
+{
+ std::ostringstream tmp_os;
+ bool expect_initial_quote = true;
+ bool is_json = false;
+ bool was_backslash = false;
+ for (;;) {
+ char c = is.get();
+ if (is.eof())
+ break;
+
+ if (expect_initial_quote && c == '"') {
+ tmp_os << c;
+ is_json = true;
+ } else if(is_json) {
+ tmp_os << c;
+ if (was_backslash)
+ was_backslash = false;
+ else if (c == '\\')
+ was_backslash = true;
+ else if (c == '"')
+ break; // Found end of string
+ } else {
+ if (c == ' ') {
+ // Found end of word
+ is.unget();
+ break;
+ } else {
+ tmp_os << c;
+ }
+ }
+ expect_initial_quote = false;
+ }
+ if (is_json) {
+ std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
+ return deSerializeJsonString(tmp_is);
+ } else
+ return tmp_os.str();
+}
+
////
//// String/Struct conversions
////