Optimized JSON::Value for files, and not a little bit, either.

This commit is contained in:
Thulinma 2014-01-10 14:13:06 +01:00
parent 10e4a78398
commit 583ffd7e89
3 changed files with 81 additions and 46 deletions

View file

@ -54,7 +54,8 @@ bool DTSC::Stream::parsePacket(std::string & buffer){
return false;
}
unsigned int i = 0;
JSON::Value meta = JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i);
JSON::Value meta;
JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i, meta);
metadata = Meta(meta);
buffer.erase(0, len + 8);
if (buffer.length() <= 8){
@ -76,10 +77,10 @@ bool DTSC::Stream::parsePacket(std::string & buffer){
JSON::Value newPack;
unsigned int i = 0;
if (version == 1){
newPack = JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i);
JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i, newPack);
}
if (version == 2){
newPack = JSON::fromDTMI2((unsigned char*)buffer.c_str() + 8, len, i);
JSON::fromDTMI2((unsigned char*)buffer.c_str() + 8, len, i, newPack);
}
buffer.erase(0, len + 8);
addPacket(newPack);
@ -123,7 +124,8 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){
}
unsigned int i = 0;
std::string wholepacket = buffer.remove(len + 8);
JSON::Value meta = JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i);
JSON::Value meta;
JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i, meta);
addMeta(meta);
//recursively calls itself until failure or data packet instead of header
return parsePacket(buffer);
@ -144,10 +146,10 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){
unsigned int i = 0;
std::string wholepacket = buffer.remove(len + 8);
if (version == 1){
newPack = JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i);
JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i, newPack);
}
if (version == 2){
newPack = JSON::fromDTMI2((unsigned char*)wholepacket.c_str() + 8, len, i);
JSON::fromDTMI2((unsigned char*)wholepacket.c_str() + 8, len, i, newPack);
}
addPacket(newPack);
syncing = false;
@ -626,7 +628,7 @@ void DTSC::File::readHeader(int pos){
metadata = readOnlyMeta();
return;
}
metaStorage = JSON::fromDTMI(strbuffer);
JSON::fromDTMI(strbuffer, metaStorage);
metadata = readOnlyMeta(metaStorage);//make readonly
}
//if there is another header, read it and replace metadata with that one.
@ -720,9 +722,9 @@ void DTSC::File::seekNext(){
return;
}
if (version == 2){
jsonbuffer = JSON::fromDTMI2(strbuffer);
JSON::fromDTMI2(strbuffer, jsonbuffer);
}else{
jsonbuffer = JSON::fromDTMI(strbuffer);
JSON::fromDTMI(strbuffer, jsonbuffer);
}
if ( metadata.merged){
int tempLoc = getBytePos();
@ -799,7 +801,7 @@ void DTSC::File::parseNext(){
jsonbuffer.null();
return;
}
jsonbuffer = JSON::fromDTMI(strbuffer);
JSON::fromDTMI(strbuffer, jsonbuffer);
}
return;
}
@ -832,9 +834,9 @@ void DTSC::File::parseNext(){
return;
}
if (version == 2){
jsonbuffer = JSON::fromDTMI2(strbuffer);
JSON::fromDTMI2(strbuffer, jsonbuffer);
}else{
jsonbuffer = JSON::fromDTMI(strbuffer);
JSON::fromDTMI(strbuffer, jsonbuffer);
}
}

View file

