Merge branch 'development' into json_mod_LTS

# Conflicts:
#	lib/shared_memory.cpp
#	src/controller/controller.cpp
#	src/io.cpp
#	src/output/output.cpp
#	src/output/output_http_internal.cpp
This commit is contained in:
Thulinma 2015-10-07 11:05:49 +02:00
commit 74c8932106
18 changed files with 535 additions and 348 deletions

View file

@ -84,11 +84,11 @@ void Util::Config::addOption(std::string optname, JSON::Value option) {
vals[optname].removeMember("default");
}
long_count = 0;
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
if (it->second.isMember("long")) {
jsonForEach(vals, it) {
if (it->isMember("long")) {
long_count++;
}
if (it->second.isMember("long_off")) {
if (it->isMember("long_off")) {
long_count++;
}
}
@ -98,33 +98,33 @@ void Util::Config::addOption(std::string optname, JSON::Value option) {
void Util::Config::printHelp(std::ostream & output) {
unsigned int longest = 0;
std::map<long long int, std::string> args;
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
jsonForEach(vals, it) {
unsigned int current = 0;
if (it->second.isMember("long")) {
current += it->second["long"].asString().size() + 4;
if (it->isMember("long")) {
current += (*it)["long"].asString().size() + 4;
}
if (it->second.isMember("short")) {
current += it->second["short"].asString().size() + 3;
if (it->isMember("short")) {
current += (*it)["short"].asString().size() + 3;
}
if (current > longest) {
longest = current;
}
current = 0;
if (it->second.isMember("long_off")) {
current += it->second["long_off"].asString().size() + 4;
if (it->isMember("long_off")) {
current += (*it)["long_off"].asString().size() + 4;
}
if (it->second.isMember("short_off")) {
current += it->second["short_off"].asString().size() + 3;
if (it->isMember("short_off")) {
current += (*it)["short_off"].asString().size() + 3;
}
if (current > longest) {
longest = current;
}
if (it->second.isMember("arg_num")) {
current = it->first.size() + 3;
if (it->isMember("arg_num")) {
current = it.key().size() + 3;
if (current > longest) {
longest = current;
}
args[it->second["arg_num"].asInt()] = it->first;
args[(*it)["arg_num"].asInt()] = it.key();
}
}
output << "Usage: " << getString("cmd") << " [options]";
@ -136,54 +136,54 @@ void Util::Config::printHelp(std::ostream & output) {
}
}
output << std::endl << std::endl;
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
jsonForEach(vals, it) {
std::string f;
if (it->second.isMember("long") || it->second.isMember("short")) {
if (it->second.isMember("long") && it->second.isMember("short")) {
f = "--" + it->second["long"].asString() + ", -" + it->second["short"].asString();
if (it->isMember("long") || it->isMember("short")) {
if (it->isMember("long") && it->isMember("short")) {
f = "--" + (*it)["long"].asString() + ", -" + (*it)["short"].asString();
} else {
if (it->second.isMember("long")) {
f = "--" + it->second["long"].asString();
if (it->isMember("long")) {
f = "--" + (*it)["long"].asString();
}
if (it->second.isMember("short")) {
f = "-" + it->second["short"].asString();
if (it->isMember("short")) {
f = "-" + (*it)["short"].asString();
}
}
while (f.size() < longest) {
f.append(" ");
}
if (it->second.isMember("arg")) {
output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl;
if (it->isMember("arg")) {
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl;
} else {
output << f << it->second["help"].asString() << std::endl;
output << f << (*it)["help"].asString() << std::endl;
}
}
if (it->second.isMember("long_off") || it->second.isMember("short_off")) {
if (it->second.isMember("long_off") && it->second.isMember("short_off")) {
f = "--" + it->second["long_off"].asString() + ", -" + it->second["short_off"].asString();
if (it->isMember("long_off") || it->isMember("short_off")) {
if (it->isMember("long_off") && it->isMember("short_off")) {
f = "--" + (*it)["long_off"].asString() + ", -" + (*it)["short_off"].asString();
} else {
if (it->second.isMember("long_off")) {
f = "--" + it->second["long_off"].asString();
if (it->isMember("long_off")) {
f = "--" + (*it)["long_off"].asString();
}
if (it->second.isMember("short_off")) {
f = "-" + it->second["short_off"].asString();
if (it->isMember("short_off")) {
f = "-" + (*it)["short_off"].asString();
}
}
while (f.size() < longest) {
f.append(" ");
}
if (it->second.isMember("arg")) {
output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl;
if (it->isMember("arg")) {
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl;
} else {
output << f << it->second["help"].asString() << std::endl;
output << f << (*it)["help"].asString() << std::endl;
}
}
if (it->second.isMember("arg_num")) {
f = it->first;
if (it->isMember("arg_num")) {
f = it.key();
while (f.size() < longest) {
f.append(" ");
}
output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl;
output << f << "(" << (*it)["arg"].asString() << ") " << (*it)["help"].asString() << std::endl;
}
}
}
@ -197,42 +197,43 @@ bool Util::Config::parseArgs(int & argc, char ** & argv) {
int long_i = 0;
int arg_count = 0;
if (vals.size()) {
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
if (it->second.isMember("short")) {
shortopts += it->second["short"].asString();
if (it->second.isMember("arg")) {
jsonForEach(vals, it) {
if (it->isMember("short")) {
shortopts += (*it)["short"].asString();
if (it->isMember("arg")) {
shortopts += ":";
}
}
if (it->second.isMember("short_off")) {
shortopts += it->second["short_off"].asString();
if (it->second.isMember("arg")) {
if (it->isMember("short_off")) {
shortopts += (*it)["short_off"].asString();
if (it->isMember("arg")) {
shortopts += ":";
}
}
if (it->second.isMember("long")) {
longOpts[long_i].name = it->second["long"].asString().c_str();
longOpts[long_i].val = it->second["short"].asString()[0];
if (it->second.isMember("arg")) {
if (it->isMember("long")) {
longOpts[long_i].name = (*it)["long"].asStringRef().c_str();
longOpts[long_i].val = (*it)["short"].asString()[0];
if (it->isMember("arg")) {
longOpts[long_i].has_arg = 1;
}
long_i++;
}
if (it->second.isMember("long_off")) {
longOpts[long_i].name = it->second["long_off"].asString().c_str();
longOpts[long_i].val = it->second["short_off"].asString()[0];
if (it->second.isMember("arg")) {
if (it->isMember("long_off")) {
longOpts[long_i].name = (*it)["long_off"].asStringRef().c_str();
longOpts[long_i].val = (*it)["short_off"].asString()[0];
if (it->isMember("arg")) {
longOpts[long_i].has_arg = 1;
}
long_i++;
}
if (it->second.isMember("arg_num") && !(it->second.isMember("value") && it->second["value"].size())) {
if (it->second["arg_num"].asInt() > arg_count) {
arg_count = it->second["arg_num"].asInt();
if (it->isMember("arg_num") && !(it->isMember("value") && (*it)["value"].size())) {
if ((*it)["arg_num"].asInt() > arg_count) {
arg_count = (*it)["arg_num"].asInt();
}
}
}
}
while ((opt = getopt_long(argc, argv, shortopts.c_str(), longOpts, 0)) != -1) {
switch (opt) {
case 'h':
@ -267,17 +268,17 @@ bool Util::Config::parseArgs(int & argc, char ** & argv) {
exit(1);
break;
default:
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
if (it->second.isMember("short") && it->second["short"].asString()[0] == opt) {
if (it->second.isMember("arg")) {
it->second["value"].append((std::string)optarg);
jsonForEach(vals, it) {
if (it->isMember("short") && (*it)["short"].asString()[0] == opt) {
if (it->isMember("arg")) {
(*it)["value"].append((std::string)optarg);
} else {
it->second["value"].append((long long int)1);
(*it)["value"].append((long long int)1);
}
break;
}
if (it->second.isMember("short_off") && it->second["short_off"].asString()[0] == opt) {
it->second["value"].append((long long int)0);
if (it->isMember("short_off") && (*it)["short_off"].asString()[0] == opt) {
(*it)["value"].append((long long int)0);
}
}
break;
@ -286,9 +287,9 @@ bool Util::Config::parseArgs(int & argc, char ** & argv) {
free(longOpts); //free the long options array
long_i = 1; //re-use long_i as an argument counter
while (optind < argc) { //parse all remaining options, ignoring anything unexpected.
for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) {
if (it->second.isMember("arg_num") && it->second["arg_num"].asInt() == long_i) {
it->second["value"].append((std::string)argv[optind]);
jsonForEach(vals, it) {
if (it->isMember("arg_num") && (*it)["arg_num"].asInt() == long_i) {
(*it)["value"].append((std::string)argv[optind]);
break;
}
}

View file

@ -1325,9 +1325,10 @@ namespace DTSC {
if (meta.isMember("buffer_window")) {
bufferWindow = meta["buffer_window"].asInt();
}
for (JSON::ObjIter it = meta["tracks"].ObjBegin(); it != meta["tracks"].ObjEnd(); it++) {
if (it->second["trackid"].asInt()) {
tracks[it->second["trackid"].asInt()] = Track(it->second);
//for (JSON::ObjIter it = meta["tracks"].ObjBegin(); it != meta["tracks"].ObjEnd(); it++) {
jsonForEach(meta["tracks"], it) {
if ((*it)["trackid"].asInt()) {
tracks[(*it)["trackid"].asInt()] = Track((*it));
}
}
if (meta.isMember("moreheader")) {

View file

@ -9,6 +9,140 @@
#include <string.h> //for memcpy
#include <arpa/inet.h> //for htonl
/// Construct from a root Value to iterate over.
JSON::Iter::Iter(Value & root){
myType = root.myType;
i = 0;
r = &root;
if (!root.size()){myType = JSON::EMPTY;}
if (myType == JSON::ARRAY){
aIt = root.arrVal.begin();
}
if (myType == JSON::OBJECT){
oIt = root.objVal.begin();
}
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
JSON::Value & JSON::Iter::operator*() const{
if (myType == JSON::ARRAY && aIt != r->arrVal.end()){
return **aIt;
}
if (myType == JSON::OBJECT && oIt != r->objVal.end()){
return *(oIt->second);
}
static JSON::Value error;
WARN_MSG("Dereferenced invalid JSON iterator");
return error;
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
JSON::Value * JSON::Iter::operator->() const{
return &(operator*());
}
/// True if not done iterating.
JSON::Iter::operator bool() const{
return ((myType == JSON::ARRAY && aIt != r->arrVal.end()) || (myType == JSON::OBJECT && oIt != r->objVal.end()));
}
/// Go to next iteration.
JSON::Iter & JSON::Iter::operator++(){
if (*this){
++i;
if (myType == JSON::ARRAY){
++aIt;
}
if (myType == JSON::OBJECT){
++oIt;
}
}
}
/// Return the name of the current indice.
const std::string & JSON::Iter::key() const{
if (myType == JSON::OBJECT && *this){
return oIt->first;
}
static const std::string empty;
WARN_MSG("Got key from invalid JSON iterator");
return empty;
}
/// Return the number of the current indice.
unsigned int JSON::Iter::num() const{
return i;
}
/// Construct from a root Value to iterate over.
JSON::ConstIter::ConstIter(const Value & root){
myType = root.myType;
i = 0;
r = &root;
if (!root.size()){myType = JSON::EMPTY;}
if (myType == JSON::ARRAY){
aIt = root.arrVal.begin();
}
if (myType == JSON::OBJECT){
oIt = root.objVal.begin();
}
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
const JSON::Value & JSON::ConstIter::operator*() const{
if (myType == JSON::ARRAY && aIt != r->arrVal.end()){
return **aIt;
}
if (myType == JSON::OBJECT && oIt != r->objVal.end()){
return *(oIt->second);
}
static JSON::Value error;
WARN_MSG("Dereferenced invalid JSON iterator");
return error;
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
const JSON::Value * JSON::ConstIter::operator->() const{
return &(operator*());
}
/// True if not done iterating.
JSON::ConstIter::operator bool() const{
return ((myType == JSON::ARRAY && aIt != r->arrVal.end()) || (myType == JSON::OBJECT && oIt != r->objVal.end()));
}
/// Go to next iteration.
JSON::ConstIter & JSON::ConstIter::operator++(){
if (*this){
++i;
if (myType == JSON::ARRAY){
++aIt;
}
if (myType == JSON::OBJECT){
++oIt;
}
}
}
/// Return the name of the current indice.
const std::string & JSON::ConstIter::key() const{
if (myType == JSON::OBJECT && *this){
return oIt->first;
}
static const std::string empty;
WARN_MSG("Got key from invalid JSON iterator");
return empty;
}
/// Return the number of the current indice.
unsigned int JSON::ConstIter::num() const{
return i;
}
static inline char c2hex(char c) {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
@ -142,6 +276,16 @@ JSON::Value::Value() {
null();
}
/// Sets this JSON::Value to null
JSON::Value::~Value() {
null();
}
JSON::Value::Value(const Value & rhs) {
null();
*this = rhs;
}
/// Sets this JSON::Value to read from this position in the std::istream
JSON::Value::Value(std::istream & fromstream) {
null();
@ -271,6 +415,16 @@ JSON::Value::Value(long long int val) {
intVal = val;
}
/// Sets this JSON::Value to the given integer.
JSON::Value::Value(bool val) {
myType = BOOL;
if (val){
intVal = 1;
}else{
intVal = 0;
}
}
/// Compares a JSON::Value to another for equality.
bool JSON::Value::operator==(const JSON::Value & rhs) const {
if (myType != rhs.myType) return false;
@ -285,11 +439,11 @@ bool JSON::Value::operator==(const JSON::Value & rhs) const {
}
if (myType == OBJECT) {
if (objVal.size() != rhs.objVal.size()) return false;
for (std::map<std::string, Value>::const_iterator it = objVal.begin(); it != objVal.end(); ++it) {
for (std::map<std::string, Value*>::const_iterator it = objVal.begin(); it != objVal.end(); ++it) {
if (!rhs.isMember(it->first)) {
return false;
}
if (it->second != rhs.objVal.find(it->first)->second) {
if (*(it->second) != rhs.objVal.find(it->first)->second) {
return false;
}
}
@ -298,8 +452,8 @@ bool JSON::Value::operator==(const JSON::Value & rhs) const {
if (myType == ARRAY) {
if (arrVal.size() != rhs.arrVal.size()) return false;
int i = 0;
for (std::deque<Value>::const_iterator it = arrVal.begin(); it != arrVal.end(); ++it) {
if (*it != rhs.arrVal[i]) {
for (std::deque<Value*>::const_iterator it = arrVal.begin(); it != arrVal.end(); ++it) {
if (**it != *(rhs.arrVal[i])) {
return false;
}
i++;
@ -314,6 +468,38 @@ bool JSON::Value::operator!=(const JSON::Value & rhs) const {
return !((*this) == rhs);
}
/// Completely clears the contents of this value,
/// changing its type to NULL in the process.
void JSON::Value::null() {
shrink(0);
strVal.clear();
intVal = 0;
myType = EMPTY;
}
/// Sets this JSON::Value to be equal to the given JSON::Value.
JSON::Value & JSON::Value::operator=(const JSON::Value & rhs) {
null();
myType = rhs.myType;
if (myType == STRING){
strVal = rhs.strVal;
}
if (myType == BOOL || myType == INTEGER){
intVal = rhs.intVal;
}
if (myType == OBJECT){
jsonForEachConst(rhs, i){
(*this)[i.key()] = *i;
}
}
if (myType == ARRAY){
jsonForEachConst(rhs, i){
append(*i);
}
}
return *this;
}
/// Sets this JSON::Value to the given boolean.
JSON::Value & JSON::Value::operator=(const bool & rhs) {
null();
@ -445,7 +631,12 @@ JSON::Value & JSON::Value::operator[](const std::string i) {
null();
myType = OBJECT;
}
return objVal[i];
Value * pntr = objVal[i];
if (!pntr){
objVal[i] = new JSON::Value();
pntr = objVal[i];
}
return *pntr;
}
/// Retrieves or sets the JSON::Value at this position in the object.
@ -455,7 +646,12 @@ JSON::Value & JSON::Value::operator[](const char * i) {
null();
myType = OBJECT;
}
return objVal[i];
Value * pntr = objVal[i];
if (!pntr){
objVal[i] = new JSON::Value();
pntr = objVal[i];
}
return *pntr;
}
/// Retrieves or sets the JSON::Value at this position in the array.
@ -466,27 +662,27 @@ JSON::Value & JSON::Value::operator[](unsigned int i) {
myType = ARRAY;
}
while (i >= arrVal.size()) {
append(JSON::Value());
append(new JSON::Value());
}
return arrVal[i];
return *arrVal[i];
}
/// Retrieves the JSON::Value at this position in the object.
/// Fails horribly if that values does not exist.
const JSON::Value & JSON::Value::operator[](const std::string i) const {
return objVal.find(i)->second;
return *objVal.find(i)->second;
}
/// Retrieves the JSON::Value at this position in the object.
/// Fails horribly if that values does not exist.
const JSON::Value & JSON::Value::operator[](const char * i) const {
return objVal.find(i)->second;
return *objVal.find(i)->second;
}
/// Retrieves the JSON::Value at this position in the array.
/// Fails horribly if that values does not exist.
const JSON::Value & JSON::Value::operator[](unsigned int i) const {
return arrVal[i];
return *arrVal[i];
}
/// Packs to a std::string for transfer over the network.
@ -517,12 +713,12 @@ std::string JSON::Value::toPacked() const {
if (isObject()) {
r += 0xE0;
if (objVal.size() > 0) {
for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) {
if (it->first.size() > 0) {
r += it->first.size() / 256;
r += it->first.size() % 256;
r += it->first;
r += it->second.toPacked();
jsonForEachConst(*this, i){
if (i.key().size() > 0) {
r += i.key().size() / 256;
r += i.key().size() % 256;
r += i.key();
r += i->toPacked();
}
}
}
@ -532,8 +728,8 @@ std::string JSON::Value::toPacked() const {
}
if (isArray()) {
r += 0x0A;
for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) {
r += it->toPacked();
jsonForEachConst(*this, i){
r += i->toPacked();
}
r += (char)0x0;
r += (char)0x0;
@ -563,13 +759,13 @@ void JSON::Value::sendTo(Socket::Connection & socket) const {
}
if (isObject()) {
if (isMember("trackid") && isMember("time")) {
unsigned int trackid = objVal.find("trackid")->second.asInt();
long long time = objVal.find("time")->second.asInt();
unsigned int trackid = objVal.find("trackid")->second->asInt();
long long time = objVal.find("time")->second->asInt();
unsigned int size = 16;
if (objVal.size() > 0) {
for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) {
if (it->first.size() > 0 && it->first != "trackid" && it->first != "time" && it->first != "datatype") {
size += 2 + it->first.size() + it->second.packedSize();
jsonForEachConst(*this, i){
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" && i.key() != "datatype") {
size += 2 + i.key().size() + i->packedSize();
}
}
}
@ -584,14 +780,14 @@ void JSON::Value::sendTo(Socket::Connection & socket) const {
socket.SendNow((char *)&tmpHalf, 4);
socket.SendNow("\340", 1);
if (objVal.size() > 0) {
for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) {
if (it->first.size() > 0 && it->first != "trackid" && it->first != "time" && it->first != "datatype") {
jsonForEachConst(*this, i){
if (i.key().size() > 0 && i.key() != "trackid" && i.key() != "time" && i.key() != "datatype") {
char sizebuffer[2] = {0, 0};
sizebuffer[0] = (it->first.size() >> 8) & 0xFF;
sizebuffer[1] = it->first.size() & 0xFF;
sizebuffer[0] = (i.key().size() >> 8) & 0xFF;
sizebuffer[1] = i.key().size() & 0xFF;
socket.SendNow(sizebuffer, 2);
socket.SendNow(it->first);
it->second.sendTo(socket);
socket.SendNow(i.key());
i->sendTo(socket);
}
}
}
@ -605,14 +801,14 @@ void JSON::Value::sendTo(Socket::Connection & socket) const {
}
socket.SendNow("\340", 1);
if (objVal.size() > 0) {
for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) {
if (it->first.size() > 0) {
jsonForEachConst(*this, i){
if (i.key().size() > 0) {
char sizebuffer[2] = {0, 0};
sizebuffer[0] = (it->first.size() >> 8) & 0xFF;
sizebuffer[1] = it->first.size() & 0xFF;
sizebuffer[0] = (i.key().size() >> 8) & 0xFF;
sizebuffer[1] = i.key().size() & 0xFF;
socket.SendNow(sizebuffer, 2);
socket.SendNow(it->first);
it->second.sendTo(socket);
socket.SendNow(i.key());
i->sendTo(socket);
}
}
}
@ -621,8 +817,8 @@ void JSON::Value::sendTo(Socket::Connection & socket) const {
}
if (isArray()) {
socket.SendNow("\012", 1);
for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) {
it->sendTo(socket);
jsonForEachConst(*this, i){
i->sendTo(socket);
}
socket.SendNow("\000\000\356", 3);
return;
@ -640,9 +836,9 @@ unsigned int JSON::Value::packedSize() const {
if (isObject()) {
unsigned int ret = 4;
if (objVal.size() > 0) {
for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) {
if (it->first.size() > 0) {
ret += 2 + it->first.size() + it->second.packedSize();
jsonForEachConst(*this, i){
if (i.key().size() > 0) {
ret += 2 + i.key().size() + i->packedSize();
}
}
}
@ -650,8 +846,8 @@ unsigned int JSON::Value::packedSize() const {
}
if (isArray()) {
unsigned int ret = 4;
for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) {
ret += it->packedSize();
jsonForEachConst(*this, i){
ret += i->packedSize();
}
return ret;
}
@ -669,20 +865,20 @@ void JSON::Value::netPrepare() {
std::string packed = toPacked();
//insert proper header for this type of data
int packID = -1;
long long unsigned int time = objVal["time"].asInt();
long long unsigned int time = (*this)["time"].asInt();
std::string dataType;
if (isMember("datatype") || isMember("trackid")) {
dataType = objVal["datatype"].asString();
dataType = (*this)["datatype"].asString();
if (isMember("trackid")) {
packID = objVal["trackid"].asInt();
packID = (*this)["trackid"].asInt();
} else {
if (objVal["datatype"].asString() == "video") {
if ((*this)["datatype"].asString() == "video") {
packID = 1;
}
if (objVal["datatype"].asString() == "audio") {
if ((*this)["datatype"].asString() == "audio") {
packID = 2;
}
if (objVal["datatype"].asString() == "meta") {
if ((*this)["datatype"].asString() == "meta") {
packID = 3;
}
//endmark and the likes...
@ -696,9 +892,9 @@ void JSON::Value::netPrepare() {
}
removeMember("trackid");
packed = toPacked();
objVal["time"] = (long long int)time;
objVal["datatype"] = dataType;
objVal["trackid"] = packID;
(*this)["time"] = (long long int)time;
(*this)["datatype"] = dataType;
(*this)["trackid"] = packID;
strVal.resize(packed.size() + 20);
memcpy((void *)strVal.c_str(), "DTP2", 4);
} else {
@ -771,9 +967,9 @@ std::string JSON::Value::toString() const {
case ARRAY: {
std::string tmp = "[";
if (arrVal.size() > 0) {
for (ArrConstIter it = ArrBegin(); it != ArrEnd(); it++) {
tmp += it->toString();
if (it + 1 != ArrEnd()) {
jsonForEachConst(*this, i){
tmp += i->toString();
if (i.num()+1 != arrVal.size()) {
tmp += ",";
}
}
@ -785,12 +981,10 @@ std::string JSON::Value::toString() const {
case OBJECT: {
std::string tmp2 = "{";
if (objVal.size() > 0) {
ObjConstIter it3 = ObjEnd();
--it3;
for (ObjConstIter it2 = ObjBegin(); it2 != ObjEnd(); it2++) {
tmp2 += string_escape(it2->first) + ":";
tmp2 += it2->second.toString();
if (it2 != it3) {
jsonForEachConst(*this, i){
tmp2 += string_escape(i.key()) + ":";
tmp2 += i->toString();
if (i.num()+1 != objVal.size()) {
tmp2 += ",";
}
}
@ -828,9 +1022,9 @@ std::string JSON::Value::toPrettyString(int indentation) const {
case ARRAY: {
if (arrVal.size() > 0) {
std::string tmp = "[\n" + std::string(indentation + 2, ' ');
for (ArrConstIter it = ArrBegin(); it != ArrEnd(); it++) {
tmp += it->toPrettyString(indentation + 2);
if (it + 1 != ArrEnd()) {
jsonForEachConst(*this, i){
tmp += i->toPrettyString(indentation + 2);
if (i.num() + 1 != arrVal.size()) {
tmp += ", ";
}
}
@ -848,12 +1042,10 @@ std::string JSON::Value::toPrettyString(int indentation) const {
shortMode = true;
}
std::string tmp2 = "{" + std::string((shortMode ? "" : "\n"));
ObjConstIter it3 = ObjEnd();
--it3;
for (ObjConstIter it2 = ObjBegin(); it2 != ObjEnd(); it2++) {
tmp2 += (shortMode ? std::string("") : std::string(indentation + 2, ' ')) + string_escape(it2->first) + ":";
tmp2 += it2->second.toPrettyString(indentation + 2);
if (it2 != it3) {
jsonForEachConst(*this, i){
tmp2 += (shortMode ? std::string("") : std::string(indentation + 2, ' ')) + string_escape(i.key()) + ":";
tmp2 += i->toPrettyString(indentation + 2);
if (i.num() + 1 != objVal.size()) {
tmp2 += "," + std::string((shortMode ? " " : "\n"));
}
}
@ -878,7 +1070,7 @@ void JSON::Value::append(const JSON::Value & rhs) {
null();
myType = ARRAY;
}
arrVal.push_back(rhs);
arrVal.push_back(new JSON::Value(rhs));
}
/// Prepends the given value to the beginning of this JSON::Value array.
@ -888,7 +1080,7 @@ void JSON::Value::prepend(const JSON::Value & rhs) {
null();
myType = ARRAY;
}
arrVal.push_front(rhs);
arrVal.push_front(new JSON::Value(rhs));
}
/// For array and object JSON::Value objects, reduces them
@ -898,24 +1090,23 @@ void JSON::Value::prepend(const JSON::Value & rhs) {
/// do anything if the size is already lower or equal to the
/// given size.
void JSON::Value::shrink(unsigned int size) {
if (myType == ARRAY) {
while (arrVal.size() > size) {
arrVal.pop_front();
}
return;
while (arrVal.size() > size) {
delete arrVal.front();
arrVal.pop_front();
}
if (myType == OBJECT) {
while (objVal.size() > size) {
objVal.erase(objVal.begin());
}
return;
while (objVal.size() > size) {
delete objVal.begin()->second;
objVal.erase(objVal.begin());
}
}
/// For object JSON::Value objects, removes the member with
/// the given name, if it exists. Has no effect otherwise.
void JSON::Value::removeMember(const std::string & name) {
objVal.erase(name);
if (objVal.count(name)){
delete objVal[name];
objVal.erase(name);
}
}
/// For object JSON::Value objects, returns true if the
@ -954,61 +1145,11 @@ bool JSON::Value::isNull() const {
return (myType == EMPTY);
}
/// Returns an iterator to the begin of the object map, if any.
JSON::ObjIter JSON::Value::ObjBegin() {
return objVal.begin();
}
/// Returns an iterator to the end of the object map, if any.
JSON::ObjIter JSON::Value::ObjEnd() {
return objVal.end();
}
/// Returns an iterator to the begin of the array, if any.
JSON::ArrIter JSON::Value::ArrBegin() {
return arrVal.begin();
}
/// Returns an iterator to the end of the array, if any.
JSON::ArrIter JSON::Value::ArrEnd() {
return arrVal.end();
}
/// Returns an iterator to the begin of the object map, if any.
JSON::ObjConstIter JSON::Value::ObjBegin() const {
return objVal.begin();
}
/// Returns an iterator to the end of the object map, if any.
JSON::ObjConstIter JSON::Value::ObjEnd() const {
return objVal.end();
}
/// Returns an iterator to the begin of the array, if any.
JSON::ArrConstIter JSON::Value::ArrBegin() const {
return arrVal.begin();
}
/// Returns an iterator to the end of the array, if any.
JSON::ArrConstIter JSON::Value::ArrEnd() const {
return arrVal.end();
}
/// Returns the total of the objects and array size combined.
unsigned int JSON::Value::size() const {
return objVal.size() + arrVal.size();
}
/// Completely clears the contents of this value,
/// changing its type to NULL in the process.
void JSON::Value::null() {
objVal.clear();
arrVal.clear();
strVal.clear();
intVal = 0;
myType = EMPTY;
}
/// Converts a std::string to a JSON::Value.
JSON::Value JSON::fromString(std::string json) {
std::istringstream is(json);
@ -1101,8 +1242,9 @@ void JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int &
case 0x0A: { //array
++i;
while (data[i] + data[i + 1] != 0 && i < len) { //while not encountering 0x0000 (we assume 0x0000EE)
ret.append(JSON::Value());
fromDTMI(data, len, i, *--ret.ArrEnd()); //add content, recursively parsed, updating i
JSON::Value tval;
fromDTMI(data, len, i, tval); //add content, recursively parsed, updating i
ret.append(tval);
}
i += 3; //skip 0x0000EE
return;

View file

@ -21,27 +21,24 @@ namespace JSON {
EMPTY, BOOL, INTEGER, STRING, ARRAY, OBJECT
};
class Value;
//forward declaration for below typedef
typedef std::map<std::string, Value>::iterator ObjIter;
typedef std::deque<Value>::iterator ArrIter;
typedef std::map<std::string, Value>::const_iterator ObjConstIter;
typedef std::deque<Value>::const_iterator ArrConstIter;
/// A JSON::Value is either a string or an integer, but may also be an object, array or null.
class Value {
friend class Iter;
friend class ConstIter;
private:
ValueType myType;
long long int intVal;
std::string strVal;
std::deque<Value> arrVal;
std::map<std::string, Value> objVal;
std::deque<Value*> arrVal;
std::map<std::string, Value*> objVal;
public:
//friends
friend class DTSC::Stream; //for access to strVal
//constructors
//constructors/destructors
Value();
~Value();
Value(const Value & rhs);
Value(std::istream & fromstream);
Value(const std::string & val);
Value(const char * val);
@ -51,6 +48,7 @@ namespace JSON {
bool operator==(const Value & rhs) const;
bool operator!=(const Value & rhs) const;
//assignment operators
Value & operator=(const Value & rhs);
Value & operator=(const std::string & rhs);
Value & operator=(const char * rhs);
Value & operator=(const long long int & rhs);
@ -92,14 +90,6 @@ namespace JSON {
bool isObject() const;
bool isArray() const;
bool isNull() const;
ObjIter ObjBegin();
ObjIter ObjEnd();
ArrIter ArrBegin();
ArrIter ArrEnd();
ObjConstIter ObjBegin() const;
ObjConstIter ObjEnd() const;
ArrConstIter ArrBegin() const;
ArrConstIter ArrEnd() const;
unsigned int size() const;
void null();
};
@ -115,6 +105,41 @@ namespace JSON {
void fromDTMI(std::string & data, Value & ret);
void fromDTMI(const unsigned char * data, unsigned int len, unsigned int & i, Value & ret);
class Iter {
public:
Iter(Value & root);///<Construct from a root Value to iterate over.
Value & operator*() const;///< Dereferences into a Value reference.
Value* operator->() const;///< Dereferences into a Value reference.
operator bool() const;///< True if not done iterating.
Iter & operator++();///<Go to next iteration.
const std::string & key() const;///<Return the name of the current indice.
unsigned int num() const;///<Return the number of the current indice.
private:
ValueType myType;
Value * r;
unsigned int i;
std::deque<Value*>::iterator aIt;
std::map<std::string, Value*>::iterator oIt;
};
class ConstIter {
public:
ConstIter(const Value & root);///<Construct from a root Value to iterate over.
const Value & operator*() const;///< Dereferences into a Value reference.
const Value* operator->() const;///< Dereferences into a Value reference.
operator bool() const;///< True if not done iterating.
ConstIter & operator++();///<Go to next iteration.
const std::string & key() const;///<Return the name of the current indice.
unsigned int num() const;///<Return the number of the current indice.
private:
ValueType myType;
const Value * r;
unsigned int i;
std::deque<Value*>::const_iterator aIt;
std::map<std::string, Value*>::const_iterator oIt;
};
#define jsonForEach(val, i) for(JSON::Iter i(val); i; ++i)
#define jsonForEachConst(val, i) for(JSON::ConstIter i(val); i; ++i)
template <typename T>
std::string encodeVector(T begin, T end) {
std::string result;

View file

@ -13,6 +13,7 @@
#include "stream.h"
#include "procs.h"
#include "bitfields.h"
#include "timing.h"
namespace IPC {
@ -206,6 +207,18 @@ namespace IPC {
WARN_MSG("Consistency error caught on semaphore %s", myName.c_str());
result = 0;
}
#elif defined(__APPLE__)
/// \todo (roxlu) test tryWaitOneSecond, shared_memory.cpp
long long unsigned int now = Util::getMicros();
long long unsigned int timeout = now + 1e6;
while (now < timeout) {
if (0 == sem_trywait(mySem)) {
return true;
}
usleep(100e3);
now = Util::getMicros();
}
return false;
#else
struct timespec wt;
wt.tv_sec = 1;