@ -1006,16 +1006,29 @@ JSON::Value JSON::fromFile(std::string filename){
/// \param i Current parsing position in the raw data (defaults to 0).
/// \returns A single JSON::Value, parsed from the raw data.
JSON::Value JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int &i){
JSON::Value ret;
fromDTMI(data, len, i, ret);
return ret;
}
/// Parses a single DTMI type - used recursively by the JSON::fromDTMI functions.
/// This function updates i every call with the new position in the data.
/// \param data The raw data to parse.
/// \param len The size of the raw data.
/// \param i Current parsing position in the raw data (defaults to 0).
/// \param ret Will be set to JSON::Value, parsed from the raw data.
void JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int &i, JSON::Value & ret){
#if DEBUG >= 10
fprintf(stderr, "Note: AMF type %hhx found. %i bytes left\n", data[i], len-i);
#endif
ret.null();
if (i >= len){
return JSON::Value();
return;
}
switch (data[i]){
case 0x01: { //integer
if (i+8 >= len){
return JSON::Value();
return;
}
unsigned char tmpdbl[8];
tmpdbl[7] = data[i + 1];
@ -1028,47 +1041,49 @@ JSON::Value JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigne
tmpdbl[0] = data[i + 8];
i += 9; //skip 8(an uint64_t)+1 forwards
uint64_t * d = (uint64_t*)tmpdbl;
return JSON::Value((long long int) *d);
ret = (long long int) *d;
return;
break;
}
case 0x02: { //string
if (i+4 >= len){
return JSON::Value();
return;
}
unsigned int tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; //set tmpi to UTF-8-long length
std::string tmpstr = std::string((const char *)data + i + 5, (size_t)tmpi); //set the string data
if (i+4+tmpi >= len){
return JSON::Value();
return;
}
i += tmpi + 5; //skip length+size+1 forwards
return JSON::Value(tmpstr);
ret = tmpstr;
return;
break;
}
case 0xFF: //also object
case 0xE0: { //object
++i;
JSON::Value ret;
while (data[i] + data[i + 1] != 0 && i < len){ //while not encountering 0x0000 (we assume 0x0000EE)
if (i+2 >= len){
return JSON::Value();
return;
}
unsigned int tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length
std::string tmpstr = std::string((const char *)data + i + 2, (size_t)tmpi); //set the string data
i += tmpi + 2; //skip length+size forwards
ret[tmpstr] = fromDTMI(data, len, i); //add content, recursively parsed, updating i, setting indice to tmpstr
ret[tmpstr].null();
fromDTMI(data, len, i, ret[tmpstr]); //add content, recursively parsed, updating i, setting indice to tmpstr
}
i += 3; //skip 0x0000EE
return ret;
return;
break;
}
case 0x0A: { //array
JSON::Value ret;
++i;
while (data[i] + data[i + 1] != 0 && i < len){ //while not encountering 0x0000 (we assume 0x0000EE)
ret.append(fromDTMI(data, len, i)); //add content, recursively parsed, updating i
ret.append(JSON::Value());
fromDTMI(data, len, i, *--ret.ArrEnd()); //add content, recursively parsed, updating i
}
i += 3; //skip 0x0000EE
return ret;
return;
break;
}
}
@ -1076,37 +1091,51 @@ JSON::Value JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigne
fprintf(stderr, "Error: Unimplemented DTMI type %hhx, @ %i / %i - returning.\n", data[i], i, len);
#endif
i += 1;
return JSON::Value();
return;
} //fromOneDTMI
/// Parses a std::string to a valid JSON::Value.
/// This function will find one DTMI object in the string and return it.
JSON::Value JSON::fromDTMI(std::string data){
void JSON::fromDTMI(std::string & data, JSON::Value & ret){
unsigned int i = 0;
return fromDTMI((const unsigned char*)data.c_str(), data.size(), i, ret);
} //fromDTMI
/// Parses a std::string to a valid JSON::Value.
/// This function will find one DTMI object in the string and return it.
JSON::Value JSON::fromDTMI(std::string & data){
unsigned int i = 0;
return fromDTMI((const unsigned char*)data.c_str(), data.size(), i);
} //fromDTMI
JSON::Value JSON::fromDTMI2(std::string data){
long long int tmpTrackID = ntohl(((int*)(data.c_str()))[0]);
JSON::Value tmp = fromDTMI(data.substr(12));
long long int tmpTime = ntohl(((int*)(data.c_str() + 4))[0]);
tmpTime <<= 32;
tmpTime += ntohl(((int*)(data.c_str() + 8))[0]);
tmp["time"] = tmpTime;
tmp["trackid"] = tmpTrackID;
return tmp;
void JSON::fromDTMI2(std::string & data, JSON::Value & ret){
unsigned int i = 0;
fromDTMI2((const unsigned char*)data.c_str(), data.size(), i, ret);
return;
}
JSON::Value JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i){
JSON::Value tmp;
if (len < 13){return tmp;}
JSON::Value JSON::fromDTMI2(std::string & data){
JSON::Value ret;
unsigned int i = 0;
fromDTMI2((const unsigned char*)data.c_str(), data.size(), i, ret);
return ret;
}
void JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i, JSON::Value & ret){
if (len < 13){return;}
long long int tmpTrackID = ntohl(((int*)data)[0]);
long long int tmpTime = ntohl(((int*)data)[1]);
tmpTime <<= 32;
tmpTime += ntohl(((int*)data)[2]);
i += 12;
tmp = fromDTMI(data, len, i);
tmp["time"] = tmpTime;
tmp["trackid"] = tmpTrackID;
return tmp;
fromDTMI(data, len, i, ret);
ret["time"] = tmpTime;
ret["trackid"] = tmpTrackID;
return;
}
JSON::Value JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i){
JSON::Value ret;
fromDTMI2(data, len, i, ret);
return ret;
}

View file

@ -104,12 +104,16 @@ namespace JSON {
void null();
};
Value fromDTMI2(std::string data);
Value fromDTMI2(std::string & data);
Value fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i);
Value fromDTMI(std::string data);
Value fromDTMI(std::string & data);
Value fromDTMI(const unsigned char * data, unsigned int len, unsigned int &i);
Value fromString(std::string json);
Value fromFile(std::string filename);
void fromDTMI2(std::string & data, Value & ret);
void fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i, Value & ret);
void fromDTMI(std::string & data, Value & ret);
void fromDTMI(const unsigned char * data, unsigned int len, unsigned int &i, Value & ret);
template <typename T>
std::string encodeVector(T begin, T end){