diff --git a/lib/amf.cpp b/lib/amf.cpp index 8995f4f8..3d3fa9bc 100644 --- a/lib/amf.cpp +++ b/lib/amf.cpp @@ -6,49 +6,49 @@ #include /// Returns the std::string Indice for the current object, if available. /// Returns an empty string if no indice exists. -std::string AMF::Object::Indice(){ +std::string AMF::Object::Indice() { return myIndice; } /// Returns the AMF::obj0type AMF0 object type for this object. -AMF::obj0type AMF::Object::GetType(){ +AMF::obj0type AMF::Object::GetType() { return myType; } /// Returns the numeric value of this object, if available. /// If this object holds no numeric value, 0 is returned. -double AMF::Object::NumValue(){ +double AMF::Object::NumValue() { return numval; } /// Returns the std::string value of this object, if available. /// If this object holds no string value, an empty string is returned. -std::string AMF::Object::StrValue(){ +std::string AMF::Object::StrValue() { return strval; } /// Returns the C-string value of this object, if available. /// If this object holds no string value, an empty C-string is returned. -const char * AMF::Object::Str(){ +const char * AMF::Object::Str() { return strval.c_str(); } /// Returns a count of the amount of objects this object currently holds. /// If this object is not a container type, this function will always return 0. -int AMF::Object::hasContent(){ +int AMF::Object::hasContent() { return contents.size(); } /// Adds an AMF::Object to this object. Works for all types, but only makes sense for container types. -void AMF::Object::addContent(AMF::Object c){ +void AMF::Object::addContent(AMF::Object c) { contents.push_back(c); } /// Returns a pointer to the object held at indice i. /// Returns AMF::AMF0_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param i The indice of the object in this container. -AMF::Object* AMF::Object::getContentP(unsigned int i){ - if (i >= contents.size()){ +AMF::Object * AMF::Object::getContentP(unsigned int i) { + if (i >= contents.size()) { return 0; } return &contents.at(i); @@ -57,17 +57,17 @@ AMF::Object* AMF::Object::getContentP(unsigned int i){ /// Returns a copy of the object held at indice i. /// Returns a AMF::AMF0_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param i The indice of the object in this container. -AMF::Object AMF::Object::getContent(unsigned int i){ +AMF::Object AMF::Object::getContent(unsigned int i) { return contents.at(i); } /// Returns a pointer to the object held at indice s. /// Returns NULL if no object is held at this indice. /// \param s The indice of the object in this container. -AMF::Object* AMF::Object::getContentP(std::string s){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - if (it->Indice() == s){ - return &( *it); +AMF::Object * AMF::Object::getContentP(std::string s) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + if (it->Indice() == s) { + return &(*it); } } return 0; @@ -76,9 +76,9 @@ AMF::Object* AMF::Object::getContentP(std::string s){ /// Returns a copy of the object held at indice s. /// Returns a AMF::AMF0_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param s The indice of the object in this container. -AMF::Object AMF::Object::getContent(std::string s){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - if (it->Indice() == s){ +AMF::Object AMF::Object::getContent(std::string s) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + if (it->Indice() == s) { return *it; } } @@ -87,7 +87,7 @@ AMF::Object AMF::Object::getContent(std::string s){ /// Default constructor. /// Simply fills the data with AMF::Object("error", AMF0_DDV_CONTAINER) -AMF::Object::Object(){ +AMF::Object::Object() { *this = AMF::Object("error", AMF0_DDV_CONTAINER); } //default constructor @@ -96,7 +96,7 @@ AMF::Object::Object(){ /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param val The numeric value of this object. Numeric AMF0 objects only support double-type values. /// \param setType The object type to force this object to. -AMF::Object::Object(std::string indice, double val, AMF::obj0type setType){ //num type initializer +AMF::Object::Object(std::string indice, double val, AMF::obj0type setType) { //num type initializer myIndice = indice; myType = setType; strval = ""; @@ -109,7 +109,7 @@ AMF::Object::Object(std::string indice, double val, AMF::obj0type setType){ //nu /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param val The string value of this object. /// \param setType The object type to force this object to. -AMF::Object::Object(std::string indice, std::string val, AMF::obj0type setType){ //str type initializer +AMF::Object::Object(std::string indice, std::string val, AMF::obj0type setType) { //str type initializer myIndice = indice; myType = setType; strval = val; @@ -120,7 +120,7 @@ AMF::Object::Object(std::string indice, std::string val, AMF::obj0type setType){ /// The object type is by default AMF::AMF0_OBJECT, but this can be forced to a different value. /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param setType The object type to force this object to. -AMF::Object::Object(std::string indice, AMF::obj0type setType){ //object type initializer +AMF::Object::Object(std::string indice, AMF::obj0type setType) { //object type initializer myIndice = indice; myType = setType; strval = ""; @@ -130,11 +130,11 @@ AMF::Object::Object(std::string indice, AMF::obj0type setType){ //object type in /// Return the contents as a human-readable string. /// If this object contains other objects, it will call itself recursively /// and print all nested content as well. -std::string AMF::Object::Print(std::string indent){ +std::string AMF::Object::Print(std::string indent) { std::stringstream st; st << indent; // print my type - switch (myType){ + switch (myType) { case AMF::AMF0_NUMBER: st << "Number"; break; @@ -194,7 +194,7 @@ std::string AMF::Object::Print(std::string indent){ // print my string indice, if available st << " " << myIndice << " "; // print my numeric or string contents - switch (myType){ + switch (myType) { case AMF::AMF0_NUMBER: case AMF::AMF0_BOOL: case AMF::AMF0_REFERENCE: @@ -212,8 +212,8 @@ std::string AMF::Object::Print(std::string indent){ } st << std::endl; // if I hold other objects, print those too, recursively. - if (contents.size() > 0){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ + if (contents.size() > 0) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { st << it->Print(indent + " "); } } @@ -223,37 +223,37 @@ std::string AMF::Object::Print(std::string indent){ /// Packs the AMF object to a std::string for transfer over the network. /// If the object is a container type, this function will call itself recursively and contain all contents. /// Tip: When sending multiple AMF objects in one go, put them in a single AMF::AMF0_DDV_CONTAINER for easy transfer. -std::string AMF::Object::Pack(){ +std::string AMF::Object::Pack() { std::string r = ""; //check for string/longstring conversion - if ((myType == AMF::AMF0_STRING) && (strval.size() > 0xFFFF)){ + if ((myType == AMF::AMF0_STRING) && (strval.size() > 0xFFFF)) { myType = AMF::AMF0_LONGSTRING; } //skip output of DDV container types, they do not exist. Only output their contents. - if (myType != AMF::AMF0_DDV_CONTAINER){ + if (myType != AMF::AMF0_DDV_CONTAINER) { r += myType; } //output the properly formatted AMF0 data stream for this object's contents. - switch (myType){ + switch (myType) { case AMF::AMF0_NUMBER: - r += *(((char*) &numval) + 7); - r += *(((char*) &numval) + 6); - r += *(((char*) &numval) + 5); - r += *(((char*) &numval) + 4); - r += *(((char*) &numval) + 3); - r += *(((char*) &numval) + 2); - r += *(((char*) &numval) + 1); - r += *(((char*) &numval)); + r += *(((char *) &numval) + 7); + r += *(((char *) &numval) + 6); + r += *(((char *) &numval) + 5); + r += *(((char *) &numval) + 4); + r += *(((char *) &numval) + 3); + r += *(((char *) &numval) + 2); + r += *(((char *) &numval) + 1); + r += *(((char *) &numval)); break; case AMF::AMF0_DATE: - r += *(((char*) &numval) + 7); - r += *(((char*) &numval) + 6); - r += *(((char*) &numval) + 5); - r += *(((char*) &numval) + 4); - r += *(((char*) &numval) + 3); - r += *(((char*) &numval) + 2); - r += *(((char*) &numval) + 1); - r += *(((char*) &numval)); + r += *(((char *) &numval) + 7); + r += *(((char *) &numval) + 6); + r += *(((char *) &numval) + 5); + r += *(((char *) &numval) + 4); + r += *(((char *) &numval) + 3); + r += *(((char *) &numval) + 2); + r += *(((char *) &numval) + 1); + r += *(((char *) &numval)); r += (char)0; //timezone always 0 r += (char)0; //timezone always 0 break; @@ -277,10 +277,10 @@ std::string AMF::Object::Pack(){ r += Indice().size() / 256; r += Indice().size() % 256; r += Indice(); - /* no break */ + /* no break */ case AMF::AMF0_OBJECT: - if (contents.size() > 0){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ + if (contents.size() > 0) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { r += it->Indice().size() / 256; r += it->Indice().size() % 256; r += it->Indice(); @@ -305,52 +305,52 @@ std::string AMF::Object::Pack(){ r += (char)((int)numval % 256); break; case AMF::AMF0_ECMA_ARRAY: { - int arrlen = 0; - if (contents.size() > 0){ - arrlen = contents.size(); - r += arrlen / (256 * 256 * 256); - r += arrlen / (256 * 256); - r += arrlen / 256; - r += arrlen % 256; - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - r += it->Indice().size() / 256; - r += it->Indice().size() % 256; - r += it->Indice(); - r += it->Pack(); + int arrlen = 0; + if (contents.size() > 0) { + arrlen = contents.size(); + r += arrlen / (256 * 256 * 256); + r += arrlen / (256 * 256); + r += arrlen / 256; + r += arrlen % 256; + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + r += it->Indice().size() / 256; + r += it->Indice().size() % 256; + r += it->Indice(); + r += it->Pack(); + } + } else { + r += (char)0; + r += (char)0; + r += (char)0; + r += (char)0; } - }else{ - r += (char)0; - r += (char)0; r += (char)0; r += (char)0; + r += (char)9; } - r += (char)0; - r += (char)0; - r += (char)9; - } break; case AMF::AMF0_STRICT_ARRAY: { - int arrlen = 0; - if (contents.size() > 0){ - arrlen = contents.size(); - r += arrlen / (256 * 256 * 256); - r += arrlen / (256 * 256); - r += arrlen / 256; - r += arrlen % 256; - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - r += it->Pack(); + int arrlen = 0; + if (contents.size() > 0) { + arrlen = contents.size(); + r += arrlen / (256 * 256 * 256); + r += arrlen / (256 * 256); + r += arrlen / 256; + r += arrlen % 256; + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + r += it->Pack(); + } + } else { + r += (char)0; + r += (char)0; + r += (char)0; + r += (char)0; } - }else{ - r += (char)0; - r += (char)0; - r += (char)0; - r += (char)0; } - } break; case AMF::AMF0_DDV_CONTAINER: //only send contents - if (contents.size() > 0){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ + if (contents.size() > 0) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { r += it->Pack(); } } @@ -366,12 +366,12 @@ std::string AMF::Object::Pack(){ /// \param i Current parsing position in the raw data. /// \param name Indice name for any new object created. /// \returns A single AMF::Object, parsed from the raw data. -AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int &len, unsigned int &i, std::string name){ +AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int & len, unsigned int & i, std::string name) { std::string tmpstr; unsigned int tmpi = 0; unsigned char tmpdbl[8]; - double *d; // hack to work around strict aliasing - switch (data[i]){ + double * d; // hack to work around strict aliasing + switch (data[i]) { case AMF::AMF0_NUMBER: tmpdbl[7] = data[i + 1]; tmpdbl[6] = data[i + 2]; @@ -382,7 +382,7 @@ AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int &len, unsign tmpdbl[1] = data[i + 7]; tmpdbl[0] = data[i + 8]; i += 9; //skip 8(a double)+1 forwards - d = (double*)tmpdbl; + d = (double *)tmpdbl; return AMF::Object(name, *d, AMF::AMF0_NUMBER); break; case AMF::AMF0_DATE: @@ -395,14 +395,14 @@ AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int &len, unsign tmpdbl[1] = data[i + 7]; tmpdbl[0] = data[i + 8]; i += 11; //skip 8(a double)+1+timezone(2) forwards - d = (double*)tmpdbl; + d = (double *)tmpdbl; return AMF::Object(name, *d, AMF::AMF0_DATE); break; case AMF::AMF0_BOOL: i += 2; //skip bool+1 forwards - if (data[i - 1] == 0){ + if (data[i - 1] == 0) { return AMF::Object(name, (double)0, AMF::AMF0_BOOL); - }else{ + } else { return AMF::Object(name, (double)1, AMF::AMF0_BOOL); } break; @@ -439,61 +439,61 @@ AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int &len, unsign return AMF::Object(name, (double)0, (AMF::obj0type)data[i - 1]); break; case AMF::AMF0_OBJECT: { - ++i; - AMF::Object ret(name, AMF::AMF0_OBJECT); - while (data[i] + data[i + 1] != 0){ //while not encountering 0x0000 (we assume 0x000009) - tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length - tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i + 2, (size_t)tmpi); //add the string data - i += tmpi + 2; //skip length+size forwards - ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + ++i; + AMF::Object ret(name, AMF::AMF0_OBJECT); + while (data[i] + data[i + 1] != 0) { //while not encountering 0x0000 (we assume 0x000009) + tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length + tmpstr.clear(); //clean tmpstr, just to be sure + tmpstr.append((const char *)data + i + 2, (size_t)tmpi); //add the string data + i += tmpi + 2; //skip length+size forwards + ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + } + i += 3; //skip 0x000009 + return ret; } - i += 3; //skip 0x000009 - return ret; - } break; case AMF::AMF0_TYPED_OBJ: { - ++i; - tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length - tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i + 2, (size_t)tmpi); //add the string data - AMF::Object ret(tmpstr, AMF::AMF0_TYPED_OBJ); //the object is not named "name" but tmpstr - while (data[i] + data[i + 1] != 0){ //while not encountering 0x0000 (we assume 0x000009) + ++i; tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i + 2, (size_t)tmpi); //add the string data - i += tmpi + 2; //skip length+size forwards - ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + tmpstr.append((const char *)data + i + 2, (size_t)tmpi); //add the string data + AMF::Object ret(tmpstr, AMF::AMF0_TYPED_OBJ); //the object is not named "name" but tmpstr + while (data[i] + data[i + 1] != 0) { //while not encountering 0x0000 (we assume 0x000009) + tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length + tmpstr.clear(); //clean tmpstr, just to be sure + tmpstr.append((const char *)data + i + 2, (size_t)tmpi); //add the string data + i += tmpi + 2; //skip length+size forwards + ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + } + i += 3; //skip 0x000009 + return ret; } - i += 3; //skip 0x000009 - return ret; - } break; case AMF::AMF0_ECMA_ARRAY: { - ++i; - AMF::Object ret(name, AMF::AMF0_ECMA_ARRAY); - i += 4; //ignore the array length, we re-calculate it - while (data[i] + data[i + 1] != 0){ //while not encountering 0x0000 (we assume 0x000009) - tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length - tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i + 2, (size_t)tmpi); //add the string data - i += tmpi + 2; //skip length+size forwards - ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + ++i; + AMF::Object ret(name, AMF::AMF0_ECMA_ARRAY); + i += 4; //ignore the array length, we re-calculate it + while (data[i] + data[i + 1] != 0) { //while not encountering 0x0000 (we assume 0x000009) + tmpi = data[i] * 256 + data[i + 1]; //set tmpi to the UTF-8 length + tmpstr.clear(); //clean tmpstr, just to be sure + tmpstr.append((const char *)data + i + 2, (size_t)tmpi); //add the string data + i += tmpi + 2; //skip length+size forwards + ret.addContent(AMF::parseOne(data, len, i, tmpstr)); //add content, recursively parsed, updating i, setting indice to tmpstr + } + i += 3; //skip 0x000009 + return ret; } - i += 3; //skip 0x000009 - return ret; - } break; case AMF::AMF0_STRICT_ARRAY: { - AMF::Object ret(name, AMF::AMF0_STRICT_ARRAY); - tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; //set tmpi to array length - i += 5; //skip size+1 forwards - while (tmpi > 0){ //while not done parsing array - ret.addContent(AMF::parseOne(data, len, i, "arrVal")); //add content, recursively parsed, updating i - --tmpi; + AMF::Object ret(name, AMF::AMF0_STRICT_ARRAY); + tmpi = data[i + 1] * 256 * 256 * 256 + data[i + 2] * 256 * 256 + data[i + 3] * 256 + data[i + 4]; //set tmpi to array length + i += 5; //skip size+1 forwards + while (tmpi > 0) { //while not done parsing array + ret.addContent(AMF::parseOne(data, len, i, "arrVal")); //add content, recursively parsed, updating i + --tmpi; + } + return ret; } - return ret; - } break; } DEBUG_MSG(DLVL_ERROR, "Error: Unimplemented AMF type %hhx - returning.", data[i]); @@ -503,14 +503,14 @@ AMF::Object AMF::parseOne(const unsigned char *& data, unsigned int &len, unsign /// Parses a C-string to a valid AMF::Object. /// This function will find all AMF objects in the string and return /// them all packed in a single AMF::AMF0_DDV_CONTAINER AMF::Object. -AMF::Object AMF::parse(const unsigned char * data, unsigned int len){ +AMF::Object AMF::parse(const unsigned char * data, unsigned int len) { AMF::Object ret("returned", AMF::AMF0_DDV_CONTAINER); //container type unsigned int i = 0, j = 0; - while (i < len){ + while (i < len) { ret.addContent(AMF::parseOne(data, len, i, "")); - if (i > j){ + if (i > j) { j = i; - }else{ + } else { return ret; } } @@ -520,77 +520,77 @@ AMF::Object AMF::parse(const unsigned char * data, unsigned int len){ /// Parses a std::string to a valid AMF::Object. /// This function will find all AMF objects in the string and return /// them all packed in a single AMF::AMF0_DDV_CONTAINER AMF::Object. -AMF::Object AMF::parse(std::string data){ - return AMF::parse((const unsigned char*)data.c_str(), data.size()); +AMF::Object AMF::parse(std::string data) { + return AMF::parse((const unsigned char *)data.c_str(), data.size()); } //parse /// Returns the std::string Indice for the current object, if available. /// Returns an empty string if no indice exists. -std::string AMF::Object3::Indice(){ +std::string AMF::Object3::Indice() { return myIndice; } /// Returns the AMF::obj0type AMF0 object type for this object. -AMF::obj3type AMF::Object3::GetType(){ +AMF::obj3type AMF::Object3::GetType() { return myType; } /// Returns the double value of this object, if available. /// If this object holds no double value, 0 is returned. -double AMF::Object3::DblValue(){ +double AMF::Object3::DblValue() { return dblval; } /// Returns the integer value of this object, if available. /// If this object holds no integer value, 0 is returned. -int AMF::Object3::IntValue(){ +int AMF::Object3::IntValue() { return intval; } /// Returns the std::string value of this object, if available. /// If this object holds no string value, an empty string is returned. -std::string AMF::Object3::StrValue(){ +std::string AMF::Object3::StrValue() { return strval; } /// Returns the C-string value of this object, if available. /// If this object holds no string value, an empty C-string is returned. -const char * AMF::Object3::Str(){ +const char * AMF::Object3::Str() { return strval.c_str(); } /// Returns a count of the amount of objects this object currently holds. /// If this object is not a container type, this function will always return 0. -int AMF::Object3::hasContent(){ +int AMF::Object3::hasContent() { return contents.size(); } /// Adds an AMF::Object to this object. Works for all types, but only makes sense for container types. -void AMF::Object3::addContent(AMF::Object3 c){ +void AMF::Object3::addContent(AMF::Object3 c) { contents.push_back(c); } /// Returns a pointer to the object held at indice i. /// Returns AMF::AMF3_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param i The indice of the object in this container. -AMF::Object3* AMF::Object3::getContentP(int i){ +AMF::Object3 * AMF::Object3::getContentP(int i) { return &contents.at(i); } /// Returns a copy of the object held at indice i. /// Returns a AMF::AMF3_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param i The indice of the object in this container. -AMF::Object3 AMF::Object3::getContent(int i){ +AMF::Object3 AMF::Object3::getContent(int i) { return contents.at(i); } /// Returns a pointer to the object held at indice s. /// Returns NULL if no object is held at this indice. /// \param s The indice of the object in this container. -AMF::Object3* AMF::Object3::getContentP(std::string s){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - if (it->Indice() == s){ - return &( *it); +AMF::Object3 * AMF::Object3::getContentP(std::string s) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + if (it->Indice() == s) { + return &(*it); } } return 0; @@ -599,9 +599,9 @@ AMF::Object3* AMF::Object3::getContentP(std::string s){ /// Returns a copy of the object held at indice s. /// Returns a AMF::AMF0_DDV_CONTAINER of indice "error" if no object is held at this indice. /// \param s The indice of the object in this container. -AMF::Object3 AMF::Object3::getContent(std::string s){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ - if (it->Indice() == s){ +AMF::Object3 AMF::Object3::getContent(std::string s) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { + if (it->Indice() == s) { return *it; } } @@ -610,7 +610,7 @@ AMF::Object3 AMF::Object3::getContent(std::string s){ /// Default constructor. /// Simply fills the data with AMF::Object3("error", AMF3_DDV_CONTAINER) -AMF::Object3::Object3(){ +AMF::Object3::Object3() { *this = AMF::Object3("error", AMF3_DDV_CONTAINER); } //default constructor @@ -619,7 +619,7 @@ AMF::Object3::Object3(){ /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param val The numeric value of this object. Double AMF3 objects only support double-type values. /// \param setType The object type to force this object to. -AMF::Object3::Object3(std::string indice, double val, AMF::obj3type setType){ //num type initializer +AMF::Object3::Object3(std::string indice, double val, AMF::obj3type setType) { //num type initializer myIndice = indice; myType = setType; strval = ""; @@ -632,7 +632,7 @@ AMF::Object3::Object3(std::string indice, double val, AMF::obj3type setType){ // /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param val The numeric value of this object. Integer AMF3 objects only support integer-type values. /// \param setType The object type to force this object to. -AMF::Object3::Object3(std::string indice, int val, AMF::obj3type setType){ //num type initializer +AMF::Object3::Object3(std::string indice, int val, AMF::obj3type setType) { //num type initializer myIndice = indice; myType = setType; strval = ""; @@ -646,7 +646,7 @@ AMF::Object3::Object3(std::string indice, int val, AMF::obj3type setType){ //num /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param val The string value of this object. /// \param setType The object type to force this object to. -AMF::Object3::Object3(std::string indice, std::string val, AMF::obj3type setType){ //str type initializer +AMF::Object3::Object3(std::string indice, std::string val, AMF::obj3type setType) { //str type initializer myIndice = indice; myType = setType; strval = val; @@ -658,7 +658,7 @@ AMF::Object3::Object3(std::string indice, std::string val, AMF::obj3type setType /// The object type is by default AMF::AMF0_OBJECT, but this can be forced to a different value. /// \param indice The string indice of this object in its container, or empty string if none. Numeric indices are automatic. /// \param setType The object type to force this object to. -AMF::Object3::Object3(std::string indice, AMF::obj3type setType){ //object type initializer +AMF::Object3::Object3(std::string indice, AMF::obj3type setType) { //object type initializer myIndice = indice; myType = setType; strval = ""; @@ -669,11 +669,11 @@ AMF::Object3::Object3(std::string indice, AMF::obj3type setType){ //object type /// Return the contents as a human-readable string. /// If this object contains other objects, it will call itself recursively /// and print all nested content as well. -std::string AMF::Object3::Print(std::string indent){ +std::string AMF::Object3::Print(std::string indent) { std::stringstream st; st << indent; // print my type - switch (myType){ + switch (myType) { case AMF::AMF3_UNDEFINED: st << "Undefined"; break; @@ -720,7 +720,7 @@ std::string AMF::Object3::Print(std::string indent){ // print my string indice, if available st << " " << myIndice << " "; // print my numeric or string contents - switch (myType){ + switch (myType) { case AMF::AMF3_INTEGER: st << intval; break; @@ -731,22 +731,22 @@ std::string AMF::Object3::Print(std::string indent){ case AMF::AMF3_XMLDOC: case AMF::AMF3_XML: case AMF::AMF3_BYTES: - if (intval > 0){ + if (intval > 0) { st << "REF" << intval; - }else{ + } else { st << strval; } break; case AMF::AMF3_DATE: - if (intval > 0){ + if (intval > 0) { st << "REF" << intval; - }else{ + } else { st << dblval; } break; case AMF::AMF3_ARRAY: case AMF::AMF3_OBJECT: - if (intval > 0){ + if (intval > 0) { st << "REF" << intval; } break; @@ -755,8 +755,8 @@ std::string AMF::Object3::Print(std::string indent){ } st << std::endl; // if I hold other objects, print those too, recursively. - if (contents.size() > 0){ - for (std::vector::iterator it = contents.begin(); it != contents.end(); it++){ + if (contents.size() > 0) { + for (std::vector::iterator it = contents.begin(); it != contents.end(); it++) { st << it->Print(indent + " "); } } @@ -766,7 +766,7 @@ std::string AMF::Object3::Print(std::string indent){ /// Packs the AMF object to a std::string for transfer over the network. /// If the object is a container type, this function will call itself recursively and contain all contents. /// Tip: When sending multiple AMF objects in one go, put them in a single AMF::AMF0_DDV_CONTAINER for easy transfer. -std::string AMF::Object3::Pack(){ +std::string AMF::Object3::Pack() { std::string r = ""; return r; } //pack @@ -778,13 +778,13 @@ std::string AMF::Object3::Pack(){ /// \param i Current parsing position in the raw data. /// \param name Indice name for any new object created. /// \returns A single AMF::Object3, parsed from the raw data. -AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsigned int &i, std::string name){ +AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int & len, unsigned int & i, std::string name) { std::string tmpstr; unsigned int tmpi = 0; unsigned int arrsize = 0; unsigned char tmpdbl[8]; - double *d; // hack to work around strict aliasing - switch (data[i]){ + double * d; // hack to work around strict aliasing + switch (data[i]) { case AMF::AMF3_UNDEFINED: case AMF::AMF3_NULL: case AMF::AMF3_FALSE: @@ -793,20 +793,20 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi return AMF::Object3(name, (AMF::obj3type)data[i - 1]); break; case AMF::AMF3_INTEGER: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -826,24 +826,24 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi tmpdbl[1] = data[i + 7]; tmpdbl[0] = data[i + 8]; i += 9; //skip 8(a double)+1 forwards - d = (double*)tmpdbl; + d = (double *)tmpdbl; return AMF::Object3(name, *d, AMF::AMF3_DOUBLE); break; case AMF::AMF3_STRING: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -851,7 +851,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } } tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ + if ((tmpi & 1) == 0) { return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_STRING); //reference type } tmpstr.clear(); //clean tmpstr, just to be sure @@ -860,20 +860,20 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi return AMF::Object3(name, tmpstr, AMF::AMF3_STRING); //normal type break; case AMF::AMF3_XMLDOC: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -881,7 +881,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } } tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ + if ((tmpi & 1) == 0) { return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_XMLDOC); //reference type } tmpstr.clear(); //clean tmpstr, just to be sure @@ -890,20 +890,20 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi return AMF::Object3(name, tmpstr, AMF::AMF3_XMLDOC); //normal type break; case AMF::AMF3_XML: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -911,7 +911,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } } tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ + if ((tmpi & 1) == 0) { return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_XML); //reference type } tmpstr.clear(); //clean tmpstr, just to be sure @@ -920,20 +920,20 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi return AMF::Object3(name, tmpstr, AMF::AMF3_XML); //normal type break; case AMF::AMF3_BYTES: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; tmpi = (tmpi << 3) >> 3; //fix sign bit @@ -941,7 +941,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } } } - if ((tmpi & 1) == 0){ + if ((tmpi & 1) == 0) { return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_BYTES); //reference type } tmpstr.clear(); //clean tmpstr, just to be sure @@ -950,20 +950,20 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi return AMF::Object3(name, tmpstr, AMF::AMF3_BYTES); //normal type break; case AMF::AMF3_DATE: - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -971,7 +971,7 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } } tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ + if ((tmpi & 1) == 0) { return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_DATE); //reference type } tmpdbl[7] = data[i]; @@ -982,123 +982,52 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi tmpdbl[2] = data[i + 5]; tmpdbl[1] = data[i + 6]; tmpdbl[0] = data[i + 7]; - d = (double*)tmpdbl; + d = (double *)tmpdbl; i += 8; //skip a double forwards return AMF::Object3(name, *d, AMF::AMF3_DATE); break; case AMF::AMF3_ARRAY: { - if (data[i + 1] < 0x80){ - tmpi = data[i + 1]; - i += 2; - }else{ - tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ - tmpi |= data[i + 2]; - i += 3; - }else{ - tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ - tmpi |= data[i + 3]; - i += 4; - }else{ - tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. - tmpi |= data[i + 4]; - i += 5; - } - } - } - tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ - return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_ARRAY); //reference type - } - AMF::Object3 ret(name, AMF::AMF3_ARRAY); - arrsize = tmpi >> 1; - do{ - if (data[i + 1] < 0x80){ + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; } } } - tmpi = (tmpi << 3) >> 4; //fix sign bit, ignore references for now... - /// \todo Fix references? - if (tmpi > 0){ - tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i, (size_t)tmpi); //add the string data - ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); //add content, recursively parsed, updating i + tmpi = (tmpi << 3) >> 3; //fix sign bit + if ((tmpi & 1) == 0) { + return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_ARRAY); //reference type } - }while (tmpi > 0); - while (arrsize > 0){ //while not done parsing array - ret.addContent(AMF::parseOne3(data, len, i, "arrVal")); //add content, recursively parsed, updating i - --arrsize; - } - return ret; - } - break; - case AMF::AMF3_OBJECT: { - if (data[i + 1] < 0x80){ - tmpi = data[i + 1]; - i += 2; - }else{ - tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ - tmpi |= data[i + 2]; - i += 3; - }else{ - tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ - tmpi |= data[i + 3]; - i += 4; - }else{ - tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. - tmpi |= data[i + 4]; - i += 5; - } - } - } - tmpi = (tmpi << 3) >> 3; //fix sign bit - if ((tmpi & 1) == 0){ - return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_OBJECT); //reference type - } - AMF::Object3 ret(name, AMF::AMF3_OBJECT); - bool isdynamic = false; - if ((tmpi & 2) == 0){ //traits by reference, skip for now - /// \todo Implement traits by reference. Or references in general, of course... - }else{ - isdynamic = ((tmpi & 8) == 8); - arrsize = tmpi >> 4; //count of sealed members - /// \todo Read in arrsize sealed member names, then arrsize sealed members. - } - if (isdynamic){ - do{ - if (data[i + 1] < 0x80){ + AMF::Object3 ret(name, AMF::AMF3_ARRAY); + arrsize = tmpi >> 1; + do { + if (data[i + 1] < 0x80) { tmpi = data[i + 1]; i += 2; - }else{ + } else { tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. - if (data[i + 2] < 0x80){ + if (data[i + 2] < 0x80) { tmpi |= data[i + 2]; i += 3; - }else{ + } else { tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. - if (data[i + 3] < 0x80){ + if (data[i + 3] < 0x80) { tmpi |= data[i + 3]; i += 4; - }else{ + } else { tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. tmpi |= data[i + 4]; i += 5; @@ -1107,15 +1036,86 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi } tmpi = (tmpi << 3) >> 4; //fix sign bit, ignore references for now... /// \todo Fix references? - if (tmpi > 0){ + if (tmpi > 0) { tmpstr.clear(); //clean tmpstr, just to be sure - tmpstr.append((const char*)data + i, (size_t)tmpi); //add the string data + tmpstr.append((const char *)data + i, (size_t)tmpi); //add the string data ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); //add content, recursively parsed, updating i } - }while (tmpi > 0); //keep reading dynamic values until empty string - } //dynamic types - return ret; - } + } while (tmpi > 0); + while (arrsize > 0) { //while not done parsing array + ret.addContent(AMF::parseOne3(data, len, i, "arrVal")); //add content, recursively parsed, updating i + --arrsize; + } + return ret; + } + break; + case AMF::AMF3_OBJECT: { + if (data[i + 1] < 0x80) { + tmpi = data[i + 1]; + i += 2; + } else { + tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. + if (data[i + 2] < 0x80) { + tmpi |= data[i + 2]; + i += 3; + } else { + tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. + if (data[i + 3] < 0x80) { + tmpi |= data[i + 3]; + i += 4; + } else { + tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. + tmpi |= data[i + 4]; + i += 5; + } + } + } + tmpi = (tmpi << 3) >> 3; //fix sign bit + if ((tmpi & 1) == 0) { + return AMF::Object3(name, (int)((tmpi >> 1) + 1), AMF::AMF3_OBJECT); //reference type + } + AMF::Object3 ret(name, AMF::AMF3_OBJECT); + bool isdynamic = false; + if ((tmpi & 2) == 0) { //traits by reference, skip for now + /// \todo Implement traits by reference. Or references in general, of course... + } else { + isdynamic = ((tmpi & 8) == 8); + arrsize = tmpi >> 4; //count of sealed members + /// \todo Read in arrsize sealed member names, then arrsize sealed members. + } + if (isdynamic) { + do { + if (data[i + 1] < 0x80) { + tmpi = data[i + 1]; + i += 2; + } else { + tmpi = (data[i + 1] & 0x7F) << 7; //strip the upper bit, shift 7 up. + if (data[i + 2] < 0x80) { + tmpi |= data[i + 2]; + i += 3; + } else { + tmpi = (tmpi | (data[i + 2] & 0x7F)) << 7; //strip the upper bit, shift 7 up. + if (data[i + 3] < 0x80) { + tmpi |= data[i + 3]; + i += 4; + } else { + tmpi = (tmpi | (data[i + 3] & 0x7F)) << 8; //strip the upper bit, shift 7 up. + tmpi |= data[i + 4]; + i += 5; + } + } + } + tmpi = (tmpi << 3) >> 4; //fix sign bit, ignore references for now... + /// \todo Fix references? + if (tmpi > 0) { + tmpstr.clear(); //clean tmpstr, just to be sure + tmpstr.append((const char *)data + i, (size_t)tmpi); //add the string data + ret.addContent(AMF::parseOne3(data, len, i, tmpstr)); //add content, recursively parsed, updating i + } + } while (tmpi > 0); //keep reading dynamic values until empty string + } //dynamic types + return ret; + } break; } DEBUG_MSG(DLVL_ERROR, "Error: Unimplemented AMF3 type %hhx - returning.", data[i]); @@ -1125,14 +1125,14 @@ AMF::Object3 AMF::parseOne3(const unsigned char *& data, unsigned int &len, unsi /// Parses a C-string to a valid AMF::Object3. /// This function will find all AMF3 objects in the string and return /// them all packed in a single AMF::AMF3_DDV_CONTAINER AMF::Object3. -AMF::Object3 AMF::parse3(const unsigned char * data, unsigned int len){ +AMF::Object3 AMF::parse3(const unsigned char * data, unsigned int len) { AMF::Object3 ret("returned", AMF::AMF3_DDV_CONTAINER); //container type unsigned int i = 0, j = 0; - while (i < len){ + while (i < len) { ret.addContent(AMF::parseOne3(data, len, i, "")); - if (i > j){ + if (i > j) { j = i; - }else{ + } else { return ret; } } @@ -1142,6 +1142,6 @@ AMF::Object3 AMF::parse3(const unsigned char * data, unsigned int len){ /// Parses a std::string to a valid AMF::Object3. /// This function will find all AMF3 objects in the string and return /// them all packed in a single AMF::AMF3_DDV_CONTAINER AMF::Object3. -AMF::Object3 AMF::parse3(std::string data){ - return AMF::parse3((const unsigned char*)data.c_str(), data.size()); +AMF::Object3 AMF::parse3(std::string data) { + return AMF::parse3((const unsigned char *)data.c_str(), data.size()); } //parse diff --git a/lib/amf.h b/lib/amf.h index 4e2bc0f6..4d560bdd 100644 --- a/lib/amf.h +++ b/lib/amf.h @@ -10,7 +10,7 @@ namespace AMF { /// Enumerates all possible AMF0 types, adding a special DDVTECH container type for ease of use. - enum obj0type{ + enum obj0type { AMF0_NUMBER = 0x00, AMF0_BOOL = 0x01, AMF0_STRING = 0x02, @@ -33,7 +33,7 @@ namespace AMF { }; /// Enumerates all possible AMF3 types, adding a special DDVTECH container type for ease of use. - enum obj3type{ + enum obj3type { AMF3_UNDEFINED = 0x00, AMF3_NULL = 0x01, AMF3_FALSE = 0x02, @@ -52,7 +52,7 @@ namespace AMF { /// Recursive class that holds AMF0 objects. /// It supports all AMF0 types (defined in AMF::obj0type), adding support for a special DDVTECH container type. - class Object{ + class Object { public: std::string Indice(); obj0type GetType(); @@ -61,9 +61,9 @@ namespace AMF { const char * Str(); int hasContent(); void addContent(AMF::Object c); - Object* getContentP(unsigned int i); + Object * getContentP(unsigned int i); Object getContent(unsigned int i); - Object* getContentP(std::string s); + Object * getContentP(std::string s); Object getContent(std::string s); Object(); Object(std::string indice, double val, obj0type setType = AMF0_NUMBER); @@ -85,11 +85,11 @@ namespace AMF { /// Parses a std::string to a valid AMF::Object. Object parse(std::string data); /// Parses a single AMF0 type - used recursively by the AMF::parse() functions. - Object parseOne(const unsigned char *& data, unsigned int &len, unsigned int &i, std::string name); + Object parseOne(const unsigned char *& data, unsigned int & len, unsigned int & i, std::string name); /// Recursive class that holds AMF3 objects. /// It supports all AMF3 types (defined in AMF::obj3type), adding support for a special DDVTECH container type. - class Object3{ + class Object3 { public: std::string Indice(); obj3type GetType(); @@ -99,9 +99,9 @@ namespace AMF { const char * Str(); int hasContent(); void addContent(AMF::Object3 c); - Object3* getContentP(int i); + Object3 * getContentP(int i); Object3 getContent(int i); - Object3* getContentP(std::string s); + Object3 * getContentP(std::string s); Object3 getContent(std::string s); Object3(); Object3(std::string indice, int val, obj3type setType = AMF3_INTEGER); @@ -125,6 +125,6 @@ namespace AMF { /// Parses a std::string to a valid AMF::Object3. Object3 parse3(std::string data); /// Parses a single AMF3 type - used recursively by the AMF::parse3() functions. - Object3 parseOne3(const unsigned char *& data, unsigned int &len, unsigned int &i, std::string name); + Object3 parseOne3(const unsigned char *& data, unsigned int & len, unsigned int & i, std::string name); } //AMF namespace diff --git a/lib/auth.cpp b/lib/auth.cpp index df649766..ad5f8d83 100644 --- a/lib/auth.cpp +++ b/lib/auth.cpp @@ -9,40 +9,41 @@ namespace Secure { static unsigned char __gbv2keypub_der[] = {0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe5, 0xd7, 0x9c, 0x7d, 0x73, 0xc6, 0xe6, 0xfb, - 0x35, 0x7e, 0xd7, 0x57, 0x99, 0x07, 0xdb, 0x99, 0x70, 0xc9, 0xd0, 0x3e, 0x53, 0x57, 0x3c, 0x1e, 0x55, 0xda, 0x0f, 0x69, 0xbf, 0x26, 0x79, 0xc7, - 0xb6, 0xdd, 0x8e, 0x83, 0x32, 0x65, 0x74, 0x0d, 0x74, 0x48, 0x42, 0x49, 0x22, 0x52, 0x58, 0x56, 0xc3, 0xe4, 0x49, 0x5d, 0xac, 0x6a, 0x94, 0xb1, - 0x64, 0x14, 0xbf, 0x4d, 0xd5, 0xd7, 0x3a, 0xca, 0x5c, 0x1e, 0x6f, 0x42, 0x30, 0xac, 0x29, 0xaa, 0xa0, 0x85, 0xd2, 0x16, 0xa2, 0x8e, 0x89, 0x12, - 0xc4, 0x92, 0x06, 0xea, 0xed, 0x48, 0xf6, 0xdb, 0xed, 0x4f, 0x62, 0x6c, 0xfa, 0xcf, 0xc2, 0xb9, 0x8d, 0x04, 0xb2, 0xba, 0x63, 0xc9, 0xcc, 0xee, - 0x23, 0x64, 0x46, 0x14, 0x12, 0xc8, 0x38, 0x67, 0x69, 0x6b, 0xaf, 0xd1, 0x7c, 0xb1, 0xb5, 0x79, 0xe4, 0x4e, 0x3a, 0xa7, 0xe8, 0x28, 0x89, 0x25, - 0xc0, 0xd0, 0xd8, 0xc7, 0xd2, 0x26, 0xaa, 0xf5, 0xbf, 0x36, 0x55, 0x01, 0x89, 0x58, 0x1f, 0x1e, 0xf5, 0xa5, 0x42, 0x8f, 0x60, 0x2e, 0xc2, 0xd8, - 0x21, 0x0b, 0x6c, 0x8d, 0xbb, 0x72, 0xf2, 0x19, 0x30, 0xe3, 0x4c, 0x3e, 0x80, 0xe7, 0xf2, 0xe3, 0x89, 0x4f, 0xd4, 0xee, 0x96, 0x3e, 0x4a, 0x9b, - 0xe5, 0x16, 0x01, 0xf1, 0x98, 0xc9, 0x0b, 0xd6, 0xdf, 0x8a, 0x64, 0x47, 0xc4, 0x44, 0xcc, 0x92, 0x69, 0x28, 0xee, 0x7d, 0xac, 0xdc, 0x30, 0x56, - 0x3a, 0xe7, 0xbc, 0xba, 0x45, 0x16, 0x2c, 0x4c, 0x46, 0x6b, 0x2b, 0x20, 0xfb, 0x3d, 0x20, 0x35, 0xbb, 0x48, 0x49, 0x13, 0x65, 0xc9, 0x9a, 0x38, - 0x10, 0x84, 0x1a, 0x8c, 0xc9, 0xd7, 0xde, 0x07, 0x10, 0x5a, 0xfb, 0xb4, 0x95, 0xae, 0x18, 0xf2, 0xe3, 0x15, 0xe8, 0xad, 0x7e, 0xe5, 0x3c, 0xa8, - 0x47, 0x85, 0xd6, 0x1f, 0x54, 0xb5, 0xa3, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01}; ///< The GBv2 public key file. + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe5, 0xd7, 0x9c, 0x7d, 0x73, 0xc6, 0xe6, 0xfb, + 0x35, 0x7e, 0xd7, 0x57, 0x99, 0x07, 0xdb, 0x99, 0x70, 0xc9, 0xd0, 0x3e, 0x53, 0x57, 0x3c, 0x1e, 0x55, 0xda, 0x0f, 0x69, 0xbf, 0x26, 0x79, 0xc7, + 0xb6, 0xdd, 0x8e, 0x83, 0x32, 0x65, 0x74, 0x0d, 0x74, 0x48, 0x42, 0x49, 0x22, 0x52, 0x58, 0x56, 0xc3, 0xe4, 0x49, 0x5d, 0xac, 0x6a, 0x94, 0xb1, + 0x64, 0x14, 0xbf, 0x4d, 0xd5, 0xd7, 0x3a, 0xca, 0x5c, 0x1e, 0x6f, 0x42, 0x30, 0xac, 0x29, 0xaa, 0xa0, 0x85, 0xd2, 0x16, 0xa2, 0x8e, 0x89, 0x12, + 0xc4, 0x92, 0x06, 0xea, 0xed, 0x48, 0xf6, 0xdb, 0xed, 0x4f, 0x62, 0x6c, 0xfa, 0xcf, 0xc2, 0xb9, 0x8d, 0x04, 0xb2, 0xba, 0x63, 0xc9, 0xcc, 0xee, + 0x23, 0x64, 0x46, 0x14, 0x12, 0xc8, 0x38, 0x67, 0x69, 0x6b, 0xaf, 0xd1, 0x7c, 0xb1, 0xb5, 0x79, 0xe4, 0x4e, 0x3a, 0xa7, 0xe8, 0x28, 0x89, 0x25, + 0xc0, 0xd0, 0xd8, 0xc7, 0xd2, 0x26, 0xaa, 0xf5, 0xbf, 0x36, 0x55, 0x01, 0x89, 0x58, 0x1f, 0x1e, 0xf5, 0xa5, 0x42, 0x8f, 0x60, 0x2e, 0xc2, 0xd8, + 0x21, 0x0b, 0x6c, 0x8d, 0xbb, 0x72, 0xf2, 0x19, 0x30, 0xe3, 0x4c, 0x3e, 0x80, 0xe7, 0xf2, 0xe3, 0x89, 0x4f, 0xd4, 0xee, 0x96, 0x3e, 0x4a, 0x9b, + 0xe5, 0x16, 0x01, 0xf1, 0x98, 0xc9, 0x0b, 0xd6, 0xdf, 0x8a, 0x64, 0x47, 0xc4, 0x44, 0xcc, 0x92, 0x69, 0x28, 0xee, 0x7d, 0xac, 0xdc, 0x30, 0x56, + 0x3a, 0xe7, 0xbc, 0xba, 0x45, 0x16, 0x2c, 0x4c, 0x46, 0x6b, 0x2b, 0x20, 0xfb, 0x3d, 0x20, 0x35, 0xbb, 0x48, 0x49, 0x13, 0x65, 0xc9, 0x9a, 0x38, + 0x10, 0x84, 0x1a, 0x8c, 0xc9, 0xd7, 0xde, 0x07, 0x10, 0x5a, 0xfb, 0xb4, 0x95, 0xae, 0x18, 0xf2, 0xe3, 0x15, 0xe8, 0xad, 0x7e, 0xe5, 0x3c, 0xa8, + 0x47, 0x85, 0xd6, 0x1f, 0x54, 0xb5, 0xa3, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01 + }; ///< The GBv2 public key file. static unsigned int __gbv2keypub_der_len = 294; ///< Length of GBv2 public key data /// Attempts to load the GBv2 public key. - Auth::Auth(){ + Auth::Auth() { const unsigned char * key = __gbv2keypub_der; - pubkey = (void*)d2i_RSAPublicKey(0, &key, __gbv2keypub_der_len); + pubkey = (void *)d2i_RSAPublicKey(0, &key, __gbv2keypub_der_len); } /// Attempts to verify RSA signature using the public key. /// Assumes basesign argument is base64 encoded RSA signature for data. /// Returns true if the data could be verified, false otherwise. - bool Auth::PubKey_Check(std::string & data, std::string basesign){ + bool Auth::PubKey_Check(std::string & data, std::string basesign) { std::string sign = Base64::decode(basesign); - return (RSA_verify(NID_md5, (unsigned char*)data.c_str(), data.size(), (unsigned char*)sign.c_str(), sign.size(), (RSA*)pubkey) == 1); + return (RSA_verify(NID_md5, (unsigned char *)data.c_str(), data.size(), (unsigned char *)sign.c_str(), sign.size(), (RSA *)pubkey) == 1); } /// Wrapper function for openssl MD5 implementation - std::string md5(std::string input){ + std::string md5(std::string input) { char tmp[3]; std::string ret; - const unsigned char * res = MD5((const unsigned char*)input.c_str(), input.length(), 0); - for (int i = 0; i < 16; ++i){ + const unsigned char * res = MD5((const unsigned char *)input.c_str(), input.length(), 0); + for (int i = 0; i < 16; ++i) { snprintf(tmp, 3, "%02x", res[i]); ret += tmp; } diff --git a/lib/auth.h b/lib/auth.h index 7024e36f..2db4df86 100644 --- a/lib/auth.h +++ b/lib/auth.h @@ -2,7 +2,7 @@ #include namespace Secure { - class Auth{ + class Auth { private: void * pubkey; ///< Holds the public key. public: diff --git a/lib/base64.cpp b/lib/base64.cpp index 8a15611f..7048616c 100644 --- a/lib/base64.cpp +++ b/lib/base64.cpp @@ -4,39 +4,39 @@ const std::string Base64::chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// Helper for base64_decode function -inline bool Base64::is_base64(unsigned char c){ +inline bool Base64::is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } /// Used to base64 encode data. Input is the plaintext as std::string, output is the encoded data as std::string. /// \param input Plaintext data to encode. /// \returns Base64 encoded data. -std::string Base64::encode(std::string const input){ +std::string Base64::encode(std::string const input) { std::string ret; unsigned int in_len = input.size(); char quad[4], triple[3]; unsigned int i, x, n = 3; - for (x = 0; x < in_len; x = x + 3){ - if ((in_len - x) / 3 == 0){ + for (x = 0; x < in_len; x = x + 3) { + if ((in_len - x) / 3 == 0) { n = (in_len - x) % 3; } - for (i = 0; i < 3; i++){ + for (i = 0; i < 3; i++) { triple[i] = '0'; } - for (i = 0; i < n; i++){ + for (i = 0; i < n; i++) { triple[i] = input[x + i]; } quad[0] = chars[(triple[0] & 0xFC) >> 2]; // FC = 11111100 quad[1] = chars[((triple[0] & 0x03) << 4) | ((triple[1] & 0xF0) >> 4)]; // 03 = 11 quad[2] = chars[((triple[1] & 0x0F) << 2) | ((triple[2] & 0xC0) >> 6)]; // 0F = 1111, C0=11110 quad[3] = chars[triple[2] & 0x3F]; // 3F = 111111 - if (n < 3){ + if (n < 3) { quad[3] = '='; } - if (n < 2){ + if (n < 2) { quad[2] = '='; } - for (i = 0; i < 4; i++){ + for (i = 0; i < 4; i++) { ret += quad[i]; } } @@ -46,34 +46,34 @@ std::string Base64::encode(std::string const input){ /// Used to base64 decode data. Input is the encoded data as std::string, output is the plaintext data as std::string. /// \param encoded_string Base64 encoded data to decode. /// \returns Plaintext decoded data. -std::string Base64::decode(std::string const& encoded_string){ +std::string Base64::decode(std::string const & encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; - while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])){ + while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++ ] = encoded_string[in_]; in_++; - if (i == 4){ - for (i = 0; i < 4; i++){ + if (i == 4) { + for (i = 0; i < 4; i++) { char_array_4[i] = chars.find(char_array_4[i]); } char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - for (i = 0; (i < 3); i++){ + for (i = 0; (i < 3); i++) { ret += char_array_3[i]; } i = 0; } } - if (i){ - for (j = i; j < 4; j++){ + if (i) { + for (j = i; j < 4; j++) { char_array_4[j] = 0; } - for (j = 0; j < 4; j++){ + for (j = 0; j < 4; j++) { char_array_4[j] = chars.find(char_array_4[j]); } char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); diff --git a/lib/base64.h b/lib/base64.h index 6adc5123..684c4ba1 100644 --- a/lib/base64.h +++ b/lib/base64.h @@ -2,11 +2,11 @@ #include /// Holds base64 decoding and encoding functions. -class Base64{ +class Base64 { private: static const std::string chars; static inline bool is_base64(unsigned char c); public: static std::string encode(std::string const input); - static std::string decode(std::string const& encoded_string); + static std::string decode(std::string const & encoded_string); }; diff --git a/lib/bitstream.cpp b/lib/bitstream.cpp index cec44b34..01d5d5da 100644 --- a/lib/bitstream.cpp +++ b/lib/bitstream.cpp @@ -3,51 +3,51 @@ #include #include -namespace Utils{ - bitstream::bitstream(){ +namespace Utils { + bitstream::bitstream() { data = NULL; offset = 0; dataSize = 0; bufferSize = 0; } - - bool bitstream::checkBufferSize(unsigned int size){ - if (size > bufferSize){ - void* temp = realloc(data, size); - if (temp){ - data = (char*) temp; + + bool bitstream::checkBufferSize(unsigned int size) { + if (size > bufferSize) { + void * temp = realloc(data, size); + if (temp) { + data = (char *) temp; bufferSize = size; return true; - }else{ + } else { return false; } - }else{ + } else { return true; } } - - void bitstream::append(char* input, size_t bytes){ - if (checkBufferSize(dataSize+bytes)){ - memcpy(data+dataSize, input, bytes); + + void bitstream::append(char * input, size_t bytes) { + if (checkBufferSize(dataSize + bytes)) { + memcpy(data + dataSize, input, bytes); dataSize += bytes; } } - void bitstream::append(std::string input){ - append((char*)input.c_str(), input.size()); + void bitstream::append(std::string input) { + append((char *)input.c_str(), input.size()); } - - bool bitstream::peekOffset(size_t peekOffset){ + + bool bitstream::peekOffset(size_t peekOffset) { peekOffset += offset; return ((data[peekOffset >> 3]) >> (7 - (peekOffset & 7))) & 1; } - - long long unsigned int bitstream::peek(size_t count){ - if (count > 64){ + + long long unsigned int bitstream::peek(size_t count) { + if (count > 64) { DEBUG_MSG(DLVL_WARN, "Can not read %d bits into a long long unsigned int!", (int)count); //return 0; } - if (count > size()){ + if (count > size()) { DEBUG_MSG(DLVL_ERROR, "Not enough bits left in stream. Left: %d requested: %d", (int)size(), (int)count); return 0; } @@ -56,11 +56,11 @@ namespace Utils{ size_t readSize; size_t readOff; char readBuff; - while (curPlace < count){ - readBuff = data[(int)((offset+curPlace)/8)]; + while (curPlace < count) { + readBuff = data[(int)((offset + curPlace) / 8)]; readSize = 8; readOff = (offset + curPlace) % 8; //the reading offset within the byte - if (readOff != 0){ + if (readOff != 0) { //if we start our read not on the start of a byte //curplace and retval should both be 0 //this should be the first read that aligns reading to bytes, if we read over the end of read byte @@ -69,7 +69,7 @@ namespace Utils{ readBuff = readBuff & ((1 << readSize) - 1);//bitmasking } //up until here we assume we read to the end of the byte - if (count - curPlace < readSize){//if we do not read to the end of the byte + if (count - curPlace < readSize) { //if we do not read to the end of the byte //we cut off the LSb off of the read buffer by bitshift readSize = count - curPlace; readBuff = readBuff >> (8 - readSize - readOff); @@ -79,99 +79,99 @@ namespace Utils{ } return retval; } - - long long unsigned int bitstream::get(size_t count){ - if(count <= size()){ + + long long unsigned int bitstream::get(size_t count) { + if (count <= size()) { long long unsigned int retVal; retVal = peek(count); skip(count); return retVal; - }else{ + } else { return 0; } } - - void bitstream::skip(size_t count){ - if(count <= size()){ + + void bitstream::skip(size_t count) { + if (count <= size()) { offset += count; - }else{ - offset = dataSize*8; + } else { + offset = dataSize * 8; } - + } - - long long unsigned int bitstream::size(){ + + long long unsigned int bitstream::size() { return (dataSize * 8) - offset; } - - void bitstream::clear(){ + + void bitstream::clear() { dataSize = 0; offset = 0; } - - void bitstream::flush(){ - memmove(data, data + (offset/8), dataSize - (offset/8)); + + void bitstream::flush() { + memmove(data, data + (offset / 8), dataSize - (offset / 8)); dataSize -= offset / 8; offset %= 8; } - - long long unsigned int bitstream::golombPeeker(){ - for (size_t i = 0; i < 64 && i < size(); i++){ - if (peekOffset(i)){ - return peek((i * 2) + 1 ); + + long long unsigned int bitstream::golombPeeker() { + for (size_t i = 0; i < 64 && i < size(); i++) { + if (peekOffset(i)) { + return peek((i * 2) + 1); } } return 0; } - - long long unsigned int bitstream::golombGetter(){ - for (size_t i = 0; i < 64 && i < size(); i++){ - if (peekOffset(i)){ + + long long unsigned int bitstream::golombGetter() { + for (size_t i = 0; i < 64 && i < size(); i++) { + if (peekOffset(i)) { return get((i * 2) + 1); } } return 0; } - - long long int bitstream::getExpGolomb(){ + + long long int bitstream::getExpGolomb() { long long unsigned int temp = golombGetter(); return (temp >> 1) * (1 - ((temp & 1) << 1)); //Is actually return (temp / 2) * (1 - (temp & 1) * 2); } - - long long unsigned int bitstream::getUExpGolomb(){ + + long long unsigned int bitstream::getUExpGolomb() { return golombGetter() - 1; } - - long long int bitstream::peekExpGolomb(){ + + long long int bitstream::peekExpGolomb() { long long unsigned int temp = golombPeeker(); return (temp >> 1) * (1 - ((temp & 1) << 1)); //Is actually return (temp / 2) * (1 - (temp & 1) * 2); } - - long long unsigned int bitstream::peekUExpGolomb(){ + + long long unsigned int bitstream::peekUExpGolomb() { return golombPeeker() - 1; } - -//Note: other bitstream here - bitstreamLSBF::bitstreamLSBF(){ + +//Note: other bitstream here + bitstreamLSBF::bitstreamLSBF() { readBufferOffset = 0; readBuffer = 0; } - - void bitstreamLSBF::append (char* input, size_t bytes){ - append(std::string(input,bytes)); + + void bitstreamLSBF::append(char * input, size_t bytes) { + append(std::string(input, bytes)); } - - void bitstreamLSBF::append (std::string input){ + + void bitstreamLSBF::append(std::string input) { data += input; fixData(); } - - long long unsigned int bitstreamLSBF::size(){ + + long long unsigned int bitstreamLSBF::size() { return data.size() * 8 + readBufferOffset; } - - long long unsigned int bitstreamLSBF::get(size_t count){ - if (count <= 32 && count <= readBufferOffset){ + + long long unsigned int bitstreamLSBF::get(size_t count) { + if (count <= 32 && count <= readBufferOffset) { long long unsigned int retval = readBuffer & (((long long unsigned int)1 << count) - 1); readBuffer = readBuffer >> count; readBufferOffset -= count; @@ -181,29 +181,29 @@ namespace Utils{ return 42; } - void bitstreamLSBF::skip(size_t count){ - if (count <= 32 && count <= readBufferOffset){ + void bitstreamLSBF::skip(size_t count) { + if (count <= 32 && count <= readBufferOffset) { readBuffer = readBuffer >> count; readBufferOffset -= count; fixData(); } } - - long long unsigned int bitstreamLSBF::peek(size_t count){ - if (count <= 32 && count <= readBufferOffset){ + + long long unsigned int bitstreamLSBF::peek(size_t count) { + if (count <= 32 && count <= readBufferOffset) { return readBuffer & ((1 << count) - 1); } return 0; } - - void bitstreamLSBF::clear(){ + + void bitstreamLSBF::clear() { data = ""; readBufferOffset = 0; readBuffer = 0; } - - void bitstreamLSBF::fixData(){ - while (readBufferOffset <= 32 && data.size() != 0){ + + void bitstreamLSBF::fixData() { + while (readBufferOffset <= 32 && data.size() != 0) { //readBuffer = readBuffer & ((1 << readBufferOffset) - 1) | (data[0] << readBufferOffset); readBuffer |= (((long long unsigned int)data[0]) << readBufferOffset); data = data.substr(1); diff --git a/lib/bitstream.h b/lib/bitstream.h index 8fb47103..29ad39f0 100644 --- a/lib/bitstream.h +++ b/lib/bitstream.h @@ -1,19 +1,19 @@ #include -namespace Utils{ - class bitstream{ +namespace Utils { + class bitstream { public: bitstream(); - bitstream& operator<< (std::string input){ + bitstream & operator<< (std::string input) { append(input); return *this; }; - bitstream& operator<< (char input){ + bitstream & operator<< (char input) { append(std::string(input, 1)); return *this; }; - void append (char* input, size_t bytes); - void append (std::string input); + void append(char * input, size_t bytes); + void append(std::string input); long long unsigned int size(); void skip(size_t count); long long unsigned int get(size_t count); @@ -29,21 +29,21 @@ namespace Utils{ bool checkBufferSize(unsigned int size); long long unsigned int golombGetter(); long long unsigned int golombPeeker(); - char* data; + char * data; size_t offset; size_t dataSize; size_t bufferSize; }; - class bitstreamLSBF{ + class bitstreamLSBF { public: bitstreamLSBF(); - bitstreamLSBF& operator<< (std::string input){ + bitstreamLSBF & operator<< (std::string input) { append(input); return *this; }; - void append (char* input, size_t bytes); - void append (std::string input); + void append(char * input, size_t bytes); + void append(std::string input); long long unsigned int size(); void skip(size_t count); long long unsigned int get(size_t count); diff --git a/lib/config.cpp b/lib/config.cpp index 514286b4..6500f524 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -37,7 +37,7 @@ bool Util::Config::is_active = false; unsigned int Util::Config::printDebugLevel = DEBUG;// std::string Util::Config::libver = PACKAGE_VERSION; -Util::Config::Config(){ +Util::Config::Config() { //global options here vals["debug"]["long"] = "debug"; vals["debug"]["short"] = "g"; @@ -51,7 +51,7 @@ Util::Config::Config(){ } /// Creates a new configuration manager. -Util::Config::Config(std::string cmd, std::string version){ +Util::Config::Config(std::string cmd, std::string version) { vals.null(); long_count = 2; vals["cmd"]["value"].append(cmd); @@ -67,7 +67,7 @@ Util::Config::Config(std::string cmd, std::string version){ vals["debug"]["short"] = "g"; vals["debug"]["arg"] = "integer"; vals["debug"]["help"] = "The debug level at which messages need to be printed."; - vals["debug"]["value"].append((long long)DEBUG); + vals["debug"]["value"].append((long long)DEBUG); } /// Adds an option to the configuration parser. @@ -84,110 +84,110 @@ Util::Config::Config(std::string cmd, std::string version){ /// "help":"Blahblahblah" //The helptext for this option. /// } ///\endcode -void Util::Config::addOption(std::string optname, JSON::Value option){ +void Util::Config::addOption(std::string optname, JSON::Value option) { vals[optname] = option; - if ( !vals[optname].isMember("value") && vals[optname].isMember("default")){ + if (!vals[optname].isMember("value") && vals[optname].isMember("default")) { vals[optname]["value"].append(vals[optname]["default"]); vals[optname].removeMember("default"); } long_count = 0; - for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++){ - if (it->second.isMember("long")){ + for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) { + if (it->second.isMember("long")) { long_count++; } - if (it->second.isMember("long_off")){ + if (it->second.isMember("long_off")) { long_count++; } } } /// Prints a usage message to the given output. -void Util::Config::printHelp(std::ostream & output){ +void Util::Config::printHelp(std::ostream & output) { unsigned int longest = 0; std::map args; - for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++){ + for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) { unsigned int current = 0; - if (it->second.isMember("long")){ + if (it->second.isMember("long")) { current += it->second["long"].asString().size() + 4; } - if (it->second.isMember("short")){ + if (it->second.isMember("short")) { current += it->second["short"].asString().size() + 3; } - if (current > longest){ + if (current > longest) { longest = current; } current = 0; - if (it->second.isMember("long_off")){ + if (it->second.isMember("long_off")) { current += it->second["long_off"].asString().size() + 4; } - if (it->second.isMember("short_off")){ + if (it->second.isMember("short_off")) { current += it->second["short_off"].asString().size() + 3; } - if (current > longest){ + if (current > longest) { longest = current; } - if (it->second.isMember("arg_num")){ + if (it->second.isMember("arg_num")) { current = it->first.size() + 3; - if (current > longest){ + if (current > longest) { longest = current; } args[it->second["arg_num"].asInt()] = it->first; } } output << "Usage: " << getString("cmd") << " [options]"; - for (std::map::iterator i = args.begin(); i != args.end(); i++){ - if (vals[i->second].isMember("value") && vals[i->second]["value"].size()){ + for (std::map::iterator i = args.begin(); i != args.end(); i++) { + if (vals[i->second].isMember("value") && vals[i->second]["value"].size()) { output << " [" << i->second << "]"; - }else{ + } else { output << " " << i->second; } } output << std::endl << std::endl; - for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++){ + for (JSON::ObjIter it = vals.ObjBegin(); it != vals.ObjEnd(); it++) { std::string f; - if (it->second.isMember("long") || it->second.isMember("short")){ - if (it->second.isMember("long") && it->second.isMember("short")){ + 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(); - }else{ - if (it->second.isMember("long")){ + } else { + if (it->second.isMember("long")) { f = "--" + it->second["long"].asString(); } - if (it->second.isMember("short")){ + if (it->second.isMember("short")) { f = "-" + it->second["short"].asString(); } } - while (f.size() < longest){ + while (f.size() < longest) { f.append(" "); } - if (it->second.isMember("arg")){ + if (it->second.isMember("arg")) { output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl; - }else{ + } else { output << f << it->second["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")){ + 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(); - }else{ - if (it->second.isMember("long_off")){ + } else { + if (it->second.isMember("long_off")) { f = "--" + it->second["long_off"].asString(); } - if (it->second.isMember("short_off")){ + if (it->second.isMember("short_off")) { f = "-" + it->second["short_off"].asString(); } } - while (f.size() < longest){ + while (f.size() < longest) { f.append(" "); } - if (it->second.isMember("arg")){ + if (it->second.isMember("arg")) { output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl; - }else{ + } else { output << f << it->second["help"].asString() << std::endl; } } - if (it->second.isMember("arg_num")){ + if (it->second.isMember("arg_num")) { f = it->first; - while (f.size() < longest){ + while (f.size() < longest) { f.append(" "); } output << f << "(" << it->second["arg"].asString() << ") " << it->second["help"].asString() << std::endl; @@ -197,51 +197,51 @@ void Util::Config::printHelp(std::ostream & output){ /// Parses commandline arguments. /// Calls exit if an unknown option is encountered, printing a help message. -bool Util::Config::parseArgs(int & argc, char ** & argv){ +bool Util::Config::parseArgs(int & argc, char ** & argv) { int opt = 0; std::string shortopts; - struct option * longOpts = (struct option*)calloc(long_count + 1, sizeof(struct option)); + struct option * longOpts = (struct option *)calloc(long_count + 1, sizeof(struct option)); 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")){ + 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")){ + if (it->second.isMember("arg")) { shortopts += ":"; } } - if (it->second.isMember("short_off")){ + if (it->second.isMember("short_off")) { shortopts += it->second["short_off"].asString(); - if (it->second.isMember("arg")){ + if (it->second.isMember("arg")) { shortopts += ":"; } } - if (it->second.isMember("long")){ + 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->second.isMember("arg")) { longOpts[long_i].has_arg = 1; } long_i++; } - if (it->second.isMember("long_off")){ + 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->second.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){ + 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(); } } } } - while ((opt = getopt_long(argc, argv, shortopts.c_str(), longOpts, 0)) != -1){ - switch (opt){ + while ((opt = getopt_long(argc, argv, shortopts.c_str(), longOpts, 0)) != -1) { + switch (opt) { case 'h': case '?': printHelp(std::cout); @@ -251,16 +251,16 @@ 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")){ + 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); - }else{ + } else { it->second["value"].append((long long int)1); } break; } - if (it->second.isMember("short_off") && it->second["short_off"].asString()[0] == opt){ + if (it->second.isMember("short_off") && it->second["short_off"].asString()[0] == opt) { it->second["value"].append((long long int)0); } } @@ -269,9 +269,9 @@ bool Util::Config::parseArgs(int & argc, char ** & argv){ } //commandline options parser 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){ + 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]); break; } @@ -279,7 +279,7 @@ bool Util::Config::parseArgs(int & argc, char ** & argv){ optind++; long_i++; } - if (long_i <= arg_count){ + if (long_i <= arg_count) { return false; } printDebugLevel = getInteger("debug"); @@ -288,17 +288,17 @@ bool Util::Config::parseArgs(int & argc, char ** & argv){ /// Returns a reference to the current value of an option or default if none was set. /// If the option does not exist, this exits the application with a return code of 37. -JSON::Value & Util::Config::getOption(std::string optname, bool asArray){ - if ( !vals.isMember(optname)){ +JSON::Value & Util::Config::getOption(std::string optname, bool asArray) { + if (!vals.isMember(optname)) { std::cout << "Fatal error: a non-existent option '" << optname << "' was accessed." << std::endl; exit(37); } - if ( !vals[optname].isMember("value") || !vals[optname]["value"].isArray()){ + if (!vals[optname].isMember("value") || !vals[optname]["value"].isArray()) { vals[optname]["value"].append(JSON::Value()); } - if (asArray){ + if (asArray) { return vals[optname]["value"]; - }else{ + } else { int n = vals[optname]["value"].size(); return vals[optname]["value"][n - 1]; } @@ -306,30 +306,30 @@ JSON::Value & Util::Config::getOption(std::string optname, bool asArray){ /// Returns the current value of an option or default if none was set as a string. /// Calls getOption internally. -std::string Util::Config::getString(std::string optname){ +std::string Util::Config::getString(std::string optname) { return getOption(optname).asString(); } /// Returns the current value of an option or default if none was set as a long long int. /// Calls getOption internally. -long long int Util::Config::getInteger(std::string optname){ +long long int Util::Config::getInteger(std::string optname) { return getOption(optname).asInt(); } /// Returns the current value of an option or default if none was set as a bool. /// Calls getOption internally. -bool Util::Config::getBool(std::string optname){ +bool Util::Config::getBool(std::string optname) { return getOption(optname).asBool(); } -struct callbackData{ +struct callbackData { Socket::Connection * sock; int (*cb)(Socket::Connection &); }; -static void callThreadCallback(void * cDataArg){ +static void callThreadCallback(void * cDataArg) { DEBUG_MSG(DLVL_INSANE, "Thread for %p started", cDataArg); - callbackData * cData = (callbackData*)cDataArg; + callbackData * cData = (callbackData *)cDataArg; cData->cb(*(cData->sock)); cData->sock->close(); delete cData->sock; @@ -337,19 +337,19 @@ static void callThreadCallback(void * cDataArg){ DEBUG_MSG(DLVL_INSANE, "Thread for %p ended", cDataArg); } -int Util::Config::threadServer(Socket::Server & server_socket, int (*callback)(Socket::Connection &)){ - while (is_active && server_socket.connected()){ +int Util::Config::threadServer(Socket::Server & server_socket, int (*callback)(Socket::Connection &)) { + while (is_active && server_socket.connected()) { Socket::Connection S = server_socket.accept(); - if (S.connected()){ //check if the new connection is valid + if (S.connected()) { //check if the new connection is valid callbackData * cData = new callbackData; cData->sock = new Socket::Connection(S); cData->cb = callback; //spawn a new thread for this connection - tthread::thread T(callThreadCallback, (void*)cData); + tthread::thread T(callThreadCallback, (void *)cData); //detach it, no need to keep track of it anymore T.detach(); DEBUG_MSG(DLVL_HIGH, "Spawned new thread for socket %i", S.getSocket()); - }else{ + } else { Util::sleep(10); //sleep 10ms } } @@ -357,19 +357,19 @@ int Util::Config::threadServer(Socket::Server & server_socket, int (*callback)(S return 0; } -int Util::Config::forkServer(Socket::Server & server_socket, int (*callback)(Socket::Connection &)){ - while (is_active && server_socket.connected()){ +int Util::Config::forkServer(Socket::Server & server_socket, int (*callback)(Socket::Connection &)) { + while (is_active && server_socket.connected()) { Socket::Connection S = server_socket.accept(); - if (S.connected()){ //check if the new connection is valid + if (S.connected()) { //check if the new connection is valid pid_t myid = fork(); - if (myid == 0){ //if new child, start MAINHANDLER + if (myid == 0) { //if new child, start MAINHANDLER server_socket.drop(); return callback(S); - }else{ //otherwise, do nothing or output debugging text + } else { //otherwise, do nothing or output debugging text DEBUG_MSG(DLVL_HIGH, "Forked new process %i for socket %i", (int)myid, S.getSocket()); S.drop(); } - }else{ + } else { Util::sleep(10); //sleep 10ms } } @@ -377,15 +377,15 @@ int Util::Config::forkServer(Socket::Server & server_socket, int (*callback)(Soc return 0; } -int Util::Config::serveThreadedSocket(int (*callback)(Socket::Connection &)){ +int Util::Config::serveThreadedSocket(int (*callback)(Socket::Connection &)) { Socket::Server server_socket; - if (vals.isMember("socket")){ + if (vals.isMember("socket")) { server_socket = Socket::Server(Util::getTmpFolder() + getString("socket")); } - if (vals.isMember("listen_port") && vals.isMember("listen_interface")){ + if (vals.isMember("listen_port") && vals.isMember("listen_interface")) { server_socket = Socket::Server(getInteger("listen_port"), getString("listen_interface"), false); } - if (!server_socket.connected()){ + if (!server_socket.connected()) { DEBUG_MSG(DLVL_DEVEL, "Failure to open socket"); return 1; } @@ -394,15 +394,15 @@ int Util::Config::serveThreadedSocket(int (*callback)(Socket::Connection &)){ return threadServer(server_socket, callback); } -int Util::Config::serveForkedSocket(int (*callback)(Socket::Connection & S)){ +int Util::Config::serveForkedSocket(int (*callback)(Socket::Connection & S)) { Socket::Server server_socket; - if (vals.isMember("socket")){ + if (vals.isMember("socket")) { server_socket = Socket::Server(Util::getTmpFolder() + getString("socket")); } - if (vals.isMember("listen_port") && vals.isMember("listen_interface")){ + if (vals.isMember("listen_port") && vals.isMember("listen_interface")) { server_socket = Socket::Server(getInteger("listen_port"), getString("listen_interface"), false); } - if (!server_socket.connected()){ + if (!server_socket.connected()) { DEBUG_MSG(DLVL_DEVEL, "Failure to open socket"); return 1; } @@ -416,21 +416,21 @@ int Util::Config::serveForkedSocket(int (*callback)(Socket::Connection & S)){ /// - Daemonize the process if "daemonize" exists and is true. /// - Set is_active to true. /// - Set up a signal handler to set is_active to false for the SIGINT, SIGHUP and SIGTERM signals. -void Util::Config::activate(){ - if (vals.isMember("username")){ +void Util::Config::activate() { + if (vals.isMember("username")) { setUser(getString("username")); } - if (vals.isMember("daemonize") && getBool("daemonize")){ - if(vals.isMember("logfile") && getString("logfile") != ""){ + if (vals.isMember("daemonize") && getBool("daemonize")) { + if (vals.isMember("logfile") && getString("logfile") != "") { Daemonize(true); - }else{ + } else { Daemonize(false); } } struct sigaction new_action; struct sigaction cur_action; new_action.sa_handler = signal_handler; - sigemptyset( &new_action.sa_mask); + sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGINT, &new_action, NULL); sigaction(SIGHUP, &new_action, NULL); @@ -438,8 +438,8 @@ void Util::Config::activate(){ sigaction(SIGPIPE, &new_action, NULL); //check if a child signal handler isn't set already, if so, set it. sigaction(SIGCHLD, 0, &cur_action); - if (cur_action.sa_handler == SIG_DFL || cur_action.sa_handler == SIG_IGN){ - sigaction(SIGCHLD, &new_action, NULL); + if (cur_action.sa_handler == SIG_DFL || cur_action.sa_handler == SIG_IGN) { + sigaction(SIGCHLD, &new_action, NULL); } is_active = true; } @@ -447,24 +447,24 @@ void Util::Config::activate(){ /// Basic signal handler. Sets is_active to false if it receives /// a SIGINT, SIGHUP or SIGTERM signal, reaps children for the SIGCHLD /// signal, and ignores all other signals. -void Util::Config::signal_handler(int signum){ - switch (signum){ +void Util::Config::signal_handler(int signum) { + switch (signum) { case SIGINT: //these three signals will set is_active to false. case SIGHUP: case SIGTERM: is_active = false; break; - case SIGCHLD:{ //when a child dies, reap it. - int status; - pid_t ret = -1; - while (ret != 0){ - ret = waitpid( -1, &status, WNOHANG); - if (ret < 0 && errno != EINTR){ - break; - } - } - break; - } + case SIGCHLD: { //when a child dies, reap it. + int status; + pid_t ret = -1; + while (ret != 0) { + ret = waitpid(-1, &status, WNOHANG); + if (ret < 0 && errno != EINTR) { + break; + } + } + break; + } default: //other signals are ignored break; } @@ -472,7 +472,7 @@ void Util::Config::signal_handler(int signum){ /// Adds the default connector options. Also updates the capabilities structure with the default options. /// Besides the options addBasicConnectorOptions adds, this function also adds port and interface options. -void Util::Config::addConnectorOptions(int port, JSON::Value & capabilities){ +void Util::Config::addConnectorOptions(int port, JSON::Value & capabilities) { JSON::Value option; option.null(); option["long"] = "port"; @@ -482,11 +482,11 @@ void Util::Config::addConnectorOptions(int port, JSON::Value & capabilities){ option["value"].append((long long)port); addOption("listen_port", option); capabilities["optional"]["port"]["name"] = "TCP port"; - capabilities["optional"]["port"]["help"] = "TCP port to listen on - default if unprovided is "+option["value"][0u].asString(); + capabilities["optional"]["port"]["help"] = "TCP port to listen on - default if unprovided is " + option["value"][0u].asString(); capabilities["optional"]["port"]["type"] = "uint"; capabilities["optional"]["port"]["option"] = "--port"; capabilities["optional"]["port"]["default"] = option["value"][0u]; - + option.null(); option["long"] = "interface"; option["short"] = "i"; @@ -498,12 +498,12 @@ void Util::Config::addConnectorOptions(int port, JSON::Value & capabilities){ capabilities["optional"]["interface"]["help"] = "Address of the interface to listen on - default if unprovided is all interfaces"; capabilities["optional"]["interface"]["option"] = "--interface"; capabilities["optional"]["interface"]["type"] = "str"; - + addBasicConnectorOptions(capabilities); } //addConnectorOptions /// Adds the default connector options. Also updates the capabilities structure with the default options. -void Util::Config::addBasicConnectorOptions(JSON::Value & capabilities){ +void Util::Config::addBasicConnectorOptions(JSON::Value & capabilities) { JSON::Value option; option.null(); option["long"] = "username"; @@ -518,7 +518,7 @@ void Util::Config::addBasicConnectorOptions(JSON::Value & capabilities){ capabilities["optional"]["username"]["type"] = "str"; - if (capabilities.isMember("socket")){ + if (capabilities.isMember("socket")) { option.null(); option["arg"] = "string"; option["help"] = "Socket name that can be connected to for this connector."; @@ -534,7 +534,7 @@ void Util::Config::addBasicConnectorOptions(JSON::Value & capabilities){ option["help"] = "Whether or not to daemonize the process after starting."; option["value"].append(0ll); addOption("daemonize", option); - + option.null(); option["long"] = "json"; option["short"] = "j"; @@ -546,29 +546,29 @@ void Util::Config::addBasicConnectorOptions(JSON::Value & capabilities){ /// Gets directory the current executable is stored in. -std::string Util::getMyPath(){ +std::string Util::getMyPath() { char mypath[500]; - #ifdef __CYGWIN__ +#ifdef __CYGWIN__ GetModuleFileName(0, mypath, 500); - #else - #ifdef __APPLE__ - memset( mypath, 0, 500); +#else +#ifdef __APPLE__ + memset(mypath, 0, 500); unsigned int refSize = 500; - int ret = _NSGetExecutablePath(mypath,&refSize); - #else + int ret = _NSGetExecutablePath(mypath, &refSize); +#else int ret = readlink("/proc/self/exe", mypath, 500); - if (ret != -1){ + if (ret != -1) { mypath[ret] = 0; - }else{ + } else { mypath[0] = 0; } - #endif - #endif +#endif +#endif std::string tPath = mypath; size_t slash = tPath.rfind('/'); - if (slash == std::string::npos){ + if (slash == std::string::npos) { slash = tPath.rfind('\\'); - if (slash == std::string::npos){ + if (slash == std::string::npos) { return ""; } } @@ -577,46 +577,48 @@ std::string Util::getMyPath(){ } /// Gets all executables in getMyPath that start with "Mist". -void Util::getMyExec(std::deque & execs){ +void Util::getMyExec(std::deque & execs) { std::string path = Util::getMyPath(); - #ifdef __CYGWIN__ +#ifdef __CYGWIN__ path += "\\Mist*"; WIN32_FIND_DATA FindFileData; HANDLE hdl = FindFirstFile(path.c_str(), &FindFileData); - while (hdl != INVALID_HANDLE_VALUE){ + while (hdl != INVALID_HANDLE_VALUE) { execs.push_back(FindFileData.cFileName); - if (!FindNextFile(hdl, &FindFileData)){ + if (!FindNextFile(hdl, &FindFileData)) { FindClose(hdl); hdl = INVALID_HANDLE_VALUE; } } - #else +#else DIR * d = opendir(path.c_str()); - if (!d){return;} - struct dirent *dp; + if (!d) { + return; + } + struct dirent * dp; do { errno = 0; - if ((dp = readdir(d))){ - if (strncmp(dp->d_name, "Mist", 4) == 0){ + if ((dp = readdir(d))) { + if (strncmp(dp->d_name, "Mist", 4) == 0) { execs.push_back(dp->d_name); } } } while (dp != NULL); closedir(d); - #endif +#endif } /// Sets the current process' running user -void Util::setUser(std::string username){ - if (username != "root"){ +void Util::setUser(std::string username) { + if (username != "root") { struct passwd * user_info = getpwnam(username.c_str()); - if ( !user_info){ + if (!user_info) { DEBUG_MSG(DLVL_ERROR, "Error: could not setuid %s: could not get PID", username.c_str()); return; - }else{ - if (setuid(user_info->pw_uid) != 0){ + } else { + if (setuid(user_info->pw_uid) != 0) { DEBUG_MSG(DLVL_ERROR, "Error: could not setuid %s: not allowed", username.c_str()); - }else{ + } else { DEBUG_MSG(DLVL_DEVEL, "Change user to %s", username.c_str()); } } @@ -627,13 +629,13 @@ void Util::setUser(std::string username){ /// Works by calling daemon(1,0): /// Does not change directory to root. /// Does redirect output to /dev/null -void Util::Daemonize(bool notClose){ +void Util::Daemonize(bool notClose) { DEBUG_MSG(DLVL_DEVEL, "Going into background mode..."); int noClose = 0; - if(notClose){ + if (notClose) { noClose = 1; } - if (daemon(1, noClose) < 0){ + if (daemon(1, noClose) < 0) { DEBUG_MSG(DLVL_ERROR, "Failed to daemonize: %s", strerror(errno)); } } diff --git a/lib/config.h b/lib/config.h index 984e7ae4..642194ae 100644 --- a/lib/config.h +++ b/lib/config.h @@ -14,7 +14,7 @@ namespace Util { /// Deals with parsing configuration from commandline options. - class Config{ + class Config { private: JSON::Value vals; ///< Holds all current config values int long_count; @@ -49,7 +49,7 @@ namespace Util { /// Gets all executables in getMyPath that start with "Mist". void getMyExec(std::deque & execs); - + /// Will set the active user to the named username. void setUser(std::string user); diff --git a/lib/converter.cpp b/lib/converter.cpp index 5eba384d..752b0664 100644 --- a/lib/converter.cpp +++ b/lib/converter.cpp @@ -11,62 +11,64 @@ #include "config.h" namespace Converter { - + ///\brief The base constructor - Converter::Converter(){ + Converter::Converter() { fillFFMpegEncoders(); } - + ///\brief A function that fill the internal variables with values provided by examing ffmpeg output /// ///Checks for the following encoders: /// - AAC /// - H264 /// - MP3 - void Converter::fillFFMpegEncoders(){ - std::vector cmd; + void Converter::fillFFMpegEncoders() { + std::vector cmd; cmd.reserve(3); - cmd.push_back((char*)"ffmpeg"); - cmd.push_back((char*)"-encoders"); + cmd.push_back((char *)"ffmpeg"); + cmd.push_back((char *)"-encoders"); cmd.push_back(NULL); int outFD = -1; Util::Procs::StartPiped("FFMpegInfo", &cmd[0], 0, &outFD, 0); - while( Util::Procs::isActive("FFMpegInfo")){ Util::sleep(100); } - FILE * outFile = fdopen( outFD, "r" ); + while (Util::Procs::isActive("FFMpegInfo")) { + Util::sleep(100); + } + FILE * outFile = fdopen(outFD, "r"); char * fileBuf = 0; size_t fileBufLen = 0; - while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){ - if (strstr(fileBuf, "aac") || strstr(fileBuf, "AAC")){ + while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { + if (strstr(fileBuf, "aac") || strstr(fileBuf, "AAC")) { strtok(fileBuf, " \t"); allCodecs["ffmpeg"][strtok(NULL, " \t")] = "aac"; } - if (strstr(fileBuf, "h264") || strstr(fileBuf, "H264")){ + if (strstr(fileBuf, "h264") || strstr(fileBuf, "H264")) { strtok(fileBuf, " \t"); allCodecs["ffmpeg"][strtok(NULL, " \t")] = "h264"; } - if (strstr(fileBuf, "mp3") || strstr(fileBuf, "MP3")){ + if (strstr(fileBuf, "mp3") || strstr(fileBuf, "MP3")) { strtok(fileBuf, " \t"); allCodecs["ffmpeg"][strtok(NULL, " \t")] = "mp3"; } } - fclose( outFile ); + fclose(outFile); } - + ///\brief A function to obtain all available codecs that have been obtained from the encoders. ///\return A reference to the allCodecs member. - converterInfo & Converter::getCodecs(){ + converterInfo & Converter::getCodecs() { return allCodecs; } ///\brief A function to obtain the available encoders in JSON format. ///\return A JSON::Value containing all encoder:codec pairs. - JSON::Value Converter::getEncoders(){ + JSON::Value Converter::getEncoders() { JSON::Value result; - for (converterInfo::iterator convIt = allCodecs.begin(); convIt != allCodecs.end(); convIt++){ - for (codecInfo::iterator codIt = convIt->second.begin(); codIt != convIt->second.end(); codIt++){ - if (codIt->second == "h264"){ + for (converterInfo::iterator convIt = allCodecs.begin(); convIt != allCodecs.end(); convIt++) { + for (codecInfo::iterator codIt = convIt->second.begin(); codIt != convIt->second.end(); codIt++) { + if (codIt->second == "h264") { result[convIt->first]["video"][codIt->first] = codIt->second; - }else{ + } else { result[convIt->first]["audio"][codIt->first] = codIt->second; } @@ -74,30 +76,30 @@ namespace Converter { } return result; } - + ///\brief Looks in a given path for all files that could be converted ///\param myPath The location to look at, this should be a folder. ///\return A JSON::Value containing all media files in the location, with their corresponding metadata values. - JSON::Value Converter::queryPath(std::string myPath){ + JSON::Value Converter::queryPath(std::string myPath) { char const * cmd[3] = {0, 0, 0}; std::string mistPath = Util::getMyPath() + "MistInfo"; cmd[0] = mistPath.c_str(); JSON::Value result; DIR * Dirp = opendir(myPath.c_str()); struct stat StatBuf; - if (Dirp){ + if (Dirp) { dirent * entry; - while ((entry = readdir(Dirp))){ - if (stat(std::string(myPath + "/" + entry->d_name).c_str(), &StatBuf) == -1){ + while ((entry = readdir(Dirp))) { + if (stat(std::string(myPath + "/" + entry->d_name).c_str(), &StatBuf) == -1) { continue; } - if ((StatBuf.st_mode & S_IFREG) == 0){ + if ((StatBuf.st_mode & S_IFREG) == 0) { continue; } std::string fileName = entry->d_name; - std::string mijnPad = std::string(myPath + (myPath[myPath.size()-1] == '/' ? "" : "/") + entry->d_name); + std::string mijnPad = std::string(myPath + (myPath[myPath.size() - 1] == '/' ? "" : "/") + entry->d_name); cmd[1] = mijnPad.c_str(); - result[fileName] = JSON::fromString(Util::Procs::getOutputOf((char* const*)cmd)); + result[fileName] = JSON::fromString(Util::Procs::getOutputOf((char * const *)cmd)); } } return result; @@ -118,11 +120,11 @@ namespace Converter { /// - codec The codec to encode audio in, or copy to use the current codec /// - samplerate The target samplerate for the audio, in hz void Converter::startConversion(std::string name, JSON::Value parameters) { - if ( !parameters.isMember("input")){ + if (!parameters.isMember("input")) { statusHistory[name] = "No input file supplied"; return; } - if ( !parameters.isMember("output")){ + if (!parameters.isMember("output")) { statusHistory[name] = "No output file supplied"; return; } @@ -130,81 +132,81 @@ namespace Converter { std::string outPath = parameters["output"].asString(); outPath = outPath.substr(0, outPath.rfind('/')); int statRes = stat(outPath.c_str(), & statBuf); - if (statRes == -1 || !S_ISDIR(statBuf.st_mode)){ + if (statRes == -1 || !S_ISDIR(statBuf.st_mode)) { statusHistory[name] = "Output path is either non-existent, or not a path."; return; } - if ( !parameters.isMember("encoder")){ + if (!parameters.isMember("encoder")) { statusHistory[name] = "No encoder specified"; return; } - if (allCodecs.find(parameters["encoder"]) == allCodecs.end()){ + if (allCodecs.find(parameters["encoder"]) == allCodecs.end()) { statusHistory[name] = "Can not find encoder " + parameters["encoder"].asString(); return; } - if (parameters.isMember("video")){ - if (parameters["video"].isMember("width") && !parameters["video"].isMember("height")){ + if (parameters.isMember("video")) { + if (parameters["video"].isMember("width") && !parameters["video"].isMember("height")) { statusHistory[name] = "No height parameter given"; return; } - if (parameters["video"].isMember("height") && !parameters["video"].isMember("width")){ + if (parameters["video"].isMember("height") && !parameters["video"].isMember("width")) { statusHistory[name] = "No width parameter given"; return; } } std::stringstream encoderCommand; - if (parameters["encoder"] == "ffmpeg"){ + if (parameters["encoder"] == "ffmpeg") { encoderCommand << "ffmpeg -i "; encoderCommand << parameters["input"].asString() << " "; - if (parameters.isMember("video")){ - if ( !parameters["video"].isMember("codec") || parameters["video"]["codec"] == "copy"){ + if (parameters.isMember("video")) { + if (!parameters["video"].isMember("codec") || parameters["video"]["codec"] == "copy") { encoderCommand << "-vcodec copy "; - }else{ + } else { codecInfo::iterator vidCodec = allCodecs["ffmpeg"].find(parameters["video"]["codec"]); - if (vidCodec == allCodecs["ffmpeg"].end()){ + if (vidCodec == allCodecs["ffmpeg"].end()) { statusHistory[name] = "Can not find video codec " + parameters["video"]["codec"].asString(); return; } encoderCommand << "-vcodec " << vidCodec->first << " "; - if (parameters["video"]["codec"].asString() == "h264"){ + if (parameters["video"]["codec"].asString() == "h264") { //Enforce baseline - encoderCommand << "-preset slow -profile:v baseline -level 30 "; + encoderCommand << "-preset slow -profile:v baseline -level 30 "; } - if (parameters["video"].isMember("fpks")){ - encoderCommand << "-r " << parameters["video"]["fpks"].asInt() / 1000 << " "; + if (parameters["video"].isMember("fpks")) { + encoderCommand << "-r " << parameters["video"]["fpks"].asInt() / 1000 << " "; } - if (parameters["video"].isMember("width")){ + if (parameters["video"].isMember("width")) { encoderCommand << "-s " << parameters["video"]["width"].asInt() << "x" << parameters["video"]["height"].asInt() << " "; } ///\todo Keyframe interval (different in older and newer versions of ffmpeg?) } - }else{ + } else { encoderCommand << "-vn "; } - if (parameters.isMember("audio")){ - if ( !parameters["audio"].isMember("codec")){ + if (parameters.isMember("audio")) { + if (!parameters["audio"].isMember("codec")) { encoderCommand << "-acodec copy "; - }else{ + } else { codecInfo::iterator audCodec = allCodecs["ffmpeg"].find(parameters["audio"]["codec"]); - if (audCodec == allCodecs["ffmpeg"].end()){ + if (audCodec == allCodecs["ffmpeg"].end()) { statusHistory[name] = "Can not find audio codec " + parameters["audio"]["codec"].asString(); return; } - if (audCodec->second == "aac"){ + if (audCodec->second == "aac") { encoderCommand << "-strict -2 "; } encoderCommand << "-acodec " << audCodec->first << " "; - if (parameters["audio"].isMember("samplerate")){ + if (parameters["audio"].isMember("samplerate")) { encoderCommand << "-ar " << parameters["audio"]["samplerate"].asInt() << " "; } } - }else{ + } else { encoderCommand << "-an "; } encoderCommand << "-f flv -"; } int statusFD = -1; - Util::Procs::StartPiped2(name,encoderCommand.str(),Util::getMyPath() + "MistFLV2DTSC -o " + parameters["output"].asString(),0,0,&statusFD,0); + Util::Procs::StartPiped2(name, encoderCommand.str(), Util::getMyPath() + "MistFLV2DTSC -o " + parameters["output"].asString(), 0, 0, &statusFD, 0); parameters["statusFD"] = statusFD; allConversions[name] = parameters; allConversions[name]["status"]["duration"] = "?"; @@ -212,53 +214,53 @@ namespace Converter { allConversions[name]["status"]["frame"] = 0; allConversions[name]["status"]["time"] = 0; } - + ///\brief Updates the internal status of the converter class. /// ///Will check for each running conversion whether it is still running, and update its status accordingly - void Converter::updateStatus(){ - if (allConversions.size()){ - std::map::iterator cIt; + void Converter::updateStatus() { + if (allConversions.size()) { + std::map::iterator cIt; bool hasChanged = true; - while (hasChanged && allConversions.size()){ + while (hasChanged && allConversions.size()) { hasChanged = false; - for (cIt = allConversions.begin(); cIt != allConversions.end(); cIt++){ - if (Util::Procs::isActive(cIt->first)){ + for (cIt = allConversions.begin(); cIt != allConversions.end(); cIt++) { + if (Util::Procs::isActive(cIt->first)) { int statusFD = dup(cIt->second["statusFD"].asInt()); - fsync( statusFD ); - FILE* statusFile = fdopen( statusFD, "r" ); + fsync(statusFD); + FILE * statusFile = fdopen(statusFD, "r"); char * fileBuf = 0; size_t fileBufLen = 0; - fseek(statusFile,0,SEEK_END); + fseek(statusFile, 0, SEEK_END); std::string line; int totalTime = 0; - do{ + do { getdelim(&fileBuf, &fileBufLen, '\r', statusFile); line = fileBuf; - if (line.find("Duration") != std::string::npos){ + if (line.find("Duration") != std::string::npos) { int curOffset = line.find("Duration: ") + 10; totalTime += atoi(line.substr(curOffset, 2).c_str()) * 60 * 60 * 1000; - totalTime += atoi(line.substr(curOffset+3, 2).c_str()) * 60 * 1000; - totalTime += atoi(line.substr(curOffset+6, 2).c_str()) *1000; - totalTime += atoi(line.substr(curOffset+9, 2).c_str()) * 10; + totalTime += atoi(line.substr(curOffset + 3, 2).c_str()) * 60 * 1000; + totalTime += atoi(line.substr(curOffset + 6, 2).c_str()) * 1000; + totalTime += atoi(line.substr(curOffset + 9, 2).c_str()) * 10; cIt->second["duration"] = totalTime; } - }while ( !feof(statusFile) && line.find("frame") != 0);//"frame" is the fist word on an actual status line of ffmpeg - if ( !feof(statusFile)){ - cIt->second["status"] = parseFFMpegStatus( line ); + } while (!feof(statusFile) && line.find("frame") != 0); //"frame" is the fist word on an actual status line of ffmpeg + if (!feof(statusFile)) { + cIt->second["status"] = parseFFMpegStatus(line); cIt->second["status"]["duration"] = cIt->second["duration"]; cIt->second["status"]["progress"] = (cIt->second["status"]["time"].asInt() * 100) / cIt->second["duration"].asInt(); - }else{ - line.erase(line.end()-1); - line = line.substr( line.rfind("\n") + 1 ); + } else { + line.erase(line.end() - 1); + line = line.substr(line.rfind("\n") + 1); cIt->second["status"] = line; } free(fileBuf); fclose(statusFile); - }else{ - if (statusHistory.find( cIt->first ) == statusHistory.end()){ + } else { + if (statusHistory.find(cIt->first) == statusHistory.end()) { statusHistory[cIt->first] = "Conversion successful, running DTSCFix"; - Util::Procs::Start(cIt->first+"DTSCFix",Util::getMyPath() + "MistDTSCFix " + cIt->second["output"].asString()); + Util::Procs::Start(cIt->first + "DTSCFix", Util::getMyPath() + "MistDTSCFix " + cIt->second["output"].asString()); } allConversions.erase(cIt); hasChanged = true; @@ -267,11 +269,11 @@ namespace Converter { } } } - if(statusHistory.size()){ - std::map::iterator sIt; - for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++){ - if (statusHistory[sIt->first].find("DTSCFix") != std::string::npos){ - if (Util::Procs::isActive(sIt->first+"DTSCFIX")){ + if (statusHistory.size()) { + std::map::iterator sIt; + for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++) { + if (statusHistory[sIt->first].find("DTSCFix") != std::string::npos) { + if (Util::Procs::isActive(sIt->first + "DTSCFIX")) { continue; } statusHistory[sIt->first] = "Conversion successful"; @@ -279,48 +281,48 @@ namespace Converter { } } } - + ///\brief Parses a single ffmpeg status line into a JSON format ///\param statusLine The current status of ffmpeg ///\return A JSON::Value with the following values set: /// - frame The current last encoded frame /// - time The current last encoded timestamp - JSON::Value Converter::parseFFMpegStatus(std::string statusLine){ + JSON::Value Converter::parseFFMpegStatus(std::string statusLine) { JSON::Value result; int curOffset = statusLine.find("frame=") + 6; - result["frame"] = atoi(statusLine.substr(curOffset, statusLine.find("fps=") - curOffset).c_str() ); + result["frame"] = atoi(statusLine.substr(curOffset, statusLine.find("fps=") - curOffset).c_str()); curOffset = statusLine.find("time=") + 5; int myTime = 0; myTime += atoi(statusLine.substr(curOffset, 2).c_str()) * 60 * 60 * 1000; - myTime += atoi(statusLine.substr(curOffset+3, 2).c_str()) * 60 * 1000; - myTime += atoi(statusLine.substr(curOffset+6, 2).c_str()) *1000; - myTime += atoi(statusLine.substr(curOffset+9, 2).c_str()) * 10; + myTime += atoi(statusLine.substr(curOffset + 3, 2).c_str()) * 60 * 1000; + myTime += atoi(statusLine.substr(curOffset + 6, 2).c_str()) * 1000; + myTime += atoi(statusLine.substr(curOffset + 9, 2).c_str()) * 10; result["time"] = myTime; return result; } - + ///\brief Obtain the current internal status of the conversion class ///\return A JSON::Value with the status of each conversion - JSON::Value Converter::getStatus(){ + JSON::Value Converter::getStatus() { updateStatus(); JSON::Value result; - if (allConversions.size()){ - for (std::map::iterator cIt = allConversions.begin(); cIt != allConversions.end(); cIt++){ + if (allConversions.size()) { + for (std::map::iterator cIt = allConversions.begin(); cIt != allConversions.end(); cIt++) { result[cIt->first] = cIt->second["status"]; result[cIt->first]["details"] = cIt->second; } } - if (statusHistory.size()){ - std::map::iterator sIt; - for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++){ + if (statusHistory.size()) { + std::map::iterator sIt; + for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++) { result[sIt->first] = sIt->second; } } return result; } - + ///\brief Clears the status history of all conversions - void Converter::clearStatus(){ + void Converter::clearStatus() { statusHistory.clear(); } } diff --git a/lib/converter.h b/lib/converter.h index c3a6a0bf..a082e994 100644 --- a/lib/converter.h +++ b/lib/converter.h @@ -4,9 +4,9 @@ #include "json.h" ///\brief A typedef to simplify accessing all codecs -typedef std::map codecInfo; +typedef std::map codecInfo; ///\brief A typedef to simplify accessing all encoders -typedef std::map converterInfo; +typedef std::map converterInfo; ///\brief A namespace containing all functions for handling the conversion API namespace Converter { @@ -28,8 +28,8 @@ namespace Converter { ///\brief Holds a list of all current known codecs converterInfo allCodecs; ///\brief Holds a list of all the current conversions - std::map allConversions; + std::map allConversions; ///\brief Stores the status of all conversions, and the history - std::map statusHistory; + std::map statusHistory; }; } diff --git a/lib/defines.h b/lib/defines.h index bc686b3d..300c0dea 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -1,52 +1,52 @@ // Defines to print debug messages. #ifndef MIST_DEBUG - #define MIST_DEBUG 1 - #define DLVL_NONE 0 // All debugging disabled. - #define DLVL_FAIL 1 // Only messages about failed operations. - #define DLVL_ERROR 2 // Only messages about errors and failed operations. - #define DLVL_WARN 3 // Warnings, errors, and fail messages. - #define DLVL_DEVEL 4 // All of the above, plus status messages handy during development. - #define DLVL_INFO 4 // All of the above, plus status messages handy during development. - #define DLVL_MEDIUM 5 // Slightly more than just development-level messages. - #define DLVL_HIGH 6 // Verbose debugging messages. - #define DLVL_VERYHIGH 7 // Very verbose debugging messages. - #define DLVL_EXTREME 8 // Everything is reported in extreme detail. - #define DLVL_INSANE 9 // Everything is reported in insane detail. - #define DLVL_DONTEVEN 10 // All messages enabled, even pointless ones. - #if DEBUG > -1 +#define MIST_DEBUG 1 +#define DLVL_NONE 0 // All debugging disabled. +#define DLVL_FAIL 1 // Only messages about failed operations. +#define DLVL_ERROR 2 // Only messages about errors and failed operations. +#define DLVL_WARN 3 // Warnings, errors, and fail messages. +#define DLVL_DEVEL 4 // All of the above, plus status messages handy during development. +#define DLVL_INFO 4 // All of the above, plus status messages handy during development. +#define DLVL_MEDIUM 5 // Slightly more than just development-level messages. +#define DLVL_HIGH 6 // Verbose debugging messages. +#define DLVL_VERYHIGH 7 // Very verbose debugging messages. +#define DLVL_EXTREME 8 // Everything is reported in extreme detail. +#define DLVL_INSANE 9 // Everything is reported in insane detail. +#define DLVL_DONTEVEN 10 // All messages enabled, even pointless ones. +#if DEBUG > -1 - #include - #include - #include "config.h" - static const char* DBG_LVL_LIST[] = {"NONE","FAIL","ERROR","WARN","INFO","MEDIUM","HIGH","VERYHIGH","EXTREME","INSANE","DONTEVEN"}; - - #if !defined(__APPLE__) && !defined(__MACH__) && defined(__GNUC__) - #include - extern char * program_invocation_short_name; - - #if DEBUG >= DLVL_DEVEL - #define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d|%s:%d|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), __FILE__, __LINE__, ##__VA_ARGS__);} - #else - #define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d||" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), ##__VA_ARGS__);} - #endif - #else - #if DEBUG >= DLVL_DEVEL - #define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s||%d|%s:%d|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, __LINE__, ##__VA_ARGS__);} - #else - #define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s||%d||" msg "\n", DBG_LVL_LIST[lvl], getpid(), ##__VA_ARGS__);} - #endif - #endif - - #else +#include +#include +#include "config.h" +static const char * DBG_LVL_LIST[] = {"NONE", "FAIL", "ERROR", "WARN", "INFO", "MEDIUM", "HIGH", "VERYHIGH", "EXTREME", "INSANE", "DONTEVEN"}; - #define DEBUG_MSG(lvl, msg, ...) // Debugging disabled. +#if !defined(__APPLE__) && !defined(__MACH__) && defined(__GNUC__) +#include +extern char * program_invocation_short_name; + +#if DEBUG >= DLVL_DEVEL +#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d|%s:%d|" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), __FILE__, __LINE__, ##__VA_ARGS__);} +#else +#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s|%s|%d||" msg "\n", DBG_LVL_LIST[lvl], program_invocation_short_name, getpid(), ##__VA_ARGS__);} +#endif +#else +#if DEBUG >= DLVL_DEVEL +#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s||%d|%s:%d|" msg "\n", DBG_LVL_LIST[lvl], getpid(), __FILE__, __LINE__, ##__VA_ARGS__);} +#else +#define DEBUG_MSG(lvl, msg, ...) if (Util::Config::printDebugLevel >= lvl){fprintf(stderr, "%s||%d||" msg "\n", DBG_LVL_LIST[lvl], getpid(), ##__VA_ARGS__);} +#endif +#endif + +#else + +#define DEBUG_MSG(lvl, msg, ...) // Debugging disabled. + +#endif + +#define FAIL_MSG(msg, ...) DEBUG_MSG(DLVL_FAIL, msg, ##__VA_ARGS__) +#define ERROR_MSG(msg, ...) DEBUG_MSG(DLVL_ERROR, msg, ##__VA_ARGS__) +#define WARN_MSG(msg, ...) DEBUG_MSG(DLVL_WARN, msg, ##__VA_ARGS__) +#define DEVEL_MSG(msg, ...) DEBUG_MSG(DLVL_DEVEL, msg, ##__VA_ARGS__) +#define INFO_MSG(msg, ...) DEBUG_MSG(DLVL_DEVEL, msg, ##__VA_ARGS__) - #endif - - #define FAIL_MSG(msg, ...) DEBUG_MSG(DLVL_FAIL, msg, ##__VA_ARGS__) - #define ERROR_MSG(msg, ...) DEBUG_MSG(DLVL_ERROR, msg, ##__VA_ARGS__) - #define WARN_MSG(msg, ...) DEBUG_MSG(DLVL_WARN, msg, ##__VA_ARGS__) - #define DEVEL_MSG(msg, ...) DEBUG_MSG(DLVL_DEVEL, msg, ##__VA_ARGS__) - #define INFO_MSG(msg, ...) DEBUG_MSG(DLVL_DEVEL, msg, ##__VA_ARGS__) - #endif diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 828ce97e..5d0c7d29 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -11,7 +11,7 @@ char DTSC::Magic_Packet[] = "DTPD"; char DTSC::Magic_Packet2[] = "DTP2"; /// Initializes a DTSC::Stream with only one packet buffer. -DTSC::Stream::Stream(){ +DTSC::Stream::Stream() { datapointertype = DTSC::INVALID; buffercount = 1; buffertime = 0; @@ -19,9 +19,9 @@ DTSC::Stream::Stream(){ /// Initializes a DTSC::Stream with a minimum of rbuffers packet buffers. /// The actual buffer count may not at all times be the requested amount. -DTSC::Stream::Stream(unsigned int rbuffers, unsigned int bufferTime){ +DTSC::Stream::Stream(unsigned int rbuffers, unsigned int bufferTime) { datapointertype = DTSC::INVALID; - if (rbuffers < 1){ + if (rbuffers < 1) { rbuffers = 1; } buffercount = rbuffers; @@ -30,12 +30,12 @@ DTSC::Stream::Stream(unsigned int rbuffers, unsigned int bufferTime){ /// This function does nothing, it's supposed to be overridden. /// It will be called right before a buffer position is deleted. -void DTSC::Stream::deletionCallback(livePos deleting){} +void DTSC::Stream::deletionCallback(livePos deleting) {} /// Returns the time in milliseconds of the last received packet. /// This is _not_ the time this packet was received, only the stored time. -unsigned int DTSC::Stream::getTime(){ - if ( !buffers.size()){ +unsigned int DTSC::Stream::getTime() { + if (!buffers.size()) { return 0; } return buffers.rbegin()->second["time"].asInt(); @@ -45,43 +45,43 @@ unsigned int DTSC::Stream::getTime(){ /// Returns true if successful, removing the parsed part from the buffer string. /// Returns false if invalid or not enough data is in the buffer. /// \arg buffer The std::string buffer to attempt to parse. -bool DTSC::Stream::parsePacket(std::string & buffer){ +bool DTSC::Stream::parsePacket(std::string & buffer) { uint32_t len; static bool syncing = false; - if (buffer.length() > 8){ - if (memcmp(buffer.c_str(), DTSC::Magic_Header, 4) == 0){ + if (buffer.length() > 8) { + if (memcmp(buffer.c_str(), DTSC::Magic_Header, 4) == 0) { len = ntohl(((uint32_t *)buffer.c_str())[1]); - if (buffer.length() < len + 8){ + if (buffer.length() < len + 8) { return false; } unsigned int i = 0; JSON::Value meta; - JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i, meta); + JSON::fromDTMI((unsigned char *)buffer.c_str() + 8, len, i, meta); metadata = Meta(meta); buffer.erase(0, len + 8); - if (buffer.length() <= 8){ + if (buffer.length() <= 8) { return false; } } int version = 0; - if (memcmp(buffer.c_str(), DTSC::Magic_Packet, 4) == 0){ + if (memcmp(buffer.c_str(), DTSC::Magic_Packet, 4) == 0) { version = 1; } - if (memcmp(buffer.c_str(), DTSC::Magic_Packet2, 4) == 0){ + if (memcmp(buffer.c_str(), DTSC::Magic_Packet2, 4) == 0) { version = 2; } - if (version){ + if (version) { len = ntohl(((uint32_t *)buffer.c_str())[1]); - if (buffer.length() < len + 8){ + if (buffer.length() < len + 8) { return false; } JSON::Value newPack; unsigned int i = 0; - if (version == 1){ - JSON::fromDTMI((unsigned char*)buffer.c_str() + 8, len, i, newPack); + if (version == 1) { + JSON::fromDTMI((unsigned char *)buffer.c_str() + 8, len, i, newPack); } - if (version == 2){ - JSON::fromDTMI2((unsigned char*)buffer.c_str() + 8, len, i, newPack); + if (version == 2) { + JSON::fromDTMI2((unsigned char *)buffer.c_str() + 8, len, i, newPack); } buffer.erase(0, len + 8); addPacket(newPack); @@ -89,20 +89,20 @@ bool DTSC::Stream::parsePacket(std::string & buffer){ return true; } #if DEBUG >= DLVL_WARN - if (!syncing){ + if (!syncing) { DEBUG_MSG(DLVL_WARN, "Invalid DTMI data detected - re-syncing"); syncing = true; } #endif size_t magic_search = buffer.find(Magic_Packet); size_t magic_search2 = buffer.find(Magic_Packet2); - if (magic_search2 == std::string::npos){ - if (magic_search == std::string::npos){ + if (magic_search2 == std::string::npos) { + if (magic_search == std::string::npos) { buffer.clear(); - }else{ + } else { buffer.erase(0, magic_search); } - }else{ + } else { buffer.erase(0, magic_search2); } } @@ -113,51 +113,51 @@ bool DTSC::Stream::parsePacket(std::string & buffer){ /// Returns true if successful, removing the parsed part from the buffer. /// Returns false if invalid or not enough data is in the buffer. /// \arg buffer The Socket::Buffer to attempt to parse. -bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ +bool DTSC::Stream::parsePacket(Socket::Buffer & buffer) { uint32_t len; static bool syncing = false; - if (buffer.available(8)){ + if (buffer.available(8)) { std::string header_bytes = buffer.copy(8); - if (memcmp(header_bytes.c_str(), DTSC::Magic_Header, 4) == 0){ + if (memcmp(header_bytes.c_str(), DTSC::Magic_Header, 4) == 0) { len = ntohl(((uint32_t *)header_bytes.c_str())[1]); - if ( !buffer.available(len + 8)){ + if (!buffer.available(len + 8)) { return false; } unsigned int i = 0; std::string wholepacket = buffer.remove(len + 8); JSON::Value meta; - JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i, 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); } int version = 0; - if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet, 4) == 0){ + if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet, 4) == 0) { version = 1; } - if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet2, 4) == 0){ + if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet2, 4) == 0) { version = 2; } - if (version){ + if (version) { len = ntohl(((uint32_t *)header_bytes.c_str())[1]); - if ( !buffer.available(len + 8)){ + if (!buffer.available(len + 8)) { return false; } JSON::Value newPack; unsigned int i = 0; std::string wholepacket = buffer.remove(len + 8); - if (version == 1){ - JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i, newPack); + if (version == 1) { + JSON::fromDTMI((unsigned char *)wholepacket.c_str() + 8, len, i, newPack); } - if (version == 2){ - JSON::fromDTMI2((unsigned char*)wholepacket.c_str() + 8, len, i, newPack); + if (version == 2) { + JSON::fromDTMI2((unsigned char *)wholepacket.c_str() + 8, len, i, newPack); } addPacket(newPack); syncing = false; return true; } #if DEBUG >= DLVL_WARN - if (!syncing){ + if (!syncing) { DEBUG_MSG(DLVL_WARN, "Invalid DTMI data detected - syncing"); syncing = true; } @@ -168,9 +168,11 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ } /// Adds a keyframe packet to all tracks, so the stream can be fully played. -void DTSC::Stream::endStream(){ - if (!metadata.tracks.size()){return;} - for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++){ +void DTSC::Stream::endStream() { + if (!metadata.tracks.size()) { + return; + } + for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) { JSON::Value newPack; newPack["time"] = (long long)it->second.lastms; newPack["trackid"] = it->first; @@ -183,24 +185,24 @@ void DTSC::Stream::endStream(){ /// Blocks until either the stream has metadata available or the sourceSocket errors. /// This function is intended to be run before any commands are sent and thus will not throw away anything important. /// It will time out after 3 seconds, disconnecting the sourceSocket. -void DTSC::Stream::waitForMeta(Socket::Connection & sourceSocket){ +void DTSC::Stream::waitForMeta(Socket::Connection & sourceSocket) { bool wasBlocking = sourceSocket.isBlocking(); sourceSocket.setBlocking(false); //cancel the attempt after 5000 milliseconds long long int start = Util::getMS(); - while ( !metadata && sourceSocket.connected() && Util::getMS() - start < 3000){ + while (!metadata && sourceSocket.connected() && Util::getMS() - start < 3000) { //we have data? attempt to read header - if (sourceSocket.Received().size()){ + if (sourceSocket.Received().size()) { //return value is ignored because we're not interested in data packets, just metadata. parsePacket(sourceSocket.Received()); } //still no header? check for more data - if ( !metadata){ - if (sourceSocket.spool()){ + if (!metadata) { + if (sourceSocket.spool()) { //more received? attempt to read //return value is ignored because we're not interested in data packets, just metadata. parsePacket(sourceSocket.Received()); - }else{ + } else { //nothing extra to receive? wait a bit and retry Util::sleep(10); } @@ -208,7 +210,7 @@ void DTSC::Stream::waitForMeta(Socket::Connection & sourceSocket){ } sourceSocket.setBlocking(wasBlocking); //if the timeout has passed, close the socket - if (Util::getMS() - start >= 3000){ + if (Util::getMS() - start >= 3000) { sourceSocket.close(); //and optionally print a debug message that this happened DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for metadata"); @@ -218,24 +220,24 @@ void DTSC::Stream::waitForMeta(Socket::Connection & sourceSocket){ /// Blocks until either the stream encounters a pause mark or the sourceSocket errors. /// This function is intended to be run after the 'q' command is sent, throwing away superfluous packets. /// It will time out after 5 seconds, disconnecting the sourceSocket. -void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket){ +void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket) { bool wasBlocking = sourceSocket.isBlocking(); sourceSocket.setBlocking(false); //cancel the attempt after 5000 milliseconds long long int start = Util::getMS(); - while (lastType() != DTSC::PAUSEMARK && sourceSocket.connected() && Util::getMS() - start < 5000){ + while (lastType() != DTSC::PAUSEMARK && sourceSocket.connected() && Util::getMS() - start < 5000) { //we have data? parse it - if (sourceSocket.Received().size()){ + if (sourceSocket.Received().size()) { //return value is ignored because we're not interested. parsePacket(sourceSocket.Received()); } //still no pause mark? check for more data - if (lastType() != DTSC::PAUSEMARK){ - if (sourceSocket.spool()){ + if (lastType() != DTSC::PAUSEMARK) { + if (sourceSocket.spool()) { //more received? attempt to read //return value is ignored because we're not interested in data packets, just metadata. parsePacket(sourceSocket.Received()); - }else{ + } else { //nothing extra to receive? wait a bit and retry Util::sleep(10); } @@ -243,7 +245,7 @@ void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket){ } sourceSocket.setBlocking(wasBlocking); //if the timeout has passed, close the socket - if (Util::getMS() - start >= 5000){ + if (Util::getMS() - start >= 5000) { sourceSocket.close(); //and optionally print a debug message that this happened DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for pause break"); @@ -251,8 +253,8 @@ void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket){ } /// Resets the stream by clearing the buffers and keyframes, making sure to call the deletionCallback first. -void DTSC::Stream::resetStream(){ - for (std::map::iterator it = buffers.begin(); it != buffers.end(); it++){ +void DTSC::Stream::resetStream() { + for (std::map::iterator it = buffers.begin(); it != buffers.end(); it++) { deletionCallback(it->first); } buffers.clear(); @@ -262,49 +264,51 @@ void DTSC::Stream::resetStream(){ /// Adds a set of metadata to the steam. /// This is implemented by simply replacing the current metadata. /// This effectively resets the stream. -void DTSC::Stream::addMeta(JSON::Value & newMeta){ +void DTSC::Stream::addMeta(JSON::Value & newMeta) { metadata = Meta(newMeta); } /// Adds a single DTSC packet to the stream, updating the internal metadata if needed. -void DTSC::Stream::addPacket(JSON::Value & newPack){ +void DTSC::Stream::addPacket(JSON::Value & newPack) { livePos newPos; newPos.trackID = newPack["trackid"].asInt(); newPos.seekTime = newPack["time"].asInt(); - if (!metadata.tracks.count(newPos.trackID) && (!newPack.isMember("mark") || newPack["mark"].asStringRef() != "pause")){return;} - if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime()){ + if (!metadata.tracks.count(newPos.trackID) && (!newPack.isMember("mark") || newPack["mark"].asStringRef() != "pause")) { + return; + } + if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime()) { resetStream(); } - while (buffers.count(newPos) > 0){ + while (buffers.count(newPos) > 0) { newPos.seekTime++; } - while (buffercount == 1 && buffers.size() > 0){ + while (buffercount == 1 && buffers.size() > 0) { cutOneBuffer(); } buffers[newPos] = newPack; datapointertype = INVALID; std::string tmp = ""; - if (newPack.isMember("trackid") && newPack["trackid"].asInt() > 0){ + if (newPack.isMember("trackid") && newPack["trackid"].asInt() > 0) { tmp = metadata.tracks[newPack["trackid"].asInt()].type; } - if (newPack.isMember("datatype")){ + if (newPack.isMember("datatype")) { tmp = newPack["datatype"].asStringRef(); } - if (tmp == "video"){ + if (tmp == "video") { datapointertype = VIDEO; } - if (tmp == "audio"){ + if (tmp == "audio") { datapointertype = AUDIO; } - if (tmp == "meta"){ + if (tmp == "meta") { datapointertype = META; } - if (tmp == "pause_marker" || (newPack.isMember("mark") && newPack["mark"].asStringRef() == "pause")){ + if (tmp == "pause_marker" || (newPack.isMember("mark") && newPack["mark"].asStringRef() == "pause")) { datapointertype = PAUSEMARK; } - if (buffercount > 1){ + if (buffercount > 1) { metadata.update(newPack); - if (newPack.isMember("keyframe") || (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime() == newPos.seekTime){ + if (newPack.isMember("keyframe") || (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime() == newPos.seekTime) { keyframes[newPos.trackID].insert(newPos); } metadata.live = true; @@ -312,41 +316,43 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ int trid = buffers.begin()->first.trackID; int firstTime = buffers.begin()->first.seekTime; int lastTime = buffers.rbegin()->first.seekTime - buffertime; - while ((!metadata.tracks[trid].keys.size() && firstTime < lastTime) || (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys.rbegin()->getTime() < lastTime) || (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime)){ + while ((!metadata.tracks[trid].keys.size() && firstTime < lastTime) || (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys.rbegin()->getTime() < lastTime) || (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime)) { cutOneBuffer(); trid = buffers.begin()->first.trackID; firstTime = buffers.begin()->first.seekTime; } metadata.bufferWindow = buffertime; } - + } /// Deletes a the first part of the buffer, updating the keyframes list and metadata as required. /// Will print a warning if a track has less than 2 keyframes left because of this. -void DTSC::Stream::cutOneBuffer(){ - if ( !buffers.size()){return;} +void DTSC::Stream::cutOneBuffer() { + if (!buffers.size()) { + return; + } int trid = buffers.begin()->first.trackID; long long unsigned int delTime = buffers.begin()->first.seekTime; - if (buffercount > 1){ - while (keyframes[trid].size() > 0 && keyframes[trid].begin()->seekTime <= delTime){ + if (buffercount > 1) { + while (keyframes[trid].size() > 0 && keyframes[trid].begin()->seekTime <= delTime) { keyframes[trid].erase(keyframes[trid].begin()); } - while (metadata.tracks[trid].keys.size() && (long long unsigned int)metadata.tracks[trid].keys[0].getTime() <= delTime){ - for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++){ + while (metadata.tracks[trid].keys.size() && (long long unsigned int)metadata.tracks[trid].keys[0].getTime() <= delTime) { + for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++) { metadata.tracks[trid].parts.pop_front(); } metadata.tracks[trid].keys.pop_front(); } - if (metadata.tracks[trid].keys.size()){ + if (metadata.tracks[trid].keys.size()) { metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime(); //delete fragments of which the beginning can no longer be reached - while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()){ + while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()) { metadata.tracks[trid].fragments.pop_front(); //increase the missed fragments counter metadata.tracks[trid].missedFrags++; } - }else{ + } else { metadata.tracks[trid].fragments.clear(); } } @@ -356,33 +362,33 @@ void DTSC::Stream::cutOneBuffer(){ /// Returns a direct pointer to the data attribute of the last received packet, if available. /// Returns NULL if no valid pointer or packet is available. -std::string & DTSC::Stream::lastData(){ +std::string & DTSC::Stream::lastData() { return buffers.rbegin()->second["data"].strVal; } /// Returns the packet in this buffer number. /// \arg num Buffer number. -JSON::Value & DTSC::Stream::getPacket(livePos num){ +JSON::Value & DTSC::Stream::getPacket(livePos num) { static JSON::Value empty; - if (buffers.find(num) == buffers.end()){ + if (buffers.find(num) == buffers.end()) { return empty; } return buffers[num]; } -JSON::Value & DTSC::Stream::getPacket(){ +JSON::Value & DTSC::Stream::getPacket() { return buffers.begin()->second; } /// Returns the type of the last received packet. -DTSC::datatype DTSC::Stream::lastType(){ +DTSC::datatype DTSC::Stream::lastType() { return datapointertype; } /// Returns true if the current stream contains at least one video track. -bool DTSC::Stream::hasVideo(){ - for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++){ - if (it->second.type == "video"){ +bool DTSC::Stream::hasVideo() { + for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) { + if (it->second.type == "video") { return true; } } @@ -390,42 +396,42 @@ bool DTSC::Stream::hasVideo(){ } /// Returns true if the current stream contains at least one audio track. -bool DTSC::Stream::hasAudio(){ - for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++){ - if (it->second.type == "audio"){ +bool DTSC::Stream::hasAudio() { + for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) { + if (it->second.type == "audio") { return true; } } return false; } -void DTSC::Stream::setBufferTime(unsigned int ms){ +void DTSC::Stream::setBufferTime(unsigned int ms) { buffertime = ms; } -std::string & DTSC::Stream::outPacket(){ +std::string & DTSC::Stream::outPacket() { static std::string emptystring; - if (!buffers.size() || !buffers.rbegin()->second.isObject()){ + if (!buffers.size() || !buffers.rbegin()->second.isObject()) { return emptystring; } return buffers.rbegin()->second.toNetPacked(); } /// Returns a packed DTSC packet, ready to sent over the network. -std::string & DTSC::Stream::outPacket(livePos num){ +std::string & DTSC::Stream::outPacket(livePos num) { static std::string emptystring; if (buffers.find(num) == buffers.end() || !buffers[num].isObject()) return emptystring; return buffers[num].toNetPacked(); } /// Returns a packed DTSC header, ready to sent over the network. -std::string & DTSC::Stream::outHeader(){ +std::string & DTSC::Stream::outHeader() { return metadata.toJSON().toNetPacked(); } /// Constructs a new Ring, at the given buffer position. /// \arg v Position for buffer. -DTSC::Ring::Ring(livePos v){ +DTSC::Ring::Ring(livePos v) { b = v; waiting = false; starved = false; @@ -436,11 +442,11 @@ DTSC::Ring::Ring(livePos v){ /// Requests a new Ring, which will be created and added to the internal Ring list. /// This Ring will be kept updated so it always points to valid data or has the starved boolean set. /// Don't forget to call dropRing() for all requested Ring classes that are no longer neccessary! -DTSC::Ring * DTSC::Stream::getRing(){ +DTSC::Ring * DTSC::Stream::getRing() { livePos tmp = buffers.begin()->first; - std::map >::iterator it; - for (it = keyframes.begin(); it != keyframes.end(); it++){ - if ((*it->second.begin()).seekTime > tmp.seekTime){ + std::map >::iterator it; + for (it = keyframes.begin(); it != keyframes.end(); it++) { + if ((*it->second.begin()).seekTime > tmp.seekTime) { tmp = *it->second.begin(); } } @@ -449,54 +455,58 @@ DTSC::Ring * DTSC::Stream::getRing(){ /// Deletes a given out Ring class from memory and internal Ring list. /// Checks for NULL pointers and invalid pointers, silently discarding them. -void DTSC::Stream::dropRing(DTSC::Ring * ptr){ - if (ptr){ +void DTSC::Stream::dropRing(DTSC::Ring * ptr) { + if (ptr) { delete ptr; } } /// Returns 0 if seeking is possible, -1 if the wanted frame is too old, 1 if the wanted frame is too new. /// This function looks in the header - not in the buffered data itself. -int DTSC::Stream::canSeekms(unsigned int ms){ +int DTSC::Stream::canSeekms(unsigned int ms) { bool too_late = false; //no tracks? Frame too new by definition. - if ( !metadata.tracks.size()){ + if (!metadata.tracks.size()) { return 1; } //loop trough all the tracks - for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++){ - if (it->second.keys.size()){ - if (it->second.keys[0].getTime() <= ms && it->second.keys[it->second.keys.size() - 1].getTime() >= ms){ + for (std::map::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) { + if (it->second.keys.size()) { + if (it->second.keys[0].getTime() <= ms && it->second.keys[it->second.keys.size() - 1].getTime() >= ms) { return 0; } - if (it->second.keys[0].getTime() > ms){too_late = true;} + if (it->second.keys[0].getTime() > ms) { + too_late = true; + } } } //did we spot a track already past this point? return too late. - if (too_late){return -1;} + if (too_late) { + return -1; + } //otherwise, assume not available yet return 1; } -DTSC::livePos DTSC::Stream::msSeek(unsigned int ms, std::set & allowedTracks){ +DTSC::livePos DTSC::Stream::msSeek(unsigned int ms, std::set & allowedTracks) { std::set seekTracks = allowedTracks; livePos result = buffers.begin()->first; - for (std::set::iterator it = allowedTracks.begin(); it != allowedTracks.end(); it++){ - if (metadata.tracks[*it].type == "video"){ + for (std::set::iterator it = allowedTracks.begin(); it != allowedTracks.end(); it++) { + if (metadata.tracks[*it].type == "video") { int trackNo = *it; seekTracks.clear(); seekTracks.insert(trackNo); break; } } - for (std::map::iterator bIt = buffers.begin(); bIt != buffers.end(); bIt++){ - if (seekTracks.find(bIt->first.trackID) != seekTracks.end()){ - // if (bIt->second.isMember("keyframe")){ - result = bIt->first; - if (bIt->first.seekTime >= ms){ - return result; - } - //} + for (std::map::iterator bIt = buffers.begin(); bIt != buffers.end(); bIt++) { + if (seekTracks.find(bIt->first.trackID) != seekTracks.end()) { + // if (bIt->second.isMember("keyframe")){ + result = bIt->first; + if (bIt->first.seekTime >= ms) { + return result; + } + //} } } return result; @@ -504,15 +514,17 @@ DTSC::livePos DTSC::Stream::msSeek(unsigned int ms, std::set & allowedTrack /// Returns whether the current position is the last currently available position within allowedTracks. /// Simply returns the result of getNext(pos, allowedTracks) == pos -bool DTSC::Stream::isNewest(DTSC::livePos & pos, std::set & allowedTracks){ +bool DTSC::Stream::isNewest(DTSC::livePos & pos, std::set & allowedTracks) { return getNext(pos, allowedTracks) == pos; } /// Returns the next available position within allowedTracks, or the current position if no next is availble. -DTSC::livePos DTSC::Stream::getNext(DTSC::livePos & pos, std::set & allowedTracks){ - std::map::iterator iter = buffers.upper_bound(pos); - while (iter != buffers.end()){ - if (allowedTracks.count(iter->first.trackID)){return iter->first;} +DTSC::livePos DTSC::Stream::getNext(DTSC::livePos & pos, std::set & allowedTracks) { + std::map::iterator iter = buffers.upper_bound(pos); + while (iter != buffers.end()) { + if (allowedTracks.count(iter->first.trackID)) { + return iter->first; + } iter++; } return pos; @@ -520,29 +532,29 @@ DTSC::livePos DTSC::Stream::getNext(DTSC::livePos & pos, std::set & allowed /// Properly cleans up the object for erasing. /// Drops all Ring classes that have been given out. -DTSC::Stream::~Stream(){ +DTSC::Stream::~Stream() { } -DTSC::File::File(){ +DTSC::File::File() { F = 0; buffer = malloc(4); endPos = 0; } -DTSC::File::File(const File & rhs){ +DTSC::File::File(const File & rhs) { buffer = malloc(4); *this = rhs; } -DTSC::File & DTSC::File::operator =(const File & rhs){ +DTSC::File & DTSC::File::operator =(const File & rhs) { created = rhs.created; - if (rhs.F){ - F = fdopen( dup(fileno(rhs.F)), (created ? "w+b": "r+b")); - }else{ + if (rhs.F) { + F = fdopen(dup(fileno(rhs.F)), (created ? "w+b" : "r+b")); + } else { F = 0; } endPos = rhs.endPos; - if (rhs.myPack){ + if (rhs.myPack) { myPack = rhs.myPack; } metaStorage = rhs.metaStorage; @@ -555,17 +567,17 @@ DTSC::File & DTSC::File::operator =(const File & rhs){ return *this; } -DTSC::File::operator bool() const{ +DTSC::File::operator bool() const { return F; } /// Open a filename for DTSC reading/writing. /// If create is true and file does not exist, attempt to create. -DTSC::File::File(std::string filename, bool create){ +DTSC::File::File(std::string filename, bool create) { buffer = malloc(4); - if (create){ + if (create) { F = fopen(filename.c_str(), "w+b"); - if(!F){ + if (!F) { DEBUG_MSG(DLVL_ERROR, "Could not create file %s: %s", filename.c_str(), strerror(errno)); return; } @@ -575,11 +587,11 @@ DTSC::File::File(std::string filename, bool create){ memset(buffer, 0, 4); fwrite(buffer, 4, 1, F); //write 4 zero-bytes headerSize = 0; - }else{ + } else { F = fopen(filename.c_str(), "r+b"); } created = create; - if ( !F){ + if (!F) { DEBUG_MSG(DLVL_ERROR, "Could not open file %s", filename.c_str()); return; } @@ -587,52 +599,52 @@ DTSC::File::File(std::string filename, bool create){ endPos = ftell(F); bool sepHeader = false; - if (!create){ + if (!create) { fseek(F, 0, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1){ - DEBUG_MSG(DLVL_ERROR, "Can't read file contents of %s", filename.c_str()); + if (fread(buffer, 4, 1, F) != 1) { + DEBUG_MSG(DLVL_ERROR, "Can't read file contents of %s", filename.c_str()); fclose(F); F = 0; return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) != 0){ - if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0){ + if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) { + if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0) { File Fhead(filename + ".dtsh"); - if (Fhead){ + if (Fhead) { metaStorage = Fhead.metaStorage; metadata = metaStorage; sepHeader = true; - }else{ - DEBUG_MSG(DLVL_ERROR, "%s is not a valid DTSC file", filename.c_str()); + } else { + DEBUG_MSG(DLVL_ERROR, "%s is not a valid DTSC file", filename.c_str()); fclose(F); F = 0; return; } - }else{ + } else { metadata.moreheader = -1; } } } //we now know the first 4 bytes are DTSC::Magic_Header and we have a valid file fseek(F, 4, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1){ + if (fread(buffer, 4, 1, F) != 1) { fseek(F, 4, SEEK_SET); memset(buffer, 0, 4); fwrite(buffer, 4, 1, F); //write 4 zero-bytes - }else{ + } else { headerSize = ntohl(((uint32_t *)buffer)[0]); } - if (metadata.moreheader != -1){ - if (!sepHeader){ + if (metadata.moreheader != -1) { + if (!sepHeader) { readHeader(0); fseek(F, 8 + headerSize, SEEK_SET); - }else{ + } else { fseek(F, 0, SEEK_SET); } - }else{ + } else { fseek(F, 0, SEEK_SET); File Fhead(filename + ".dtsh"); - if (Fhead){ + if (Fhead) { metaStorage = Fhead.metaStorage; metadata = metaStorage; } @@ -641,22 +653,22 @@ DTSC::File::File(std::string filename, bool create){ } /// Returns the header metadata for this file as JSON::Value. -DTSC::readOnlyMeta & DTSC::File::getMeta(){ +DTSC::readOnlyMeta & DTSC::File::getMeta() { return metadata; } /// (Re)writes the given string to the header area if the size is the same as the existing header. /// Forces a write if force is set to true. -bool DTSC::File::writeHeader(std::string & header, bool force){ - if (headerSize != header.size() && !force){ +bool DTSC::File::writeHeader(std::string & header, bool force) { + if (headerSize != header.size() && !force) { DEBUG_MSG(DLVL_ERROR, "Could not overwrite header - not equal size"); return false; } headerSize = header.size(); int pSize = htonl(header.size()); fseek(F, 4, SEEK_SET); - int tmpret = fwrite((void*)( &pSize), 4, 1, F); - if (tmpret != 1){ + int tmpret = fwrite((void *)(&pSize), 4, 1, F); + if (tmpret != 1) { return false; } fseek(F, 8, SEEK_SET); @@ -667,20 +679,20 @@ bool DTSC::File::writeHeader(std::string & header, bool force){ /// Adds the given string as a new header to the end of the file. /// \returns The positon the header was written at, or 0 on failure. -long long int DTSC::File::addHeader(std::string & header){ +long long int DTSC::File::addHeader(std::string & header) { fseek(F, 0, SEEK_END); long long int writePos = ftell(F); int hSize = htonl(header.size()); int ret = fwrite(DTSC::Magic_Header, 4, 1, F); //write header - if (ret != 1){ + if (ret != 1) { return 0; } - ret = fwrite((void*)( &hSize), 4, 1, F); //write size - if (ret != 1){ + ret = fwrite((void *)(&hSize), 4, 1, F); //write size + if (ret != 1) { return 0; } ret = fwrite(header.c_str(), header.size(), 1, F); //write contents - if (ret != 1){ + if (ret != 1) { return 0; } fseek(F, 0, SEEK_END); @@ -691,32 +703,32 @@ long long int DTSC::File::addHeader(std::string & header){ /// Reads the header at the given file position. /// If the packet could not be read for any reason, the reason is printed. /// Reading the header means the file position is moved to after the header. -void DTSC::File::readHeader(int pos){ +void DTSC::File::readHeader(int pos) { fseek(F, pos, SEEK_SET); - if (fread(buffer, 4, 1, F) != 1){ - if (feof(F)){ + if (fread(buffer, 4, 1, F) != 1) { + if (feof(F)) { DEBUG_MSG(DLVL_DEVEL, "End of file reached while reading header @ %d", pos); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", pos); } metadata = readOnlyMeta(); return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) != 0){ - DEBUG_MSG(DLVL_ERROR, "Invalid header - %.4s != %.4s @ %i", (char*)buffer, DTSC::Magic_Header, pos); + if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) { + DEBUG_MSG(DLVL_ERROR, "Invalid header - %.4s != %.4s @ %i", (char *)buffer, DTSC::Magic_Header, pos); metadata = readOnlyMeta(); return; } - if (fread(buffer, 4, 1, F) != 1){ + if (fread(buffer, 4, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %i", pos); metadata = readOnlyMeta(); return; } - long packSize = ntohl(((unsigned long*)buffer)[0]); + long packSize = ntohl(((unsigned long *)buffer)[0]); std::string strBuffer; strBuffer.resize(packSize); - if (packSize){ - if (fread((void*)strBuffer.c_str(), packSize, 1, F) != 1){ + if (packSize) { + if (fread((void *)strBuffer.c_str(), packSize, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read header packet @ %i", pos); metadata = readOnlyMeta(); return; @@ -725,8 +737,8 @@ void DTSC::File::readHeader(int pos){ metadata = readOnlyMeta(metaStorage);//make readonly } //if there is another header, read it and replace metadata with that one. - if (metadata.moreheader){ - if (metadata.moreheader < getBytePosEOF()){ + if (metadata.moreheader) { + if (metadata.moreheader < getBytePosEOF()) { readHeader(metadata.moreheader); return; } @@ -735,103 +747,103 @@ void DTSC::File::readHeader(int pos){ metadata.live = false; } -long int DTSC::File::getBytePosEOF(){ +long int DTSC::File::getBytePosEOF() { return endPos; } -long int DTSC::File::getBytePos(){ +long int DTSC::File::getBytePos() { return ftell(F); } -bool DTSC::File::reachedEOF(){ +bool DTSC::File::reachedEOF() { return feof(F); } /// Reads the packet available at the current file position. /// If the packet could not be read for any reason, the reason is printed. /// Reading the packet means the file position is increased to the next packet. -void DTSC::File::seekNext(){ - if ( !currentPositions.size()){ +void DTSC::File::seekNext() { + if (!currentPositions.size()) { DEBUG_MSG(DLVL_WARN, "No seek positions set - returning empty packet."); myPack.null(); return; } - fseek(F,currentPositions.begin()->bytePos, SEEK_SET); - if ( reachedEOF()){ + fseek(F, currentPositions.begin()->bytePos, SEEK_SET); + if (reachedEOF()) { myPack.null(); return; } clearerr(F); - if ( !metadata.merged){ + if (!metadata.merged) { seek_time(currentPositions.begin()->seekTime + 1, currentPositions.begin()->trackID); - fseek(F,currentPositions.begin()->bytePos, SEEK_SET); + fseek(F, currentPositions.begin()->bytePos, SEEK_SET); } currentPositions.erase(currentPositions.begin()); lastreadpos = ftell(F); - if (fread(buffer, 4, 1, F) != 1){ - if (feof(F)){ + if (fread(buffer, 4, 1, F) != 1) { + if (feof(F)) { DEBUG_MSG(DLVL_DEVEL, "End of file reached while seeking @ %i", (int)lastreadpos); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Could not seek to next @ %i", (int)lastreadpos); } myPack.null(); return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) == 0){ + if (memcmp(buffer, DTSC::Magic_Header, 4) == 0) { seek_time(myPack.getTime() + 1, myPack.getTrackId(), true); return seekNext(); } long long unsigned int version = 0; - if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){ + if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0) { version = 1; } - if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){ + if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0) { version = 2; } - if (version == 0){ - DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char*)buffer, DTSC::Magic_Packet2, (int)lastreadpos); + if (version == 0) { + DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos); myPack.null(); return; } - if (fread(buffer, 4, 1, F) != 1){ + if (fread(buffer, 4, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %d", (int)lastreadpos); myPack.null(); return; } - long packSize = ntohl(((unsigned long*)buffer)[0]); - char * packBuffer = (char*)malloc(packSize+8); - if (version == 1){ + long packSize = ntohl(((unsigned long *)buffer)[0]); + char * packBuffer = (char *)malloc(packSize + 8); + if (version == 1) { memcpy(packBuffer, "DTPD", 4); - }else{ + } else { memcpy(packBuffer, "DTP2", 4); } - memcpy(packBuffer+4, buffer, 4); - if (fread((void*)(packBuffer + 8), packSize, 1, F) != 1){ + memcpy(packBuffer + 4, buffer, 4); + if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read packet @ %d", (int)lastreadpos); myPack.null(); free(packBuffer); return; } - myPack.reInit(packBuffer, packSize+8); + myPack.reInit(packBuffer, packSize + 8); free(packBuffer); - if ( metadata.merged){ + if (metadata.merged) { int tempLoc = getBytePos(); char newHeader[20]; bool insert = false; seekPos tmpPos; - if (fread((void*)newHeader, 20, 1, F) == 1){ - if (memcmp(newHeader, DTSC::Magic_Packet2, 4) == 0){ + if (fread((void *)newHeader, 20, 1, F) == 1) { + if (memcmp(newHeader, DTSC::Magic_Packet2, 4) == 0) { tmpPos.bytePos = tempLoc; - tmpPos.trackID = ntohl(((int*)newHeader)[2]); + tmpPos.trackID = ntohl(((int *)newHeader)[2]); tmpPos.seekTime = 0; - if (selectedTracks.find(tmpPos.trackID) != selectedTracks.end()){ - tmpPos.seekTime = ((long long unsigned int)ntohl(((int*)newHeader)[3])) << 32; - tmpPos.seekTime += ntohl(((int*)newHeader)[4]); + if (selectedTracks.find(tmpPos.trackID) != selectedTracks.end()) { + tmpPos.seekTime = ((long long unsigned int)ntohl(((int *)newHeader)[3])) << 32; + tmpPos.seekTime += ntohl(((int *)newHeader)[4]); insert = true; - }else{ + } else { long tid = myPack.getTrackId(); - for (unsigned int i = 0; i != metadata.tracks[tid].keyLen; i++){ - if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()){ + for (unsigned int i = 0; i != metadata.tracks[tid].keyLen; i++) { + if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()) { tmpPos.seekTime = metadata.tracks[tid].keys[i].getTime(); tmpPos.bytePos = metadata.tracks[tid].keys[i].getBpos(); tmpPos.trackID = tid; @@ -840,9 +852,9 @@ void DTSC::File::seekNext(){ } } } - if (currentPositions.size()){ - for (std::set::iterator curPosIter = currentPositions.begin(); curPosIter != currentPositions.end(); curPosIter++){ - if ((*curPosIter).trackID == tmpPos.trackID && (*curPosIter).seekTime >= tmpPos.seekTime){ + if (currentPositions.size()) { + for (std::set::iterator curPosIter = currentPositions.begin(); curPosIter != currentPositions.end(); curPosIter++) { + if ((*curPosIter).trackID == tmpPos.trackID && (*curPosIter).seekTime >= tmpPos.seekTime) { insert = false; break; } @@ -850,9 +862,9 @@ void DTSC::File::seekNext(){ } } } - if (insert){ + if (insert) { currentPositions.insert(tmpPos); - }else{ + } else { seek_time(myPack.getTime() + 1, myPack.getTrackId(), true); } seek_bpos(tempLoc); @@ -860,34 +872,34 @@ void DTSC::File::seekNext(){ } -void DTSC::File::parseNext(){ +void DTSC::File::parseNext() { lastreadpos = ftell(F); - if (fread(buffer, 4, 1, F) != 1){ - if (feof(F)){ + if (fread(buffer, 4, 1, F) != 1) { + if (feof(F)) { DEBUG_MSG(DLVL_DEVEL, "End of file reached @ %d", (int)lastreadpos); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", (int)lastreadpos); } myPack.null(); return; } - if (memcmp(buffer, DTSC::Magic_Header, 4) == 0){ - if (lastreadpos != 0){ + if (memcmp(buffer, DTSC::Magic_Header, 4) == 0) { + if (lastreadpos != 0) { readHeader(lastreadpos); std::string tmp = metaStorage.toNetPacked(); myPack.reInit(tmp.data(), tmp.size()); - DEBUG_MSG(DLVL_DEVEL,"Read another header"); - }else{ - if (fread(buffer, 4, 1, F) != 1){ + DEBUG_MSG(DLVL_DEVEL, "Read another header"); + } else { + if (fread(buffer, 4, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %d", (int)lastreadpos); myPack.null(); return; } - long packSize = ntohl(((unsigned long*)buffer)[0]); + long packSize = ntohl(((unsigned long *)buffer)[0]); std::string strBuffer = "DTSC"; - strBuffer.append((char*)buffer, 4); + strBuffer.append((char *)buffer, 4); strBuffer.resize(packSize + 8); - if (fread((void*)(strBuffer.c_str() + 8), packSize, 1, F) != 1){ + if (fread((void *)(strBuffer.c_str() + 8), packSize, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", (int)lastreadpos); myPack.null(); return; @@ -897,81 +909,81 @@ void DTSC::File::parseNext(){ return; } long long unsigned int version = 0; - if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){ + if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0) { version = 1; } - if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){ + if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0) { version = 2; } - if (version == 0){ - DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char*)buffer, DTSC::Magic_Packet2, (int)lastreadpos); + if (version == 0) { + DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos); myPack.null(); return; } - if (fread(buffer, 4, 1, F) != 1){ + if (fread(buffer, 4, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %d", (int)lastreadpos); myPack.null(); return; } - long packSize = ntohl(((unsigned long*)buffer)[0]); - char * packBuffer = (char*)malloc(packSize+8); - if (version == 1){ + long packSize = ntohl(((unsigned long *)buffer)[0]); + char * packBuffer = (char *)malloc(packSize + 8); + if (version == 1) { memcpy(packBuffer, "DTPD", 4); - }else{ + } else { memcpy(packBuffer, "DTP2", 4); } - memcpy(packBuffer+4, buffer, 4); - if (fread((void*)(packBuffer + 8), packSize, 1, F) != 1){ + memcpy(packBuffer + 4, buffer, 4); + if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1) { DEBUG_MSG(DLVL_ERROR, "Could not read packet @ %d", (int)lastreadpos); myPack.null(); free(packBuffer); return; } - myPack.reInit(packBuffer, packSize+8); + myPack.reInit(packBuffer, packSize + 8); free(packBuffer); } /// Returns the byte positon of the start of the last packet that was read. -long long int DTSC::File::getLastReadPos(){ +long long int DTSC::File::getLastReadPos() { return lastreadpos; } /// Returns the internal buffer of the last read packet in raw binary format. -DTSC::Packet & DTSC::File::getPacket(){ +DTSC::Packet & DTSC::File::getPacket() { return myPack; } -bool DTSC::File::seek_time(unsigned int ms, int trackNo, bool forceSeek){ +bool DTSC::File::seek_time(unsigned int ms, int trackNo, bool forceSeek) { seekPos tmpPos; tmpPos.trackID = trackNo; - if (!forceSeek && myPack && ms > myPack.getTime() && trackNo >= myPack.getTrackId()){ + if (!forceSeek && myPack && ms > myPack.getTime() && trackNo >= myPack.getTrackId()) { tmpPos.seekTime = myPack.getTime(); tmpPos.bytePos = getBytePos(); - }else{ + } else { tmpPos.seekTime = 0; tmpPos.bytePos = 0; } - if (reachedEOF()){ + if (reachedEOF()) { clearerr(F); seek_bpos(0); tmpPos.bytePos = 0; tmpPos.seekTime = 0; } DTSC::readOnlyTrack & trackRef = metadata.tracks[trackNo]; - for (unsigned int i = 0; i < trackRef.keyLen; i++){ + for (unsigned int i = 0; i < trackRef.keyLen; i++) { long keyTime = trackRef.keys[i].getTime(); - if (keyTime > ms){ + if (keyTime > ms) { break; } - if ((long long unsigned int)keyTime > tmpPos.seekTime){ + if ((long long unsigned int)keyTime > tmpPos.seekTime) { tmpPos.seekTime = keyTime; tmpPos.bytePos = trackRef.keys[i].getBpos(); } } bool foundPacket = false; - while ( !foundPacket){ + while (!foundPacket) { lastreadpos = ftell(F); - if (reachedEOF()){ + if (reachedEOF()) { DEBUG_MSG(DLVL_WARN, "Reached EOF during seek to %u in track %d - aborting @ %lld", ms, trackNo, lastreadpos); return false; } @@ -979,12 +991,12 @@ bool DTSC::File::seek_time(unsigned int ms, int trackNo, bool forceSeek){ seek_bpos(tmpPos.bytePos); //read the header char header[20]; - fread((void*)header, 20, 1, F); + fread((void *)header, 20, 1, F); //check if packetID matches, if not, skip size + 8 bytes. - int packSize = ntohl(((int*)header)[1]); - int packID = ntohl(((int*)header)[2]); - if (memcmp(header,Magic_Packet2,4) != 0 || packID != trackNo){ - if (memcmp(header,"DT",2) != 0){ + int packSize = ntohl(((int *)header)[1]); + int packID = ntohl(((int *)header)[2]); + if (memcmp(header, Magic_Packet2, 4) != 0 || packID != trackNo) { + if (memcmp(header, "DT", 2) != 0) { DEBUG_MSG(DLVL_WARN, "Invalid header during seek to %u in track %d @ %lld - resetting bytePos from %lld to zero", ms, trackNo, lastreadpos, tmpPos.bytePos); tmpPos.bytePos = 0; continue; @@ -993,12 +1005,12 @@ bool DTSC::File::seek_time(unsigned int ms, int trackNo, bool forceSeek){ continue; } //get timestamp of packet, if too large, break, if not, skip size bytes. - long long unsigned int myTime = ((long long unsigned int)ntohl(((int*)header)[3]) << 32); - myTime += ntohl(((int*)header)[4]); + long long unsigned int myTime = ((long long unsigned int)ntohl(((int *)header)[3]) << 32); + myTime += ntohl(((int *)header)[4]); tmpPos.seekTime = myTime; - if (myTime >= ms){ + if (myTime >= ms) { foundPacket = true; - }else{ + } else { tmpPos.bytePos += 8 + packSize; continue; } @@ -1010,66 +1022,66 @@ bool DTSC::File::seek_time(unsigned int ms, int trackNo, bool forceSeek){ /// Attempts to seek to the given time in ms within the file. /// Returns true if successful, false otherwise. -bool DTSC::File::seek_time(unsigned int ms){ +bool DTSC::File::seek_time(unsigned int ms) { currentPositions.clear(); - if (selectedTracks.size()){ - for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ - seek_time(ms,(*it)); + if (selectedTracks.size()) { + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++) { + seek_time(ms, (*it)); } } return true; } -bool DTSC::File::seek_bpos(int bpos){ - if (fseek(F, bpos, SEEK_SET) == 0){ +bool DTSC::File::seek_bpos(int bpos) { + if (fseek(F, bpos, SEEK_SET) == 0) { return true; } return false; } -void DTSC::File::rewritePacket(std::string & newPacket, int bytePos){ +void DTSC::File::rewritePacket(std::string & newPacket, int bytePos) { fseek(F, bytePos, SEEK_SET); fwrite(newPacket.c_str(), newPacket.size(), 1, F); fseek(F, 0, SEEK_END); - if (ftell(F) > endPos){ + if (ftell(F) > endPos) { endPos = ftell(F); } } -void DTSC::File::writePacket(std::string & newPacket){ +void DTSC::File::writePacket(std::string & newPacket) { fseek(F, 0, SEEK_END); fwrite(newPacket.c_str(), newPacket.size(), 1, F); //write contents fseek(F, 0, SEEK_END); endPos = ftell(F); } -void DTSC::File::writePacket(JSON::Value & newPacket){ +void DTSC::File::writePacket(JSON::Value & newPacket) { writePacket(newPacket.toNetPacked()); } -bool DTSC::File::atKeyframe(){ - if (myPack.getFlag("keyframe")){ +bool DTSC::File::atKeyframe() { + if (myPack.getFlag("keyframe")) { return true; } long long int bTime = myPack.getTime(); DTSC::readOnlyTrack & trackRef = metadata.tracks[myPack.getTrackId()]; - for (unsigned int i = 0; i < trackRef.keyLen; i++){ - if (trackRef.keys[i].getTime() >= bTime){ + for (unsigned int i = 0; i < trackRef.keyLen; i++) { + if (trackRef.keys[i].getTime() >= bTime) { return (trackRef.keys[i].getTime() == bTime); } } return false; } -void DTSC::File::selectTracks(std::set & tracks){ +void DTSC::File::selectTracks(std::set & tracks) { selectedTracks = tracks; currentPositions.clear(); seek_time(0); } /// Close the file if open -DTSC::File::~File(){ - if (F){ +DTSC::File::~File() { + if (F) { fclose(F); F = 0; } @@ -1077,23 +1089,27 @@ DTSC::File::~File(){ } -bool DTSC::isFixed(JSON::Value & metadata){ - if (metadata.isMember("is_fixed")){return true;} - if ( !metadata.isMember("tracks")){return false;} - for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++){ - if (it->second["type"].asString() == "meta"){ +bool DTSC::isFixed(JSON::Value & metadata) { + if (metadata.isMember("is_fixed")) { + return true; + } + if (!metadata.isMember("tracks")) { + return false; + } + for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++) { + if (it->second["type"].asString() == "meta") { continue; } - if (!it->second["keys"].isString()){ + if (!it->second["keys"].isString()) { return false; } //Check for bpos: last element bpos != 0 std::string keyRef = it->second["keys"].asStringRef(); - if (keyRef.size() < 16){ + if (keyRef.size() < 16) { return false; } int offset = keyRef.size() - 17; - if (!(keyRef[offset] | keyRef[offset+1] | keyRef[offset+2] | keyRef[offset+3] | keyRef[offset+4])){ + if (!(keyRef[offset] | keyRef[offset + 1] | keyRef[offset + 2] | keyRef[offset + 3] | keyRef[offset + 4])) { return false; } } diff --git a/lib/dtsc.h b/lib/dtsc.h index 50661b69..506dee34 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -58,7 +58,7 @@ namespace DTSC { unsigned int trackID;///< Stores the track the DTSC packet referenced by this structure is associated with. }; - enum packType{ + enum packType { DTSC_INVALID, DTSC_HEAD, DTSC_V1, @@ -67,26 +67,26 @@ namespace DTSC { /// This class allows scanning through raw binary format DTSC data. /// It can be used as an iterator or as a direct accessor. - class Scan{ - public: - Scan(); - Scan(char * pointer, size_t len); - std::string toPrettyString(unsigned int indent = 0); - Scan getMember(std::string indice); - Scan getMember(const char * indice); - Scan getMember(const char * indice, const unsigned int ind_len); - Scan getIndice(unsigned int num); - - char getType(); - bool asBool(); - long long asInt(); - std::string asString(); - void getString(char *& result, unsigned int & len); - private: - char * p; - size_t len; + class Scan { + public: + Scan(); + Scan(char * pointer, size_t len); + std::string toPrettyString(unsigned int indent = 0); + Scan getMember(std::string indice); + Scan getMember(const char * indice); + Scan getMember(const char * indice, const unsigned int ind_len); + Scan getIndice(unsigned int num); + + char getType(); + bool asBool(); + long long asInt(); + std::string asString(); + void getString(char *& result, unsigned int & len); + private: + char * p; + size_t len; }; - + /// DTSC::Packets can currently be three types: /// DTSC_HEAD packets are the "DTSC" header string, followed by 4 bytes len and packed content. /// DTSC_V1 packets are "DTPD", followed by 4 bytes len and packed content. @@ -125,7 +125,7 @@ namespace DTSC { unsigned int bufferLen; unsigned int dataLen; }; - + /// A simple structure used for ordering byte seek positions. struct livePos { livePos() { @@ -375,7 +375,7 @@ namespace DTSC { private: long int endPos; void readHeader(int pos); - DTSC::Packet myPack; + DTSC::Packet myPack; JSON::Value metaStorage; readOnlyMeta metadata; std::map trackMapping; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index 521fab4c..76e069b5 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -61,12 +61,12 @@ namespace DTSC { /// Copier for packets, copies an existing packet with same noCopy flag as original. /// If going from copy to noCopy, this will free the data pointer first. void Packet::operator = (const Packet & rhs) { - if (master && !rhs.master){ + if (master && !rhs.master) { null(); } - if (rhs){ + if (rhs) { reInit(rhs.data, rhs.dataLen, !rhs.master); - }else{ + } else { null(); } } @@ -82,7 +82,7 @@ namespace DTSC { DEBUG_MSG(DLVL_DONTEVEN, "Datalen < 8"); return false; } - if (version == DTSC_INVALID){ + if (version == DTSC_INVALID) { DEBUG_MSG(DLVL_DONTEVEN, "No valid version"); return false; } @@ -94,15 +94,15 @@ namespace DTSC { } /// Returns the recognized packet type. - /// This type is set by reInit and all constructors, and then just referenced from there on. - packType Packet::getVersion() const{ + /// This type is set by reInit and all constructors, and then just referenced from there on. + packType Packet::getVersion() const { return version; } /// Resets this packet back to the same state as if it had just been freshly constructed. /// If needed, this frees the data pointer. void Packet::null() { - if (master && data){ + if (master && data) { free(data); } master = false; @@ -132,12 +132,12 @@ namespace DTSC { ///\param len The length of the data pointed to by data_ ///\param noCopy Determines whether to make a copy or not void Packet::reInit(const char * data_, unsigned int len, bool noCopy) { - if (!data_){ + if (!data_) { DEBUG_MSG(DLVL_DEVEL, "ReInit received a null pointer with len %d, ignoring", len); null(); return; } - if (data_[0] != 'D' || data_[1] != 'T'){ + if (data_[0] != 'D' || data_[1] != 'T') { DEBUG_MSG(DLVL_HIGH, "ReInit received a pointer that didn't start with 'DT' - data corruption?"); null(); return; @@ -146,80 +146,80 @@ namespace DTSC { len = ntohl(((int *)data_)[1]) + 8; } //clear any existing controlled contents - if (master && noCopy){ + if (master && noCopy) { null(); } //set control flag to !noCopy master = !noCopy; //either copy the data, or only the pointer, depending on flag - if (noCopy){ - data = (char*)data_; - }else{ + if (noCopy) { + data = (char *)data_; + } else { resize(len); memcpy(data, data_, len); } //check header type and store packet length dataLen = len; version = DTSC_INVALID; - if (len > 3){ - if (!memcmp(data, Magic_Packet2, 4)){ + if (len > 3) { + if (!memcmp(data, Magic_Packet2, 4)) { version = DTSC_V2; - }else{ - if (!memcmp(data, Magic_Packet, 4)){ + } else { + if (!memcmp(data, Magic_Packet, 4)) { version = DTSC_V1; - }else{ - if (!memcmp(data, Magic_Header, 4)){ + } else { + if (!memcmp(data, Magic_Header, 4)) { version = DTSC_HEAD; - }else{ + } else { DEBUG_MSG(DLVL_FAIL, "ReInit received a packet with invalid header"); return; } } } - }else{ + } else { DEBUG_MSG(DLVL_FAIL, "ReInit received a packet with size < 4"); return; } } - + /// Helper function for skipping over whole DTSC parts - static char * skipDTSC(char * p, char * max){ - if (p+1 >= max || p[0] == 0x00){ + static char * skipDTSC(char * p, char * max) { + if (p + 1 >= max || p[0] == 0x00) { return 0;//out of packet! 1 == error } - if (p[0] == DTSC_INT){ + if (p[0] == DTSC_INT) { //int, skip 9 bytes to next value - return p+9; + return p + 9; } - if (p[0] == DTSC_STR){ - if (p+4 >= max){ + if (p[0] == DTSC_STR) { + if (p + 4 >= max) { return 0;//out of packet! } return p + 5 + p[1] * 256 * 256 * 256 + p[2] * 256 * 256 + p[3] * 256 + p[4]; } - if (p[0] == DTSC_OBJ || p[0] == DTSC_CON){ + if (p[0] == DTSC_OBJ || p[0] == DTSC_CON) { p++; //object, scan contents - while (p[0] + p[1] != 0 && p < max){ //while not encountering 0x0000 (we assume 0x0000EE) - if (p+2 >= max){ + while (p[0] + p[1] != 0 && p < max) { //while not encountering 0x0000 (we assume 0x0000EE) + if (p + 2 >= max) { return 0;//out of packet! } p += 2 + (p[0] * 256 + p[1]);//skip size //otherwise, search through the contents, if needed, and continue p = skipDTSC(p, max); - if (!p){ + if (!p) { return 0; } } - return p+3; + return p + 3; } - if (p[0] == DTSC_ARR){ + if (p[0] == DTSC_ARR) { p++; //array, scan contents - while (p[0] + p[1] != 0 && p < max){ //while not encountering 0x0000 (we assume 0x0000EE) + while (p[0] + p[1] != 0 && p < max) { //while not encountering 0x0000 (we assume 0x0000EE) //search through contents... p = skipDTSC(p, max); - if (!p){ + if (!p) { return 0; } } @@ -227,33 +227,33 @@ namespace DTSC { } return 0;//out of packet! 1 == error } - + ///\brief Retrieves a single parameter as a string ///\param identifier The name of the parameter ///\param result A location on which the string will be returned ///\param len An integer in which the length of the string will be returned - void Packet::getString(const char * identifier, char *& result, unsigned int & len) const{ + void Packet::getString(const char * identifier, char *& result, unsigned int & len) const { getScan().getMember(identifier).getString(result, len); } ///\brief Retrieves a single parameter as a string ///\param identifier The name of the parameter ///\param result The string in which to store the result - void Packet::getString(const char * identifier, std::string & result) const{ + void Packet::getString(const char * identifier, std::string & result) const { result = getScan().getMember(identifier).asString(); } ///\brief Retrieves a single parameter as an integer ///\param identifier The name of the parameter ///\param result The result is stored in this integer - void Packet::getInt(const char * identifier, int & result) const{ + void Packet::getInt(const char * identifier, int & result) const { result = getScan().getMember(identifier).asInt(); } ///\brief Retrieves a single parameter as an integer ///\param identifier The name of the parameter ///\result The requested parameter as an integer - int Packet::getInt(const char * identifier) const{ + int Packet::getInt(const char * identifier) const { int result; getInt(identifier, result); return result; @@ -262,7 +262,7 @@ namespace DTSC { ///\brief Retrieves a single parameter as a boolean ///\param identifier The name of the parameter ///\param result The result is stored in this boolean - void Packet::getFlag(const char * identifier, bool & result) const{ + void Packet::getFlag(const char * identifier, bool & result) const { int result_; getInt(identifier, result_); result = (bool)result_; @@ -271,7 +271,7 @@ namespace DTSC { ///\brief Retrieves a single parameter as a boolean ///\param identifier The name of the parameter ///\result The requested parameter as a boolean - bool Packet::getFlag(const char * identifier) const{ + bool Packet::getFlag(const char * identifier) const { bool result; getFlag(identifier, result); return result; @@ -280,15 +280,17 @@ namespace DTSC { ///\brief Checks whether a parameter exists ///\param identifier The name of the parameter ///\result Whether the parameter exists or not - bool Packet::hasMember(const char * identifier) const{ + bool Packet::hasMember(const char * identifier) const { return getScan().getMember(identifier).getType() > 0; } ///\brief Returns the timestamp of the packet. ///\return The timestamp of this packet. - long long unsigned int Packet::getTime() const{ - if (version != DTSC_V2){ - if (!data){return 0;} + long long unsigned int Packet::getTime() const { + if (version != DTSC_V2) { + if (!data) { + return 0; + } return getInt("time"); } return ((long long int)ntohl(((int *)(data + 12))[0]) << 32) | ntohl(((int *)(data + 12))[1]); @@ -296,8 +298,8 @@ namespace DTSC { ///\brief Returns the track id of the packet. ///\return The track id of this packet. - long int Packet::getTrackId() const{ - if (version != DTSC_V2){ + long int Packet::getTrackId() const { + if (version != DTSC_V2) { return getInt("trackid"); } return ntohl(((int *)data)[2]); @@ -305,134 +307,134 @@ namespace DTSC { ///\brief Returns a pointer to the payload of this packet. ///\return A pointer to the payload of this packet. - char * Packet::getData() const{ + char * Packet::getData() const { return data; } ///\brief Returns the size of this packet. ///\return The size of this packet. - int Packet::getDataLen() const{ - return dataLen; + int Packet::getDataLen() const { + return dataLen; } ///\brief Returns the size of the payload of this packet. ///\return The size of the payload of this packet. - int Packet::getPayloadLen() const{ - if (version == DTSC_V2){ - return dataLen-20; - }else{ - return dataLen-8; + int Packet::getPayloadLen() const { + if (version == DTSC_V2) { + return dataLen - 20; + } else { + return dataLen - 8; } } - + /// Returns a DTSC::Scan instance to the contents of this packet. /// May return an invalid instance if this packet is invalid. - Scan Packet::getScan() const{ - return Scan(data+(getDataLen()-getPayloadLen()), getPayloadLen()); + Scan Packet::getScan() const { + return Scan(data + (getDataLen() - getPayloadLen()), getPayloadLen()); } - + ///\brief Converts the packet into a JSON value ///\return A JSON::Value representation of this packet. - JSON::Value Packet::toJSON() const{ + JSON::Value Packet::toJSON() const { JSON::Value result; unsigned int i = 8; - if (getVersion() == DTSC_V1){ + if (getVersion() == DTSC_V1) { JSON::fromDTMI((const unsigned char *)data, dataLen, i, result); } - if (getVersion() == DTSC_V2){ + if (getVersion() == DTSC_V2) { JSON::fromDTMI2((const unsigned char *)data, dataLen, i, result); } return result; } - + /// Create an invalid DTSC::Scan object by default. - Scan::Scan(){ + Scan::Scan() { p = 0; len = 0; } - - + + /// Create a DTSC::Scan object from memory pointer. - Scan::Scan(char * pointer, size_t length){ + Scan::Scan(char * pointer, size_t length) { p = pointer; len = length; } - + /// Returns an object representing the named indice of this object. /// Returns an invalid object if this indice doesn't exist or this isn't an object type. - Scan Scan::getMember(std::string indice){ + Scan Scan::getMember(std::string indice) { return getMember(indice.data(), indice.size()); } /// Returns an object representing the named indice of this object. /// Returns an invalid object if this indice doesn't exist or this isn't an object type. - Scan Scan::getMember(const char * indice, const unsigned int ind_len){ - if (getType() != DTSC_OBJ && getType() != DTSC_CON){ + Scan Scan::getMember(const char * indice, const unsigned int ind_len) { + if (getType() != DTSC_OBJ && getType() != DTSC_CON) { return Scan(); } - char * i = p+1; + char * i = p + 1; //object, scan contents - while (i[0] + i[1] != 0 && i < p+len){ //while not encountering 0x0000 (we assume 0x0000EE) - if (i+2 >= p+len){ + while (i[0] + i[1] != 0 && i < p + len) { //while not encountering 0x0000 (we assume 0x0000EE) + if (i + 2 >= p + len) { return Scan();//out of packet! } unsigned int strlen = i[0] * 256 + i[1]; i += 2; - if (ind_len == strlen && strncmp(indice, i, strlen) == 0){ - return Scan(i+strlen, len-(i-p)); - }else{ - i = skipDTSC(i+strlen, p+len); - if (!i){ + if (ind_len == strlen && strncmp(indice, i, strlen) == 0) { + return Scan(i + strlen, len - (i - p)); + } else { + i = skipDTSC(i + strlen, p + len); + if (!i) { return Scan(); } } } return Scan(); } - + /// Returns an object representing the named indice of this object. /// Returns an invalid object if this indice doesn't exist or this isn't an object type. - Scan Scan::getMember(const char * indice){ + Scan Scan::getMember(const char * indice) { return getMember(indice, strlen(indice)); } - + /// Returns an object representing the num-th indice of this array. /// If not an array but an object, it returns the num-th member, instead. /// Returns an invalid object if this indice doesn't exist or this isn't an array or object type. - Scan Scan::getIndice(unsigned int num){ - if (getType() == DTSC_ARR){ - char * i = p+1; + Scan Scan::getIndice(unsigned int num) { + if (getType() == DTSC_ARR) { + char * i = p + 1; unsigned int arr_indice = 0; //array, scan contents - while (i[0] + i[1] != 0 && i < p+len){ //while not encountering 0x0000 (we assume 0x0000EE) + while (i[0] + i[1] != 0 && i < p + len) { //while not encountering 0x0000 (we assume 0x0000EE) //search through contents... - if (arr_indice == num){ - return Scan(i, len-(i-p)); - }else{ + if (arr_indice == num) { + return Scan(i, len - (i - p)); + } else { arr_indice++; - i = skipDTSC(i, p+len); - if (!i){ + i = skipDTSC(i, p + len); + if (!i) { return Scan(); } } } } - if (getType() == DTSC_OBJ || getType() == DTSC_CON){ - char * i = p+1; + if (getType() == DTSC_OBJ || getType() == DTSC_CON) { + char * i = p + 1; unsigned int arr_indice = 0; //object, scan contents - while (i[0] + i[1] != 0 && i < p+len){ //while not encountering 0x0000 (we assume 0x0000EE) - if (i+2 >= p+len){ + while (i[0] + i[1] != 0 && i < p + len) { //while not encountering 0x0000 (we assume 0x0000EE) + if (i + 2 >= p + len) { return Scan();//out of packet! } unsigned int strlen = i[0] * 256 + i[1]; i += 2; - if (arr_indice == num){ - return Scan(i+strlen, len-(i-p)); - }else{ + if (arr_indice == num) { + return Scan(i + strlen, len - (i - p)); + } else { arr_indice++; - i = skipDTSC(i+strlen, p+len); - if (!i){ + i = skipDTSC(i + strlen, p + len); + if (!i) { return Scan(); } } @@ -440,20 +442,22 @@ namespace DTSC { } return Scan(); } - + /// Returns the first byte of this DTSC value, or 0 on error. - char Scan::getType(){ - if (!p){return 0;} + char Scan::getType() { + if (!p) { + return 0; + } return p[0]; } - + /// Returns the boolean value of this DTSC value. /// Numbers are compared to 0. /// Strings are checked for non-zero length. /// Objects and arrays are checked for content. /// Returns false on error or in other cases. - bool Scan::asBool(){ - switch (getType()){ + bool Scan::asBool() { + switch (getType()) { case DTSC_STR: return (p[1] | p[2] | p[3] | p[4]); case DTSC_INT: @@ -466,42 +470,44 @@ namespace DTSC { return false; } } - + /// Returns the long long value of this DTSC number value. /// Will convert string values to numbers, taking octal and hexadecimal types into account. /// Illegal or invalid values return 0. - long long Scan::asInt(){ - switch (getType()){ + long long Scan::asInt() { + switch (getType()) { case DTSC_INT: return ((long long int)p[1] << 56) | ((long long int)p[2] << 48) | ((long long int)p[3] << 40) | ((long long int)p[4] << 32) | ((long long int)p[5] << 24) | ((long long int)p[6] << 16) | ((long long int)p[7] << 8) | p[8]; case DTSC_STR: char * str; unsigned int strlen; getString(str, strlen); - if (!strlen){return 0;} + if (!strlen) { + return 0; + } return strtoll(str, 0, 0); default: return 0; } } - + /// Returns the string value of this DTSC string value. /// Uses getString internally, does no conversion. /// Returns an empty string on error. - std::string Scan::asString(){ + std::string Scan::asString() { char * str; unsigned int strlen; getString(str, strlen); return std::string(str, strlen); } - + /// Sets result to a pointer to the string, and strlen to the lenght of it. /// Sets both to zero if this isn't a DTSC string value. /// Attempts absolutely no conversion. - void Scan::getString(char *& result, unsigned int & strlen){ - switch (getType()){ + void Scan::getString(char *& result, unsigned int & strlen) { + switch (getType()) { case DTSC_STR: - result = p+5; + result = p + 5; strlen = p[1] * 256 * 256 * 256 + p[2] * 256 * 256 + p[3] * 256 + p[4]; return; default: @@ -510,20 +516,24 @@ namespace DTSC { return; } } - + /// \todo Move this function to some generic area. Duplicate from json.cpp - static inline char hex2c(char c){ - if (c < 10){return '0' + c;} - if (c < 16){return 'A' + (c - 10);} + static inline char hex2c(char c) { + if (c < 10) { + return '0' + c; + } + if (c < 16) { + return 'A' + (c - 10); + } return '0'; } - + /// \todo Move this function to some generic area. Duplicate from json.cpp - static std::string string_escape(const std::string val){ + static std::string string_escape(const std::string val) { std::stringstream out; out << "\""; - for (unsigned int i = 0; i < val.size(); ++i){ - switch (val.data()[i]){ + for (unsigned int i = 0; i < val.size(); ++i) { + switch (val.data()[i]) { case '"': out << "\\\""; break; @@ -546,11 +556,11 @@ namespace DTSC { out << "\\t"; break; default: - if (val.data()[i] < 32 || val.data()[i] > 126){ + if (val.data()[i] < 32 || val.data()[i] > 126) { out << "\\u00"; out << hex2c((val.data()[i] >> 4) & 0xf); out << hex2c(val.data()[i] & 0xf); - }else{ + } else { out << val.data()[i]; } break; @@ -559,71 +569,71 @@ namespace DTSC { out << "\""; return out.str(); } - - std::string Scan::toPrettyString(unsigned int indent){ - switch (getType()){ - case DTSC_STR:{ - unsigned int strlen = p[1] * 256 * 256 * 256 + p[2] * 256 * 256 + p[3] * 256 + p[4]; - if (strlen > 250){ + + std::string Scan::toPrettyString(unsigned int indent) { + switch (getType()) { + case DTSC_STR: { + unsigned int strlen = p[1] * 256 * 256 * 256 + p[2] * 256 * 256 + p[3] * 256 + p[4]; + if (strlen > 250) { + std::stringstream ret; + ret << "\"" << strlen << " bytes of data\""; + return ret.str(); + } + return string_escape(asString()); + } + case DTSC_INT: { std::stringstream ret; - ret << "\"" << strlen << " bytes of data\""; + ret << asInt(); return ret.str(); } - return string_escape(asString()); - } - case DTSC_INT:{ - std::stringstream ret; - ret << asInt(); - return ret.str(); - } case DTSC_OBJ: - case DTSC_CON:{ - std::stringstream ret; - ret << "{" << std::endl; - indent += 2; - char * i = p+1; - //object, scan contents - while (i[0] + i[1] != 0 && i < p+len){ //while not encountering 0x0000 (we assume 0x0000EE) - if (i+2 >= p+len){ - indent -= 2; - ret << std::string((size_t)indent, ' ') << "} //walked out of object here"; - return ret.str(); - } - unsigned int strlen = i[0] * 256 + i[1]; - i += 2; - ret << std::string((size_t)indent, ' ') << "\"" << std::string(i, strlen) << "\": " << Scan(i+strlen, len-(i-p)).toPrettyString(indent) << "," << std::endl; - i = skipDTSC(i+strlen, p+len); - if (!i){ - indent -= 2; - ret << std::string((size_t)indent, ' ') << "} //could not locate next object"; - return ret.str(); + case DTSC_CON: { + std::stringstream ret; + ret << "{" << std::endl; + indent += 2; + char * i = p + 1; + //object, scan contents + while (i[0] + i[1] != 0 && i < p + len) { //while not encountering 0x0000 (we assume 0x0000EE) + if (i + 2 >= p + len) { + indent -= 2; + ret << std::string((size_t)indent, ' ') << "} //walked out of object here"; + return ret.str(); + } + unsigned int strlen = i[0] * 256 + i[1]; + i += 2; + ret << std::string((size_t)indent, ' ') << "\"" << std::string(i, strlen) << "\": " << Scan(i + strlen, len - (i - p)).toPrettyString(indent) << "," << std::endl; + i = skipDTSC(i + strlen, p + len); + if (!i) { + indent -= 2; + ret << std::string((size_t)indent, ' ') << "} //could not locate next object"; + return ret.str(); + } } + indent -= 2; + ret << std::string((size_t)indent, ' ') << "}"; + return ret.str(); + } + case DTSC_ARR: { + std::stringstream ret; + ret << "[" << std::endl; + indent += 2; + Scan tmpScan; + unsigned int i = 0; + do { + tmpScan = getIndice(i++); + if (tmpScan.getType()) { + ret << std::string((size_t)indent, ' ') << tmpScan.toPrettyString(indent) << "," << std::endl; + } + } while (tmpScan.getType()); + indent -= 2; + ret << std::string((size_t)indent, ' ') << "]"; + return ret.str(); } - indent -= 2; - ret << std::string((size_t)indent, ' ') << "}"; - return ret.str(); - } - case DTSC_ARR:{ - std::stringstream ret; - ret << "[" << std::endl; - indent += 2; - Scan tmpScan; - unsigned int i = 0; - do { - tmpScan = getIndice(i++); - if (tmpScan.getType()){ - ret << std::string((size_t)indent, ' ') << tmpScan.toPrettyString(indent) << "," << std::endl; - } - }while(tmpScan.getType()); - indent -= 2; - ret << std::string((size_t)indent, ' ') << "]"; - return ret.str(); - } default: return "Error"; } } - + ///\brief Returns the payloadsize of a part @@ -666,7 +676,7 @@ namespace DTSC { ///\brief Converts a part to a human readable string ///\param str The stringstream to append to ///\param indent the amount of indentation needed - void Part::toPrettyString(std::ostream & str, int indent){ + void Part::toPrettyString(std::ostream & str, int indent) { str << std::string(indent, ' ') << "Part: Size(" << getSize() << "), Dur(" << getDuration() << "), Offset(" << getOffset() << ")" << std::endl; } @@ -734,7 +744,7 @@ namespace DTSC { ///\brief Converts a keyframe to a human readable string ///\param str The stringstream to append to ///\param indent the amount of indentation needed - void Key::toPrettyString(std::ostream & str, int indent){ + void Key::toPrettyString(std::ostream & str, int indent) { str << std::string(indent, ' ') << "Key " << getNumber() << ": Pos(" << getBpos() << "), Dur(" << getLength() << "), Parts(" << getParts() << "), Time(" << getTime() << ")" << std::endl; } @@ -786,7 +796,7 @@ namespace DTSC { ///\brief Converts a fragment to a human readable string ///\param str The stringstream to append to ///\param indent the amount of indentation needed - void Fragment::toPrettyString(std::ostream & str, int indent){ + void Fragment::toPrettyString(std::ostream & str, int indent) { str << std::string(indent, ' ') << "Fragment " << getNumber() << ": Dur(" << getDuration() << "), Len(" << (int)getLength() << "), Size(" << getSize() << ")" << std::endl; } @@ -938,22 +948,22 @@ namespace DTSC { commentHeader = trackRef["commentheader"].asStringRef(); } } - + ///\brief Constructs a track from a JSON::Value Track::Track(Scan & trackRef) { - if (trackRef.getMember("fragments").getType() == DTSC_STR){ + if (trackRef.getMember("fragments").getType() == DTSC_STR) { char * tmp = 0; unsigned int tmplen = 0; trackRef.getMember("fragments").getString(tmp, tmplen); fragments = std::deque((Fragment *)tmp, ((Fragment *)tmp) + (tmplen / 11)); } - if (trackRef.getMember("keys").getType() == DTSC_STR){ + if (trackRef.getMember("keys").getType() == DTSC_STR) { char * tmp = 0; unsigned int tmplen = 0; trackRef.getMember("keys").getString(tmp, tmplen); keys = std::deque((Key *)tmp, ((Key *)tmp) + (tmplen / 16)); } - if (trackRef.getMember("parts").getType() == DTSC_STR){ + if (trackRef.getMember("parts").getType() == DTSC_STR) { char * tmp = 0; unsigned int tmplen = 0; trackRef.getMember("parts").getString(tmp, tmplen); @@ -1187,19 +1197,19 @@ namespace DTSC { ///\param str The stringstream to append to ///\param indent the amount of indentation needed ///\param verbosity How verbose the output needs to be - void readOnlyTrack::toPrettyString(std::ostream & str, int indent, int verbosity){ + void readOnlyTrack::toPrettyString(std::ostream & str, int indent, int verbosity) { str << std::string(indent, ' ') << "Track " << getWritableIdentifier() << std::endl; str << std::string(indent + 2, ' ') << "ID: " << trackID << std::endl; str << std::string(indent + 2, ' ') << "Firstms: " << firstms << std::endl; str << std::string(indent + 2, ' ') << "Lastms: " << lastms << std::endl; str << std::string(indent + 2, ' ') << "Bps: " << bps << std::endl; - if (missedFrags){ + if (missedFrags) { str << std::string(indent + 2, ' ') << "missedFrags: " << missedFrags << std::endl; } str << std::string(indent + 2, ' ') << "Codec: " << codec << std::endl; str << std::string(indent + 2, ' ') << "Type: " << type << std::endl; str << std::string(indent + 2, ' ') << "Init: "; - for (unsigned int i = 0; i < init.size(); ++i){ + for (unsigned int i = 0; i < init.size(); ++i) { str << std::hex << std::setw(2) << std::setfill('0') << (int)init[i]; } str << std::dec << std::endl; @@ -1217,20 +1227,20 @@ namespace DTSC { str << std::string(indent + 2, ' ') << "CommentHeader: " << commentHeader << std::endl; } str << std::string(indent + 2, ' ') << "Fragments: " << fragLen << std::endl; - if (fragments && verbosity & 0x01){ - for (unsigned int i = 0; i < fragLen; i++){ + if (fragments && verbosity & 0x01) { + for (unsigned int i = 0; i < fragLen; i++) { fragments[i].toPrettyString(str, indent + 4); } } str << std::string(indent + 2, ' ') << "Keys: " << keyLen << std::endl; if (keys && verbosity & 0x02) { - for (unsigned int i = 0; i < keyLen; i++){ + for (unsigned int i = 0; i < keyLen; i++) { keys[i].toPrettyString(str, indent + 4); } } str << std::string(indent + 2, ' ') << "Parts: " << partLen << std::endl; if (parts && verbosity & 0x04) { - for (unsigned int i = 0; i < partLen; i++){ + for (unsigned int i = 0; i < partLen; i++) { parts[i].toPrettyString(str, indent + 4); } } @@ -1256,12 +1266,12 @@ namespace DTSC { } moreheader = rhs.moreheader; } - - Meta::Meta(const DTSC::Packet & source){ + + Meta::Meta(const DTSC::Packet & source) { reinit(source); } - - void Meta::reinit(const DTSC::Packet & source){ + + void Meta::reinit(const DTSC::Packet & source) { tracks.clear(); vod = source.getFlag("vod"); live = source.getFlag("live"); @@ -1271,16 +1281,16 @@ namespace DTSC { Scan tmpTracks = source.getScan().getMember("tracks"); unsigned int num = 0; Scan tmpTrack; - do{ + do { tmpTrack = tmpTracks.getIndice(num); - if (tmpTrack.asBool()){ + if (tmpTrack.asBool()) { int trackId = tmpTrack.getMember("trackid").asInt(); - if (trackId){ + if (trackId) { tracks[trackId] = Track(tmpTrack); } num++; } - }while(tmpTrack.asBool()); + } while (tmpTrack.asBool()); } ///\brief Creates a meta object from a JSON::Value @@ -1326,19 +1336,19 @@ namespace DTSC { ///\param str The stringstream to append to ///\param indent the amount of indentation needed ///\param verbosity How verbose the output needs to be - void Track::toPrettyString(std::ostream & str, int indent, int verbosity){ + void Track::toPrettyString(std::ostream & str, int indent, int verbosity) { str << std::string(indent, ' ') << "Track " << getWritableIdentifier() << std::endl; str << std::string(indent + 2, ' ') << "ID: " << trackID << std::endl; str << std::string(indent + 2, ' ') << "Firstms: " << firstms << std::endl; str << std::string(indent + 2, ' ') << "Lastms: " << lastms << std::endl; str << std::string(indent + 2, ' ') << "Bps: " << bps << std::endl; - if (missedFrags){ + if (missedFrags) { str << std::string(indent + 2, ' ') << "missedFrags: " << missedFrags << std::endl; } str << std::string(indent + 2, ' ') << "Codec: " << codec << std::endl; str << std::string(indent + 2, ' ') << "Type: " << type << std::endl; str << std::string(indent + 2, ' ') << "Init: "; - for (unsigned int i = 0; i < init.size(); ++i){ + for (unsigned int i = 0; i < init.size(); ++i) { str << std::hex << std::setw(2) << std::setfill('0') << (int)init[i]; } str << std::dec << std::endl; @@ -1356,25 +1366,25 @@ namespace DTSC { str << std::string(indent + 2, ' ') << "CommentHeader: " << commentHeader << std::endl; } str << std::string(indent + 2, ' ') << "Fragments: " << fragments.size() << std::endl; - if (verbosity & 0x01){ - for (unsigned int i = 0; i < fragments.size(); i++){ + if (verbosity & 0x01) { + for (unsigned int i = 0; i < fragments.size(); i++) { fragments[i].toPrettyString(str, indent + 4); } } str << std::string(indent + 2, ' ') << "Keys: " << keys.size() << std::endl; if (verbosity & 0x02) { - for (unsigned int i = 0; i < keys.size(); i++){ + for (unsigned int i = 0; i < keys.size(); i++) { keys[i].toPrettyString(str, indent + 4); } } str << std::string(indent + 2, ' ') << "Parts: " << parts.size() << std::endl; if (verbosity & 0x04) { - for (unsigned int i = 0; i < parts.size(); i++){ + for (unsigned int i = 0; i < parts.size(); i++) { parts[i].toPrettyString(str, indent + 4); } } } - + ///\brief Converts a short to a char* char * convertShort(short input) { static char result[2]; @@ -1448,11 +1458,11 @@ namespace DTSC { } return result; } - + ///\brief Writes a pointer to the specified destination /// ///Does a memcpy and increases the destination pointer accordingly - static void writePointer(char *& p, const char * src, unsigned int len){ + static void writePointer(char *& p, const char * src, unsigned int len) { memcpy(p, src, len); p += len; } @@ -1460,12 +1470,12 @@ namespace DTSC { ///\brief Writes a pointer to the specified destination /// ///Does a memcpy and increases the destination pointer accordingly - static void writePointer(char *& p, const std::string & src){ + static void writePointer(char *& p, const std::string & src) { writePointer(p, src.data(), src.size()); } ///\brief Writes a read-only track to a pointer - void readOnlyTrack::writeTo(char *& p){ + void readOnlyTrack::writeTo(char *& p) { std::string iden = getWritableIdentifier(); writePointer(p, convertShort(iden.size()), 2); writePointer(p, iden); @@ -1525,7 +1535,7 @@ namespace DTSC { } writePointer(p, "\000\000\356", 3);//End this track Object } - + ///\brief Writes a read-only track to a socket void readOnlyTrack::send(Socket::Connection & conn) { conn.SendNow(convertShort(getWritableIdentifier().size()), 2); @@ -1586,9 +1596,9 @@ namespace DTSC { } conn.SendNow("\000\000\356", 3);//End this track Object } - + ///\brief Writes a track to a pointer - void Track::writeTo(char *& p){ + void Track::writeTo(char *& p) { writePointer(p, convertShort(getWritableIdentifier().size()), 2); writePointer(p, getWritableIdentifier()); writePointer(p, "\340", 1);//Begin track object @@ -1721,17 +1731,17 @@ namespace DTSC { conn.SendNow("\000\000\356", 3);//End this track Object } - ///\brief Determines the "packed" size of a read-only meta object - unsigned int readOnlyMeta::getSendLen(){ + ///\brief Determines the "packed" size of a read-only meta object + unsigned int readOnlyMeta::getSendLen() { unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21; for (std::map::iterator it = tracks.begin(); it != tracks.end(); it++) { dataLen += it->second.getSendLen(); } - return dataLen+8;//add 8 bytes header length + return dataLen + 8; //add 8 bytes header length } - + ///\brief Writes a read-only meta object to a pointer - void readOnlyMeta::writeTo(char * p){ + void readOnlyMeta::writeTo(char * p) { int dataLen = getSendLen() - 8;//strip 8 bytes header writePointer(p, DTSC::Magic_Header, 4); writePointer(p, convertInt(dataLen), 4); @@ -1760,10 +1770,10 @@ namespace DTSC { writePointer(p, convertLongLong(moreheader), 8); writePointer(p, "\000\000\356", 3);//End global object } - + ///\brief Writes a read-only meta object to a socket void readOnlyMeta::send(Socket::Connection & conn) { - int dataLen = getSendLen()-8;//strip 8 bytes header + int dataLen = getSendLen() - 8; //strip 8 bytes header conn.SendNow(DTSC::Magic_Header, 4); conn.SendNow(convertInt(dataLen), 4); conn.SendNow("\340\000\006tracks\340", 10); @@ -1791,19 +1801,19 @@ namespace DTSC { conn.SendNow(convertLongLong(moreheader), 8); conn.SendNow("\000\000\356", 3);//End global object } - - ///\brief Determines the "packed" size of a meta object - unsigned int Meta::getSendLen(){ + + ///\brief Determines the "packed" size of a meta object + unsigned int Meta::getSendLen() { unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21; for (std::map::iterator it = tracks.begin(); it != tracks.end(); it++) { dataLen += it->second.getSendLen(); } - return dataLen+8;//add 8 bytes header + return dataLen + 8; //add 8 bytes header } - + ///\brief Writes a meta object to a pointer - void Meta::writeTo(char * p){ - int dataLen = getSendLen()-8;//strip 8 bytes header + void Meta::writeTo(char * p) { + int dataLen = getSendLen() - 8; //strip 8 bytes header writePointer(p, DTSC::Magic_Header, 4); writePointer(p, convertInt(dataLen), 4); writePointer(p, "\340\000\006tracks\340", 10); @@ -1834,7 +1844,7 @@ namespace DTSC { ///\brief Writes a meta object to a socket void Meta::send(Socket::Connection & conn) { - int dataLen = getSendLen()-8;//strip 8 bytes header + int dataLen = getSendLen() - 8; //strip 8 bytes header conn.SendNow(DTSC::Magic_Header, 4); conn.SendNow(convertInt(dataLen), 4); conn.SendNow("\340\000\006tracks\340", 10); @@ -1974,7 +1984,7 @@ namespace DTSC { ///\param str The stringstream to append to ///\param indent the amount of indentation needed ///\param verbosity How verbose the output needs to be - void readOnlyMeta::toPrettyString(std::ostream & str, int indent, int verbosity){ + void readOnlyMeta::toPrettyString(std::ostream & str, int indent, int verbosity) { for (std::map::iterator it = tracks.begin(); it != tracks.end(); it++) { it->second.toPrettyString(str, indent, verbosity); } @@ -1997,7 +2007,7 @@ namespace DTSC { ///\param str The stringstream to append to ///\param indent the amount of indentation needed ///\param verbosity How verbose the output needs to be - void Meta::toPrettyString(std::ostream & str, int indent, int verbosity){ + void Meta::toPrettyString(std::ostream & str, int indent, int verbosity) { for (std::map::iterator it = tracks.begin(); it != tracks.end(); it++) { it->second.toPrettyString(str, indent, verbosity); } @@ -2015,7 +2025,7 @@ namespace DTSC { } str << std::string(indent, ' ') << "More Header: " << moreheader << std::endl; } - + ///\brief Converts a read-only meta object to a JSON::Value JSON::Value readOnlyMeta::toJSON() { JSON::Value result; diff --git a/lib/filesystem.cpp b/lib/filesystem.cpp index f11fe654..c2e9b76d 100644 --- a/lib/filesystem.cpp +++ b/lib/filesystem.cpp @@ -1,32 +1,32 @@ #include "filesystem.h" #include "defines.h" -Filesystem::Directory::Directory(std::string PathName, std::string BasePath){ +Filesystem::Directory::Directory(std::string PathName, std::string BasePath) { MyBase = BasePath; - if (PathName[0] == '/'){ + if (PathName[0] == '/') { PathName.erase(0, 1); } - if (BasePath[BasePath.size() - 1] != '/'){ + if (BasePath[BasePath.size() - 1] != '/') { BasePath += "/"; } MyPath = PathName; FillEntries(); } -Filesystem::Directory::~Directory(){ +Filesystem::Directory::~Directory() { } -void Filesystem::Directory::FillEntries(){ +void Filesystem::Directory::FillEntries() { ValidDir = true; struct stat StatBuf; Entries.clear(); DIR * Dirp = opendir((MyBase + MyPath).c_str()); - if ( !Dirp){ + if (!Dirp) { ValidDir = false; - }else{ + } else { dirent * entry; - while ((entry = readdir(Dirp))){ - if (stat((MyBase + MyPath + "/" + entry->d_name).c_str(), &StatBuf) == -1){ + while ((entry = readdir(Dirp))) { + if (stat((MyBase + MyPath + "/" + entry->d_name).c_str(), &StatBuf) == -1) { DEBUG_MSG(DLVL_DEVEL, "Skipping %s, reason %s", entry->d_name, strerror(errno)); continue; } @@ -36,173 +36,173 @@ void Filesystem::Directory::FillEntries(){ } } -void Filesystem::Directory::Print(){ +void Filesystem::Directory::Print() { /// \todo Remove? Libraries shouldn't print stuff. - if ( !ValidDir){ + if (!ValidDir) { DEBUG_MSG(DLVL_ERROR, "%s is not a valid directory", (MyBase + MyPath).c_str()); return; } printf("%s:\n", (MyBase + MyPath).c_str()); - for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++){ - printf("\t%s\n", ( *it).first.c_str()); + for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { + printf("\t%s\n", (*it).first.c_str()); } printf("\n"); } -bool Filesystem::Directory::IsDir(){ +bool Filesystem::Directory::IsDir() { return ValidDir; } -std::string Filesystem::Directory::PWD(){ +std::string Filesystem::Directory::PWD() { return "/" + MyPath; } -std::string Filesystem::Directory::LIST(std::vector ActiveStreams){ +std::string Filesystem::Directory::LIST(std::vector ActiveStreams) { FillEntries(); int MyPermissions; std::stringstream Converter; - passwd* pwd; //For Username - group* grp; //For Groupname - tm* tm; //For time localisation + passwd * pwd; //For Username + group * grp; //For Groupname + tm * tm; //For time localisation char datestring[256]; //For time localisation std::string MyLoc = MyBase + MyPath; - if (MyLoc[MyLoc.size() - 1] != '/'){ + if (MyLoc[MyLoc.size() - 1] != '/') { MyLoc += "/"; } - for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++){ + for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { - bool Active = (std::find(ActiveStreams.begin(), ActiveStreams.end(), ( *it).first) != ActiveStreams.end()); - if ((Active && (MyVisible[MyPath] & S_ACTIVE)) || (( !Active) && (MyVisible[MyPath] & S_INACTIVE)) || ((( *it).second.st_mode / 010000) == 4)){ - if ((( *it).second.st_mode / 010000) == 4){ + bool Active = (std::find(ActiveStreams.begin(), ActiveStreams.end(), (*it).first) != ActiveStreams.end()); + if ((Active && (MyVisible[MyPath] & S_ACTIVE)) || ((!Active) && (MyVisible[MyPath] & S_INACTIVE)) || (((*it).second.st_mode / 010000) == 4)) { + if (((*it).second.st_mode / 010000) == 4) { Converter << 'd'; - }else{ + } else { Converter << '-'; } - MyPermissions = ((( *it).second.st_mode % 010000) / 0100); - if (MyPermissions & 4){ + MyPermissions = (((*it).second.st_mode % 010000) / 0100); + if (MyPermissions & 4) { Converter << 'r'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 2){ + if (MyPermissions & 2) { Converter << 'w'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 1){ + if (MyPermissions & 1) { Converter << 'x'; - }else{ + } else { Converter << '-'; } - MyPermissions = ((( *it).second.st_mode % 0100) / 010); - if (MyPermissions & 4){ + MyPermissions = (((*it).second.st_mode % 0100) / 010); + if (MyPermissions & 4) { Converter << 'r'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 2){ + if (MyPermissions & 2) { Converter << 'w'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 1){ + if (MyPermissions & 1) { Converter << 'x'; - }else{ + } else { Converter << '-'; } - MyPermissions = (( *it).second.st_mode % 010); - if (MyPermissions & 4){ + MyPermissions = ((*it).second.st_mode % 010); + if (MyPermissions & 4) { Converter << 'r'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 2){ + if (MyPermissions & 2) { Converter << 'w'; - }else{ + } else { Converter << '-'; } - if (MyPermissions & 1){ + if (MyPermissions & 1) { Converter << 'x'; - }else{ + } else { Converter << '-'; } Converter << ' '; - Converter << ( *it).second.st_nlink; + Converter << (*it).second.st_nlink; Converter << ' '; - if ((pwd = getpwuid(( *it).second.st_uid))){ + if ((pwd = getpwuid((*it).second.st_uid))) { Converter << pwd->pw_name; - }else{ - Converter << ( *it).second.st_uid; + } else { + Converter << (*it).second.st_uid; } Converter << ' '; - if ((grp = getgrgid(( *it).second.st_gid))){ + if ((grp = getgrgid((*it).second.st_gid))) { Converter << grp->gr_name; - }else{ - Converter << ( *it).second.st_gid; + } else { + Converter << (*it).second.st_gid; } Converter << ' '; - Converter << ( *it).second.st_size; + Converter << (*it).second.st_size; Converter << ' '; - tm = localtime( &(( *it).second.st_mtime)); + tm = localtime(&((*it).second.st_mtime)); strftime(datestring, sizeof(datestring), "%b %d %H:%M", tm); Converter << datestring; Converter << ' '; - Converter << ( *it).first; + Converter << (*it).first; Converter << '\n'; } } return Converter.str(); } -bool Filesystem::Directory::CWD(std::string Path){ - if (Path[0] == '/'){ +bool Filesystem::Directory::CWD(std::string Path) { + if (Path[0] == '/') { Path.erase(0, 1); MyPath = Path; - }else{ - if (MyPath != ""){ + } else { + if (MyPath != "") { MyPath += "/"; } MyPath += Path; } FillEntries(); printf("New Path: %s\n", MyPath.c_str()); - if (MyPermissions.find(MyPath) != MyPermissions.end()){ + if (MyPermissions.find(MyPath) != MyPermissions.end()) { printf("\tPermissions: %d\n", MyPermissions[MyPath]); } return SimplifyPath(); } -bool Filesystem::Directory::CDUP(){ +bool Filesystem::Directory::CDUP() { return CWD(".."); } -std::string Filesystem::Directory::RETR(std::string Path){ +std::string Filesystem::Directory::RETR(std::string Path) { std::string Result; std::string FileName; - if (Path[0] == '/'){ + if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; - }else{ + } else { FileName = MyBase + MyPath + "/" + Path; } std::ifstream File; File.open(FileName.c_str()); - while (File.good()){ + while (File.good()) { Result += File.get(); } File.close(); return Result; } -void Filesystem::Directory::STOR(std::string Path, std::string Data){ - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_STOR)){ +void Filesystem::Directory::STOR(std::string Path, std::string Data) { + if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_STOR)) { std::string FileName; - if (Path[0] == '/'){ + if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; - }else{ + } else { FileName = MyBase + MyPath + "/" + Path; } std::ofstream File; @@ -212,48 +212,48 @@ void Filesystem::Directory::STOR(std::string Path, std::string Data){ } } -bool Filesystem::Directory::SimplifyPath(){ +bool Filesystem::Directory::SimplifyPath() { MyPath += "/"; std::vector TempPath; std::string TempString; - for (std::string::iterator it = MyPath.begin(); it != MyPath.end(); it++){ - if (( *it) == '/'){ - if (TempString == ".."){ - if ( !TempPath.size()){ + for (std::string::iterator it = MyPath.begin(); it != MyPath.end(); it++) { + if ((*it) == '/') { + if (TempString == "..") { + if (!TempPath.size()) { return false; } TempPath.erase((TempPath.end() - 1)); - }else if (TempString != "." && TempString != ""){ + } else if (TempString != "." && TempString != "") { TempPath.push_back(TempString); } TempString = ""; - }else{ - TempString += ( *it); + } else { + TempString += (*it); } } MyPath = ""; - for (std::vector::iterator it = TempPath.begin(); it != TempPath.end(); it++){ - MyPath += ( *it); - if (it != (TempPath.end() - 1)){ + for (std::vector::iterator it = TempPath.begin(); it != TempPath.end(); it++) { + MyPath += (*it); + if (it != (TempPath.end() - 1)) { MyPath += "/"; } } - if (MyVisible.find(MyPath) == MyVisible.end()){ + if (MyVisible.find(MyPath) == MyVisible.end()) { MyVisible[MyPath] = S_ALL; } return true; } -bool Filesystem::Directory::DELE(std::string Path){ - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_DELE)){ +bool Filesystem::Directory::DELE(std::string Path) { + if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_DELE)) { std::string FileName; - if (Path[0] == '/'){ + if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; - }else{ + } else { FileName = MyBase + MyPath + "/" + Path; } - if (std::remove(FileName.c_str())){ + if (std::remove(FileName.c_str())) { DEBUG_MSG(DLVL_ERROR, "Removing file %s failed", FileName.c_str()); return false; } @@ -262,15 +262,15 @@ bool Filesystem::Directory::DELE(std::string Path){ return false; } -bool Filesystem::Directory::MKD(std::string Path){ +bool Filesystem::Directory::MKD(std::string Path) { std::string FileName; - if (Path[0] == '/'){ + if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; - }else{ + } else { FileName = MyBase + MyPath + "/" + Path; } - if (mkdir(FileName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)){ + if (mkdir(FileName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { DEBUG_MSG(DLVL_ERROR, "Creating directory %s failed", FileName.c_str()); return false; } @@ -278,22 +278,22 @@ bool Filesystem::Directory::MKD(std::string Path){ return true; } -bool Filesystem::Directory::Rename(std::string From, std::string To){ - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_RNFT)){ +bool Filesystem::Directory::Rename(std::string From, std::string To) { + if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_RNFT)) { std::string FileFrom; - if (From[0] == '/'){ + if (From[0] == '/') { From.erase(0, 1); FileFrom = MyBase + From; - }else{ + } else { FileFrom = MyBase + MyPath + "/" + From; } std::string FileTo; - if (To[0] == '/'){ + if (To[0] == '/') { FileTo = MyBase + To; - }else{ + } else { FileTo = MyBase + MyPath + "/" + To; } - if (std::rename(FileFrom.c_str(), FileTo.c_str())){ + if (std::rename(FileFrom.c_str(), FileTo.c_str())) { DEBUG_MSG(DLVL_ERROR, "Renaming %s to %s failed", FileFrom.c_str(), FileTo.c_str()); return false; } @@ -302,17 +302,17 @@ bool Filesystem::Directory::Rename(std::string From, std::string To){ return false; } -void Filesystem::Directory::SetPermissions(std::string Path, char Permissions){ +void Filesystem::Directory::SetPermissions(std::string Path, char Permissions) { MyPermissions[Path] = Permissions; } -bool Filesystem::Directory::HasPermission(char Permission){ - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & Permission)){ +bool Filesystem::Directory::HasPermission(char Permission) { + if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & Permission)) { return true; } return false; } -void Filesystem::Directory::SetVisibility(std::string Pathname, char Visible){ +void Filesystem::Directory::SetVisibility(std::string Pathname, char Visible) { MyVisible[Pathname] = Visible; } diff --git a/lib/filesystem.h b/lib/filesystem.h index 204449d3..c901fcc2 100644 --- a/lib/filesystem.h +++ b/lib/filesystem.h @@ -21,7 +21,7 @@ #include namespace Filesystem { - enum DIR_Permissions{ + enum DIR_Permissions { P_LIST = 0x01, //List P_RETR = 0x02, //Retrieve P_STOR = 0x04, //Store @@ -31,11 +31,11 @@ namespace Filesystem { P_RMD = 0x40, //Remove directory }; - enum DIR_Show{ + enum DIR_Show { S_NONE = 0x00, S_ACTIVE = 0x01, S_INACTIVE = 0x02, S_ALL = 0x03, }; - class Directory{ + class Directory { public: Directory(std::string PathName = "", std::string BasePath = "."); ~Directory(); diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp index e6ce222a..1c717223 100644 --- a/lib/flv_tag.cpp +++ b/lib/flv_tag.cpp @@ -26,7 +26,7 @@ std::string FLV::Error_Str = ""; /// - The PreviousTagSize is not 0 bytes. /// /// Note that we see PreviousTagSize as part of the FLV header, not part of the tag header! -bool FLV::check_header(char * header){ +bool FLV::check_header(char * header) { if (header[0] != 'F') return false; if (header[1] != 'L') return false; if (header[2] != 'V') return false; @@ -43,7 +43,7 @@ bool FLV::check_header(char * header){ /// Checks the first 3 bytes for the string "FLV". Implementing a basic FLV header check, /// returning true if it is, false if not. -bool FLV::is_header(char * header){ +bool FLV::is_header(char * header) { if (header[0] != 'F') return false; if (header[1] != 'L') return false; if (header[2] != 'V') return false; @@ -54,10 +54,10 @@ bool FLV::is_header(char * header){ /// Will always return false if the tag type is not 0x08 or 0x09. /// Returns true for H263, AVC (H264), AAC. /// \todo Check if MP3 does or does not require init data... -bool FLV::Tag::needsInitData(){ - switch (data[0]){ +bool FLV::Tag::needsInitData() { + switch (data[0]) { case 0x09: - switch (data[11] & 0x0F){ + switch (data[11] & 0x0F) { case 2: return true; break; //H263 requires init data @@ -70,7 +70,7 @@ bool FLV::Tag::needsInitData(){ } break; case 0x08: - switch (data[11] & 0xF0){ + switch (data[11] & 0xF0) { case 0x20: return false; break; //MP3 does not...? Unsure. @@ -90,16 +90,16 @@ bool FLV::Tag::needsInitData(){ } /// True if current tag is init data for this media type. -bool FLV::Tag::isInitData(){ - switch (data[0]){ +bool FLV::Tag::isInitData() { + switch (data[0]) { case 0x09: - switch (data[11] & 0xF0){ + switch (data[11] & 0xF0) { case 0x50: return true; break; } - if ((data[11] & 0x0F) == 7){ - switch (data[12]){ + if ((data[11] & 0x0F) == 7) { + switch (data[12]) { case 0: return true; break; @@ -107,7 +107,7 @@ bool FLV::Tag::isInitData(){ } break; case 0x08: - if ((data[12] == 0) && ((data[11] & 0xF0) == 0xA0)){ + if ((data[12] == 0) && ((data[11] & 0xF0) == 0xA0)) { return true; } break; @@ -115,8 +115,8 @@ bool FLV::Tag::isInitData(){ return false; } -const char * FLV::Tag::getVideoCodec(){ - switch (data[11] & 0x0F){ +const char * FLV::Tag::getVideoCodec() { + switch (data[11] & 0x0F) { case 1: return "JPEG"; case 2: @@ -136,8 +136,8 @@ const char * FLV::Tag::getVideoCodec(){ } } -const char * FLV::Tag::getAudioCodec(){ - switch (data[11] & 0xF0){ +const char * FLV::Tag::getAudioCodec() { + switch (data[11] & 0xF0) { case 0x00: return "linear PCM PE"; case 0x10: @@ -175,13 +175,13 @@ const char * FLV::Tag::getAudioCodec(){ /// The string includes information about whether the tag is /// audio, video or metadata, what encoding is used, and the details /// of the encoding itself. -std::string FLV::Tag::tagType(){ +std::string FLV::Tag::tagType() { std::stringstream R; R << len << " bytes of "; - switch (data[0]){ + switch (data[0]) { case 0x09: R << getVideoCodec() << " video "; - switch (data[11] & 0xF0){ + switch (data[11] & 0xF0) { case 0x10: R << "keyframe"; break; @@ -198,8 +198,8 @@ std::string FLV::Tag::tagType(){ R << "videoinfo"; break; } - if ((data[11] & 0x0F) == 7){ - switch (data[12]){ + if ((data[11] & 0x0F) == 7) { + switch (data[12]) { case 0: R << " header"; break; @@ -214,7 +214,7 @@ std::string FLV::Tag::tagType(){ break; case 0x08: R << getAudioCodec(); - switch (data[11] & 0x0C){ + switch (data[11] & 0x0C) { case 0x0: R << " 5.5kHz"; break; @@ -228,7 +228,7 @@ std::string FLV::Tag::tagType(){ R << " 44kHz"; break; } - switch (data[11] & 0x02){ + switch (data[11] & 0x02) { case 0: R << " 8bit"; break; @@ -236,7 +236,7 @@ std::string FLV::Tag::tagType(){ R << " 16bit"; break; } - switch (data[11] & 0x01){ + switch (data[11] & 0x01) { case 0: R << " mono"; break; @@ -245,16 +245,16 @@ std::string FLV::Tag::tagType(){ break; } R << " audio"; - if ((data[12] == 0) && ((data[11] & 0xF0) == 0xA0)){ + if ((data[12] == 0) && ((data[11] & 0xF0) == 0xA0)) { R << " initdata"; } break; case 0x12: { - R << "(meta)data: "; - AMF::Object metadata = AMF::parse((unsigned char*)data + 11, len - 15); - R << metadata.Print(); - break; - } + R << "(meta)data: "; + AMF::Object metadata = AMF::parse((unsigned char *)data + 11, len - 15); + R << metadata.Print(); + break; + } default: R << "unknown"; break; @@ -264,29 +264,29 @@ std::string FLV::Tag::tagType(){ /// Returns the 24-bit offset of this tag. /// Returns 0 if the tag isn't H264 -int FLV::Tag::offset(){ - if ((data[11] & 0x0F) == 7){ +int FLV::Tag::offset() { + if ((data[11] & 0x0F) == 7) { return (((data[13] << 16) + (data[14] << 8) + data[15]) << 8) >> 8; - }else{ + } else { return 0; } } //offset getter /// Sets the 24-bit offset of this tag. /// Ignored if the tag isn't H264 -void FLV::Tag::offset(int o){ +void FLV::Tag::offset(int o) { data[13] = (o >> 16) & 0xFF; data[14] = (o >> 8) & 0XFF; data[15] = o & 0xFF; } //offset setter /// Returns the 32-bit timestamp of this tag. -unsigned int FLV::Tag::tagTime(){ +unsigned int FLV::Tag::tagTime() { return (data[4] << 16) + (data[5] << 8) + data[6] + (data[7] << 24); } //tagTime getter /// Sets the 32-bit timestamp of this tag. -void FLV::Tag::tagTime(unsigned int T){ +void FLV::Tag::tagTime(unsigned int T) { data[4] = ((T >> 16) & 0xFF); data[5] = ((T >> 8) & 0xFF); data[6] = (T & 0xFF); @@ -296,7 +296,7 @@ void FLV::Tag::tagTime(unsigned int T){ /// Constructor for a new, empty, tag. /// The buffer length is initialized to 0, and later automatically /// increased if neccesary. -FLV::Tag::Tag(){ +FLV::Tag::Tag() { len = 0; buf = 0; data = 0; @@ -309,13 +309,13 @@ FLV::Tag::Tag(){ /// The buffer length is initialized to the actual size of the tag /// that is being copied, and later automaticallt increased if /// neccesary. -FLV::Tag::Tag(const Tag& O){ +FLV::Tag::Tag(const Tag & O) { done = true; sofar = 0; len = O.len; data = 0; - if (len > 0){ - if (checkBufferSize()){ + if (len > 0) { + if (checkBufferSize()) { memcpy(data, O.data, len); } } @@ -326,7 +326,7 @@ FLV::Tag::Tag(const Tag& O){ /// Copies the contents of a RTMP chunk into a valid FLV tag. /// Exactly the same as making a chunk by through the default (empty) constructor /// and then calling FLV::Tag::ChunkLoader with the chunk as argument. -FLV::Tag::Tag(const RTMPStream::Chunk& O){ +FLV::Tag::Tag(const RTMPStream::Chunk & O) { len = 0; buf = 0; data = 0; @@ -337,8 +337,8 @@ FLV::Tag::Tag(const RTMPStream::Chunk& O){ } /// Generic destructor that frees the allocated memory in the internal data variable, if any. -FLV::Tag::~Tag(){ - if (data){ +FLV::Tag::~Tag() { + if (data) { free(data); data = 0; buf = 0; @@ -348,13 +348,13 @@ FLV::Tag::~Tag(){ /// Assignment operator - works exactly like the copy constructor. /// This operator checks for self-assignment. -FLV::Tag & FLV::Tag::operator=(const FLV::Tag& O){ - if (this != &O){ //no self-assignment +FLV::Tag & FLV::Tag::operator=(const FLV::Tag & O) { + if (this != &O) { //no self-assignment len = O.len; - if (len > 0){ - if (checkBufferSize()){ + if (len > 0) { + if (checkBufferSize()) { memcpy(data, O.data, len); - }else{ + } else { len = buf; } } @@ -365,99 +365,105 @@ FLV::Tag & FLV::Tag::operator=(const FLV::Tag& O){ /// FLV loader function from DTSC. /// Takes the DTSC data and makes it into FLV. -bool FLV::Tag::DTSCLoader(DTSC::Stream & S){ +bool FLV::Tag::DTSCLoader(DTSC::Stream & S) { std::string tmp = S.getPacket().toNetPacked(); DTSC::Packet tmpPack(tmp.data(), tmp.size()); return DTSCLoader(tmpPack, S.metadata.tracks[S.getPacket()["trackid"].asInt()]); } -bool FLV::Tag::DTSCLoader(DTSC::Packet & packData, DTSC::Track & track){ +bool FLV::Tag::DTSCLoader(DTSC::Packet & packData, DTSC::Track & track) { std::string meta_str; len = 0; - if (track.type == "video"){ + if (track.type == "video") { char * tmpData = 0; unsigned int tmpLen = 0; packData.getString("data", tmpData, tmpLen); len = tmpLen + 16; - if (track.codec == "H264"){ + if (track.codec == "H264") { len += 4; } - if ( !checkBufferSize()){ + if (!checkBufferSize()) { return false; } - if (track.codec == "H264"){ + if (track.codec == "H264") { memcpy(data + 16, tmpData, len - 20); data[12] = 1; - if (packData.getInt("offset") < 0){ + if (packData.getInt("offset") < 0) { offset(0); - }else{ + } else { offset(packData.getInt("offset")); } - }else{ + } else { memcpy(data + 12, tmpData, len - 16); } data[11] = 0; - if (track.codec == "H264"){ + if (track.codec == "H264") { data[11] |= 7; } - if (track.codec == "H263"){ + if (track.codec == "H263") { data[11] |= 2; } - if (packData.getFlag("keyframe")){ + if (packData.getFlag("keyframe")) { data[11] |= 0x10; - }else{ + } else { data[11] |= 0x20; } - if (packData.getFlag("disposableframe")){ + if (packData.getFlag("disposableframe")) { data[11] |= 0x30; } } - if (track.type == "audio"){ + if (track.type == "audio") { char * tmpData = 0; unsigned int tmpLen = 0; packData.getString("data", tmpData, tmpLen); len = tmpLen + 16; - if (track.codec == "AAC"){ + if (track.codec == "AAC") { len ++; } - if ( !checkBufferSize()){ + if (!checkBufferSize()) { return false; } - if (track.codec == "AAC"){ + if (track.codec == "AAC") { memcpy(data + 13, tmpData, len - 17); data[12] = 1; //raw AAC data, not sequence header - }else{ + } else { memcpy(data + 12, tmpData, len - 16); } data[11] = 0; - if (track.codec == "AAC"){ + if (track.codec == "AAC") { data[11] |= 0xA0; } - if (track.codec == "MP3"){ + if (track.codec == "MP3") { data[11] |= 0x20; } unsigned int datarate = track.rate; - if (datarate >= 44100){ + if (datarate >= 44100) { data[11] |= 0x0C; - }else if (datarate >= 22050){ + } else if (datarate >= 22050) { data[11] |= 0x08; - }else if (datarate >= 11025){ + } else if (datarate >= 11025) { data[11] |= 0x04; } - if (track.size == 16){ + if (track.size == 16) { data[11] |= 0x02; } - if (track.channels > 1){ + if (track.channels > 1) { data[11] |= 0x01; } } - if (!len){ + if (!len) { return false; } setLen(); - if (track.type == "video"){data[0] = 0x09;} - if (track.type == "audio"){data[0] = 0x08;} - if (track.type == "meta"){data[0] = 0x12;} + if (track.type == "video") { + data[0] = 0x09; + } + if (track.type == "audio") { + data[0] = 0x08; + } + if (track.type == "meta") { + data[0] = 0x12; + } data[1] = ((len - 15) >> 16) & 0xFF; data[2] = ((len - 15) >> 8) & 0xFF; data[3] = (len - 15) & 0xFF; @@ -465,14 +471,14 @@ bool FLV::Tag::DTSCLoader(DTSC::Packet & packData, DTSC::Track & track){ data[9] = 0; data[10] = 0; tagTime(packData.getTime()); - if (packData.getInt("offset")){ + if (packData.getInt("offset")) { tagTime(packData.getTime() + packData.getInt("offset")); } return true; } /// Helper function that properly sets the tag length from the internal len variable. -void FLV::Tag::setLen(){ +void FLV::Tag::setLen() { int len4 = len - 4; int i = len; data[ --i] = (len4) & 0xFF; @@ -485,15 +491,15 @@ void FLV::Tag::setLen(){ } /// FLV Video init data loader function from JSON. -bool FLV::Tag::DTSCVideoInit(DTSC::Track & video){ +bool FLV::Tag::DTSCVideoInit(DTSC::Track & video) { //Unknown? Assume H264. - if (video.codec == "?"){ + if (video.codec == "?") { video.codec = "H264"; } - if (video.codec == "H264"){ + if (video.codec == "H264") { len = video.init.size() + 20; } - if (len <= 0 || !checkBufferSize()){ + if (len <= 0 || !checkBufferSize()) { return false; } memcpy(data + 16, video.init.c_str(), len - 20); @@ -515,39 +521,39 @@ bool FLV::Tag::DTSCVideoInit(DTSC::Track & video){ } /// FLV Audio init data loader function from JSON. -bool FLV::Tag::DTSCAudioInit(DTSC::Track & audio){ +bool FLV::Tag::DTSCAudioInit(DTSC::Track & audio) { len = 0; //Unknown? Assume AAC. - if (audio.codec == "?"){ + if (audio.codec == "?") { audio.codec = "AAC"; } - if (audio.codec == "AAC"){ + if (audio.codec == "AAC") { len = audio.init.size() + 17; } - if (len <= 0 || !checkBufferSize()){ + if (len <= 0 || !checkBufferSize()) { return false; } memcpy(data + 13, audio.init.c_str(), len - 17); data[12] = 0; //AAC sequence header data[11] = 0; - if (audio.codec == "AAC"){ + if (audio.codec == "AAC") { data[11] += 0xA0; } - if (audio.codec == "MP3"){ + if (audio.codec == "MP3") { data[11] += 0x20; } unsigned int datarate = audio.rate; - if (datarate >= 44100){ + if (datarate >= 44100) { data[11] += 0x0C; - }else if (datarate >= 22050){ + } else if (datarate >= 22050) { data[11] += 0x08; - }else if (datarate >= 11025){ + } else if (datarate >= 11025) { data[11] += 0x04; } - if (audio.size == 16){ + if (audio.size == 16) { data[11] += 0x02; } - if (audio.channels > 1){ + if (audio.channels > 1) { data[11] += 0x01; } setLen(); @@ -562,32 +568,32 @@ bool FLV::Tag::DTSCAudioInit(DTSC::Track & audio){ return true; } -bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set & selTracks){ +bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set & selTracks) { AMF::Object amfdata("root", AMF::AMF0_DDV_CONTAINER); amfdata.addContent(AMF::Object("", "onMetaData")); amfdata.addContent(AMF::Object("", AMF::AMF0_ECMA_ARRAY)); AMF::Object trinfo = AMF::Object("trackinfo", AMF::AMF0_STRICT_ARRAY); int i = 0; unsigned long long mediaLen = 0; - for (std::set::iterator it = selTracks.begin(); it != selTracks.end(); it++){ - if (M.tracks[*it].lastms - M.tracks[*it].firstms > mediaLen){ + for (std::set::iterator it = selTracks.begin(); it != selTracks.end(); it++) { + if (M.tracks[*it].lastms - M.tracks[*it].firstms > mediaLen) { mediaLen = M.tracks[*it].lastms - M.tracks[*it].firstms; } - if (M.tracks[*it].type == "video"){ + if (M.tracks[*it].type == "video") { trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT)); trinfo.getContentP(i)->addContent(AMF::Object("length", ((double)M.tracks[*it].lastms / 1000) * ((double)M.tracks[*it].fpks / 1000.0), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("timescale", ((double)M.tracks[*it].fpks / 1000.0), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY)); amfdata.getContentP(1)->addContent(AMF::Object("hasVideo", 1, AMF::AMF0_BOOL)); - if (M.tracks[*it].codec == "H264"){ + if (M.tracks[*it].codec == "H264") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", (std::string)"avc1")); trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"avc1")); } - if (M.tracks[*it].codec == "VP6"){ + if (M.tracks[*it].codec == "VP6") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 4, AMF::AMF0_NUMBER)); trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"vp6")); } - if (M.tracks[*it].codec == "H263"){ + if (M.tracks[*it].codec == "H263") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 2, AMF::AMF0_NUMBER)); trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"h263")); } @@ -597,18 +603,18 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set & selTra amfdata.getContentP(1)->addContent(AMF::Object("videodatarate", (double)M.tracks[*it].bps * 128.0, AMF::AMF0_NUMBER)); ++i; } - if (M.tracks[*it].type == "audio"){ + if (M.tracks[*it].type == "audio") { trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT)); trinfo.getContentP(i)->addContent(AMF::Object("length", ((double)M.tracks[*it].lastms) * ((double)M.tracks[*it].rate), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("timescale", M.tracks[*it].rate, AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY)); amfdata.getContentP(1)->addContent(AMF::Object("hasAudio", 1, AMF::AMF0_BOOL)); amfdata.getContentP(1)->addContent(AMF::Object("audiodelay", 0, AMF::AMF0_NUMBER)); - if (M.tracks[*it].codec == "AAC"){ + if (M.tracks[*it].codec == "AAC") { amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp4a")); trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp4a")); } - if (M.tracks[*it].codec == "MP3"){ + if (M.tracks[*it].codec == "MP3") { amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp3")); trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp3")); } @@ -619,14 +625,14 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set & selTra ++i; } } - if (M.vod){ - amfdata.getContentP(1)->addContent(AMF::Object("duration", mediaLen/1000, AMF::AMF0_NUMBER)); + if (M.vod) { + amfdata.getContentP(1)->addContent(AMF::Object("duration", mediaLen / 1000, AMF::AMF0_NUMBER)); } amfdata.getContentP(1)->addContent(trinfo); - + std::string tmp = amfdata.Pack(); len = tmp.length() + 15; - if (len <= 0 || !checkBufferSize()){ + if (len <= 0 || !checkBufferSize()) { return false; } memcpy(data + 11, tmp.data(), len - 15); @@ -645,13 +651,13 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set & selTra /// FLV metadata loader function from DTSC. /// Takes the DTSC metadata and makes it into FLV. /// Assumes metadata is available - so check before calling! -bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Track & audioRef){ +bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Track & audioRef) { //Unknown? Assume AAC. - if (audioRef.codec == "?"){ + if (audioRef.codec == "?") { audioRef.codec = "AAC"; } //Unknown? Assume H264. - if (videoRef.codec == "?"){ + if (videoRef.codec == "?") { videoRef.codec = "H264"; } @@ -659,34 +665,34 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Trac amfdata.addContent(AMF::Object("", "onMetaData")); amfdata.addContent(AMF::Object("", AMF::AMF0_ECMA_ARRAY)); - if (S.metadata.vod){ + if (S.metadata.vod) { amfdata.getContentP(1)->addContent(AMF::Object("duration", videoRef.lastms / 1000, AMF::AMF0_NUMBER)); amfdata.getContentP(1)->addContent(AMF::Object("moovPosition", 40, AMF::AMF0_NUMBER)); AMF::Object keys("keyframes", AMF::AMF0_OBJECT); keys.addContent(AMF::Object("filepositions", AMF::AMF0_STRICT_ARRAY)); keys.addContent(AMF::Object("times", AMF::AMF0_STRICT_ARRAY)); int total_byterate = 0; - if (videoRef.trackID > 0){ + if (videoRef.trackID > 0) { total_byterate += videoRef.bps; } - if (audioRef.trackID > 0){ + if (audioRef.trackID > 0) { total_byterate += audioRef.bps; } - for (unsigned long long i = 0; i < videoRef.lastms / 1000; ++i){ //for each second in the file + for (unsigned long long i = 0; i < videoRef.lastms / 1000; ++i) { //for each second in the file keys.getContentP(0)->addContent(AMF::Object("", i * total_byterate, AMF::AMF0_NUMBER)); //multiply by byterate for fake byte positions keys.getContentP(1)->addContent(AMF::Object("", i, AMF::AMF0_NUMBER)); //seconds } amfdata.getContentP(1)->addContent(keys); } - if (videoRef.trackID > 0){ + if (videoRef.trackID > 0) { amfdata.getContentP(1)->addContent(AMF::Object("hasVideo", 1, AMF::AMF0_BOOL)); - if (videoRef.codec == "H264"){ + if (videoRef.codec == "H264") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", (std::string)"avc1")); } - if (videoRef.codec == "VP6"){ + if (videoRef.codec == "VP6") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 4, AMF::AMF0_NUMBER)); } - if (videoRef.codec == "H263"){ + if (videoRef.codec == "H263") { amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 2, AMF::AMF0_NUMBER)); } amfdata.getContentP(1)->addContent(AMF::Object("width", videoRef.width, AMF::AMF0_NUMBER)); @@ -694,13 +700,13 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Trac amfdata.getContentP(1)->addContent(AMF::Object("videoframerate", (double)videoRef.fpks / 1000.0, AMF::AMF0_NUMBER)); amfdata.getContentP(1)->addContent(AMF::Object("videodatarate", (double)videoRef.bps * 128.0, AMF::AMF0_NUMBER)); } - if (audioRef.trackID > 0){ + if (audioRef.trackID > 0) { amfdata.getContentP(1)->addContent(AMF::Object("hasAudio", 1, AMF::AMF0_BOOL)); amfdata.getContentP(1)->addContent(AMF::Object("audiodelay", 0, AMF::AMF0_NUMBER)); - if (audioRef.codec == "AAC"){ + if (audioRef.codec == "AAC") { amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp4a")); } - if (audioRef.codec == "MP3"){ + if (audioRef.codec == "MP3") { amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp3")); } amfdata.getContentP(1)->addContent(AMF::Object("audiochannels", audioRef.channels, AMF::AMF0_NUMBER)); @@ -710,32 +716,32 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Trac } AMF::Object trinfo = AMF::Object("trackinfo", AMF::AMF0_STRICT_ARRAY); int i = 0; - if (audioRef){ + if (audioRef) { trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT)); trinfo.getContentP(i)->addContent(AMF::Object("length", ((double)audioRef.lastms) * ((double)audioRef.rate), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("timescale", audioRef.rate, AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY)); - if (audioRef.codec == "AAC"){ + if (audioRef.codec == "AAC") { trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp4a")); } - if (audioRef.codec == "MP3"){ + if (audioRef.codec == "MP3") { trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp3")); } ++i; } - if (videoRef){ + if (videoRef) { trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT)); trinfo.getContentP(i)->addContent( - AMF::Object("length", ((double)videoRef.lastms / 1000) * ((double)videoRef.fpks / 1000.0), AMF::AMF0_NUMBER)); + AMF::Object("length", ((double)videoRef.lastms / 1000) * ((double)videoRef.fpks / 1000.0), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("timescale", ((double)videoRef.fpks / 1000.0), AMF::AMF0_NUMBER)); trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY)); - if (videoRef.codec == "H264"){ + if (videoRef.codec == "H264") { trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"avc1")); } - if (videoRef.codec == "VP6"){ + if (videoRef.codec == "VP6") { trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"vp6")); } - if (videoRef.codec == "H263"){ + if (videoRef.codec == "H263") { trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"h263")); } ++i; @@ -744,7 +750,7 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Trac std::string tmp = amfdata.Pack(); len = tmp.length() + 15; - if (len <= 0 || !checkBufferSize()){ + if (len <= 0 || !checkBufferSize()) { return false; } memcpy(data + 11, tmp.data(), len - 15); @@ -762,10 +768,10 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Trac /// FLV loader function from chunk. /// Copies the contents and wraps it in a FLV header. -bool FLV::Tag::ChunkLoader(const RTMPStream::Chunk& O){ +bool FLV::Tag::ChunkLoader(const RTMPStream::Chunk & O) { len = O.len + 15; - if (len > 0){ - if ( !checkBufferSize()){ + if (len > 0) { + if (!checkBufferSize()) { return false; } memcpy(data + 11, &(O.data[0]), O.len); @@ -790,20 +796,20 @@ bool FLV::Tag::ChunkLoader(const RTMPStream::Chunk& O){ /// \param S The size of the data buffer. /// \param P The current position in the data buffer. Will be updated to reflect new position. /// \return True if count bytes are read succesfully, false otherwise. -bool FLV::Tag::MemReadUntil(char * buffer, unsigned int count, unsigned int & sofar, char * D, unsigned int S, unsigned int & P){ - if (sofar >= count){ +bool FLV::Tag::MemReadUntil(char * buffer, unsigned int count, unsigned int & sofar, char * D, unsigned int S, unsigned int & P) { + if (sofar >= count) { return true; } int r = 0; - if (P + (count - sofar) > S){ + if (P + (count - sofar) > S) { r = S - P; - }else{ + } else { r = count - sofar; } memcpy(buffer + sofar, D + P, r); P += r; sofar += r; - if (sofar >= count){ + if (sofar >= count) { return true; } return false; @@ -816,37 +822,37 @@ bool FLV::Tag::MemReadUntil(char * buffer, unsigned int count, unsigned int & so /// \param S The size of the data buffer. /// \param P The current position in the data buffer. Will be updated to reflect new position. /// \return True if a whole tag is succesfully read, false otherwise. -bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){ - if (len < 15){ +bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P) { + if (len < 15) { len = 15; } - if ( !checkBufferSize()){ + if (!checkBufferSize()) { return false; } - if (done){ + if (done) { //read a header - if (MemReadUntil(data, 11, sofar, D, S, P)){ + if (MemReadUntil(data, 11, sofar, D, S, P)) { //if its a correct FLV header, throw away and read tag header - if (FLV::is_header(data)){ - if (MemReadUntil(data, 13, sofar, D, S, P)){ - if (FLV::check_header(data)){ + if (FLV::is_header(data)) { + if (MemReadUntil(data, 13, sofar, D, S, P)) { + if (FLV::check_header(data)) { sofar = 0; memcpy(FLV::Header, data, 13); - }else{ + } else { FLV::Parse_Error = true; Error_Str = "Invalid header received."; return false; } } - }else{ + } else { //if a tag header, calculate length and read tag body len = data[3] + 15; len += (data[2] << 8); len += (data[1] << 16); - if ( !checkBufferSize()){ + if (!checkBufferSize()) { return false; } - if (data[0] > 0x12){ + if (data[0] > 0x12) { data[0] += 32; FLV::Parse_Error = true; Error_Str = "Invalid Tag received ("; @@ -857,13 +863,13 @@ bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){ done = false; } } - }else{ + } else { //read tag body - if (MemReadUntil(data, len, sofar, D, S, P)){ + if (MemReadUntil(data, len, sofar, D, S, P)) { //calculate keyframeness, next time read header again, return true - if ((data[0] == 0x09) && (((data[11] & 0xf0) >> 4) == 1)){ + if ((data[0] == 0x09) && (((data[11] & 0xf0) >> 4) == 1)) { isKeyframe = true; - }else{ + } else { isKeyframe = false; } done = true; @@ -882,19 +888,19 @@ bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){ /// \param sofar Current amount read. /// \param f File to read from. /// \return True if count bytes are read succesfully, false otherwise. -bool FLV::Tag::FileReadUntil(char * buffer, unsigned int count, unsigned int & sofar, FILE * f){ - if (sofar >= count){ +bool FLV::Tag::FileReadUntil(char * buffer, unsigned int count, unsigned int & sofar, FILE * f) { + if (sofar >= count) { return true; } int r = 0; r = fread(buffer + sofar, 1, count - sofar, f); - if (r < 0){ + if (r < 0) { FLV::Parse_Error = true; Error_Str = "File reading error."; return false; } sofar += r; - if (sofar >= count){ + if (sofar >= count) { return true; } return false; @@ -905,42 +911,44 @@ bool FLV::Tag::FileReadUntil(char * buffer, unsigned int count, unsigned int & s /// While this function returns false, the Tag might not contain valid data. /// \param f The file to read from. /// \return True if a whole tag is succesfully read, false otherwise. -bool FLV::Tag::FileLoader(FILE * f){ +bool FLV::Tag::FileLoader(FILE * f) { int preflags = fcntl(fileno(f), F_GETFL, 0); int postflags = preflags | O_NONBLOCK; fcntl(fileno(f), F_SETFL, postflags); - - if (len < 15){len = 15;} - if ( !checkBufferSize()){ + + if (len < 15) { + len = 15; + } + if (!checkBufferSize()) { return false; } - if (done){ + if (done) { //read a header - if (FileReadUntil(data, 11, sofar, f)){ + if (FileReadUntil(data, 11, sofar, f)) { //if its a correct FLV header, throw away and read tag header - if (FLV::is_header(data)){ - if (FileReadUntil(data, 13, sofar, f)){ - if (FLV::check_header(data)){ + if (FLV::is_header(data)) { + if (FileReadUntil(data, 13, sofar, f)) { + if (FLV::check_header(data)) { sofar = 0; memcpy(FLV::Header, data, 13); - }else{ + } else { FLV::Parse_Error = true; Error_Str = "Invalid header received."; return false; } - }else{ + } else { Util::sleep(100);//sleep 100ms } - }else{ + } else { //if a tag header, calculate length and read tag body len = data[3] + 15; len += (data[2] << 8); len += (data[1] << 16); - if ( !checkBufferSize()){ + if (!checkBufferSize()) { return false; } - if (data[0] > 0x12){ + if (data[0] > 0x12) { data[0] += 32; FLV::Parse_Error = true; Error_Str = "Invalid Tag received ("; @@ -950,23 +958,23 @@ bool FLV::Tag::FileLoader(FILE * f){ } done = false; } - }else{ + } else { Util::sleep(100);//sleep 100ms } - }else{ + } else { //read tag body - if (FileReadUntil(data, len, sofar, f)){ + if (FileReadUntil(data, len, sofar, f)) { //calculate keyframeness, next time read header again, return true - if ((data[0] == 0x09) && (((data[11] & 0xf0) >> 4) == 1)){ + if ((data[0] == 0x09) && (((data[11] & 0xf0) >> 4) == 1)) { isKeyframe = true; - }else{ + } else { isKeyframe = false; } done = true; sofar = 0; fcntl(fileno(f), F_SETFL, preflags); return true; - }else{ + } else { Util::sleep(100);//sleep 100ms } } @@ -974,92 +982,92 @@ bool FLV::Tag::FileLoader(FILE * f){ return false; } //FLV_GetPacket -JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ +JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata) { JSON::Value pack_out; // Storage for outgoing metadata. - if (data[0] == 0x12){ - AMF::Object meta_in = AMF::parse((unsigned char*)data + 11, len - 15); + if (data[0] == 0x12) { + AMF::Object meta_in = AMF::parse((unsigned char *)data + 11, len - 15); AMF::Object * tmp = 0; - if (meta_in.getContentP(1) && meta_in.getContentP(0) && (meta_in.getContentP(0)->StrValue() == "onMetaData")){ + if (meta_in.getContentP(1) && meta_in.getContentP(0) && (meta_in.getContentP(0)->StrValue() == "onMetaData")) { tmp = meta_in.getContentP(1); - }else{ - if (meta_in.getContentP(2) && meta_in.getContentP(1) && (meta_in.getContentP(1)->StrValue() == "onMetaData")){ + } else { + if (meta_in.getContentP(2) && meta_in.getContentP(1) && (meta_in.getContentP(1)->StrValue() == "onMetaData")) { tmp = meta_in.getContentP(2); } } - if (tmp){ - if (tmp->getContentP("width")){ + if (tmp) { + if (tmp->getContentP("width")) { metadata.tracks[1].width = (long long int)tmp->getContentP("width")->NumValue(); - }else{ + } else { metadata.tracks[1].width = 0; } - if (tmp->getContentP("height")){ + if (tmp->getContentP("height")) { metadata.tracks[1].height = (long long int)tmp->getContentP("height")->NumValue(); - }else{ + } else { metadata.tracks[1].height = 0; } - if (tmp->getContentP("framerate")){ + if (tmp->getContentP("framerate")) { metadata.tracks[1].fpks = (long long int)(tmp->getContentP("framerate")->NumValue() * 1000.0); - }else{ + } else { metadata.tracks[1].fpks = 0; } - if (tmp->getContentP("videodatarate")){ + if (tmp->getContentP("videodatarate")) { metadata.tracks[1].bps = (long long int)(tmp->getContentP("videodatarate")->NumValue() * 1024) / 8; - }else{ + } else { metadata.tracks[1].bps = 0; } - if (tmp->getContentP("audiodatarate")){ + if (tmp->getContentP("audiodatarate")) { metadata.tracks[2].bps = (long long int)(tmp->getContentP("audiodatarate")->NumValue() * 1024) / 8; - }else{ + } else { metadata.tracks[2].bps = 0; } - if (tmp->getContentP("audiosamplerate")){ + if (tmp->getContentP("audiosamplerate")) { metadata.tracks[2].rate = (long long int)tmp->getContentP("audiosamplerate")->NumValue(); - }else{ + } else { metadata.tracks[2].rate = 0; } - if (tmp->getContentP("audiosamplesize")){ + if (tmp->getContentP("audiosamplesize")) { metadata.tracks[2].size = (long long int)tmp->getContentP("audiosamplesize")->NumValue(); - }else{ + } else { metadata.tracks[2].size = 0; } - if (tmp->getContentP("stereo")){ - if (tmp->getContentP("stereo")->NumValue() == 1){ + if (tmp->getContentP("stereo")) { + if (tmp->getContentP("stereo")->NumValue() == 1) { metadata.tracks[2].channels = 2; - }else{ + } else { metadata.tracks[2].channels = 1; } - }else{ + } else { metadata.tracks[2].channels = 1; } - for (int i = 0; i < tmp->hasContent(); ++i){ - if (tmp->getContentP(i)->Indice() == "videocodecid" || tmp->getContentP(i)->Indice() == "audiocodecid" || tmp->getContentP(i)->Indice() == "width" || tmp->getContentP(i)->Indice() == "height" || tmp->getContentP(i)->Indice() == "framerate" || tmp->getContentP(i)->Indice() == "videodatarate" || tmp->getContentP(i)->Indice() == "audiodatarate" || tmp->getContentP(i)->Indice() == "audiosamplerate" || tmp->getContentP(i)->Indice() == "audiosamplesize" || tmp->getContentP(i)->Indice() == "audiochannels"){ + for (int i = 0; i < tmp->hasContent(); ++i) { + if (tmp->getContentP(i)->Indice() == "videocodecid" || tmp->getContentP(i)->Indice() == "audiocodecid" || tmp->getContentP(i)->Indice() == "width" || tmp->getContentP(i)->Indice() == "height" || tmp->getContentP(i)->Indice() == "framerate" || tmp->getContentP(i)->Indice() == "videodatarate" || tmp->getContentP(i)->Indice() == "audiodatarate" || tmp->getContentP(i)->Indice() == "audiosamplerate" || tmp->getContentP(i)->Indice() == "audiosamplesize" || tmp->getContentP(i)->Indice() == "audiochannels") { continue; } - if (tmp->getContentP(i)->NumValue()){ + if (tmp->getContentP(i)->NumValue()) { pack_out["data"][tmp->getContentP(i)->Indice()] = (long long)tmp->getContentP(i)->NumValue(); - }else{ - if (tmp->getContentP(i)->StrValue() != ""){ + } else { + if (tmp->getContentP(i)->StrValue() != "") { pack_out["data"][tmp->getContentP(i)->Indice()] = tmp->getContentP(i)->StrValue(); } } } - if (pack_out){ + if (pack_out) { pack_out["datatype"] = "meta"; pack_out["time"] = tagTime(); } } return pack_out; //empty } - if (data[0] == 0x08){ + if (data[0] == 0x08) { char audiodata = data[11]; metadata.tracks[2].trackID = 2; metadata.tracks[2].type = "audio"; - if (metadata.tracks[2].codec == ""){ + if (metadata.tracks[2].codec == "") { metadata.tracks[2].codec = getAudioCodec(); } - if ( !metadata.tracks[2].rate){ - switch (audiodata & 0x0C){ + if (!metadata.tracks[2].rate) { + switch (audiodata & 0x0C) { case 0x0: metadata.tracks[2].rate = 5512; break; @@ -1074,8 +1082,8 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ break; } } - if ( !metadata.tracks[2].size){ - switch (audiodata & 0x02){ + if (!metadata.tracks[2].size) { + switch (audiodata & 0x02) { case 0x0: metadata.tracks[2].size = 8; break; @@ -1084,8 +1092,8 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ break; } } - if ( !metadata.tracks[2].channels){ - switch (audiodata & 0x01){ + if (!metadata.tracks[2].channels) { + switch (audiodata & 0x01) { case 0x0: metadata.tracks[2].channels = 1; break; @@ -1094,52 +1102,52 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ break; } } - if (needsInitData() && isInitData()){ - if ((audiodata & 0xF0) == 0xA0){ - metadata.tracks[2].init = std::string((char*)data + 13, (size_t)len - 17); - }else{ - metadata.tracks[2].init = std::string((char*)data + 12, (size_t)len - 16); + if (needsInitData() && isInitData()) { + if ((audiodata & 0xF0) == 0xA0) { + metadata.tracks[2].init = std::string((char *)data + 13, (size_t)len - 17); + } else { + metadata.tracks[2].init = std::string((char *)data + 12, (size_t)len - 16); } return pack_out; //skip rest of parsing, get next tag. } pack_out["time"] = tagTime(); pack_out["trackid"] = 2; - if ((audiodata & 0xF0) == 0xA0){ - if (len < 18){ + if ((audiodata & 0xF0) == 0xA0) { + if (len < 18) { return JSON::Value(); } - pack_out["data"] = std::string((char*)data + 13, (size_t)len - 17); - }else{ - if (len < 17){ + pack_out["data"] = std::string((char *)data + 13, (size_t)len - 17); + } else { + if (len < 17) { return JSON::Value(); } - pack_out["data"] = std::string((char*)data + 12, (size_t)len - 16); + pack_out["data"] = std::string((char *)data + 12, (size_t)len - 16); } return pack_out; } - if (data[0] == 0x09){ + if (data[0] == 0x09) { char videodata = data[11]; - if (metadata.tracks[1].codec == ""){ + if (metadata.tracks[1].codec == "") { metadata.tracks[1].codec = getVideoCodec(); } metadata.tracks[1].type = "video"; metadata.tracks[1].trackID = 1; - if (needsInitData() && isInitData()){ - if ((videodata & 0x0F) == 7){ - if (len < 21){ + if (needsInitData() && isInitData()) { + if ((videodata & 0x0F) == 7) { + if (len < 21) { return JSON::Value(); } - metadata.tracks[1].init = std::string((char*)data + 16, (size_t)len - 20); - }else{ - if (len < 17){ + metadata.tracks[1].init = std::string((char *)data + 16, (size_t)len - 20); + } else { + if (len < 17) { return JSON::Value(); } - metadata.tracks[1].init = std::string((char*)data + 12, (size_t)len - 16); + metadata.tracks[1].init = std::string((char *)data + 12, (size_t)len - 16); } return pack_out; //skip rest of parsing, get next tag. } pack_out["trackid"] = 1; - switch (videodata & 0xF0){ + switch (videodata & 0xF0) { case 0x10: pack_out["keyframe"] = 1; break; @@ -1157,8 +1165,8 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ break; //the video info byte we just throw away - useless to us... } pack_out["time"] = tagTime(); - if ((videodata & 0x0F) == 7){ - switch (data[12]){ + if ((videodata & 0x0F) == 7) { + switch (data[12]) { case 1: pack_out["nalu"] = 1; break; @@ -1167,15 +1175,15 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ break; } pack_out["offset"] = offset(); - if (len < 21){ + if (len < 21) { return JSON::Value(); } - pack_out["data"] = std::string((char*)data + 16, (size_t)len - 20); - }else{ - if (len < 17){ + pack_out["data"] = std::string((char *)data + 16, (size_t)len - 20); + } else { + if (len < 17) { return JSON::Value(); } - pack_out["data"] = std::string((char*)data + 12, (size_t)len - 16); + pack_out["data"] = std::string((char *)data + 12, (size_t)len - 16); } return pack_out; } @@ -1185,14 +1193,14 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata){ /// Checks if buf is large enough to contain len. /// Attempts to resize data buffer if not/ /// \returns True if buffer is large enough, false otherwise. -bool FLV::Tag::checkBufferSize(){ - if (buf < len || !data){ - char * newdata = (char*)realloc(data, len); +bool FLV::Tag::checkBufferSize() { + if (buf < len || !data) { + char * newdata = (char *)realloc(data, len); // on realloc fail, retain the old data - if (newdata != 0){ + if (newdata != 0) { data = newdata; buf = len; - }else{ + } else { len = buf; return false; } diff --git a/lib/flv_tag.h b/lib/flv_tag.h index f7dd6bc3..deef0ea7 100644 --- a/lib/flv_tag.h +++ b/lib/flv_tag.h @@ -25,7 +25,7 @@ namespace FLV { bool is_header(char * header); ///< Checks the first 3 bytes for the string "FLV". /// This class is used to hold, work with and get information about a single FLV tag. - class Tag{ + class Tag { public: int len; ///< Actual length of tag. bool isKeyframe; ///< True if current tag is a video keyframe. @@ -40,12 +40,12 @@ namespace FLV { int offset(); void offset(int o); Tag(); ///< Constructor for a new, empty, tag. - Tag(const Tag& O); ///< Copy constructor, copies the contents of an existing tag. - Tag & operator=(const Tag& O); ///< Assignment operator - works exactly like the copy constructor. - Tag(const RTMPStream::Chunk& O); /// Credentials){ +FTP::User::User(Socket::Connection NewConnection, std::map Credentials) { Conn = NewConnection; MyPassivePort = 0; USER = ""; @@ -23,545 +23,545 @@ FTP::User::User(Socket::Connection NewConnection, std::map 1){ - if (Command[1] != ' '){ - return 501; - } //Syntax error in parameters or arguments. - if (Command[2] != 'N'){ - return 504; - } //Command not implemented for that parameter. - } - TYPE = TYPE_ASCII_NONPRINT; - break; - } - case 'I': { - if (Command.size() > 1){ - if (Command[1] != ' '){ - return 501; - } //Syntax error in parameters or arguments. - if (Command[2] != 'N'){ - return 504; - } //Command not implemented for that parameter. - } - TYPE = TYPE_IMAGE_NONPRINT; - break; - } - default: { - return 504; //Command not implemented for that parameter. - break; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (Command.size() != 1 && Command.size() != 3) { + return 501; + } //Syntax error in parameters or arguments. + switch (Command[0]) { + case 'A': { + if (Command.size() > 1) { + if (Command[1] != ' ') { + return 501; + } //Syntax error in parameters or arguments. + if (Command[2] != 'N') { + return 504; + } //Command not implemented for that parameter. + } + TYPE = TYPE_ASCII_NONPRINT; + break; + } + case 'I': { + if (Command.size() > 1) { + if (Command[1] != ' ') { + return 501; + } //Syntax error in parameters or arguments. + if (Command[2] != 'N') { + return 504; + } //Command not implemented for that parameter. + } + TYPE = TYPE_IMAGE_NONPRINT; + break; + } + default: { + return 504; //Command not implemented for that parameter. + break; + } } + return 200; //Command okay. + break; } - return 200; //Command okay. - break; - } case CMD_MODE: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if (Command.size() != 1){ - return 501; - } //Syntax error in parameters or arguments. - if (Command[0] != 'S'){ - return 504; - } //Command not implemented for that parameter. - MODE = MODE_STREAM; - return 200; //Command okay. - break; - } + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (Command.size() != 1) { + return 501; + } //Syntax error in parameters or arguments. + if (Command[0] != 'S') { + return 504; + } //Command not implemented for that parameter. + MODE = MODE_STREAM; + return 200; //Command okay. + break; + } case CMD_STRU: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if (Command.size() != 1){ - return 501; - } //Syntax error in parameters or arguments. - switch (Command[0]){ - case 'F': { - STRU = STRU_FILE; - break; - } - case 'R': { - STRU = STRU_RECORD; - break; - } - default: { - return 504; //Command not implemented for that parameter. - break; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (Command.size() != 1) { + return 501; + } //Syntax error in parameters or arguments. + switch (Command[0]) { + case 'F': { + STRU = STRU_FILE; + break; + } + case 'R': { + STRU = STRU_RECORD; + break; + } + default: { + return 504; //Command not implemented for that parameter. + break; + } } + return 200; //Command okay. + break; } - return 200; //Command okay. - break; - } case CMD_PWD: { - if ( !LoggedIn()){ - return 550; - } //Not logged in. - if (Command != ""){ - return 501; - } //Syntax error in parameters or arguments. - return 2570; //257 -- 0 to indicate PWD over MKD - break; - } + if (!LoggedIn()) { + return 550; + } //Not logged in. + if (Command != "") { + return 501; + } //Syntax error in parameters or arguments. + return 2570; //257 -- 0 to indicate PWD over MKD + break; + } case CMD_CWD: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - Filesystem::Directory TmpDir = MyDir; - if (TmpDir.CWD(Command)){ - if (TmpDir.IsDir()){ - MyDir = TmpDir; - return 250; + if (!LoggedIn()) { + return 530; + } //Not logged in. + Filesystem::Directory TmpDir = MyDir; + if (TmpDir.CWD(Command)) { + if (TmpDir.IsDir()) { + MyDir = TmpDir; + return 250; + } } + return 550; + break; } - return 550; - break; - } case CMD_CDUP: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command != ""){ - return 501; - } //Syntax error in parameters or arguments. - Filesystem::Directory TmpDir = MyDir; - if (TmpDir.CDUP()){ - if (TmpDir.IsDir()){ - MyDir = TmpDir; - return 250; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command != "") { + return 501; + } //Syntax error in parameters or arguments. + Filesystem::Directory TmpDir = MyDir; + if (TmpDir.CDUP()) { + if (TmpDir.IsDir()) { + MyDir = TmpDir; + return 250; + } } + return 550; + break; } - return 550; - break; - } case CMD_DELE: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if ( !MyDir.DELE(Command)){ - return 550; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (!MyDir.DELE(Command)) { + return 550; + } + return 250; + break; } - return 250; - break; - } case CMD_RMD: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if ( !MyDir.HasPermission(Filesystem::P_RMD)){ - return 550; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (!MyDir.HasPermission(Filesystem::P_RMD)) { + return 550; + } + if (!MyDir.DELE(Command)) { + return 550; + } + return 250; + break; } - if ( !MyDir.DELE(Command)){ - return 550; - } - return 250; - break; - } case CMD_MKD: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if ( !MyDir.HasPermission(Filesystem::P_MKD)){ - return 550; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (!MyDir.HasPermission(Filesystem::P_MKD)) { + return 550; + } + if (!MyDir.MKD(Command)) { + return 550; + } + return 2571; + break; } - if ( !MyDir.MKD(Command)){ - return 550; - } - return 2571; - break; - } case CMD_RNFR: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - RNFR = Command; - return 350; //Awaiting further information - } - case CMD_RNTO: { - if ( !LoggedIn()){ - return 530; - } //Not logged in. - if (Command == ""){ - return 501; - } //Syntax error in parameters or arguments. - if (RNFR == ""){ - return 503; - } //Bad sequence of commands - if ( !MyDir.Rename(RNFR, Command)){ - return 550; + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + RNFR = Command; + return 350; //Awaiting further information + } + case CMD_RNTO: { + if (!LoggedIn()) { + return 530; + } //Not logged in. + if (Command == "") { + return 501; + } //Syntax error in parameters or arguments. + if (RNFR == "") { + return 503; + } //Bad sequence of commands + if (!MyDir.Rename(RNFR, Command)) { + return 550; + } + return 250; } - return 250; - } default: { - return 502; //Command not implemented. - break; - } + return 502; //Command not implemented. + break; + } } } -bool FTP::User::LoggedIn(){ - if (USER == "" || PASS == ""){ +bool FTP::User::LoggedIn() { + if (USER == "" || PASS == "") { return false; } - if ( !AllCredentials.size()){ + if (!AllCredentials.size()) { return true; } - if ((AllCredentials.find(USER) != AllCredentials.end()) && AllCredentials[USER] == PASS){ + if ((AllCredentials.find(USER) != AllCredentials.end()) && AllCredentials[USER] == PASS) { return true; } return false; } -std::string FTP::User::NumToMsg(int MsgNum){ +std::string FTP::User::NumToMsg(int MsgNum) { std::string Result; - switch (MsgNum){ + switch (MsgNum) { case 200: { - Result = "200 Message okay.\n"; - break; - } + Result = "200 Message okay.\n"; + break; + } case 221: { - Result = "221 Service closing control connection. Logged out if appropriate.\n"; - break; - } + Result = "221 Service closing control connection. Logged out if appropriate.\n"; + break; + } case 226: { - Result = "226 Closing data connection.\n"; - break; - } + Result = "226 Closing data connection.\n"; + break; + } case 227: { - std::stringstream sstr; - sstr << "227 Entering passive mode (0,0,0,0,"; - sstr << (MyPassivePort >> 8) % 256; - sstr << ","; - sstr << MyPassivePort % 256; - sstr << ").\n"; - Result = sstr.str(); - break; - } + std::stringstream sstr; + sstr << "227 Entering passive mode (0,0,0,0,"; + sstr << (MyPassivePort >> 8) % 256; + sstr << ","; + sstr << MyPassivePort % 256; + sstr << ").\n"; + Result = sstr.str(); + break; + } case 229: { - std::stringstream sstr; - sstr << "229 Entering extended passive mode (|||"; - sstr << MyPassivePort; - sstr << "|).\n"; - Result = sstr.str(); - break; - } + std::stringstream sstr; + sstr << "229 Entering extended passive mode (|||"; + sstr << MyPassivePort; + sstr << "|).\n"; + Result = sstr.str(); + break; + } case 230: { - Result = "230 User logged in, proceed.\n"; - break; - } + Result = "230 User logged in, proceed.\n"; + break; + } case 250: { - Result = "250 Requested file action okay, completed.\n"; - break; - } + Result = "250 Requested file action okay, completed.\n"; + break; + } case 2570: { //PWD - Result = "257 \"" + MyDir.PWD() + "\" selected as PWD\n"; - break; - } + Result = "257 \"" + MyDir.PWD() + "\" selected as PWD\n"; + break; + } case 2571: { //MKD - Result = "257 \"" + MyDir.PWD() + "\" created\n"; - break; - } + Result = "257 \"" + MyDir.PWD() + "\" created\n"; + break; + } case 331: { - Result = "331 User name okay, need password.\n"; - break; - } + Result = "331 User name okay, need password.\n"; + break; + } case 350: { - Result = "350 Requested file action pending further information\n"; - break; - } + Result = "350 Requested file action pending further information\n"; + break; + } case 501: { - Result = "501 Syntax error in parameters or arguments.\n"; - break; - } + Result = "501 Syntax error in parameters or arguments.\n"; + break; + } case 502: { - Result = "502 Command not implemented.\n"; - break; - } + Result = "502 Command not implemented.\n"; + break; + } case 503: { - Result = "503 Bad sequence of commands.\n"; - break; - } + Result = "503 Bad sequence of commands.\n"; + break; + } case 504: { - Result = "504 Command not implemented for that parameter.\n"; - break; - } + Result = "504 Command not implemented for that parameter.\n"; + break; + } case 530: { - Result = "530 Not logged in.\n"; - break; - } + Result = "530 Not logged in.\n"; + break; + } case 550: { - Result = "550 Requested action not taken.\n"; - break; - } + Result = "550 Requested action not taken.\n"; + break; + } default: { - Result = "Error msg not implemented?\n"; - break; - } + Result = "Error msg not implemented?\n"; + break; + } } return Result; } diff --git a/lib/ftp.h b/lib/ftp.h index 2c2e59bd..41350657 100644 --- a/lib/ftp.h +++ b/lib/ftp.h @@ -14,22 +14,22 @@ namespace FTP { static std::string FTPBasePath = "/tmp/mist/OnDemand/"; - enum Mode{ + enum Mode { MODE_STREAM, }; //FTP::Mode enumeration - enum Structure{ + enum Structure { STRU_FILE, STRU_RECORD, }; //FTP::Structure enumeration - enum Type{ + enum Type { TYPE_ASCII_NONPRINT, TYPE_IMAGE_NONPRINT, }; //FTP::Type enumeration - enum Commands{ + enum Commands { CMD_NOCMD, CMD_NOOP, CMD_USER, @@ -55,7 +55,7 @@ namespace FTP { }; //FTP::Commands enumeration - class User{ + class User { public: User(Socket::Connection NewConnection, std::map Credentials); ~User(); diff --git a/lib/http_parser.cpp b/lib/http_parser.cpp index b880f60f..c0838dcf 100644 --- a/lib/http_parser.cpp +++ b/lib/http_parser.cpp @@ -6,13 +6,13 @@ /// This constructor creates an empty HTTP::Parser, ready for use for either reading or writing. /// All this constructor does is call HTTP::Parser::Clean(). -HTTP::Parser::Parser(){ +HTTP::Parser::Parser() { headerOnly = false; Clean(); } /// Completely re-initializes the HTTP::Parser, leaving it ready for either reading or writing usage. -void HTTP::Parser::Clean(){ +void HTTP::Parser::Clean() { seenHeaders = false; seenReq = false; getChunks = false; @@ -30,16 +30,16 @@ void HTTP::Parser::Clean(){ /// The request is build from internal variables set before this call is made. /// To be precise, method, url, protocol, headers and body are used. /// \return A string containing a valid HTTP 1.0 or 1.1 request, ready for sending. -std::string & HTTP::Parser::BuildRequest(){ +std::string & HTTP::Parser::BuildRequest() { /// \todo Include GET/POST variable parsing? std::map::iterator it; - if (protocol.size() < 5 || protocol[4] != '/'){ + if (protocol.size() < 5 || protocol[4] != '/') { protocol = "HTTP/1.0"; } builder = method + " " + url + " " + protocol + "\r\n"; - for (it = headers.begin(); it != headers.end(); it++){ - if (( *it).first != "" && ( *it).second != ""){ - builder += ( *it).first + ": " + ( *it).second + "\r\n"; + for (it = headers.begin(); it != headers.end(); it++) { + if ((*it).first != "" && (*it).second != "") { + builder += (*it).first + ": " + (*it).second + "\r\n"; } } builder += "\r\n" + body; @@ -49,17 +49,17 @@ std::string & HTTP::Parser::BuildRequest(){ /// Creates and sends a valid HTTP 1.0 or 1.1 request. /// The request is build from internal variables set before this call is made. /// To be precise, method, url, protocol, headers and body are used. -void HTTP::Parser::SendRequest(Socket::Connection & conn){ +void HTTP::Parser::SendRequest(Socket::Connection & conn) { /// \todo Include GET/POST variable parsing? std::map::iterator it; - if (protocol.size() < 5 || protocol[4] != '/'){ + if (protocol.size() < 5 || protocol[4] != '/') { protocol = "HTTP/1.0"; } builder = method + " " + url + " " + protocol + "\r\n"; conn.SendNow(builder); - for (it = headers.begin(); it != headers.end(); it++){ - if (( *it).first != "" && ( *it).second != ""){ - builder = ( *it).first + ": " + ( *it).second + "\r\n"; + for (it = headers.begin(); it != headers.end(); it++) { + if ((*it).first != "" && (*it).second != "") { + builder = (*it).first + ": " + (*it).second + "\r\n"; conn.SendNow(builder); } } @@ -73,17 +73,17 @@ void HTTP::Parser::SendRequest(Socket::Connection & conn){ /// \param code The HTTP response code. Usually you want 200. /// \param message The HTTP response message. Usually you want "OK". /// \return A string containing a valid HTTP 1.0 or 1.1 response, ready for sending. -std::string & HTTP::Parser::BuildResponse(std::string code, std::string message){ +std::string & HTTP::Parser::BuildResponse(std::string code, std::string message) { /// \todo Include GET/POST variable parsing? std::map::iterator it; - if (protocol.size() < 5 || protocol[4] != '/'){ + if (protocol.size() < 5 || protocol[4] != '/') { protocol = "HTTP/1.0"; } builder = protocol + " " + code + " " + message + "\r\n"; - for (it = headers.begin(); it != headers.end(); it++){ - if (( *it).first != "" && ( *it).second != ""){ - if (( *it).first != "Content-Length" || ( *it).second != "0"){ - builder += ( *it).first + ": " + ( *it).second + "\r\n"; + for (it = headers.begin(); it != headers.end(); it++) { + if ((*it).first != "" && (*it).second != "") { + if ((*it).first != "Content-Length" || (*it).second != "0") { + builder += (*it).first + ": " + (*it).second + "\r\n"; } } } @@ -99,18 +99,18 @@ std::string & HTTP::Parser::BuildResponse(std::string code, std::string message) /// \param code The HTTP response code. Usually you want 200. /// \param message The HTTP response message. Usually you want "OK". /// \param conn The Socket::Connection to send the response over. -void HTTP::Parser::SendResponse(std::string code, std::string message, Socket::Connection & conn){ +void HTTP::Parser::SendResponse(std::string code, std::string message, Socket::Connection & conn) { /// \todo Include GET/POST variable parsing? std::map::iterator it; - if (protocol.size() < 5 || protocol[4] != '/'){ + if (protocol.size() < 5 || protocol[4] != '/') { protocol = "HTTP/1.0"; } builder = protocol + " " + code + " " + message + "\r\n"; conn.SendNow(builder); - for (it = headers.begin(); it != headers.end(); it++){ - if (( *it).first != "" && ( *it).second != ""){ - if (( *it).first != "Content-Length" || ( *it).second != "0"){ - builder = ( *it).first + ": " + ( *it).second + "\r\n"; + for (it = headers.begin(); it != headers.end(); it++) { + if ((*it).first != "" && (*it).second != "") { + if ((*it).first != "Content-Length" || (*it).second != "0") { + builder = (*it).first + ": " + (*it).second + "\r\n"; conn.SendNow(builder); } } @@ -126,12 +126,12 @@ void HTTP::Parser::SendResponse(std::string code, std::string message, Socket::C /// \param message The HTTP response message. Usually you want "OK". /// \param request The HTTP request to respond to. /// \param conn The connection to send over. -void HTTP::Parser::StartResponse(std::string code, std::string message, HTTP::Parser & request, Socket::Connection & conn){ +void HTTP::Parser::StartResponse(std::string code, std::string message, HTTP::Parser & request, Socket::Connection & conn) { protocol = request.protocol; body = ""; - if (protocol == "HTTP/1.1"){ + if (protocol == "HTTP/1.1") { SetHeader("Transfer-Encoding", "chunked"); - }else{ + } else { SetBody(""); } SendResponse(code, message, conn); @@ -143,7 +143,7 @@ void HTTP::Parser::StartResponse(std::string code, std::string message, HTTP::Pa /// This call simply calls StartResponse("200", "OK", request, conn) /// \param request The HTTP request to respond to. /// \param conn The connection to send over. -void HTTP::Parser::StartResponse(HTTP::Parser & request, Socket::Connection & conn){ +void HTTP::Parser::StartResponse(HTTP::Parser & request, Socket::Connection & conn) { StartResponse("200", "OK", request, conn); } @@ -152,29 +152,29 @@ void HTTP::Parser::StartResponse(HTTP::Parser & request, Socket::Connection & co /// - Retrieve all the body from the 'from' Socket::Connection. /// - Forward those contents as-is to the 'to' Socket::Connection. /// It blocks until completed or either of the connections reaches an error state. -void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to){ +void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to) { SendResponse(url, method, to); - if (getChunks){ + if (getChunks) { unsigned int proxyingChunk = 0; - while (to.connected() && from.connected()){ - if ((from.Received().size() && (from.Received().size() > 1 || *(from.Received().get().rbegin()) == '\n')) || from.spool()){ - if (proxyingChunk){ - while (proxyingChunk && from.Received().size()){ + while (to.connected() && from.connected()) { + if ((from.Received().size() && (from.Received().size() > 1 || *(from.Received().get().rbegin()) == '\n')) || from.spool()) { + if (proxyingChunk) { + while (proxyingChunk && from.Received().size()) { unsigned int toappend = from.Received().get().size(); - if (toappend > proxyingChunk){ + if (toappend > proxyingChunk) { toappend = proxyingChunk; to.SendNow(from.Received().get().c_str(), toappend); from.Received().get().erase(0, toappend); - }else{ + } else { to.SendNow(from.Received().get()); from.Received().get().clear(); } proxyingChunk -= toappend; } - }else{ + } else { //Make sure the received data ends in a newline (\n). - if ( *(from.Received().get().rbegin()) != '\n'){ - if (from.Received().size() > 1){ + if (*(from.Received().get().rbegin()) != '\n') { + if (from.Received().size() > 1) { //make a copy of the first part std::string tmp = from.Received().get(); //clear the first part, wiping it from the partlist @@ -182,26 +182,26 @@ void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to){ from.Received().size(); //take the now first (was second) part, insert the stored part in front of it from.Received().get().insert(0, tmp); - }else{ + } else { Util::sleep(100); } - if ( *(from.Received().get().rbegin()) != '\n'){ + if (*(from.Received().get().rbegin()) != '\n') { continue; } } //forward the size and any empty lines to.SendNow(from.Received().get()); - + std::string tmpA = from.Received().get().substr(0, from.Received().get().size() - 1); - while (tmpA.find('\r') != std::string::npos){ + while (tmpA.find('\r') != std::string::npos) { tmpA.erase(tmpA.find('\r')); } unsigned int chunkLen = 0; - if ( !tmpA.empty()){ - for (unsigned int i = 0; i < tmpA.size(); ++i){ + if (!tmpA.empty()) { + for (unsigned int i = 0; i < tmpA.size(); ++i) { chunkLen = (chunkLen << 4) | unhex(tmpA[i]); } - if (chunkLen == 0){ + if (chunkLen == 0) { getChunks = false; to.SendNow("\r\n", 2); return; @@ -210,24 +210,24 @@ void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to){ } from.Received().get().clear(); } - }else{ + } else { Util::sleep(100); } } - }else{ + } else { unsigned int bodyLen = length; - while (bodyLen > 0 && to.connected() && from.connected()){ - if (from.Received().size() || from.spool()){ - if (from.Received().get().size() <= bodyLen){ + while (bodyLen > 0 && to.connected() && from.connected()) { + if (from.Received().size() || from.spool()) { + if (from.Received().get().size() <= bodyLen) { to.SendNow(from.Received().get()); bodyLen -= from.Received().get().size(); from.Received().get().clear(); - }else{ + } else { to.SendNow(from.Received().get().c_str(), bodyLen); from.Received().get().erase(0, bodyLen); bodyLen = 0; } - }else{ + } else { Util::sleep(100); } } @@ -237,19 +237,19 @@ void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to){ /// Trims any whitespace at the front or back of the string. /// Used when getting/setting headers. /// \param s The string to trim. The string itself will be changed, not returned. -void HTTP::Parser::Trim(std::string & s){ +void HTTP::Parser::Trim(std::string & s) { size_t startpos = s.find_first_not_of(" \t"); size_t endpos = s.find_last_not_of(" \t"); - if ((std::string::npos == startpos) || (std::string::npos == endpos)){ + if ((std::string::npos == startpos) || (std::string::npos == endpos)) { s = ""; - }else{ + } else { s = s.substr(startpos, endpos - startpos + 1); } } /// Function that sets the body of a response or request, along with the correct Content-Length header. /// \param s The string to set the body to. -void HTTP::Parser::SetBody(std::string s){ +void HTTP::Parser::SetBody(std::string s) { body = s; SetHeader("Content-Length", s.length()); } @@ -257,39 +257,39 @@ void HTTP::Parser::SetBody(std::string s){ /// Function that sets the body of a response or request, along with the correct Content-Length header. /// \param buffer The buffer data to set the body to. /// \param len Length of the buffer data. -void HTTP::Parser::SetBody(char * buffer, int len){ +void HTTP::Parser::SetBody(char * buffer, int len) { body = ""; body.append(buffer, len); SetHeader("Content-Length", len); } /// Returns header i, if set. -std::string HTTP::Parser::getUrl(){ - if (url.find('?') != std::string::npos){ +std::string HTTP::Parser::getUrl() { + if (url.find('?') != std::string::npos) { return url.substr(0, url.find('?')); - }else{ + } else { return url; } } /// Returns header i, if set. -std::string HTTP::Parser::GetHeader(std::string i){ +std::string HTTP::Parser::GetHeader(std::string i) { return headers[i]; } /// Returns POST variable i, if set. -std::string HTTP::Parser::GetVar(std::string i){ +std::string HTTP::Parser::GetVar(std::string i) { return vars[i]; } /// Sets header i to string value v. -void HTTP::Parser::SetHeader(std::string i, std::string v){ +void HTTP::Parser::SetHeader(std::string i, std::string v) { Trim(i); Trim(v); headers[i] = v; } /// Sets header i to integer value v. -void HTTP::Parser::SetHeader(std::string i, int v){ +void HTTP::Parser::SetHeader(std::string i, int v) { Trim(i); char val[23]; //ints are never bigger than 22 chars as decimal sprintf(val, "%i", v); @@ -297,11 +297,11 @@ void HTTP::Parser::SetHeader(std::string i, int v){ } /// Sets POST variable i to string value v. -void HTTP::Parser::SetVar(std::string i, std::string v){ +void HTTP::Parser::SetVar(std::string i, std::string v) { Trim(i); Trim(v); //only set if there is actually a key - if ( !i.empty()){ + if (!i.empty()) { vars[i] = v; } } @@ -311,10 +311,10 @@ void HTTP::Parser::SetVar(std::string i, std::string v){ /// If not, as much as can be interpreted is removed and false returned. /// \param conn The socket to read from. /// \return True if a whole request or response was read, false otherwise. -bool HTTP::Parser::Read(Socket::Connection & conn){ +bool HTTP::Parser::Read(Socket::Connection & conn) { //Make sure the received data ends in a newline (\n). - while ((!seenHeaders || (getChunks && !doingChunk)) && *(conn.Received().get().rbegin()) != '\n'){ - if (conn.Received().size() > 1){ + while ((!seenHeaders || (getChunks && !doingChunk)) && *(conn.Received().get().rbegin()) != '\n') { + if (conn.Received().size() > 1) { //make a copy of the first part std::string tmp = conn.Received().get(); //clear the first part, wiping it from the partlist @@ -322,16 +322,16 @@ bool HTTP::Parser::Read(Socket::Connection & conn){ conn.Received().size(); //take the now first (was second) part, insert the stored part in front of it conn.Received().get().insert(0, tmp); - }else{ + } else { return false; } } //if a parse succeeds, simply return true - if (parse(conn.Received().get())){ + if (parse(conn.Received().get())) { return true; } //otherwise, if we have parts left, call ourselves recursively - if (conn.Received().size()){ + if (conn.Received().size()) { return Read(conn); } return false; @@ -342,7 +342,7 @@ bool HTTP::Parser::Read(Socket::Connection & conn){ /// If not, as much as can be interpreted is removed and false returned. /// \param strbuf The buffer to read from. /// \return True if a whole request or response was read, false otherwise. -bool HTTP::Parser::Read(std::string & strbuf){ +bool HTTP::Parser::Read(std::string & strbuf) { return parse(strbuf); } //HTTPReader::Read @@ -351,74 +351,74 @@ bool HTTP::Parser::Read(std::string & strbuf){ /// from the data buffer. /// \param HTTPbuffer The data buffer to read from. /// \return True on success, false otherwise. -bool HTTP::Parser::parse(std::string & HTTPbuffer){ +bool HTTP::Parser::parse(std::string & HTTPbuffer) { size_t f; std::string tmpA, tmpB, tmpC; /// \todo Make this not resize HTTPbuffer in parts, but read all at once and then remove the entire request, like doxygen claims it does? - while ( !HTTPbuffer.empty()){ - if ( !seenHeaders){ + while (!HTTPbuffer.empty()) { + if (!seenHeaders) { f = HTTPbuffer.find('\n'); if (f == std::string::npos) return false; tmpA = HTTPbuffer.substr(0, f); - if (f + 1 == HTTPbuffer.size()){ + if (f + 1 == HTTPbuffer.size()) { HTTPbuffer.clear(); - }else{ + } else { HTTPbuffer.erase(0, f + 1); } - while (tmpA.find('\r') != std::string::npos){ + while (tmpA.find('\r') != std::string::npos) { tmpA.erase(tmpA.find('\r')); } - if ( !seenReq){ + if (!seenReq) { seenReq = true; f = tmpA.find(' '); - if (f != std::string::npos){ - if (tmpA.substr(0, 4) == "HTTP"){ + if (f != std::string::npos) { + if (tmpA.substr(0, 4) == "HTTP") { protocol = tmpA.substr(0, f); tmpA.erase(0, f + 1); f = tmpA.find(' '); - if (f != std::string::npos){ + if (f != std::string::npos) { url = tmpA.substr(0, f); tmpA.erase(0, f + 1); method = tmpA; - if (url.find('?') != std::string::npos){ + if (url.find('?') != std::string::npos) { parseVars(url.substr(url.find('?') + 1)); //parse GET variables } - }else{ + } else { seenReq = false; } - }else{ + } else { method = tmpA.substr(0, f); tmpA.erase(0, f + 1); f = tmpA.find(' '); - if (f != std::string::npos){ + if (f != std::string::npos) { url = tmpA.substr(0, f); tmpA.erase(0, f + 1); protocol = tmpA; - if (url.find('?') != std::string::npos){ + if (url.find('?') != std::string::npos) { parseVars(url.substr(url.find('?') + 1)); //parse GET variables } - }else{ + } else { seenReq = false; } } - }else{ + } else { seenReq = false; } - }else{ - if (tmpA.size() == 0){ + } else { + if (tmpA.size() == 0) { seenHeaders = true; body.clear(); - if (GetHeader("Content-Length") != ""){ + if (GetHeader("Content-Length") != "") { length = atoi(GetHeader("Content-Length").c_str()); - if (body.capacity() < length){ + if (body.capacity() < length) { body.reserve(length); } } - if (GetHeader("Transfer-Encoding") == "chunked"){ + if (GetHeader("Transfer-Encoding") == "chunked") { getChunks = true; doingChunk = 0; } - }else{ + } else { f = tmpA.find(':'); if (f == std::string::npos) continue; tmpB = tmpA.substr(0, f); @@ -427,61 +427,61 @@ bool HTTP::Parser::parse(std::string & HTTPbuffer){ } } } - if (seenHeaders){ - if (length > 0){ - if (headerOnly){ + if (seenHeaders) { + if (length > 0) { + if (headerOnly) { return true; } unsigned int toappend = length - body.length(); - if (toappend > 0){ + if (toappend > 0) { body.append(HTTPbuffer, 0, toappend); HTTPbuffer.erase(0, toappend); } - if (length == body.length()){ + if (length == body.length()) { parseVars(body); //parse POST variables return true; - }else{ + } else { return false; } - }else{ - if (getChunks){ - if (headerOnly){ + } else { + if (getChunks) { + if (headerOnly) { return true; } - if (doingChunk){ + if (doingChunk) { unsigned int toappend = HTTPbuffer.size(); - if (toappend > doingChunk){ + if (toappend > doingChunk) { toappend = doingChunk; } body.append(HTTPbuffer, 0, toappend); HTTPbuffer.erase(0, toappend); doingChunk -= toappend; - }else{ + } else { f = HTTPbuffer.find('\n'); if (f == std::string::npos) return false; tmpA = HTTPbuffer.substr(0, f); - while (tmpA.find('\r') != std::string::npos){ + while (tmpA.find('\r') != std::string::npos) { tmpA.erase(tmpA.find('\r')); } unsigned int chunkLen = 0; - if ( !tmpA.empty()){ - for (unsigned int i = 0; i < tmpA.size(); ++i){ + if (!tmpA.empty()) { + for (unsigned int i = 0; i < tmpA.size(); ++i) { chunkLen = (chunkLen << 4) | unhex(tmpA[i]); } - if (chunkLen == 0){ + if (chunkLen == 0) { getChunks = false; return true; } doingChunk = chunkLen; } - if (f + 1 == HTTPbuffer.size()){ + if (f + 1 == HTTPbuffer.size()) { HTTPbuffer.clear(); - }else{ + } else { HTTPbuffer.erase(0, f + 1); } } return false; - }else{ + } else { return true; } } @@ -492,28 +492,28 @@ bool HTTP::Parser::parse(std::string & HTTPbuffer){ /// Parses GET or POST-style variable data. /// Saves to internal variable structure using HTTP::Parser::SetVar. -void HTTP::Parser::parseVars(std::string data){ +void HTTP::Parser::parseVars(std::string data) { std::string varname; std::string varval; // position where a part start (e.g. after &) size_t pos = 0; - while (pos < data.length()){ + while (pos < data.length()) { size_t nextpos = data.find('&', pos); - if (nextpos == std::string::npos){ + if (nextpos == std::string::npos) { nextpos = data.length(); } size_t eq_pos = data.find('=', pos); - if (eq_pos < nextpos){ + if (eq_pos < nextpos) { // there is a key and value varname = data.substr(pos, eq_pos - pos); varval = data.substr(eq_pos + 1, nextpos - eq_pos - 1); - }else{ + } else { // no value, only a key varname = data.substr(pos, nextpos - pos); varval.clear(); } SetVar(urlunescape(varname), urlunescape(varval)); - if (nextpos == std::string::npos){ + if (nextpos == std::string::npos) { // in case the string is gigantic break; } @@ -525,7 +525,7 @@ void HTTP::Parser::parseVars(std::string data){ /// Sends a string in chunked format if protocol is HTTP/1.1, sends as-is otherwise. /// \param bodypart The data to send. /// \param conn The connection to use for sending. -void HTTP::Parser::Chunkify(std::string & bodypart, Socket::Connection & conn){ +void HTTP::Parser::Chunkify(std::string & bodypart, Socket::Connection & conn) { Chunkify(bodypart.c_str(), bodypart.size(), conn); } @@ -533,8 +533,8 @@ void HTTP::Parser::Chunkify(std::string & bodypart, Socket::Connection & conn){ /// \param data The data to send. /// \param size The size of the data to send. /// \param conn The connection to use for sending. -void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connection & conn){ - if (protocol == "HTTP/1.1"){ +void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connection & conn) { + if (protocol == "HTTP/1.1") { char len[10]; int sizelen = snprintf(len, 10, "%x\r\n", size); //prepend the chunk size and \r\n @@ -543,39 +543,39 @@ void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connec conn.SendNow(data, size); //append \r\n conn.SendNow("\r\n", 2); - if ( !size){ + if (!size) { //append \r\n again if this was the end of the file (required by chunked transfer encoding according to spec) conn.SendNow("\r\n", 2); } - }else{ + } else { //just send the chunk itself conn.SendNow(data, size); //close the connection if this was the end of the file - if ( !size){ + if (!size) { conn.close(); } } } /// Unescapes URLencoded std::string data. -std::string HTTP::Parser::urlunescape(const std::string & in){ +std::string HTTP::Parser::urlunescape(const std::string & in) { std::string out; - for (unsigned int i = 0; i < in.length(); ++i){ - if (in[i] == '%'){ + for (unsigned int i = 0; i < in.length(); ++i) { + if (in[i] == '%') { char tmp = 0; ++i; - if (i < in.length()){ + if (i < in.length()) { tmp = unhex(in[i]) << 4; } ++i; - if (i < in.length()){ + if (i < in.length()) { tmp += unhex(in[i]); } out += tmp; - }else{ - if (in[i] == '+'){ + } else { + if (in[i] == '+') { out += ' '; - }else{ + } else { out += in[i]; } } @@ -585,19 +585,19 @@ std::string HTTP::Parser::urlunescape(const std::string & in){ /// Helper function for urlunescape. /// Takes a single char input and outputs its integer hex value. -int HTTP::Parser::unhex(char c){ +int HTTP::Parser::unhex(char c) { return (c >= '0' && c <= '9' ? c - '0' : c >= 'A' && c <= 'F' ? c - 'A' + 10 : c - 'a' + 10); } /// URLencodes std::string data. -std::string HTTP::Parser::urlencode(const std::string &c){ +std::string HTTP::Parser::urlencode(const std::string & c) { std::string escaped = ""; int max = c.length(); - for (int i = 0; i < max; i++){ + for (int i = 0; i < max; i++) { if (('0' <= c[i] && c[i] <= '9') || ('a' <= c[i] && c[i] <= 'z') || ('A' <= c[i] && c[i] <= 'Z') - || (c[i] == '~' || c[i] == '!' || c[i] == '*' || c[i] == '(' || c[i] == ')' || c[i] == '\'')){ - escaped.append( &c[i], 1); - }else{ + || (c[i] == '~' || c[i] == '!' || c[i] == '*' || c[i] == '(' || c[i] == ')' || c[i] == '\'')) { + escaped.append(&c[i], 1); + } else { escaped.append("%"); escaped.append(hex(c[i])); } @@ -607,7 +607,7 @@ std::string HTTP::Parser::urlencode(const std::string &c){ /// Helper function for urlescape. /// Encodes a character as two hex digits. -std::string HTTP::Parser::hex(char dec){ +std::string HTTP::Parser::hex(char dec) { char dig1 = (dec & 0xF0) >> 4; char dig2 = (dec & 0x0F); if (dig1 <= 9) dig1 += 48; @@ -615,7 +615,7 @@ std::string HTTP::Parser::hex(char dec){ if (dig2 <= 9) dig2 += 48; if (10 <= dig2 && dig2 <= 15) dig2 += 97 - 10; std::string r; - r.append( &dig1, 1); - r.append( &dig2, 1); + r.append(&dig1, 1); + r.append(&dig2, 1); return r; } diff --git a/lib/http_parser.h b/lib/http_parser.h index 35fdfee8..4ba5ad97 100644 --- a/lib/http_parser.h +++ b/lib/http_parser.h @@ -11,7 +11,7 @@ /// Holds all HTTP processing related code. namespace HTTP { /// Simple class for reading and writing HTTP 1.0 and 1.1. - class Parser{ + class Parser { public: Parser(); bool Read(Socket::Connection & conn); diff --git a/lib/json.cpp b/lib/json.cpp index 190dce70..68139a47 100644 --- a/lib/json.cpp +++ b/lib/json.cpp @@ -9,31 +9,35 @@ #include //for memcpy #include //for htonl -static inline char c2hex(char c){ +static inline char c2hex(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return 0; } -static inline char hex2c(char c){ - if (c < 10){return '0' + c;} - if (c < 16){return 'A' + (c - 10);} +static inline char hex2c(char c) { + if (c < 10) { + return '0' + c; + } + if (c < 16) { + return 'A' + (c - 10); + } return '0'; } -static std::string read_string(int separator, std::istream & fromstream){ +static std::string read_string(int separator, std::istream & fromstream) { std::string out; bool escaped = false; - while (fromstream.good()){ + while (fromstream.good()) { char c; fromstream.get(c); - if (c == '\\'){ + if (c == '\\') { escaped = true; continue; } - if (escaped){ - switch (c){ + if (escaped) { + switch (c) { case 'b': out += '\b'; break; @@ -50,25 +54,25 @@ static std::string read_string(int separator, std::istream & fromstream){ out += '\t'; break; case 'u': { - char d1, d2, d3, d4; - fromstream.get(d1); - fromstream.get(d2); - fromstream.get(d3); - fromstream.get(d4); - out.append(1, (c2hex(d4) + (c2hex(d3) << 4))); - //We ignore the upper two characters. - // + (c2hex(d2) << 8) + (c2hex(d1) << 16) - break; - } + char d1, d2, d3, d4; + fromstream.get(d1); + fromstream.get(d2); + fromstream.get(d3); + fromstream.get(d4); + out.append(1, (c2hex(d4) + (c2hex(d3) << 4))); + //We ignore the upper two characters. + // + (c2hex(d2) << 8) + (c2hex(d1) << 16) + break; + } default: out.append(1, c); break; } escaped = false; - }else{ - if (c == separator){ + } else { + if (c == separator) { return out; - }else{ + } else { out.append(1, c); } } @@ -76,10 +80,10 @@ static std::string read_string(int separator, std::istream & fromstream){ return out; } -static std::string string_escape(const std::string val){ +static std::string string_escape(const std::string val) { std::string out = "\""; - for (unsigned int i = 0; i < val.size(); ++i){ - switch (val.data()[i]){ + for (unsigned int i = 0; i < val.size(); ++i) { + switch (val.data()[i]) { case '"': out += "\\\""; break; @@ -102,11 +106,11 @@ static std::string string_escape(const std::string val){ out += "\\t"; break; default: - if (val.data()[i] < 32 || val.data()[i] > 126){ + if (val.data()[i] < 32 || val.data()[i] > 126) { out += "\\u00"; out += hex2c((val.data()[i] >> 4) & 0xf); out += hex2c(val.data()[i] & 0xf); - }else{ + } else { out += val.data()[i]; } break; @@ -117,16 +121,16 @@ static std::string string_escape(const std::string val){ } /// Skips an std::istream forward until any of the following characters is seen: ,]} -static void skipToEnd(std::istream & fromstream){ - while (fromstream.good()){ +static void skipToEnd(std::istream & fromstream) { + while (fromstream.good()) { char peek = fromstream.peek(); - if (peek == ','){ + if (peek == ',') { return; } - if (peek == ']'){ + if (peek == ']') { return; } - if (peek == '}'){ + if (peek == '}') { return; } peek = fromstream.get(); @@ -134,45 +138,45 @@ static void skipToEnd(std::istream & fromstream){ } /// Sets this JSON::Value to null; -JSON::Value::Value(){ +JSON::Value::Value() { null(); } /// Sets this JSON::Value to read from this position in the std::istream -JSON::Value::Value(std::istream & fromstream){ +JSON::Value::Value(std::istream & fromstream) { null(); bool reading_object = false; bool reading_array = false; bool negative = false; bool stop = false; - while (!stop && fromstream.good()){ + while (!stop && fromstream.good()) { int c = fromstream.peek(); - switch (c){ + switch (c) { case '{': reading_object = true; c = fromstream.get(); myType = OBJECT; break; case '[': { - reading_array = true; - c = fromstream.get(); - myType = ARRAY; - Value tmp = JSON::Value(fromstream); - if (tmp.myType != EMPTY){ - append(tmp); + reading_array = true; + c = fromstream.get(); + myType = ARRAY; + Value tmp = JSON::Value(fromstream); + if (tmp.myType != EMPTY) { + append(tmp); + } + break; } - break; - } case '\'': case '"': c = fromstream.get(); - if ( !reading_object){ + if (!reading_object) { myType = STRING; strVal = read_string(c, fromstream); stop = true; - }else{ + } else { std::string tmpstr = read_string(c, fromstream); - ( *this)[tmpstr] = JSON::Value(fromstream); + (*this)[tmpstr] = JSON::Value(fromstream); } break; case '-': @@ -195,23 +199,23 @@ JSON::Value::Value(std::istream & fromstream){ intVal += c - '0'; break; case ',': - if ( !reading_object && !reading_array){ + if (!reading_object && !reading_array) { stop = true; break; } c = fromstream.get(); - if (reading_array){ + if (reading_array) { append(JSON::Value(fromstream)); } break; case '}': - if (reading_object){ + if (reading_object) { c = fromstream.get(); } stop = true; break; case ']': - if (reading_array){ + if (reading_array) { c = fromstream.get(); } stop = true; @@ -242,60 +246,60 @@ JSON::Value::Value(std::istream & fromstream){ break; } } - if (negative){ + if (negative) { intVal *= -1; } } /// Sets this JSON::Value to the given string. -JSON::Value::Value(const std::string & val){ +JSON::Value::Value(const std::string & val) { myType = STRING; strVal = val; intVal = 0; } /// Sets this JSON::Value to the given string. -JSON::Value::Value(const char * val){ +JSON::Value::Value(const char * val) { myType = STRING; strVal = val; intVal = 0; } /// Sets this JSON::Value to the given integer. -JSON::Value::Value(long long int val){ +JSON::Value::Value(long long int val) { myType = INTEGER; intVal = val; } /// Compares a JSON::Value to another for equality. -bool JSON::Value::operator==(const JSON::Value & rhs) const{ +bool JSON::Value::operator==(const JSON::Value & rhs) const { if (myType != rhs.myType) return false; - if (myType == INTEGER || myType == BOOL){ + if (myType == INTEGER || myType == BOOL) { return intVal == rhs.intVal; } - if (myType == STRING){ + if (myType == STRING) { return strVal == rhs.strVal; } - if (myType == EMPTY){ + if (myType == EMPTY) { return true; } - if (myType == OBJECT){ + if (myType == OBJECT) { if (objVal.size() != rhs.objVal.size()) return false; - for (std::map::const_iterator it = objVal.begin(); it != objVal.end(); ++it){ - if ( !rhs.isMember(it->first)){ + for (std::map::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; } } return true; } - if (myType == ARRAY){ + if (myType == ARRAY) { if (arrVal.size() != rhs.arrVal.size()) return false; int i = 0; - for (std::deque::const_iterator it = arrVal.begin(); it != arrVal.end(); ++it){ - if ( *it != rhs.arrVal[i]){ + for (std::deque::const_iterator it = arrVal.begin(); it != arrVal.end(); ++it) { + if (*it != rhs.arrVal[i]) { return false; } i++; @@ -306,12 +310,12 @@ bool JSON::Value::operator==(const JSON::Value & rhs) const{ } /// Compares a JSON::Value to another for equality. -bool JSON::Value::operator!=(const JSON::Value & rhs) const{ - return !(( *this) == rhs); +bool JSON::Value::operator!=(const JSON::Value & rhs) const { + return !((*this) == rhs); } /// Sets this JSON::Value to the given boolean. -JSON::Value & JSON::Value::operator=(const bool &rhs){ +JSON::Value & JSON::Value::operator=(const bool & rhs) { null(); myType = BOOL; if (rhs) intVal = 1; @@ -319,7 +323,7 @@ JSON::Value & JSON::Value::operator=(const bool &rhs){ } /// Sets this JSON::Value to the given string. -JSON::Value & JSON::Value::operator=(const std::string &rhs){ +JSON::Value & JSON::Value::operator=(const std::string & rhs) { null(); myType = STRING; strVal = rhs; @@ -327,12 +331,12 @@ JSON::Value & JSON::Value::operator=(const std::string &rhs){ } /// Sets this JSON::Value to the given string. -JSON::Value & JSON::Value::operator=(const char * rhs){ - return (( *this) = (std::string)rhs); +JSON::Value & JSON::Value::operator=(const char * rhs) { + return ((*this) = (std::string)rhs); } /// Sets this JSON::Value to the given integer. -JSON::Value & JSON::Value::operator=(const long long int &rhs){ +JSON::Value & JSON::Value::operator=(const long long int & rhs) { null(); myType = INTEGER; intVal = rhs; @@ -340,21 +344,21 @@ JSON::Value & JSON::Value::operator=(const long long int &rhs){ } /// Sets this JSON::Value to the given integer. -JSON::Value & JSON::Value::operator=(const int &rhs){ - return (( *this) = (long long int)rhs); +JSON::Value & JSON::Value::operator=(const int & rhs) { + return ((*this) = (long long int)rhs); } /// Sets this JSON::Value to the given integer. -JSON::Value & JSON::Value::operator=(const unsigned int &rhs){ - return (( *this) = (long long int)rhs); +JSON::Value & JSON::Value::operator=(const unsigned int & rhs) { + return ((*this) = (long long int)rhs); } /// Automatic conversion to long long int - returns 0 if not convertable. -JSON::Value::operator long long int() const{ - if (myType == INTEGER){ +JSON::Value::operator long long int() const { + if (myType == INTEGER) { return intVal; } - if (myType == STRING){ + if (myType == STRING) { return atoll(strVal.c_str()); } return 0; @@ -362,13 +366,13 @@ JSON::Value::operator long long int() const{ /// Automatic conversion to std::string. /// Returns the raw string value if available, otherwise calls toString(). -JSON::Value::operator std::string() const{ - if (myType == STRING){ +JSON::Value::operator std::string() const { + if (myType == STRING) { return strVal; - }else{ - if (myType == EMPTY){ + } else { + if (myType == EMPTY) { return ""; - }else{ + } else { return toString(); } } @@ -376,48 +380,48 @@ JSON::Value::operator std::string() const{ /// Automatic conversion to bool. /// Returns true if there is anything meaningful stored into this value. -JSON::Value::operator bool() const{ - if (myType == STRING){ +JSON::Value::operator bool() const { + if (myType == STRING) { return strVal != ""; } - if (myType == INTEGER){ + if (myType == INTEGER) { return intVal != 0; } - if (myType == BOOL){ + if (myType == BOOL) { return intVal != 0; } - if (myType == OBJECT){ + if (myType == OBJECT) { return size() > 0; } - if (myType == ARRAY){ + if (myType == ARRAY) { return size() > 0; } - if (myType == EMPTY){ + if (myType == EMPTY) { return false; } return false; //unimplemented? should never happen... } /// Explicit conversion to std::string. -const std::string JSON::Value::asString() const{ - return (std::string) *this; +const std::string JSON::Value::asString() const { + return (std::string) * this; } /// Explicit conversion to long long int. -const long long int JSON::Value::asInt() const{ - return (long long int) *this; +const long long int JSON::Value::asInt() const { + return (long long int) * this; } /// Explicit conversion to bool. -const bool JSON::Value::asBool() const{ - return (bool) *this; +const bool JSON::Value::asBool() const { + return (bool) * this; } /// Explicit conversion to std::string reference. /// Returns a direct reference for string type JSON::Value objects, /// but a reference to a static empty string otherwise. /// \warning Only save to use when the JSON::Value is a string type! -const std::string & JSON::Value::asStringRef() const{ +const std::string & JSON::Value::asStringRef() const { static std::string ugly_buffer; - if (myType == STRING){ + if (myType == STRING) { return strVal; } return ugly_buffer; @@ -427,8 +431,8 @@ const std::string & JSON::Value::asStringRef() const{ /// Returns a direct reference for string type JSON::Value objects, /// a reference to an empty string otherwise. /// \warning Only save to use when the JSON::Value is a string type! -const char * JSON::Value::c_str() const{ - if (myType == STRING){ +const char * JSON::Value::c_str() const { + if (myType == STRING) { return strVal.c_str(); } return ""; @@ -436,8 +440,8 @@ const char * JSON::Value::c_str() const{ /// Retrieves or sets the JSON::Value at this position in the object. /// Converts destructively to object if not already an object. -JSON::Value & JSON::Value::operator[](const std::string i){ - if (myType != OBJECT){ +JSON::Value & JSON::Value::operator[](const std::string i) { + if (myType != OBJECT) { null(); myType = OBJECT; } @@ -446,8 +450,8 @@ JSON::Value & JSON::Value::operator[](const std::string i){ /// Retrieves or sets the JSON::Value at this position in the object. /// Converts destructively to object if not already an object. -JSON::Value & JSON::Value::operator[](const char * i){ - if (myType != OBJECT){ +JSON::Value & JSON::Value::operator[](const char * i) { + if (myType != OBJECT) { null(); myType = OBJECT; } @@ -456,12 +460,12 @@ JSON::Value & JSON::Value::operator[](const char * i){ /// Retrieves or sets the JSON::Value at this position in the array. /// Converts destructively to array if not already an array. -JSON::Value & JSON::Value::operator[](unsigned int i){ - if (myType != ARRAY){ +JSON::Value & JSON::Value::operator[](unsigned int i) { + if (myType != ARRAY) { null(); myType = ARRAY; } - while (i >= arrVal.size()){ + while (i >= arrVal.size()) { append(JSON::Value()); } return arrVal[i]; @@ -469,40 +473,40 @@ JSON::Value & JSON::Value::operator[](unsigned int 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{ +const JSON::Value & JSON::Value::operator[](const std::string i) const { 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{ +const JSON::Value & JSON::Value::operator[](const char * i) const { 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{ +const JSON::Value & JSON::Value::operator[](unsigned int i) const { return arrVal[i]; } /// Packs to a std::string for transfer over the network. /// If the object is a container type, this function will call itself recursively and contain all contents. /// As a side effect, this function clear the internal buffer of any object-types. -std::string JSON::Value::toPacked() const{ +std::string JSON::Value::toPacked() const { std::string r; - if (isInt() || isNull() || isBool()){ + if (isInt() || isNull() || isBool()) { r += 0x01; uint64_t numval = intVal; - r += *(((char*) &numval) + 7); - r += *(((char*) &numval) + 6); - r += *(((char*) &numval) + 5); - r += *(((char*) &numval) + 4); - r += *(((char*) &numval) + 3); - r += *(((char*) &numval) + 2); - r += *(((char*) &numval) + 1); - r += *(((char*) &numval)); + r += *(((char *) &numval) + 7); + r += *(((char *) &numval) + 6); + r += *(((char *) &numval) + 5); + r += *(((char *) &numval) + 4); + r += *(((char *) &numval) + 3); + r += *(((char *) &numval) + 2); + r += *(((char *) &numval) + 1); + r += *(((char *) &numval)); } - if (isString()){ + if (isString()) { r += 0x02; r += strVal.size() / (256 * 256 * 256); r += strVal.size() / (256 * 256); @@ -510,11 +514,11 @@ std::string JSON::Value::toPacked() const{ r += strVal.size() % 256; r += strVal; } - if (isObject()){ + if (isObject()) { r += 0xE0; - if (objVal.size() > 0){ - for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++){ - if (it->first.size() > 0){ + 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; @@ -526,9 +530,9 @@ std::string JSON::Value::toPacked() const{ r += (char)0x0; r += (char)0xEE; } - if (isArray()){ + if (isArray()) { r += 0x0A; - for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++){ + for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) { r += it->toPacked(); } r += (char)0x0; @@ -541,47 +545,47 @@ std::string JSON::Value::toPacked() const{ /// Packs and transfers over the network. /// If the object is a container type, this function will call itself recursively for all contents. -void JSON::Value::sendTo(Socket::Connection & socket) const{ - if (isInt() || isNull() || isBool()){ +void JSON::Value::sendTo(Socket::Connection & socket) const { + if (isInt() || isNull() || isBool()) { socket.SendNow("\001", 1); int tmpHalf = htonl((int)(intVal >> 32)); - socket.SendNow((char*)&tmpHalf, 4); + socket.SendNow((char *)&tmpHalf, 4); tmpHalf = htonl((int)(intVal & 0xFFFFFFFF)); - socket.SendNow((char*)&tmpHalf, 4); + socket.SendNow((char *)&tmpHalf, 4); return; } - if (isString()){ + if (isString()) { socket.SendNow("\002", 1); int tmpVal = htonl((int)strVal.size()); - socket.SendNow((char*)&tmpVal, 4); + socket.SendNow((char *)&tmpVal, 4); socket.SendNow(strVal); return; } - if (isObject()){ - if (isMember("trackid") && isMember("time")){ + 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 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(); + 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(); } } } socket.SendNow("DTP2", 4); size = htonl(size); - socket.SendNow((char*)&size, 4); + socket.SendNow((char *)&size, 4); trackid = htonl(trackid); - socket.SendNow((char*)&trackid, 4); + socket.SendNow((char *)&trackid, 4); int tmpHalf = htonl((int)(time >> 32)); - socket.SendNow((char*)&tmpHalf, 4); + socket.SendNow((char *)&tmpHalf, 4); tmpHalf = htonl((int)(time & 0xFFFFFFFF)); - socket.SendNow((char*)&tmpHalf, 4); + 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"){ + 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") { char sizebuffer[2] = {0, 0}; sizebuffer[0] = (it->first.size() >> 8) & 0xFF; sizebuffer[1] = it->first.size() & 0xFF; @@ -594,15 +598,15 @@ void JSON::Value::sendTo(Socket::Connection & socket) const{ socket.SendNow("\000\000\356", 3); return; } - if (isMember("tracks")){ + if (isMember("tracks")) { socket.SendNow("DTSC", 4); unsigned int size = htonl(packedSize()); - socket.SendNow((char*)&size, 4); + socket.SendNow((char *)&size, 4); } socket.SendNow("\340", 1); - if (objVal.size() > 0){ - for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++){ - if (it->first.size() > 0){ + if (objVal.size() > 0) { + for (JSON::ObjConstIter it = objVal.begin(); it != objVal.end(); it++) { + if (it->first.size() > 0) { char sizebuffer[2] = {0, 0}; sizebuffer[0] = (it->first.size() >> 8) & 0xFF; sizebuffer[1] = it->first.size() & 0xFF; @@ -615,9 +619,9 @@ void JSON::Value::sendTo(Socket::Connection & socket) const{ socket.SendNow("\000\000\356", 3); return; } - if (isArray()){ + if (isArray()) { socket.SendNow("\012", 1); - for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++){ + for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) { it->sendTo(socket); } socket.SendNow("\000\000\356", 3); @@ -626,27 +630,27 @@ void JSON::Value::sendTo(Socket::Connection & socket) const{ }//sendTo /// Returns the packed size of this Value. -unsigned int JSON::Value::packedSize() const{ - if (isInt() || isNull() || isBool()){ +unsigned int JSON::Value::packedSize() const { + if (isInt() || isNull() || isBool()) { return 9; } - if (isString()){ + if (isString()) { return 5 + strVal.size(); } - if (isObject()){ + 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(); + 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(); } } } return ret; } - if (isArray()){ + if (isArray()) { unsigned int ret = 4; - for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++){ + for (JSON::ArrConstIter it = arrVal.begin(); it != arrVal.end(); it++) { ret += it->packedSize(); } return ret; @@ -657,8 +661,8 @@ unsigned int JSON::Value::packedSize() const{ /// Pre-packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header. /// Non-object-types will print an error. /// The internal buffer is guaranteed to be up-to-date after this function is called. -void JSON::Value::netPrepare(){ - if (myType != OBJECT){ +void JSON::Value::netPrepare() { + if (myType != OBJECT) { DEBUG_MSG(DLVL_ERROR, "Only objects may be netpacked!"); return; } @@ -667,27 +671,27 @@ void JSON::Value::netPrepare(){ int packID = -1; long long unsigned int time = objVal["time"].asInt(); std::string dataType; - if (isMember("datatype") || isMember("trackid")){ + if (isMember("datatype") || isMember("trackid")) { dataType = objVal["datatype"].asString(); - if (isMember("trackid")){ + if (isMember("trackid")) { packID = objVal["trackid"].asInt(); - }else{ - if (objVal["datatype"].asString() == "video"){ + } else { + if (objVal["datatype"].asString() == "video") { packID = 1; } - if (objVal["datatype"].asString() == "audio"){ + if (objVal["datatype"].asString() == "audio") { packID = 2; } - if (objVal["datatype"].asString() == "meta"){ + if (objVal["datatype"].asString() == "meta") { packID = 3; } //endmark and the likes... - if (packID == -1){ + if (packID == -1) { packID = 0; } } removeMember("time"); - if (packID != 0){ + if (packID != 0) { removeMember("datatype"); } removeMember("trackid"); @@ -696,31 +700,31 @@ void JSON::Value::netPrepare(){ objVal["datatype"] = dataType; objVal["trackid"] = packID; strVal.resize(packed.size() + 20); - memcpy((void*)strVal.c_str(), "DTP2", 4); - }else{ + memcpy((void *)strVal.c_str(), "DTP2", 4); + } else { packID = -1; strVal.resize(packed.size() + 8); - memcpy((void*)strVal.c_str(), "DTSC", 4); + memcpy((void *)strVal.c_str(), "DTSC", 4); } //insert the packet length at bytes 4-7 unsigned int size = packed.size(); - if (packID != -1){ + if (packID != -1) { size += 12; } size = htonl(size); - memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4); + memcpy((void *)(strVal.c_str() + 4), (void *) &size, 4); //copy the rest of the string - if (packID == -1){ - memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size()); + if (packID == -1) { + memcpy((void *)(strVal.c_str() + 8), packed.c_str(), packed.size()); return; } packID = htonl(packID); - memcpy((void*)(strVal.c_str() + 8), (void*) &packID, 4); + memcpy((void *)(strVal.c_str() + 8), (void *) &packID, 4); int tmpHalf = htonl((int)(time >> 32)); - memcpy((void*)(strVal.c_str() + 12), (void*) &tmpHalf, 4); + memcpy((void *)(strVal.c_str() + 12), (void *) &tmpHalf, 4); tmpHalf = htonl((int)(time & 0xFFFFFFFF)); - memcpy((void*)(strVal.c_str() + 16), (void*) &tmpHalf, 4); - memcpy((void*)(strVal.c_str() + 20), packed.c_str(), packed.size()); + memcpy((void *)(strVal.c_str() + 16), (void *) &tmpHalf, 4); + memcpy((void *)(strVal.c_str() + 20), packed.c_str(), packed.size()); } /// Packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header. @@ -728,15 +732,15 @@ void JSON::Value::netPrepare(){ /// This function returns a reference to an internal buffer where the prepared data is kept. /// The internal buffer is *not* made stale if any changes occur inside the object - subsequent calls to toPacked() will clear the buffer, /// calls to netPrepare will guarantee it is up-to-date. -std::string & JSON::Value::toNetPacked(){ +std::string & JSON::Value::toNetPacked() { static std::string emptystring; //check if this is legal - if (myType != OBJECT){ + if (myType != OBJECT) { INFO_MSG("Ignored attempt to netpack a non-object."); return emptystring; } //if sneaky storage doesn't contain correct data, re-calculate it - if (strVal.size() == 0 || strVal[0] != 'D' || strVal[1] != 'T'){ + if (strVal.size() == 0 || strVal[0] != 'D' || strVal[1] != 'T') { netPrepare(); } return strVal; @@ -744,49 +748,49 @@ std::string & JSON::Value::toNetPacked(){ /// Converts this JSON::Value to valid JSON notation and returns it. /// Makes absolutely no attempts to pretty-print anything. :-) -std::string JSON::Value::toString() const{ - switch (myType){ +std::string JSON::Value::toString() const { + switch (myType) { case INTEGER: { - std::stringstream st; - st << intVal; - return st.str(); - break; - } + std::stringstream st; + st << intVal; + return st.str(); + break; + } case STRING: { - return string_escape(strVal); - break; - } + return string_escape(strVal); + break; + } case ARRAY: { - std::string tmp = "["; - if (arrVal.size() > 0){ - for (ArrConstIter it = ArrBegin(); it != ArrEnd(); it++){ - tmp += it->toString(); - if (it + 1 != ArrEnd()){ - tmp += ","; + std::string tmp = "["; + if (arrVal.size() > 0) { + for (ArrConstIter it = ArrBegin(); it != ArrEnd(); it++) { + tmp += it->toString(); + if (it + 1 != ArrEnd()) { + tmp += ","; + } } } + tmp += "]"; + return tmp; + break; } - tmp += "]"; - return tmp; - break; - } 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){ - tmp2 += ","; + 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) { + tmp2 += ","; + } } } + tmp2 += "}"; + return tmp2; + break; } - tmp2 += "}"; - return tmp2; - break; - } case EMPTY: default: return "null"; @@ -796,62 +800,62 @@ std::string JSON::Value::toString() const{ /// Converts this JSON::Value to valid JSON notation and returns it. /// Makes an attempt at pretty-printing. -std::string JSON::Value::toPrettyString(int indentation) const{ - switch (myType){ +std::string JSON::Value::toPrettyString(int indentation) const { + switch (myType) { case INTEGER: { - std::stringstream st; - st << intVal; - return st.str(); - break; - } + std::stringstream st; + st << intVal; + return st.str(); + break; + } case STRING: { - for (unsigned int i = 0; i < 201 && i < strVal.size(); ++i){ - if (strVal[i] < 32 || strVal[i] > 126 || strVal.size() > 200){ - return "\""+JSON::Value((long long int)strVal.size()).asString() + " bytes of data\""; + for (unsigned int i = 0; i < 201 && i < strVal.size(); ++i) { + if (strVal[i] < 32 || strVal[i] > 126 || strVal.size() > 200) { + return "\"" + JSON::Value((long long int)strVal.size()).asString() + " bytes of data\""; + } } + return string_escape(strVal); + break; } - return string_escape(strVal); - break; - } 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()){ - tmp += ", "; + 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()) { + tmp += ", "; + } } + tmp += "\n" + std::string(indentation, ' ') + "]"; + return tmp; + } else { + return "[]"; } - tmp += "\n" + std::string(indentation, ' ') + "]"; - return tmp; - }else{ - return "[]"; + break; } - break; - } case OBJECT: { - if (objVal.size() > 0){ - bool shortMode = false; - if (size() <= 3 && isMember("len")){ - 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){ - tmp2 += "," + std::string((shortMode ? " " : "\n")); + if (objVal.size() > 0) { + bool shortMode = false; + if (size() <= 3 && isMember("len")) { + 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) { + tmp2 += "," + std::string((shortMode ? " " : "\n")); + } + } + tmp2 += (shortMode ? std::string("") : "\n" + std::string(indentation, ' ')) + "}"; + return tmp2; + } else { + return "{}"; } - tmp2 += (shortMode ? std::string("") : "\n" + std::string(indentation, ' ')) + "}"; - return tmp2; - }else{ - return "{}"; + break; } - break; - } case EMPTY: default: return "null"; @@ -861,8 +865,8 @@ std::string JSON::Value::toPrettyString(int indentation) const{ /// Appends the given value to the end of this JSON::Value array. /// Turns this value into an array if it is not already one. -void JSON::Value::append(const JSON::Value & rhs){ - if (myType != ARRAY){ +void JSON::Value::append(const JSON::Value & rhs) { + if (myType != ARRAY) { null(); myType = ARRAY; } @@ -871,8 +875,8 @@ void JSON::Value::append(const JSON::Value & rhs){ /// Prepends the given value to the beginning of this JSON::Value array. /// Turns this value into an array if it is not already one. -void JSON::Value::prepend(const JSON::Value & rhs){ - if (myType != ARRAY){ +void JSON::Value::prepend(const JSON::Value & rhs) { + if (myType != ARRAY) { null(); myType = ARRAY; } @@ -885,15 +889,15 @@ void JSON::Value::prepend(const JSON::Value & rhs){ /// Does nothing for other JSON::Value types, nor does it /// 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){ +void JSON::Value::shrink(unsigned int size) { + if (myType == ARRAY) { + while (arrVal.size() > size) { arrVal.pop_front(); } return; } - if (myType == OBJECT){ - while (objVal.size() > size){ + if (myType == OBJECT) { + while (objVal.size() > size) { objVal.erase(objVal.begin()); } return; @@ -902,94 +906,94 @@ void JSON::Value::shrink(unsigned int size){ /// 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){ +void JSON::Value::removeMember(const std::string & name) { objVal.erase(name); } /// For object JSON::Value objects, returns true if the /// given name is a member. Returns false otherwise. -bool JSON::Value::isMember(const std::string & name) const{ +bool JSON::Value::isMember(const std::string & name) const { return objVal.count(name) > 0; } /// Returns true if this object is an integer. -bool JSON::Value::isInt() const{ +bool JSON::Value::isInt() const { return (myType == INTEGER); } /// Returns true if this object is a string. -bool JSON::Value::isString() const{ +bool JSON::Value::isString() const { return (myType == STRING); } /// Returns true if this object is a bool. -bool JSON::Value::isBool() const{ +bool JSON::Value::isBool() const { return (myType == BOOL); } /// Returns true if this object is an object. -bool JSON::Value::isObject() const{ +bool JSON::Value::isObject() const { return (myType == OBJECT); } /// Returns true if this object is an array. -bool JSON::Value::isArray() const{ +bool JSON::Value::isArray() const { return (myType == ARRAY); } /// Returns true if this object is null. -bool JSON::Value::isNull() const{ +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(){ +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(){ +JSON::ObjIter JSON::Value::ObjEnd() { return objVal.end(); } /// Returns an iterator to the begin of the array, if any. -JSON::ArrIter JSON::Value::ArrBegin(){ +JSON::ArrIter JSON::Value::ArrBegin() { return arrVal.begin(); } /// Returns an iterator to the end of the array, if any. -JSON::ArrIter JSON::Value::ArrEnd(){ +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{ +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{ +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{ +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{ +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{ +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(){ +void JSON::Value::null() { objVal.clear(); arrVal.clear(); strVal.clear(); @@ -998,13 +1002,13 @@ void JSON::Value::null(){ } /// Converts a std::string to a JSON::Value. -JSON::Value JSON::fromString(std::string json){ +JSON::Value JSON::fromString(std::string json) { std::istringstream is(json); return JSON::Value(is); } /// Converts a file to a JSON::Value. -JSON::Value JSON::fromFile(std::string filename){ +JSON::Value JSON::fromFile(std::string filename) { std::ifstream File; File.open(filename.c_str()); JSON::Value ret(File); @@ -1018,7 +1022,7 @@ JSON::Value JSON::fromFile(std::string filename){ /// \param len The size of the raw data. /// \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 JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int & i) { JSON::Value ret; fromDTMI(data, len, i, ret); return ret; @@ -1030,72 +1034,72 @@ JSON::Value JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigne /// \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){ +void JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int & i, JSON::Value & ret) { ret.null(); - if (i >= len){ + if (i >= len) { return; } - switch (data[i]){ + switch (data[i]) { case 0x01: { //integer - if (i+8 >= len){ - return; - } - unsigned char tmpdbl[8]; - tmpdbl[7] = data[i + 1]; - tmpdbl[6] = data[i + 2]; - tmpdbl[5] = data[i + 3]; - tmpdbl[4] = data[i + 4]; - tmpdbl[3] = data[i + 5]; - tmpdbl[2] = data[i + 6]; - tmpdbl[1] = data[i + 7]; - tmpdbl[0] = data[i + 8]; - i += 9; //skip 8(an uint64_t)+1 forwards - uint64_t * d = (uint64_t*)tmpdbl; - ret = (long long int) *d; - return; - break; - } - case 0x02: { //string - if (i+4 >= len){ - 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; - } - i += tmpi + 5; //skip length+size+1 forwards - ret = tmpstr; - return; - break; - } - case 0xFF: //also object - case 0xE0: { //object - ++i; - while (data[i] + data[i + 1] != 0 && i < len){ //while not encountering 0x0000 (we assume 0x0000EE) - if (i+2 >= len){ + if (i + 8 >= len) { 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].null(); - fromDTMI(data, len, i, ret[tmpstr]); //add content, recursively parsed, updating i, setting indice to tmpstr + unsigned char tmpdbl[8]; + tmpdbl[7] = data[i + 1]; + tmpdbl[6] = data[i + 2]; + tmpdbl[5] = data[i + 3]; + tmpdbl[4] = data[i + 4]; + tmpdbl[3] = data[i + 5]; + tmpdbl[2] = data[i + 6]; + tmpdbl[1] = data[i + 7]; + tmpdbl[0] = data[i + 8]; + i += 9; //skip 8(an uint64_t)+1 forwards + uint64_t * d = (uint64_t *)tmpdbl; + ret = (long long int) * d; + return; + break; + } + case 0x02: { //string + if (i + 4 >= len) { + 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; + } + i += tmpi + 5; //skip length+size+1 forwards + ret = tmpstr; + return; + break; + } + case 0xFF: //also object + case 0xE0: { //object + ++i; + while (data[i] + data[i + 1] != 0 && i < len) { //while not encountering 0x0000 (we assume 0x0000EE) + if (i + 2 >= len) { + 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].null(); + fromDTMI(data, len, i, ret[tmpstr]); //add content, recursively parsed, updating i, setting indice to tmpstr + } + i += 3; //skip 0x0000EE + return; + break; } - i += 3; //skip 0x0000EE - return; - break; - } 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 + ++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 + } + i += 3; //skip 0x0000EE + return; + break; } - i += 3; //skip 0x0000EE - return; - break; - } } DEBUG_MSG(DLVL_FAIL, "Unimplemented DTMI type %hhx, @ %i / %i - returning.", data[i], i, len); i += 1; @@ -1104,37 +1108,39 @@ void JSON::fromDTMI(const unsigned char * data, unsigned int len, unsigned int & /// Parses a std::string to a valid JSON::Value. /// This function will find one DTMI object in the string and return it. -void JSON::fromDTMI(std::string & data, JSON::Value & ret){ +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); + 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){ +JSON::Value JSON::fromDTMI(std::string & data) { unsigned int i = 0; - return fromDTMI((const unsigned char*)data.c_str(), data.size(), i); + return fromDTMI((const unsigned char *)data.c_str(), data.size(), i); } //fromDTMI -void JSON::fromDTMI2(std::string & data, JSON::Value & ret){ +void JSON::fromDTMI2(std::string & data, JSON::Value & ret) { unsigned int i = 0; - fromDTMI2((const unsigned char*)data.c_str(), data.size(), i, ret); + fromDTMI2((const unsigned char *)data.c_str(), data.size(), i, ret); return; } -JSON::Value JSON::fromDTMI2(std::string & data){ +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); + 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+i))[0]); - long long int tmpTime = ntohl(((int*)(data+i))[1]); +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 + i))[0]); + long long int tmpTime = ntohl(((int *)(data + i))[1]); tmpTime <<= 32; - tmpTime += ntohl(((int*)(data+i))[2]); + tmpTime += ntohl(((int *)(data + i))[2]); i += 12; fromDTMI(data, len, i, ret); ret["time"] = tmpTime; @@ -1142,7 +1148,7 @@ void JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int return; } -JSON::Value JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i){ +JSON::Value JSON::fromDTMI2(const unsigned char * data, unsigned int len, unsigned int & i) { JSON::Value ret; fromDTMI2(data, len, i, ret); return ret; diff --git a/lib/json.h b/lib/json.h index 6f69a82e..6fe3c239 100644 --- a/lib/json.h +++ b/lib/json.h @@ -17,7 +17,7 @@ namespace DTSC { namespace JSON { /// Lists all types of JSON::Value. - enum ValueType{ + enum ValueType { EMPTY, BOOL, INTEGER, STRING, ARRAY, OBJECT }; @@ -28,9 +28,9 @@ namespace JSON { typedef std::deque::iterator ArrIter; typedef std::map::const_iterator ObjConstIter; typedef std::deque::const_iterator ArrConstIter; - + /// A JSON::Value is either a string or an integer, but may also be an object, array or null. - class Value{ + class Value { private: ValueType myType; long long int intVal; @@ -48,15 +48,15 @@ namespace JSON { Value(long long int val); Value(bool val); //comparison operators - bool operator==(const Value &rhs) const; - bool operator!=(const Value &rhs) const; + bool operator==(const Value & rhs) const; + bool operator!=(const Value & rhs) const; //assignment operators - Value & operator=(const std::string &rhs); + Value & operator=(const std::string & rhs); Value & operator=(const char * rhs); - Value & operator=(const long long int &rhs); - Value & operator=(const int &rhs); - Value & operator=(const unsigned int &rhs); - Value & operator=(const bool &rhs); + Value & operator=(const long long int & rhs); + Value & operator=(const int & rhs); + Value & operator=(const unsigned int & rhs); + Value & operator=(const bool & rhs); //converts to basic types operator long long int() const; operator std::string() const; @@ -105,22 +105,22 @@ namespace JSON { }; Value fromDTMI2(std::string & data); - Value fromDTMI2(const unsigned char * data, unsigned int len, unsigned int &i); + Value fromDTMI2(const unsigned char * data, unsigned int len, unsigned int & i); Value fromDTMI(std::string & data); - Value fromDTMI(const unsigned char * data, unsigned int len, unsigned int &i); + 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 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); - + void fromDTMI(const unsigned char * data, unsigned int len, unsigned int & i, Value & ret); + template - std::string encodeVector(T begin, T end){ + std::string encodeVector(T begin, T end) { std::string result; - for( T it = begin; it != end; it++){ + for (T it = begin; it != end; it++) { long long int tmp = (*it); - while(tmp >= 0xFFFF){ + while (tmp >= 0xFFFF) { result += (char)0xFF; result += (char)0xFF; tmp -= 0xFFFF; @@ -132,13 +132,13 @@ namespace JSON { } template - void decodeVector( std::string input, T & result ){ + void decodeVector(std::string input, T & result) { result.clear(); unsigned int tmp = 0; - for( int i = 0; i < input.size(); i += 2){ + for (int i = 0; i < input.size(); i += 2) { unsigned int curLen = (input[i] << 8) + input[i + 1]; tmp += curLen; - if (curLen != 0xFFFF){ + if (curLen != 0xFFFF) { result.push_back(tmp); tmp = 0; } @@ -146,11 +146,11 @@ namespace JSON { } template - std::string encodeVector4(T begin, T end){ + std::string encodeVector4(T begin, T end) { std::string result; - for( T it = begin; it != end; it++){ + for (T it = begin; it != end; it++) { long long int tmp = (*it); - while(tmp >= 0xFFFFFFFF){ + while (tmp >= 0xFFFFFFFF) { result += (char)0xFF; result += (char)0xFF; result += (char)0xFF; @@ -166,13 +166,13 @@ namespace JSON { } template - void decodeVector4( std::string input, T & result ){ + void decodeVector4(std::string input, T & result) { result.clear(); unsigned int tmp = 0; - for( int i = 0; i < input.size(); i += 4){ - unsigned int curLen = (input[i] << 24) + (input[i+1] << 16) + (input[i+2] << 8) + (input[i+3]); + for (int i = 0; i < input.size(); i += 4) { + unsigned int curLen = (input[i] << 24) + (input[i + 1] << 16) + (input[i + 2] << 8) + (input[i + 3]); tmp += curLen; - if (curLen != 0xFFFFFFFF){ + if (curLen != 0xFFFFFFFF) { result.push_back(tmp); tmp = 0; } diff --git a/lib/mp4.cpp b/lib/mp4.cpp index 0d031da3..758c7597 100644 --- a/lib/mp4.cpp +++ b/lib/mp4.cpp @@ -16,148 +16,148 @@ namespace MP4 { /// If manage is set to true, the pointer will be realloc'ed when the box needs to be resized. /// If the datapointer is NULL, manage is assumed to be true even if explicitly given as false. /// If managed, the pointer will be free'd upon destruction. - Box::Box(char * datapointer, bool manage){ - + Box::Box(char * datapointer, bool manage) { + data = datapointer; managed = manage; payloadOffset = 8; - if (data == 0){ + if (data == 0) { clear(); - }else{ - data_size = ntohl(((int*)data)[0]); - } - } - - Box::Box(const Box & rs){ - data = rs.data; - managed = false; - payloadOffset = rs.payloadOffset; - if (data == 0){ - clear(); - }else{ - data_size = ntohl(((int*)data)[0]); + } else { + data_size = ntohl(((int *)data)[0]); } } - Box& Box::operator = (const Box & rs){ + Box::Box(const Box & rs) { + data = rs.data; + managed = false; + payloadOffset = rs.payloadOffset; + if (data == 0) { + clear(); + } else { + data_size = ntohl(((int *)data)[0]); + } + } + + Box & Box::operator = (const Box & rs) { clear(); data = rs.data; managed = false; payloadOffset = rs.payloadOffset; - if (data == 0){ + if (data == 0) { clear(); - }else{ - data_size = ntohl(((int*)data)[0]); + } else { + data_size = ntohl(((int *)data)[0]); } return *this; } /// If managed, this will free the data pointer. - Box::~Box(){ - if (managed && data != 0){ + Box::~Box() { + if (managed && data != 0) { free(data); data = 0; } } /// Returns the values at byte positions 4 through 7. - std::string Box::getType(){ + std::string Box::getType() { return std::string(data + 4, 4); } /// Returns true if the given 4-byte boxtype is equal to the values at byte positions 4 through 7. - bool Box::isType(const char* boxType){ + bool Box::isType(const char * boxType) { return !memcmp(boxType, data + 4, 4); } - /// Reads the first 8 bytes and returns - std::string readBoxType(FILE * newData){ + /// Reads the first 8 bytes and returns + std::string readBoxType(FILE * newData) { char retVal[8] = {0, 0, 0, 0, 'e', 'r', 'r', 'o'}; long long unsigned int pos = ftell(newData); - fread(retVal,8,1,newData); - fseek (newData,pos,SEEK_SET); - return std::string(retVal+4,4); + fread(retVal, 8, 1, newData); + fseek(newData, pos, SEEK_SET); + return std::string(retVal + 4, 4); } ///\todo make good working calcBoxSize with size and payloadoffset calculation - unsigned long int calcBoxSize(char readVal[16]){ + unsigned long int calcBoxSize(char readVal[16]) { return (readVal[0] << 24) | (readVal[1] << 16) | (readVal[2] << 8) | (readVal[3]); } - bool skipBox(FILE * newData){ + bool skipBox(FILE * newData) { char readVal[16]; long long unsigned int pos = ftell(newData); - if (fread(readVal,4,1,newData)){ + if (fread(readVal, 4, 1, newData)) { uint64_t size = calcBoxSize(readVal); - if (size==1){ - if (fread(readVal+4,12,1,newData)){ - size = 0 + ntohl(((int*)readVal)[2]); + if (size == 1) { + if (fread(readVal + 4, 12, 1, newData)) { + size = 0 + ntohl(((int *)readVal)[2]); size <<= 32; - size += ntohl(((int*)readVal)[3]); - }else{ + size += ntohl(((int *)readVal)[3]); + } else { return false; } - }else if (size==0){ + } else if (size == 0) { fseek(newData, 0, SEEK_END); } - DEBUG_MSG(DLVL_DEVEL,"skipping size 0x%0.8X",size); - if (fseek(newData, pos + size, SEEK_SET)==0){ + DEBUG_MSG(DLVL_DEVEL, "skipping size 0x%0.8X", size); + if (fseek(newData, pos + size, SEEK_SET) == 0) { return true; - }else{ + } else { return false; } - }else{ + } else { return false; } } - bool Box::read(FILE* newData){ + bool Box::read(FILE * newData) { char readVal[16]; long long unsigned int pos = ftell(newData); - if (fread(readVal,4,1,newData)){ + if (fread(readVal, 4, 1, newData)) { payloadOffset = 8; uint64_t size = calcBoxSize(readVal); - if (size==1){ - if (fread(readVal+4,12,1,newData)){ - size = 0 + ntohl(((int*)readVal)[2]); + if (size == 1) { + if (fread(readVal + 4, 12, 1, newData)) { + size = 0 + ntohl(((int *)readVal)[2]); size <<= 32; - size += ntohl(((int*)readVal)[3]); + size += ntohl(((int *)readVal)[3]); payloadOffset = 16; - }else{ + } else { return false; } } - fseek (newData,pos,SEEK_SET); - data = (char*)realloc(data, size); + fseek(newData, pos, SEEK_SET); + data = (char *)realloc(data, size); data_size = size; - return (fread(data,size,1,newData) == 1); - }else{ + return (fread(data, size, 1, newData) == 1); + } else { return false; } } /// Reads out a whole box (if possible) from newData, copying to the internal data storage and removing from the input string. /// \returns True on success, false otherwise. - bool Box::read(std::string & newData){ - if ( !managed){ + bool Box::read(std::string & newData) { + if (!managed) { return false; } - if (newData.size() > 4){ + if (newData.size() > 4) { payloadOffset = 8; - uint64_t size = ntohl(((int*)newData.c_str())[0]); - if (size == 1){ - if (newData.size() > 16){ - size = 0 + ntohl(((int*)newData.c_str())[2]); + uint64_t size = ntohl(((int *)newData.c_str())[0]); + if (size == 1) { + if (newData.size() > 16) { + size = 0 + ntohl(((int *)newData.c_str())[2]); size <<= 32; - size += ntohl(((int*)newData.c_str())[3]); + size += ntohl(((int *)newData.c_str())[3]); payloadOffset = 16; - }else{ + } else { return false; } } - if (newData.size() >= size){ - data = (char*)realloc(data, size); + if (newData.size() >= size) { + data = (char *)realloc(data, size); data_size = size; memcpy(data, newData.data(), size); newData.erase(0, size); @@ -168,207 +168,207 @@ namespace MP4 { } /// Returns the total boxed size of this box, including the header. - uint64_t Box::boxedSize(){ - if (payloadOffset == 16){ - return ((uint64_t)ntohl(((int*)data)[2]) << 32) + ntohl(((int*)data)[3]); + uint64_t Box::boxedSize() { + if (payloadOffset == 16) { + return ((uint64_t)ntohl(((int *)data)[2]) << 32) + ntohl(((int *)data)[3]); } - return ntohl(((int*)data)[0]); + return ntohl(((int *)data)[0]); } /// Retruns the size of the payload of thix box, excluding the header. /// This value is defined as boxedSize() - 8. - uint64_t Box::payloadSize(){ + uint64_t Box::payloadSize() { return boxedSize() - payloadOffset; } /// Returns a copy of the data pointer. - char * Box::asBox(){ + char * Box::asBox() { return data; } - char * Box::payload(){ + char * Box::payload() { return data + payloadOffset; } /// Makes this box managed if it wasn't already, resetting the internal storage to 8 bytes (the minimum). /// If this box wasn't managed, the original data is left intact - otherwise it is free'd. /// If it was somehow impossible to allocate 8 bytes (should never happen), this will cause segfaults later. - void Box::clear(){ - if (data && managed){ + void Box::clear() { + if (data && managed) { free(data); } managed = true; payloadOffset = 8; - data = (char*)malloc(8); - if (data){ + data = (char *)malloc(8); + if (data) { data_size = 8; - ((int*)data)[0] = htonl(data_size); - }else{ + ((int *)data)[0] = htonl(data_size); + } else { data_size = 0; } } /// Attempts to typecast this Box to a more specific type and call the toPrettyString() function of that type. /// If this failed, it will print out a message saying pretty-printing is not implemented for boxtype. - std::string Box::toPrettyString(uint32_t indent){ - switch (ntohl( *((int*)(data + 4)))){ //type is at this address + std::string Box::toPrettyString(uint32_t indent) { + switch (ntohl(*((int *)(data + 4)))) { //type is at this address case 0x6D666864: - return ((MFHD*)this)->toPrettyString(indent); + return ((MFHD *)this)->toPrettyString(indent); break; case 0x6D6F6F66: - return ((MOOF*)this)->toPrettyString(indent); + return ((MOOF *)this)->toPrettyString(indent); break; case 0x61627374: - return ((ABST*)this)->toPrettyString(indent); + return ((ABST *)this)->toPrettyString(indent); break; case 0x61667274: - return ((AFRT*)this)->toPrettyString(indent); + return ((AFRT *)this)->toPrettyString(indent); break; case 0x61667261: - return ((AFRA*)this)->toPrettyString(indent); + return ((AFRA *)this)->toPrettyString(indent); break; case 0x61737274: - return ((ASRT*)this)->toPrettyString(indent); + return ((ASRT *)this)->toPrettyString(indent); break; case 0x7472756E: - return ((TRUN*)this)->toPrettyString(indent); + return ((TRUN *)this)->toPrettyString(indent); break; case 0x74726166: - return ((TRAF*)this)->toPrettyString(indent); + return ((TRAF *)this)->toPrettyString(indent); break; case 0x74666864: - return ((TFHD*)this)->toPrettyString(indent); + return ((TFHD *)this)->toPrettyString(indent); break; case 0x61766343: - return ((AVCC*)this)->toPrettyString(indent); + return ((AVCC *)this)->toPrettyString(indent); break; case 0x73647470: - return ((SDTP*)this)->toPrettyString(indent); + return ((SDTP *)this)->toPrettyString(indent); break; case 0x66747970: - return ((FTYP*)this)->toPrettyString(indent); + return ((FTYP *)this)->toPrettyString(indent); break; case 0x6D6F6F76: - return ((MOOV*)this)->toPrettyString(indent); + return ((MOOV *)this)->toPrettyString(indent); break; case 0x6D766578: - return ((MVEX*)this)->toPrettyString(indent); + return ((MVEX *)this)->toPrettyString(indent); break; case 0x74726578: - return ((TREX*)this)->toPrettyString(indent); + return ((TREX *)this)->toPrettyString(indent); break; case 0x6D667261: - return ((MFRA*)this)->toPrettyString(indent); + return ((MFRA *)this)->toPrettyString(indent); break; case 0x7472616B: - return ((TRAK*)this)->toPrettyString(indent); + return ((TRAK *)this)->toPrettyString(indent); break; case 0x6D646961: - return ((MDIA*)this)->toPrettyString(indent); + return ((MDIA *)this)->toPrettyString(indent); break; case 0x6D696E66: - return ((MINF*)this)->toPrettyString(indent); + return ((MINF *)this)->toPrettyString(indent); break; case 0x64696E66: - return ((DINF*)this)->toPrettyString(indent); + return ((DINF *)this)->toPrettyString(indent); break; case 0x6D66726F: - return ((MFRO*)this)->toPrettyString(indent); + return ((MFRO *)this)->toPrettyString(indent); break; case 0x68646C72: - return ((HDLR*)this)->toPrettyString(indent); + return ((HDLR *)this)->toPrettyString(indent); break; case 0x766D6864: - return ((VMHD*)this)->toPrettyString(indent); + return ((VMHD *)this)->toPrettyString(indent); break; case 0x736D6864: - return ((SMHD*)this)->toPrettyString(indent); + return ((SMHD *)this)->toPrettyString(indent); break; case 0x686D6864: - return ((HMHD*)this)->toPrettyString(indent); + return ((HMHD *)this)->toPrettyString(indent); break; case 0x6E6D6864: - return ((NMHD*)this)->toPrettyString(indent); + return ((NMHD *)this)->toPrettyString(indent); break; case 0x6D656864: - return ((MEHD*)this)->toPrettyString(indent); + return ((MEHD *)this)->toPrettyString(indent); break; case 0x7374626C: - return ((STBL*)this)->toPrettyString(indent); + return ((STBL *)this)->toPrettyString(indent); break; case 0x64726566: - return ((DREF*)this)->toPrettyString(indent); + return ((DREF *)this)->toPrettyString(indent); break; case 0x75726C20: - return ((URL*)this)->toPrettyString(indent); + return ((URL *)this)->toPrettyString(indent); break; case 0x75726E20: - return ((URN*)this)->toPrettyString(indent); + return ((URN *)this)->toPrettyString(indent); break; case 0x6D766864: - return ((MVHD*)this)->toPrettyString(indent); + return ((MVHD *)this)->toPrettyString(indent); break; case 0x74667261: - return ((TFRA*)this)->toPrettyString(indent); + return ((TFRA *)this)->toPrettyString(indent); break; case 0x746B6864: - return ((TKHD*)this)->toPrettyString(indent); + return ((TKHD *)this)->toPrettyString(indent); break; case 0x6D646864: - return ((MDHD*)this)->toPrettyString(indent); + return ((MDHD *)this)->toPrettyString(indent); break; case 0x73747473: - return ((STTS*)this)->toPrettyString(indent); + return ((STTS *)this)->toPrettyString(indent); break; case 0x63747473: - return ((CTTS*)this)->toPrettyString(indent); + return ((CTTS *)this)->toPrettyString(indent); break; case 0x73747363: - return ((STSC*)this)->toPrettyString(indent); + return ((STSC *)this)->toPrettyString(indent); break; case 0x7374636F: - return ((STCO*)this)->toPrettyString(indent); + return ((STCO *)this)->toPrettyString(indent); break; case 0x7374737A: - return ((STSZ*)this)->toPrettyString(indent); + return ((STSZ *)this)->toPrettyString(indent); break; case 0x73747364: - return ((STSD*)this)->toPrettyString(indent); + return ((STSD *)this)->toPrettyString(indent); break; case 0x6D703461://mp4a case 0x656E6361://enca - return ((MP4A*)this)->toPrettyString(indent); + return ((MP4A *)this)->toPrettyString(indent); break; case 0x61616320: - return ((AAC*)this)->toPrettyString(indent); + return ((AAC *)this)->toPrettyString(indent); break; case 0x61766331: - return ((AVC1*)this)->toPrettyString(indent); + return ((AVC1 *)this)->toPrettyString(indent); break; case 0x68323634://h264 case 0x656E6376://encv - return ((H264*)this)->toPrettyString(indent); + return ((H264 *)this)->toPrettyString(indent); break; case 0x65647473: - return ((EDTS*)this)->toPrettyString(indent); + return ((EDTS *)this)->toPrettyString(indent); break; case 0x73747373: - return ((STSS*)this)->toPrettyString(indent); + return ((STSS *)this)->toPrettyString(indent); break; case 0x6D657461: - return ((META*)this)->toPrettyString(indent); + return ((META *)this)->toPrettyString(indent); break; case 0x656C7374: - return ((ELST*)this)->toPrettyString(indent); + return ((ELST *)this)->toPrettyString(indent); break; case 0x65736473: - return ((ESDS*)this)->toPrettyString(indent); + return ((ESDS *)this)->toPrettyString(indent); break; case 0x75647461: - return ((UDTA*)this)->toPrettyString(indent); + return ((UDTA *)this)->toPrettyString(indent); break; case 0x75756964: - return ((UUID*)this)->toPrettyString(indent); + return ((UUID *)this)->toPrettyString(indent); break; default: break; @@ -381,10 +381,10 @@ namespace MP4 { /// Sets the 8 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Fails silently if resizing failed. - void Box::setInt8(char newData, size_t index){ + void Box::setInt8(char newData, size_t index) { index += payloadOffset; - if (index >= boxedSize()){ - if ( !reserve(index, 0, 1)){ + if (index >= boxedSize()) { + if (!reserve(index, 0, 1)) { return; } } @@ -394,10 +394,10 @@ namespace MP4 { /// Gets the 8 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Returns zero if resizing failed. - char Box::getInt8(size_t index){ + char Box::getInt8(size_t index) { index += payloadOffset; - if (index >= boxedSize()){ - if ( !reserve(index, 0, 1)){ + if (index >= boxedSize()) { + if (!reserve(index, 0, 1)) { return 0; } setInt8(0, index - payloadOffset); @@ -408,40 +408,40 @@ namespace MP4 { /// Sets the 16 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Fails silently if resizing failed. - void Box::setInt16(short newData, size_t index){ + void Box::setInt16(short newData, size_t index) { index += payloadOffset; - if (index + 1 >= boxedSize()){ - if ( !reserve(index, 0, 2)){ + if (index + 1 >= boxedSize()) { + if (!reserve(index, 0, 2)) { return; } } newData = htons(newData); - memcpy(data + index, (char*) &newData, 2); + memcpy(data + index, (char *) &newData, 2); } /// Gets the 16 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Returns zero if resizing failed. - short Box::getInt16(size_t index){ + short Box::getInt16(size_t index) { index += payloadOffset; - if (index + 1 >= boxedSize()){ - if ( !reserve(index, 0, 2)){ + if (index + 1 >= boxedSize()) { + if (!reserve(index, 0, 2)) { return 0; } setInt16(0, index - payloadOffset); } short result; - memcpy((char*) &result, data + index, 2); + memcpy((char *) &result, data + index, 2); return ntohs(result); } /// Sets the 24 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Fails silently if resizing failed. - void Box::setInt24(uint32_t newData, size_t index){ + void Box::setInt24(uint32_t newData, size_t index) { index += payloadOffset; - if (index + 2 >= boxedSize()){ - if ( !reserve(index, 0, 3)){ + if (index + 2 >= boxedSize()) { + if (!reserve(index, 0, 3)) { return; } } @@ -453,10 +453,10 @@ namespace MP4 { /// Gets the 24 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Returns zero if resizing failed. - uint32_t Box::getInt24(size_t index){ + uint32_t Box::getInt24(size_t index) { index += payloadOffset; - if (index + 2 >= boxedSize()){ - if ( !reserve(index, 0, 3)){ + if (index + 2 >= boxedSize()) { + if (!reserve(index, 0, 3)) { return 0; } setInt24(0, index - payloadOffset); @@ -472,84 +472,84 @@ namespace MP4 { /// Sets the 32 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Fails silently if resizing failed. - void Box::setInt32(uint32_t newData, size_t index){ + void Box::setInt32(uint32_t newData, size_t index) { index += payloadOffset; - if (index + 3 >= boxedSize()){ - if ( !reserve(index, 0, 4)){ + if (index + 3 >= boxedSize()) { + if (!reserve(index, 0, 4)) { return; } } newData = htonl(newData); - memcpy(data + index, (char*) &newData, 4); + memcpy(data + index, (char *) &newData, 4); } /// Gets the 32 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Returns zero if resizing failed. - uint32_t Box::getInt32(size_t index){ + uint32_t Box::getInt32(size_t index) { index += payloadOffset; - if (index + 3 >= boxedSize()){ - if ( !reserve(index, 0, 4)){ + if (index + 3 >= boxedSize()) { + if (!reserve(index, 0, 4)) { return 0; } setInt32(0, index - payloadOffset); } uint32_t result; - memcpy((char*) &result, data + index, 4); + memcpy((char *) &result, data + index, 4); return ntohl(result); } /// Sets the 64 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Fails silently if resizing failed. - void Box::setInt64(uint64_t newData, size_t index){ + void Box::setInt64(uint64_t newData, size_t index) { index += payloadOffset; - if (index + 7 >= boxedSize()){ - if ( !reserve(index, 0, 8)){ + if (index + 7 >= boxedSize()) { + if (!reserve(index, 0, 8)) { return; } } - ((int*)(data + index))[0] = htonl((int)(newData >> 32)); - ((int*)(data + index))[1] = htonl((int)(newData & 0xFFFFFFFF)); + ((int *)(data + index))[0] = htonl((int)(newData >> 32)); + ((int *)(data + index))[1] = htonl((int)(newData & 0xFFFFFFFF)); } /// Gets the 64 bits integer at the given index. /// Attempts to resize the data pointer if the index is out of range. /// Returns zero if resizing failed. - uint64_t Box::getInt64(size_t index){ + uint64_t Box::getInt64(size_t index) { index += payloadOffset; - if (index + 7 >= boxedSize()){ - if ( !reserve(index, 0, 8)){ + if (index + 7 >= boxedSize()) { + if (!reserve(index, 0, 8)) { return 0; } setInt64(0, index - payloadOffset); } - uint64_t result = ntohl(((int*)(data + index))[0]); + uint64_t result = ntohl(((int *)(data + index))[0]); result <<= 32; - result += ntohl(((int*)(data + index))[1]); + result += ntohl(((int *)(data + index))[1]); return result; } /// Sets the NULL-terminated string at the given index. /// Will attempt to resize if the string doesn't fit. /// Fails silently if resizing failed. - void Box::setString(std::string newData, size_t index){ - setString((char*)newData.c_str(), newData.size(), index); + void Box::setString(std::string newData, size_t index) { + setString((char *)newData.c_str(), newData.size(), index); } /// Sets the NULL-terminated string at the given index. /// Will attempt to resize if the string doesn't fit. /// Fails silently if resizing failed. - void Box::setString(char* newData, size_t size, size_t index){ + void Box::setString(char * newData, size_t size, size_t index) { index += payloadOffset; - if (index >= boxedSize()){ - if ( !reserve(index, 0, 1)){ + if (index >= boxedSize()) { + if (!reserve(index, 0, 1)) { return; } data[index] = 0; } - if (getStringLen(index) != size){ - if ( !reserve(index, getStringLen(index) + 1, size + 1)){ + if (getStringLen(index) != size) { + if (!reserve(index, getStringLen(index) + 1, size + 1)) { return; } } @@ -559,10 +559,10 @@ namespace MP4 { /// Gets the NULL-terminated string at the given index. /// Will attempt to resize if the string is out of range. /// Returns null if resizing failed. - char * Box::getString(size_t index){ + char * Box::getString(size_t index) { index += payloadOffset; - if (index >= boxedSize()){ - if ( !reserve(index, 0, 1)){ + if (index >= boxedSize()) { + if (!reserve(index, 0, 1)) { return 0; } data[index] = 0; @@ -572,9 +572,9 @@ namespace MP4 { /// Returns the length of the NULL-terminated string at the given index. /// Returns 0 if out of range. - size_t Box::getStringLen(size_t index){ + size_t Box::getStringLen(size_t index) { index += payloadOffset; - if (index >= boxedSize()){ + if (index >= boxedSize()) { return 0; } return strlen(data + index); @@ -584,12 +584,12 @@ namespace MP4 { /// Do not store or copy this reference, for there will be raptors. /// Will attempt to resize if out of range. /// Returns an 8-byte error box if resizing failed. - Box & Box::getBox(size_t index){ - static Box retbox = Box((char*)"\000\000\000\010erro", false); + Box & Box::getBox(size_t index) { + static Box retbox = Box((char *)"\000\000\000\010erro", false); index += payloadOffset; - if (index + 8 > boxedSize()){ - if ( !reserve(index, 0, 8)){ - retbox = Box((char*)"\000\000\000\010erro", false); + if (index + 8 > boxedSize()) { + if (!reserve(index, 0, 8)) { + retbox = Box((char *)"\000\000\000\010erro", false); return retbox; } memcpy(data + index, "\000\000\000\010erro", 8); @@ -601,8 +601,8 @@ namespace MP4 { /// Returns the size of the box at the given position. /// Returns undefined values if there is no box at the given position. /// Returns 0 if out of range. - size_t Box::getBoxLen(size_t index){ - if ((index + payloadOffset + 8) > boxedSize()){ + size_t Box::getBoxLen(size_t index) { + if ((index + payloadOffset + 8) > boxedSize()) { return 0; } return getBox(index).boxedSize(); @@ -610,10 +610,10 @@ namespace MP4 { /// Replaces the existing box at the given index by the new box newEntry. /// Will resize if needed, will reserve new space if out of range. - void Box::setBox(Box & newEntry, size_t index){ + void Box::setBox(Box & newEntry, size_t index) { int oldlen = getBoxLen(index); int newlen = newEntry.boxedSize(); - if (oldlen != newlen && !reserve(index + payloadOffset, oldlen, newlen)){ + if (oldlen != newlen && !reserve(index + payloadOffset, oldlen, newlen)) { return; } memcpy(data + index + payloadOffset, newEntry.asBox(), newlen); @@ -622,90 +622,90 @@ namespace MP4 { /// Attempts to reserve enough space for wanted bytes of data at given position, where current bytes of data is now reserved. /// This will move any existing data behind the currently reserved space to the proper location after reserving. /// \returns True on success, false otherwise. - bool Box::reserve(size_t position, size_t current, size_t wanted){ - if (current == wanted){ + bool Box::reserve(size_t position, size_t current, size_t wanted) { + if (current == wanted) { return true; } - if (position > boxedSize()){ + if (position > boxedSize()) { wanted += position - boxedSize(); } - if (current < wanted){ + if (current < wanted) { //make bigger - if (boxedSize() + (wanted - current) > data_size){ + if (boxedSize() + (wanted - current) > data_size) { //realloc if managed, otherwise fail - if ( !managed){ + if (!managed) { return false; } void * ret = realloc(data, boxedSize() + (wanted - current)); - if ( !ret){ + if (!ret) { return false; } - data = (char*)ret; + data = (char *)ret; memset(data + boxedSize(), 0, wanted - current); //initialize to 0 data_size = boxedSize() + (wanted - current); } } //move data behind, if any - if (boxedSize() > (position + current)){ + if (boxedSize() > (position + current)) { memmove(data + position + wanted, data + position + current, boxedSize() - (position + current)); } //calculate and set new size - if (payloadOffset != 16){ + if (payloadOffset != 16) { int newSize = boxedSize() + (wanted - current); - ((int*)data)[0] = htonl(newSize); + ((int *)data)[0] = htonl(newSize); } return true; } - - fullBox::fullBox(){ + + fullBox::fullBox() { setVersion(0); } - - void fullBox::setVersion(char newVersion){ + + void fullBox::setVersion(char newVersion) { setInt8(newVersion, 0); } - char fullBox::getVersion(){ + char fullBox::getVersion() { return getInt8(0); } - void fullBox::setFlags(uint32_t newFlags){ + void fullBox::setFlags(uint32_t newFlags) { setInt24(newFlags, 1); } - uint32_t fullBox::getFlags(){ + uint32_t fullBox::getFlags() { return getInt24(1); } - - std::string fullBox::toPrettyString(uint32_t indent){ + + std::string fullBox::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent + 1, ' ') << "Version: " << (int)getVersion() << std::endl; r << std::string(indent + 1, ' ') << "Flags: " << getFlags() << std::endl; return r.str(); } - containerBox::containerBox(){ - + containerBox::containerBox() { + } - - uint32_t containerBox::getContentCount(){ + + uint32_t containerBox::getContentCount() { int res = 0; unsigned int tempLoc = 0; - while (tempLoc < boxedSize() - 8){ + while (tempLoc < boxedSize() - 8) { res++; tempLoc += Box(getBox(tempLoc).asBox(), false).boxedSize(); } return res; } - void containerBox::setContent(Box & newContent, uint32_t no){ + void containerBox::setContent(Box & newContent, uint32_t no) { int tempLoc = 0; unsigned int contentCount = getContentCount(); - for (unsigned int i = 0; i < no; i++){ - if (i < contentCount){ + for (unsigned int i = 0; i < no; i++) { + if (i < contentCount) { tempLoc += getBoxLen(tempLoc); - }else{ - if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){ + } else { + if (!reserve(tempLoc, 0, (no - contentCount) * 8)) { return; }; memset(data + tempLoc, 0, (no - contentCount) * 8); @@ -716,27 +716,27 @@ namespace MP4 { setBox(newContent, tempLoc); } - Box & containerBox::getContent(uint32_t no){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if (no > getContentCount()){ + Box & containerBox::getContent(uint32_t no) { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (no > getContentCount()) { return ret; } unsigned int i = 0; int tempLoc = 0; - while (i < no){ + while (i < no) { tempLoc += getBoxLen(tempLoc); i++; } return getBox(tempLoc); } - - std::string containerBox::toPrettyString(uint32_t indent){ + + std::string containerBox::toPrettyString(uint32_t indent) { std::stringstream r; - r << std::string(indent, ' ') << "[" << getType() <<"] Container Box (" << boxedSize() << ")" << std::endl; + r << std::string(indent, ' ') << "[" << getType() << "] Container Box (" << boxedSize() << ")" << std::endl; Box curBox; int tempLoc = 0; int contentCount = getContentCount(); - for (int i = 0; i < contentCount; i++){ + for (int i = 0; i < contentCount; i++) { curBox = getContent(i); r << curBox.toPrettyString(indent + 1); tempLoc += getBoxLen(tempLoc); @@ -744,24 +744,24 @@ namespace MP4 { return r.str(); } - uint32_t containerFullBox::getContentCount(){ + uint32_t containerFullBox::getContentCount() { int res = 0; unsigned int tempLoc = 4; - while (tempLoc < boxedSize() - 8){ + while (tempLoc < boxedSize() - 8) { res++; tempLoc += getBoxLen(tempLoc); } return res; } - - void containerFullBox::setContent(Box & newContent, uint32_t no){ + + void containerFullBox::setContent(Box & newContent, uint32_t no) { int tempLoc = 4; unsigned int contentCount = getContentCount(); - for (unsigned int i = 0; i < no; i++){ - if (i < contentCount){ + for (unsigned int i = 0; i < no; i++) { + if (i < contentCount) { tempLoc += getBoxLen(tempLoc); - }else{ - if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){ + } else { + if (!reserve(tempLoc, 0, (no - contentCount) * 8)) { return; }; memset(data + tempLoc, 0, (no - contentCount) * 8); @@ -771,29 +771,29 @@ namespace MP4 { } setBox(newContent, tempLoc); } - - Box & containerFullBox::getContent(uint32_t no){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if (no > getContentCount()){ + + Box & containerFullBox::getContent(uint32_t no) { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (no > getContentCount()) { return ret; } unsigned int i = 0; int tempLoc = 4; - while (i < no){ + while (i < no) { tempLoc += getBoxLen(tempLoc); i++; } return getBox(tempLoc); } - - std::string containerFullBox::toPrettyCFBString(uint32_t indent, std::string boxName){ + + std::string containerFullBox::toPrettyCFBString(uint32_t indent, std::string boxName) { std::stringstream r; - r << std::string(indent, ' ') << boxName <<" (" << boxedSize() << ")" << std::endl; + r << std::string(indent, ' ') << boxName << " (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); Box curBox; int tempLoc = 4; int contentCount = getContentCount(); - for (int i = 0; i < contentCount; i++){ + for (int i = 0; i < contentCount; i++) { curBox = getContent(i); r << curBox.toPrettyString(indent + 1); tempLoc += getBoxLen(tempLoc); diff --git a/lib/mp4.h b/lib/mp4.h index ca025771..adf3863e 100644 --- a/lib/mp4.h +++ b/lib/mp4.h @@ -18,16 +18,16 @@ namespace MP4 { std::string readBoxType(FILE * newData); bool skipBox(FILE * newData); - - class Box{ + + class Box { public: Box(char * datapointer = 0, bool manage = true); Box(const Box & rs); - Box& operator = (const Box & rs); + Box & operator = (const Box & rs); ~Box(); std::string getType(); - bool isType(const char* boxType); - bool read(FILE* newData); + bool isType(const char * boxType); + bool read(FILE * newData); bool read(std::string & newData); uint64_t boxedSize(); uint64_t payloadSize(); @@ -49,7 +49,7 @@ namespace MP4 { uint64_t getInt64(size_t index); //string functions void setString(std::string newData, size_t index); - void setString(char* newData, size_t size, size_t index); + void setString(char * newData, size_t size, size_t index); char * getString(size_t index); size_t getStringLen(size_t index); //box functions @@ -65,8 +65,8 @@ namespace MP4 { unsigned int payloadOffset; /// getInt8(countLoc)){ + if (no + 1 > getInt8(countLoc)) { int amount = no + 1 - getInt8(countLoc); - if ( !reserve(payloadOffset + tempLoc, 0, amount)){ + if (!reserve(payloadOffset + tempLoc, 0, amount)) { return; }; memset(data + payloadOffset + tempLoc, 0, amount); @@ -133,41 +133,41 @@ namespace MP4 { } ///\return Empty string if no > serverEntryCount(), serverEntry[no] otherwise. - const char* ABST::getServerEntry(uint32_t no){ - if (no + 1 > getServerEntryCount()){ + const char * ABST::getServerEntry(uint32_t no) { + if (no + 1 > getServerEntryCount()) { return ""; } int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of first entry - for (unsigned int i = 0; i < no; i++){ + for (unsigned int i = 0; i < no; i++) { tempLoc += getStringLen(tempLoc) + 1; } return getString(tempLoc); } - uint32_t ABST::getQualityEntryCount(){ + uint32_t ABST::getQualityEntryCount() { int countLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { countLoc += getStringLen(countLoc) + 1; } return getInt8(countLoc); } - void ABST::setQualityEntry(std::string & newEntry, uint32_t no){ + void ABST::setQualityEntry(std::string & newEntry, uint32_t no) { int countLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { countLoc += getStringLen(countLoc) + 1; } int tempLoc = countLoc + 1; //attempt to reach the wanted position unsigned int i; - for (i = 0; i < getInt8(countLoc) && i < no; ++i){ + for (i = 0; i < getInt8(countLoc) && i < no; ++i) { tempLoc += getStringLen(tempLoc) + 1; } //we are now either at the end, or at the right position //let's reserve any unreserved space... - if (no + 1 > getInt8(countLoc)){ + if (no + 1 > getInt8(countLoc)) { int amount = no + 1 - getInt8(countLoc); - if ( !reserve(payloadOffset + tempLoc, 0, amount)){ + if (!reserve(payloadOffset + tempLoc, 0, amount)) { return; }; memset(data + payloadOffset + tempLoc, 0, amount); @@ -178,78 +178,78 @@ namespace MP4 { setString(newEntry, tempLoc); } - const char* ABST::getQualityEntry(uint32_t no){ - if (no > getQualityEntryCount()){ + const char * ABST::getQualityEntry(uint32_t no) { + if (no > getQualityEntryCount()) { return ""; } int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of serverentries; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += 1; //first qualityentry - for (unsigned int i = 0; i < no; i++){ + for (unsigned int i = 0; i < no; i++) { tempLoc += getStringLen(tempLoc) + 1; } return getString(tempLoc); } - void ABST::setDrmData(std::string newDrm){ + void ABST::setDrmData(std::string newDrm) { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } setString(newDrm, tempLoc); } - char* ABST::getDrmData(){ + char * ABST::getDrmData() { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } return getString(tempLoc); } - void ABST::setMetaData(std::string newMetaData){ + void ABST::setMetaData(std::string newMetaData) { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; setString(newMetaData, tempLoc); } - char* ABST::getMetaData(){ + char * ABST::getMetaData() { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; return getString(tempLoc); } - uint32_t ABST::getSegmentRunTableCount(){ + uint32_t ABST::getSegmentRunTableCount() { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData @@ -257,13 +257,13 @@ namespace MP4 { return getInt8(tempLoc); } - void ABST::setSegmentRunTable(ASRT & newSegment, uint32_t no){ + void ABST::setSegmentRunTable(ASRT & newSegment, uint32_t no) { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData @@ -272,18 +272,18 @@ namespace MP4 { tempLoc++; //skip segmentRuntableCount //attempt to reach the wanted position unsigned int i; - for (i = 0; i < getInt8(countLoc) && i < no; ++i){ + for (i = 0; i < getInt8(countLoc) && i < no; ++i) { tempLoc += getBoxLen(tempLoc); } //we are now either at the end, or at the right position //let's reserve any unreserved space... - if (no + 1 > getInt8(countLoc)){ + if (no + 1 > getInt8(countLoc)) { int amount = no + 1 - getInt8(countLoc); - if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){ + if (!reserve(payloadOffset + tempLoc, 0, amount * 8)) { return; }; //set empty erro boxes as contents - for (int j = 0; j < amount; ++j){ + for (int j = 0; j < amount; ++j) { memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8); } setInt8(no + 1, countLoc); //set new count @@ -293,76 +293,76 @@ namespace MP4 { setBox(newSegment, tempLoc); } - ASRT & ABST::getSegmentRunTable(uint32_t no){ + ASRT & ABST::getSegmentRunTable(uint32_t no) { static Box result; - if (no > getSegmentRunTableCount()){ + if (no > getSegmentRunTableCount()) { static Box res; - return (ASRT&)res; + return (ASRT &)res; } uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData tempLoc += getStringLen(tempLoc) + 1; //MetaData tempLoc++; //segmentRuntableCount - for (unsigned int i = 0; i < no; ++i){ + for (unsigned int i = 0; i < no; ++i) { tempLoc += getBoxLen(tempLoc); } - return (ASRT&)getBox(tempLoc); + return (ASRT &)getBox(tempLoc); } - uint32_t ABST::getFragmentRunTableCount(){ + uint32_t ABST::getFragmentRunTableCount() { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData tempLoc += getStringLen(tempLoc) + 1; //MetaData - for (unsigned int i = getInt8(tempLoc++); i != 0; --i){ + for (unsigned int i = getInt8(tempLoc++); i != 0; --i) { tempLoc += getBoxLen(tempLoc); } return getInt8(tempLoc); } - void ABST::setFragmentRunTable(AFRT & newFragment, uint32_t no){ + void ABST::setFragmentRunTable(AFRT & newFragment, uint32_t no) { uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData tempLoc += getStringLen(tempLoc) + 1; //MetaData - for (unsigned int i = getInt8(tempLoc++); i != 0; --i){ + for (unsigned int i = getInt8(tempLoc++); i != 0; --i) { tempLoc += getBoxLen(tempLoc); } int countLoc = tempLoc; tempLoc++; //attempt to reach the wanted position unsigned int i; - for (i = 0; i < getInt8(countLoc) && i < no; ++i){ + for (i = 0; i < getInt8(countLoc) && i < no; ++i) { tempLoc += getBoxLen(tempLoc); } //we are now either at the end, or at the right position //let's reserve any unreserved space... - if (no + 1 > getInt8(countLoc)){ + if (no + 1 > getInt8(countLoc)) { unsigned int amount = no + 1 - getInt8(countLoc); - if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){ + if (!reserve(payloadOffset + tempLoc, 0, amount * 8)) { return; }; //set empty erro boxes as contents - for (unsigned int j = 0; j < amount; ++j){ + for (unsigned int j = 0; j < amount; ++j) { memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8); } setInt8(no + 1, countLoc); //set new count @@ -372,46 +372,46 @@ namespace MP4 { setBox(newFragment, tempLoc); } - AFRT & ABST::getFragmentRunTable(uint32_t no){ + AFRT & ABST::getFragmentRunTable(uint32_t no) { static Box result; - if (no >= getFragmentRunTableCount()){ + if (no >= getFragmentRunTableCount()) { static Box res; - return (AFRT&)res; + return (AFRT &)res; } uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc++; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += getStringLen(tempLoc) + 1; //DrmData tempLoc += getStringLen(tempLoc) + 1; //MetaData - for (unsigned int i = getInt8(tempLoc++); i != 0; --i){ + for (unsigned int i = getInt8(tempLoc++); i != 0; --i) { tempLoc += getBoxLen(tempLoc); } tempLoc++; - for (unsigned int i = 0; i < no; i++){ + for (unsigned int i = 0; i < no; i++) { tempLoc += getBoxLen(tempLoc); } - return (AFRT&)getBox(tempLoc); + return (AFRT &)getBox(tempLoc); } - std::string ABST::toPrettyString(uint32_t indent){ + std::string ABST::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[abst] Bootstrap Info (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl; r << std::string(indent + 1, ' ') << "BootstrapinfoVersion " << getBootstrapinfoVersion() << std::endl; r << std::string(indent + 1, ' ') << "Profile " << (int)getProfile() << std::endl; - if (getLive()){ + if (getLive()) { r << std::string(indent + 1, ' ') << "Live" << std::endl; - }else{ + } else { r << std::string(indent + 1, ' ') << "Recorded" << std::endl; } - if (getUpdate()){ + if (getUpdate()) { r << std::string(indent + 1, ' ') << "Update" << std::endl; - }else{ + } else { r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl; } r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl; @@ -419,74 +419,74 @@ namespace MP4 { r << std::string(indent + 1, ' ') << "SmpteTimeCodeOffset " << getSmpteTimeCodeOffset() << std::endl; r << std::string(indent + 1, ' ') << "MovieIdentifier " << getMovieIdentifier() << std::endl; r << std::string(indent + 1, ' ') << "ServerEntryTable (" << getServerEntryCount() << ")" << std::endl; - for (unsigned int i = 0; i < getServerEntryCount(); i++){ + for (unsigned int i = 0; i < getServerEntryCount(); i++) { r << std::string(indent + 2, ' ') << i << ": " << getServerEntry(i) << std::endl; } r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl; } r << std::string(indent + 1, ' ') << "DrmData " << getDrmData() << std::endl; r << std::string(indent + 1, ' ') << "MetaData " << getMetaData() << std::endl; r << std::string(indent + 1, ' ') << "SegmentRunTableEntries (" << getSegmentRunTableCount() << ")" << std::endl; - for (uint32_t i = 0; i < getSegmentRunTableCount(); i++){ + for (uint32_t i = 0; i < getSegmentRunTableCount(); i++) { r << ((Box)getSegmentRunTable(i)).toPrettyString(indent + 2); } r << std::string(indent + 1, ' ') + "FragmentRunTableEntries (" << getFragmentRunTableCount() << ")" << std::endl; - for (uint32_t i = 0; i < getFragmentRunTableCount(); i++){ + for (uint32_t i = 0; i < getFragmentRunTableCount(); i++) { r << ((Box)getFragmentRunTable(i)).toPrettyString(indent + 2); } return r.str(); } - AFRT::AFRT(){ + AFRT::AFRT() { memcpy(data + 4, "afrt", 4); setVersion(0); setUpdate(0); setTimeScale(1000); } - void AFRT::setVersion(char newVersion){ + void AFRT::setVersion(char newVersion) { setInt8(newVersion, 0); } - uint32_t AFRT::getVersion(){ + uint32_t AFRT::getVersion() { return getInt8(0); } - void AFRT::setUpdate(uint32_t newUpdate){ + void AFRT::setUpdate(uint32_t newUpdate) { setInt24(newUpdate, 1); } - uint32_t AFRT::getUpdate(){ + uint32_t AFRT::getUpdate() { return getInt24(1); } - void AFRT::setTimeScale(uint32_t newScale){ + void AFRT::setTimeScale(uint32_t newScale) { setInt32(newScale, 4); } - uint32_t AFRT::getTimeScale(){ + uint32_t AFRT::getTimeScale() { return getInt32(4); } - uint32_t AFRT::getQualityEntryCount(){ + uint32_t AFRT::getQualityEntryCount() { return getInt8(8); } - void AFRT::setQualityEntry(std::string & newEntry, uint32_t no){ + void AFRT::setQualityEntry(std::string & newEntry, uint32_t no) { int countLoc = 8; int tempLoc = countLoc + 1; //attempt to reach the wanted position unsigned int i; - for (i = 0; i < getQualityEntryCount() && i < no; ++i){ + for (i = 0; i < getQualityEntryCount() && i < no; ++i) { tempLoc += getStringLen(tempLoc) + 1; } //we are now either at the end, or at the right position //let's reserve any unreserved space... - if (no + 1 > getQualityEntryCount()){ + if (no + 1 > getQualityEntryCount()) { int amount = no + 1 - getQualityEntryCount(); - if ( !reserve(payloadOffset + tempLoc, 0, amount)){ + if (!reserve(payloadOffset + tempLoc, 0, amount)) { return; }; memset(data + payloadOffset + tempLoc, 0, amount); @@ -497,151 +497,151 @@ namespace MP4 { setString(newEntry, tempLoc); } - const char* AFRT::getQualityEntry(uint32_t no){ - if (no + 1 > getQualityEntryCount()){ + const char * AFRT::getQualityEntry(uint32_t no) { + if (no + 1 > getQualityEntryCount()) { return ""; } int tempLoc = 9; //position of first quality entry - for (unsigned int i = 0; i < no; i++){ + for (unsigned int i = 0; i < no; i++) { tempLoc += getStringLen(tempLoc) + 1; } return getString(tempLoc); } - uint32_t AFRT::getFragmentRunCount(){ + uint32_t AFRT::getFragmentRunCount() { int tempLoc = 9; - for (unsigned int i = 0; i < getQualityEntryCount(); ++i){ + for (unsigned int i = 0; i < getQualityEntryCount(); ++i) { tempLoc += getStringLen(tempLoc) + 1; } return getInt32(tempLoc); } - void AFRT::setFragmentRun(afrt_runtable newRun, uint32_t no){ + void AFRT::setFragmentRun(afrt_runtable newRun, uint32_t no) { int tempLoc = 9; - for (unsigned int i = 0; i < getQualityEntryCount(); ++i){ + for (unsigned int i = 0; i < getQualityEntryCount(); ++i) { tempLoc += getStringLen(tempLoc) + 1; } int countLoc = tempLoc; unsigned int count = getInt32(countLoc); tempLoc += 4; - for (unsigned int i = 0; i < no; i++){ - if (i + 1 > count){ + for (unsigned int i = 0; i < no; i++) { + if (i + 1 > count) { setInt32(0, tempLoc); setInt64(0, tempLoc + 4); setInt32(1, tempLoc + 12); } - if (getInt32(tempLoc + 12) == 0){ + if (getInt32(tempLoc + 12) == 0) { tempLoc += 17; - }else{ + } else { tempLoc += 16; } } setInt32(newRun.firstFragment, tempLoc); setInt64(newRun.firstTimestamp, tempLoc + 4); setInt32(newRun.duration, tempLoc + 12); - if (newRun.duration == 0){ + if (newRun.duration == 0) { setInt8(newRun.discontinuity, tempLoc + 16); } - if (count < no + 1){ + if (count < no + 1) { setInt32(no + 1, countLoc); } } - afrt_runtable AFRT::getFragmentRun(uint32_t no){ + afrt_runtable AFRT::getFragmentRun(uint32_t no) { afrt_runtable res; - if (no > getFragmentRunCount()){ + if (no > getFragmentRunCount()) { return res; } int tempLoc = 9; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += 4; - for (unsigned int i = 0; i < no; i++){ - if (getInt32(tempLoc + 12) == 0){ + for (unsigned int i = 0; i < no; i++) { + if (getInt32(tempLoc + 12) == 0) { tempLoc += 17; - }else{ + } else { tempLoc += 16; } } res.firstFragment = getInt32(tempLoc); res.firstTimestamp = getInt64(tempLoc + 4); res.duration = getInt32(tempLoc + 12); - if (res.duration){ + if (res.duration) { res.discontinuity = getInt8(tempLoc + 16); - }else{ + } else { res.discontinuity = 0; } return res; } - std::string AFRT::toPrettyString(uint32_t indent){ + std::string AFRT::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[afrt] Fragment Run Table (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl; - if (getUpdate()){ + if (getUpdate()) { r << std::string(indent + 1, ' ') << "Update" << std::endl; - }else{ + } else { r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl; } r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl; r << std::string(indent + 1, ' ') << "QualitySegmentUrlModifiers (" << getQualityEntryCount() << ")" << std::endl; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl; } r << std::string(indent + 1, ' ') << "FragmentRunEntryTable (" << getFragmentRunCount() << ")" << std::endl; - for (unsigned int i = 0; i < getFragmentRunCount(); i++){ + for (unsigned int i = 0; i < getFragmentRunCount(); i++) { afrt_runtable myRun = getFragmentRun(i); - if (myRun.duration){ + if (myRun.duration) { r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale()) - << "s, " << ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl; - }else{ + << "s, " << ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl; + } else { r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale()) - << "s, discontinuity type " << myRun.discontinuity << std::endl; + << "s, discontinuity type " << myRun.discontinuity << std::endl; } } return r.str(); } - ASRT::ASRT(){ + ASRT::ASRT() { memcpy(data + 4, "asrt", 4); setVersion(0); setUpdate(0); } - void ASRT::setVersion(char newVersion){ + void ASRT::setVersion(char newVersion) { setInt8(newVersion, 0); } - uint32_t ASRT::getVersion(){ + uint32_t ASRT::getVersion() { return getInt8(0); } - void ASRT::setUpdate(uint32_t newUpdate){ + void ASRT::setUpdate(uint32_t newUpdate) { setInt24(newUpdate, 1); } - uint32_t ASRT::getUpdate(){ + uint32_t ASRT::getUpdate() { return getInt24(1); } - uint32_t ASRT::getQualityEntryCount(){ + uint32_t ASRT::getQualityEntryCount() { return getInt8(4); } - void ASRT::setQualityEntry(std::string & newEntry, uint32_t no){ + void ASRT::setQualityEntry(std::string & newEntry, uint32_t no) { int countLoc = 4; int tempLoc = countLoc + 1; //attempt to reach the wanted position unsigned int i; - for (i = 0; i < getQualityEntryCount() && i < no; ++i){ + for (i = 0; i < getQualityEntryCount() && i < no; ++i) { tempLoc += getStringLen(tempLoc) + 1; } //we are now either at the end, or at the right position //let's reserve any unreserved space... - if (no + 1 > getQualityEntryCount()){ + if (no + 1 > getQualityEntryCount()) { int amount = no + 1 - getQualityEntryCount(); - if ( !reserve(payloadOffset + tempLoc, 0, amount)){ + if (!reserve(payloadOffset + tempLoc, 0, amount)) { return; }; memset(data + payloadOffset + tempLoc, 0, amount); @@ -652,46 +652,46 @@ namespace MP4 { setString(newEntry, tempLoc); } - const char* ASRT::getQualityEntry(uint32_t no){ - if (no > getQualityEntryCount()){ + const char * ASRT::getQualityEntry(uint32_t no) { + if (no > getQualityEntryCount()) { return ""; } int tempLoc = 5; //position of qualityentry count; - for (unsigned int i = 0; i < no; i++){ + for (unsigned int i = 0; i < no; i++) { tempLoc += getStringLen(tempLoc) + 1; } return getString(tempLoc); } - uint32_t ASRT::getSegmentRunEntryCount(){ + uint32_t ASRT::getSegmentRunEntryCount() { int tempLoc = 5; //position of qualityentry count; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } return getInt32(tempLoc); } - void ASRT::setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no){ + void ASRT::setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no) { int tempLoc = 5; //position of qualityentry count; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { tempLoc += getStringLen(tempLoc) + 1; } int countLoc = tempLoc; tempLoc += 4 + no * 8; - if (no + 1 > getInt32(countLoc)){ + if (no + 1 > getInt32(countLoc)) { setInt32(no + 1, countLoc); //set new qualityEntryCount } setInt32(firstSegment, tempLoc); setInt32(fragmentsPerSegment, tempLoc + 4); } - asrt_runtable ASRT::getSegmentRun(uint32_t no){ + asrt_runtable ASRT::getSegmentRun(uint32_t no) { asrt_runtable res; - if (no >= getSegmentRunEntryCount()){ + if (no >= getSegmentRunEntryCount()) { return res; } int tempLoc = 5; //position of qualityentry count; - for (unsigned int i = 0; i < getQualityEntryCount(); ++i){ + for (unsigned int i = 0; i < getQualityEntryCount(); ++i) { tempLoc += getStringLen(tempLoc) + 1; } tempLoc += 4 + 8 * no; @@ -700,205 +700,205 @@ namespace MP4 { return res; } - std::string ASRT::toPrettyString(uint32_t indent){ + std::string ASRT::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[asrt] Segment Run Table (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl; - if (getUpdate()){ + if (getUpdate()) { r << std::string(indent + 1, ' ') << "Update" << std::endl; - }else{ + } else { r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl; } r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl; - for (unsigned int i = 0; i < getQualityEntryCount(); i++){ + for (unsigned int i = 0; i < getQualityEntryCount(); i++) { r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl; } r << std::string(indent + 1, ' ') << "SegmentRunEntryTable (" << getSegmentRunEntryCount() << ")" << std::endl; - for (unsigned int i = 0; i < getSegmentRunEntryCount(); i++){ + for (unsigned int i = 0; i < getSegmentRunEntryCount(); i++) { r << std::string(indent + 2, ' ') << i << ": First=" << getSegmentRun(i).firstSegment << ", FragmentsPerSegment=" - << getSegmentRun(i).fragmentsPerSegment << std::endl; + << getSegmentRun(i).fragmentsPerSegment << std::endl; } return r.str(); } - AFRA::AFRA(){ + AFRA::AFRA() { memcpy(data + 4, "afra", 4); setInt32(0, 9); //entrycount = 0 setFlags(0); } - void AFRA::setVersion(uint32_t newVersion){ + void AFRA::setVersion(uint32_t newVersion) { setInt8(newVersion, 0); } - uint32_t AFRA::getVersion(){ + uint32_t AFRA::getVersion() { return getInt8(0); } - void AFRA::setFlags(uint32_t newFlags){ + void AFRA::setFlags(uint32_t newFlags) { setInt24(newFlags, 1); } - uint32_t AFRA::getFlags(){ + uint32_t AFRA::getFlags() { return getInt24(1); } - void AFRA::setLongIDs(bool newVal){ - if (newVal){ + void AFRA::setLongIDs(bool newVal) { + if (newVal) { setInt8((getInt8(4) & 0x7F) + 0x80, 4); - }else{ + } else { setInt8((getInt8(4) & 0x7F), 4); } } - bool AFRA::getLongIDs(){ + bool AFRA::getLongIDs() { return getInt8(4) & 0x80; } - void AFRA::setLongOffsets(bool newVal){ - if (newVal){ + void AFRA::setLongOffsets(bool newVal) { + if (newVal) { setInt8((getInt8(4) & 0xBF) + 0x40, 4); - }else{ + } else { setInt8((getInt8(4) & 0xBF), 4); } } - bool AFRA::getLongOffsets(){ + bool AFRA::getLongOffsets() { return getInt8(4) & 0x40; } - void AFRA::setGlobalEntries(bool newVal){ - if (newVal){ + void AFRA::setGlobalEntries(bool newVal) { + if (newVal) { setInt8((getInt8(4) & 0xDF) + 0x20, 4); - }else{ + } else { setInt8((getInt8(4) & 0xDF), 4); } } - bool AFRA::getGlobalEntries(){ + bool AFRA::getGlobalEntries() { return getInt8(4) & 0x20; } - void AFRA::setTimeScale(uint32_t newVal){ + void AFRA::setTimeScale(uint32_t newVal) { setInt32(newVal, 5); } - uint32_t AFRA::getTimeScale(){ + uint32_t AFRA::getTimeScale() { return getInt32(5); } - uint32_t AFRA::getEntryCount(){ + uint32_t AFRA::getEntryCount() { return getInt32(9); } - void AFRA::setEntry(afraentry newEntry, uint32_t no){ + void AFRA::setEntry(afraentry newEntry, uint32_t no) { int entrysize = 12; - if (getLongOffsets()){ + if (getLongOffsets()) { entrysize = 16; } setInt64(newEntry.time, 13 + entrysize * no); - if (getLongOffsets()){ + if (getLongOffsets()) { setInt64(newEntry.offset, 21 + entrysize * no); - }else{ + } else { setInt32(newEntry.offset, 21 + entrysize * no); } - if (no + 1 > getEntryCount()){ + if (no + 1 > getEntryCount()) { setInt32(no + 1, 9); } } - afraentry AFRA::getEntry(uint32_t no){ + afraentry AFRA::getEntry(uint32_t no) { afraentry ret; int entrysize = 12; - if (getLongOffsets()){ + if (getLongOffsets()) { entrysize = 16; } ret.time = getInt64(13 + entrysize * no); - if (getLongOffsets()){ + if (getLongOffsets()) { ret.offset = getInt64(21 + entrysize * no); - }else{ + } else { ret.offset = getInt32(21 + entrysize * no); } return ret; } - uint32_t AFRA::getGlobalEntryCount(){ - if ( !getGlobalEntries()){ + uint32_t AFRA::getGlobalEntryCount() { + if (!getGlobalEntries()) { return 0; } int entrysize = 12; - if (getLongOffsets()){ + if (getLongOffsets()) { entrysize = 16; } return getInt32(13 + entrysize * getEntryCount()); } - void AFRA::setGlobalEntry(globalafraentry newEntry, uint32_t no){ + void AFRA::setGlobalEntry(globalafraentry newEntry, uint32_t no) { int offset = 13 + 12 * getEntryCount() + 4; - if (getLongOffsets()){ + if (getLongOffsets()) { offset = 13 + 16 * getEntryCount() + 4; } int entrysize = 20; - if (getLongIDs()){ + if (getLongIDs()) { entrysize += 4; } - if (getLongOffsets()){ + if (getLongOffsets()) { entrysize += 8; } setInt64(newEntry.time, offset + entrysize * no); - if (getLongIDs()){ + if (getLongIDs()) { setInt32(newEntry.segment, offset + entrysize * no + 8); setInt32(newEntry.fragment, offset + entrysize * no + 12); - }else{ + } else { setInt16(newEntry.segment, offset + entrysize * no + 8); setInt16(newEntry.fragment, offset + entrysize * no + 10); } - if (getLongOffsets()){ + if (getLongOffsets()) { setInt64(newEntry.afraoffset, offset + entrysize * no + entrysize - 16); setInt64(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 8); - }else{ + } else { setInt32(newEntry.afraoffset, offset + entrysize * no + entrysize - 8); setInt32(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 4); } - if (getInt32(offset - 4) < no + 1){ + if (getInt32(offset - 4) < no + 1) { setInt32(no + 1, offset - 4); } } - globalafraentry AFRA::getGlobalEntry(uint32_t no){ + globalafraentry AFRA::getGlobalEntry(uint32_t no) { globalafraentry ret; int offset = 13 + 12 * getEntryCount() + 4; - if (getLongOffsets()){ + if (getLongOffsets()) { offset = 13 + 16 * getEntryCount() + 4; } int entrysize = 20; - if (getLongIDs()){ + if (getLongIDs()) { entrysize += 4; } - if (getLongOffsets()){ + if (getLongOffsets()) { entrysize += 8; } ret.time = getInt64(offset + entrysize * no); - if (getLongIDs()){ + if (getLongIDs()) { ret.segment = getInt32(offset + entrysize * no + 8); ret.fragment = getInt32(offset + entrysize * no + 12); - }else{ + } else { ret.segment = getInt16(offset + entrysize * no + 8); ret.fragment = getInt16(offset + entrysize * no + 10); } - if (getLongOffsets()){ + if (getLongOffsets()) { ret.afraoffset = getInt64(offset + entrysize * no + entrysize - 16); ret.offsetfromafra = getInt64(offset + entrysize * no + entrysize - 8); - }else{ + } else { ret.afraoffset = getInt32(offset + entrysize * no + entrysize - 8); ret.offsetfromafra = getInt32(offset + entrysize * no + entrysize - 4); } return ret; } - std::string AFRA::toPrettyString(uint32_t indent){ + std::string AFRA::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[afra] Fragment Random Access (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl; @@ -910,18 +910,18 @@ namespace MP4 { uint32_t count = getEntryCount(); r << std::string(indent + 1, ' ') << "Entries (" << count << ") " << std::endl; - for (uint32_t i = 0; i < count; ++i){ + for (uint32_t i = 0; i < count; ++i) { afraentry tmpent = getEntry(i); r << std::string(indent + 1, ' ') << i << ": Time " << tmpent.time << ", Offset " << tmpent.offset << std::endl; } - if (getGlobalEntries()){ + if (getGlobalEntries()) { count = getGlobalEntryCount(); r << std::string(indent + 1, ' ') << "Global Entries (" << count << ") " << std::endl; - for (uint32_t i = 0; i < count; ++i){ + for (uint32_t i = 0; i < count; ++i) { globalafraentry tmpent = getGlobalEntry(i); r << std::string(indent + 1, ' ') << i << ": T " << tmpent.time << ", S" << tmpent.segment << "F" << tmpent.fragment << ", " - << tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl; + << tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl; } } return r.str(); diff --git a/lib/mp4_adobe.h b/lib/mp4_adobe.h index 3ab14fcc..ca8b42d0 100644 --- a/lib/mp4_adobe.h +++ b/lib/mp4_adobe.h @@ -4,17 +4,17 @@ namespace MP4 { //class Box; - - struct afrt_runtable{ - uint32_t firstFragment; - uint64_t firstTimestamp; - uint32_t duration; - uint32_t discontinuity; + + struct afrt_runtable { + uint32_t firstFragment; + uint64_t firstTimestamp; + uint32_t duration; + uint32_t discontinuity; }; //fragmentRun /// AFRT Box class - class AFRT: public Box{ + class AFRT: public Box { public: AFRT(); void setVersion(char newVersion); @@ -33,13 +33,13 @@ namespace MP4 { }; //AFRT Box - struct asrt_runtable{ - uint32_t firstSegment; - uint32_t fragmentsPerSegment; + struct asrt_runtable { + uint32_t firstSegment; + uint32_t fragmentsPerSegment; }; /// ASRT Box class - class ASRT: public Box{ + class ASRT: public Box { public: ASRT(); void setVersion(char newVersion); @@ -48,7 +48,7 @@ namespace MP4 { uint32_t getUpdate(); uint32_t getQualityEntryCount(); void setQualityEntry(std::string & newQuality, uint32_t no); - const char* getQualityEntry(uint32_t no); + const char * getQualityEntry(uint32_t no); uint32_t getSegmentRunEntryCount(); void setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no); asrt_runtable getSegmentRun(uint32_t no); @@ -57,7 +57,7 @@ namespace MP4 { //ASRT Box /// ABST Box class - class ABST: public Box{ + class ABST: public Box { public: ABST(); void setVersion(char newVersion); @@ -100,18 +100,18 @@ namespace MP4 { }; //ABST Box - struct afraentry{ - uint64_t time; - uint64_t offset; + struct afraentry { + uint64_t time; + uint64_t offset; }; - struct globalafraentry{ - uint64_t time; - uint32_t segment; - uint32_t fragment; - uint64_t afraoffset; - uint64_t offsetfromafra; + struct globalafraentry { + uint64_t time; + uint32_t segment; + uint32_t fragment; + uint64_t afraoffset; + uint64_t offsetfromafra; }; - class AFRA: public Box{ + class AFRA: public Box { public: AFRA(); void setVersion(uint32_t newVersion); diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp index 4daf0754..d098ff67 100644 --- a/lib/mp4_generic.cpp +++ b/lib/mp4_generic.cpp @@ -1,53 +1,53 @@ #include "mp4_generic.h" #include "defines.h" -namespace MP4{ - MFHD::MFHD(){ +namespace MP4 { + MFHD::MFHD() { memcpy(data + 4, "mfhd", 4); setInt32(0, 0); } - void MFHD::setSequenceNumber(uint32_t newSequenceNumber){ + void MFHD::setSequenceNumber(uint32_t newSequenceNumber) { setInt32(newSequenceNumber, 4); } - uint32_t MFHD::getSequenceNumber(){ + uint32_t MFHD::getSequenceNumber() { return getInt32(4); } - std::string MFHD::toPrettyString(uint32_t indent){ + std::string MFHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[mfhd] Movie Fragment Header (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "SequenceNumber " << getSequenceNumber() << std::endl; return r.str(); } - MOOF::MOOF(){ + MOOF::MOOF() { memcpy(data + 4, "moof", 4); } - TRAF::TRAF(){ + TRAF::TRAF() { memcpy(data + 4, "traf", 4); } - uint32_t TRAF::getContentCount(){ + uint32_t TRAF::getContentCount() { int res = 0; unsigned int tempLoc = 0; - while (tempLoc < boxedSize() - 8){ + while (tempLoc < boxedSize() - 8) { res++; tempLoc += getBoxLen(tempLoc); } return res; } - void TRAF::setContent(Box & newContent, uint32_t no){ + void TRAF::setContent(Box & newContent, uint32_t no) { int tempLoc = 0; unsigned int contentCount = getContentCount(); - for (unsigned int i = 0; i < no; i++){ - if (i < contentCount){ + for (unsigned int i = 0; i < no; i++) { + if (i < contentCount) { tempLoc += getBoxLen(tempLoc); - }else{ - if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){ + } else { + if (!reserve(tempLoc, 0, (no - contentCount) * 8)) { return; }; memset(data + tempLoc, 0, (no - contentCount) * 8); @@ -58,225 +58,225 @@ namespace MP4{ setBox(newContent, tempLoc); } - Box & TRAF::getContent(uint32_t no){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if (no > getContentCount()){ + Box & TRAF::getContent(uint32_t no) { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (no > getContentCount()) { return ret; } unsigned int i = 0; int tempLoc = 0; - while (i < no){ + while (i < no) { tempLoc += getBoxLen(tempLoc); i++; } return getBox(tempLoc); } - std::string TRAF::toPrettyString(uint32_t indent){ + std::string TRAF::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[traf] Track Fragment Box (" << boxedSize() << ")" << std::endl; int contentCount = getContentCount(); - for (int i = 0; i < contentCount; i++){ - Box curBox = Box(getContent(i).asBox(),false); + for (int i = 0; i < contentCount; i++) { + Box curBox = Box(getContent(i).asBox(), false); r << curBox.toPrettyString(indent + 1); } return r.str(); } - TRUN::TRUN(){ + TRUN::TRUN() { memcpy(data + 4, "trun", 4); } - void TRUN::setFlags(uint32_t newFlags){ + void TRUN::setFlags(uint32_t newFlags) { setInt24(newFlags, 1); } - uint32_t TRUN::getFlags(){ + uint32_t TRUN::getFlags() { return getInt24(1); } - void TRUN::setDataOffset(uint32_t newOffset){ - if (getFlags() & trundataOffset){ + void TRUN::setDataOffset(uint32_t newOffset) { + if (getFlags() & trundataOffset) { setInt32(newOffset, 8); } } - uint32_t TRUN::getDataOffset(){ - if (getFlags() & trundataOffset){ + uint32_t TRUN::getDataOffset() { + if (getFlags() & trundataOffset) { return getInt32(8); - }else{ + } else { return 0; } } - void TRUN::setFirstSampleFlags(uint32_t newSampleFlags){ - if ( !(getFlags() & trunfirstSampleFlags)){ + void TRUN::setFirstSampleFlags(uint32_t newSampleFlags) { + if (!(getFlags() & trunfirstSampleFlags)) { return; } - if (getFlags() & trundataOffset){ + if (getFlags() & trundataOffset) { setInt32(newSampleFlags, 12); - }else{ + } else { setInt32(newSampleFlags, 8); } } - uint32_t TRUN::getFirstSampleFlags(){ - if ( !(getFlags() & trunfirstSampleFlags)){ + uint32_t TRUN::getFirstSampleFlags() { + if (!(getFlags() & trunfirstSampleFlags)) { return 0; } - if (getFlags() & trundataOffset){ + if (getFlags() & trundataOffset) { return getInt32(12); - }else{ + } else { return getInt32(8); } } - uint32_t TRUN::getSampleInformationCount(){ + uint32_t TRUN::getSampleInformationCount() { return getInt32(4); } - void TRUN::setSampleInformation(trunSampleInformation newSample, uint32_t no){ + void TRUN::setSampleInformation(trunSampleInformation newSample, uint32_t no) { uint32_t flags = getFlags(); uint32_t sampInfoSize = 0; - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { sampInfoSize += 4; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { sampInfoSize += 4; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { sampInfoSize += 4; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { sampInfoSize += 4; } uint32_t offset = 8; - if (flags & trundataOffset){ + if (flags & trundataOffset) { offset += 4; } - if (flags & trunfirstSampleFlags){ + if (flags & trunfirstSampleFlags) { offset += 4; } uint32_t innerOffset = 0; - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { setInt32(newSample.sampleDuration, offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { setInt32(newSample.sampleSize, offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { setInt32(newSample.sampleFlags, offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { setInt32(newSample.sampleOffset, offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (getSampleInformationCount() < no + 1){ + if (getSampleInformationCount() < no + 1) { setInt32(no + 1, 4); } } - trunSampleInformation TRUN::getSampleInformation(uint32_t no){ + trunSampleInformation TRUN::getSampleInformation(uint32_t no) { trunSampleInformation ret; ret.sampleDuration = 0; ret.sampleSize = 0; ret.sampleFlags = 0; ret.sampleOffset = 0; - if (getSampleInformationCount() < no + 1){ + if (getSampleInformationCount() < no + 1) { return ret; } uint32_t flags = getFlags(); uint32_t sampInfoSize = 0; - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { sampInfoSize += 4; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { sampInfoSize += 4; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { sampInfoSize += 4; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { sampInfoSize += 4; } uint32_t offset = 8; - if (flags & trundataOffset){ + if (flags & trundataOffset) { offset += 4; } - if (flags & trunfirstSampleFlags){ + if (flags & trunfirstSampleFlags) { offset += 4; } uint32_t innerOffset = 0; - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { ret.sampleDuration = getInt32(offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { ret.sampleSize = getInt32(offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { ret.sampleFlags = getInt32(offset + no * sampInfoSize + innerOffset); innerOffset += 4; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { ret.sampleOffset = getInt32(offset + no * sampInfoSize + innerOffset); innerOffset += 4; } return ret; } - std::string TRUN::toPrettyString(uint32_t indent){ + std::string TRUN::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[trun] Track Fragment Run (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl; uint32_t flags = getFlags(); r << std::string(indent + 1, ' ') << "Flags"; - if (flags & trundataOffset){ + if (flags & trundataOffset) { r << " dataOffset"; } - if (flags & trunfirstSampleFlags){ + if (flags & trunfirstSampleFlags) { r << " firstSampleFlags"; } - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { r << " sampleDuration"; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { r << " sampleSize"; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { r << " sampleFlags"; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { r << " sampleOffsets"; } r << std::endl; - if (flags & trundataOffset){ + if (flags & trundataOffset) { r << std::string(indent + 1, ' ') << "Data Offset " << getDataOffset() << std::endl; } - if (flags & trundataOffset){ + if (flags & trundataOffset) { r << std::string(indent + 1, ' ') << "Sample Flags" << prettySampleFlags(getFirstSampleFlags()) << std::endl; } r << std::string(indent + 1, ' ') << "SampleInformation (" << getSampleInformationCount() << "):" << std::endl; - for (unsigned int i = 0; i < getSampleInformationCount(); ++i){ + for (unsigned int i = 0; i < getSampleInformationCount(); ++i) { r << std::string(indent + 2, ' ') << "[" << i << "] "; trunSampleInformation samp = getSampleInformation(i); - if (flags & trunsampleDuration){ + if (flags & trunsampleDuration) { r << "Duration=" << samp.sampleDuration << " "; } - if (flags & trunsampleSize){ + if (flags & trunsampleSize) { r << "Size=" << samp.sampleSize << " "; } - if (flags & trunsampleFlags){ + if (flags & trunsampleFlags) { r << "Flags=" << prettySampleFlags(samp.sampleFlags) << " "; } - if (flags & trunsampleOffsets){ + if (flags & trunsampleOffsets) { r << "Offset=" << samp.sampleOffset << " "; } r << std::endl; @@ -285,234 +285,234 @@ namespace MP4{ return r.str(); } - std::string prettySampleFlags(uint32_t flag){ + std::string prettySampleFlags(uint32_t flag) { std::stringstream r; - if (flag & noIPicture){ + if (flag & noIPicture) { r << " noIPicture"; } - if (flag & isIPicture){ + if (flag & isIPicture) { r << " isIPicture"; } - if (flag & noDisposable){ + if (flag & noDisposable) { r << " noDisposable"; } - if (flag & isDisposable){ + if (flag & isDisposable) { r << " isDisposable"; } - if (flag & isRedundant){ + if (flag & isRedundant) { r << " isRedundant"; } - if (flag & noRedundant){ + if (flag & noRedundant) { r << " noRedundant"; } - if (flag & noKeySample){ + if (flag & noKeySample) { r << " noKeySample"; - }else{ + } else { r << " isKeySample"; } return r.str(); } - TFHD::TFHD(){ + TFHD::TFHD() { memcpy(data + 4, "tfhd", 4); } - void TFHD::setFlags(uint32_t newFlags){ + void TFHD::setFlags(uint32_t newFlags) { setInt24(newFlags, 1); } - uint32_t TFHD::getFlags(){ + uint32_t TFHD::getFlags() { return getInt24(1); } - void TFHD::setTrackID(uint32_t newID){ + void TFHD::setTrackID(uint32_t newID) { setInt32(newID, 4); } - uint32_t TFHD::getTrackID(){ + uint32_t TFHD::getTrackID() { return getInt32(4); } - void TFHD::setBaseDataOffset(uint64_t newOffset){ - if (getFlags() & tfhdBaseOffset){ + void TFHD::setBaseDataOffset(uint64_t newOffset) { + if (getFlags() & tfhdBaseOffset) { setInt64(newOffset, 8); } } - uint64_t TFHD::getBaseDataOffset(){ - if (getFlags() & tfhdBaseOffset){ + uint64_t TFHD::getBaseDataOffset() { + if (getFlags() & tfhdBaseOffset) { return getInt64(8); - }else{ + } else { return 0; } } - void TFHD::setSampleDescriptionIndex(uint32_t newIndex){ - if ( !(getFlags() & tfhdSampleDesc)){ + void TFHD::setSampleDescriptionIndex(uint32_t newIndex) { + if (!(getFlags() & tfhdSampleDesc)) { return; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } setInt32(newIndex, offset); } - uint32_t TFHD::getSampleDescriptionIndex(){ - if ( !(getFlags() & tfhdSampleDesc)){ + uint32_t TFHD::getSampleDescriptionIndex() { + if (!(getFlags() & tfhdSampleDesc)) { return 0; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } return getInt32(offset); } - void TFHD::setDefaultSampleDuration(uint32_t newDuration){ - if ( !(getFlags() & tfhdSampleDura)){ + void TFHD::setDefaultSampleDuration(uint32_t newDuration) { + if (!(getFlags() & tfhdSampleDura)) { return; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } setInt32(newDuration, offset); } - uint32_t TFHD::getDefaultSampleDuration(){ - if ( !(getFlags() & tfhdSampleDura)){ + uint32_t TFHD::getDefaultSampleDuration() { + if (!(getFlags() & tfhdSampleDura)) { return 0; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } return getInt32(offset); } - void TFHD::setDefaultSampleSize(uint32_t newSize){ - if ( !(getFlags() & tfhdSampleSize)){ + void TFHD::setDefaultSampleSize(uint32_t newSize) { + if (!(getFlags() & tfhdSampleSize)) { return; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } - if (getFlags() & tfhdSampleDura){ + if (getFlags() & tfhdSampleDura) { offset += 4; } setInt32(newSize, offset); } - uint32_t TFHD::getDefaultSampleSize(){ - if ( !(getFlags() & tfhdSampleSize)){ + uint32_t TFHD::getDefaultSampleSize() { + if (!(getFlags() & tfhdSampleSize)) { return 0; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } - if (getFlags() & tfhdSampleDura){ + if (getFlags() & tfhdSampleDura) { offset += 4; } return getInt32(offset); } - void TFHD::setDefaultSampleFlags(uint32_t newFlags){ - if ( !(getFlags() & tfhdSampleFlag)){ + void TFHD::setDefaultSampleFlags(uint32_t newFlags) { + if (!(getFlags() & tfhdSampleFlag)) { return; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } - if (getFlags() & tfhdSampleDura){ + if (getFlags() & tfhdSampleDura) { offset += 4; } - if (getFlags() & tfhdSampleSize){ + if (getFlags() & tfhdSampleSize) { offset += 4; } setInt32(newFlags, offset); } - uint32_t TFHD::getDefaultSampleFlags(){ - if ( !(getFlags() & tfhdSampleFlag)){ + uint32_t TFHD::getDefaultSampleFlags() { + if (!(getFlags() & tfhdSampleFlag)) { return 0; } int offset = 8; - if (getFlags() & tfhdBaseOffset){ + if (getFlags() & tfhdBaseOffset) { offset += 8; } - if (getFlags() & tfhdSampleDesc){ + if (getFlags() & tfhdSampleDesc) { offset += 4; } - if (getFlags() & tfhdSampleDura){ + if (getFlags() & tfhdSampleDura) { offset += 4; } - if (getFlags() & tfhdSampleSize){ + if (getFlags() & tfhdSampleSize) { offset += 4; } return getInt32(offset); } - std::string TFHD::toPrettyString(uint32_t indent){ + std::string TFHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[tfhd] Track Fragment Header (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl; uint32_t flags = getFlags(); r << std::string(indent + 1, ' ') << "Flags"; - if (flags & tfhdBaseOffset){ + if (flags & tfhdBaseOffset) { r << " BaseOffset"; } - if (flags & tfhdSampleDesc){ + if (flags & tfhdSampleDesc) { r << " SampleDesc"; } - if (flags & tfhdSampleDura){ + if (flags & tfhdSampleDura) { r << " SampleDura"; } - if (flags & tfhdSampleSize){ + if (flags & tfhdSampleSize) { r << " SampleSize"; } - if (flags & tfhdSampleFlag){ + if (flags & tfhdSampleFlag) { r << " SampleFlag"; } - if (flags & tfhdNoDuration){ + if (flags & tfhdNoDuration) { r << " NoDuration"; } r << std::endl; r << std::string(indent + 1, ' ') << "TrackID " << getTrackID() << std::endl; - if (flags & tfhdBaseOffset){ + if (flags & tfhdBaseOffset) { r << std::string(indent + 1, ' ') << "Base Offset " << getBaseDataOffset() << std::endl; } - if (flags & tfhdSampleDesc){ + if (flags & tfhdSampleDesc) { r << std::string(indent + 1, ' ') << "Sample Description Index " << getSampleDescriptionIndex() << std::endl; } - if (flags & tfhdSampleDura){ + if (flags & tfhdSampleDura) { r << std::string(indent + 1, ' ') << "Default Sample Duration " << getDefaultSampleDuration() << std::endl; } - if (flags & tfhdSampleSize){ + if (flags & tfhdSampleSize) { r << std::string(indent + 1, ' ') << "Default Same Size " << getDefaultSampleSize() << std::endl; } - if (flags & tfhdSampleFlag){ + if (flags & tfhdSampleFlag) { r << std::string(indent + 1, ' ') << "Default Sample Flags " << prettySampleFlags(getDefaultSampleFlags()) << std::endl; } @@ -520,95 +520,95 @@ namespace MP4{ } - AVCC::AVCC(){ + AVCC::AVCC() { memcpy(data + 4, "avcC", 4); setInt8(0xFF, 4); //reserved + 4-bytes NAL length } - void AVCC::setVersion(uint32_t newVersion){ + void AVCC::setVersion(uint32_t newVersion) { setInt8(newVersion, 0); } - uint32_t AVCC::getVersion(){ + uint32_t AVCC::getVersion() { return getInt8(0); } - void AVCC::setProfile(uint32_t newProfile){ + void AVCC::setProfile(uint32_t newProfile) { setInt8(newProfile, 1); } - uint32_t AVCC::getProfile(){ + uint32_t AVCC::getProfile() { return getInt8(1); } - void AVCC::setCompatibleProfiles(uint32_t newCompatibleProfiles){ + void AVCC::setCompatibleProfiles(uint32_t newCompatibleProfiles) { setInt8(newCompatibleProfiles, 2); } - uint32_t AVCC::getCompatibleProfiles(){ + uint32_t AVCC::getCompatibleProfiles() { return getInt8(2); } - void AVCC::setLevel(uint32_t newLevel){ + void AVCC::setLevel(uint32_t newLevel) { setInt8(newLevel, 3); } - uint32_t AVCC::getLevel(){ + uint32_t AVCC::getLevel() { return getInt8(3); } - void AVCC::setSPSNumber(uint32_t newSPSNumber){ + void AVCC::setSPSNumber(uint32_t newSPSNumber) { setInt8(newSPSNumber, 5); } - uint32_t AVCC::getSPSNumber(){ + uint32_t AVCC::getSPSNumber() { return getInt8(5); } - void AVCC::setSPS(std::string newSPS){ + void AVCC::setSPS(std::string newSPS) { setInt16(newSPS.size(), 6); - for (unsigned int i = 0; i < newSPS.size(); i++){ + for (unsigned int i = 0; i < newSPS.size(); i++) { setInt8(newSPS[i], 8 + i); } //not null-terminated } - uint32_t AVCC::getSPSLen(){ + uint32_t AVCC::getSPSLen() { return getInt16(6); } - char* AVCC::getSPS(){ + char * AVCC::getSPS() { return payload() + 8; } - void AVCC::setPPSNumber(uint32_t newPPSNumber){ + void AVCC::setPPSNumber(uint32_t newPPSNumber) { int offset = 8 + getSPSLen(); setInt8(newPPSNumber, offset); } - uint32_t AVCC::getPPSNumber(){ + uint32_t AVCC::getPPSNumber() { int offset = 8 + getSPSLen(); return getInt8(offset); } - void AVCC::setPPS(std::string newPPS){ + void AVCC::setPPS(std::string newPPS) { int offset = 8 + getSPSLen() + 1; setInt16(newPPS.size(), offset); - for (unsigned int i = 0; i < newPPS.size(); i++){ + for (unsigned int i = 0; i < newPPS.size(); i++) { setInt8(newPPS[i], offset + 2 + i); } //not null-terminated } - uint32_t AVCC::getPPSLen(){ + uint32_t AVCC::getPPSLen() { int offset = 8 + getSPSLen() + 1; return getInt16(offset); } - char* AVCC::getPPS(){ + char * AVCC::getPPS() { int offset = 8 + getSPSLen() + 3; return payload() + offset; } - std::string AVCC::toPrettyString(uint32_t indent){ + std::string AVCC::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[avcC] H.264 Init Data (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl; @@ -622,7 +622,7 @@ namespace MP4{ return r.str(); } - std::string AVCC::asAnnexB(){ + std::string AVCC::asAnnexB() { std::stringstream r; r << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01; r.write(getSPS(), getSPSLen()); @@ -631,16 +631,16 @@ namespace MP4{ return r.str(); } - void AVCC::setPayload(std::string newPayload){ - if ( !reserve(0, payloadSize(), newPayload.size())){ + void AVCC::setPayload(std::string newPayload) { + if (!reserve(0, payloadSize(), newPayload.size())) { DEBUG_MSG(DLVL_ERROR, "Cannot allocate enough memory for payload"); return; } - memcpy((char*)payload(), (char*)newPayload.c_str(), newPayload.size()); + memcpy((char *)payload(), (char *)newPayload.c_str(), newPayload.size()); } - + //fullbox, start at 4 - ESDS::ESDS(){ + ESDS::ESDS() { memcpy(data + 4, "esds", 4); setESDescriptorType(0x03); setExtendedESDescriptorType(0x808080); @@ -654,11 +654,11 @@ namespace MP4{ setSLConfigExtendedDescriptorTypeTag(0x808010); setSLValue(0x02); } - - ESDS::ESDS(std::string init, uint32_t bps){ + + ESDS::ESDS(std::string init, uint32_t bps) { memcpy(data + 4, "esds", 4); char temp[] = {0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x80, 0x80, 0x00, 0x00, 0x02, 0x10, 0x04, 0x80, 0x80, 0x80, 0x00, 0x40, 0x15, 0x13, 0x12, 0xD0, 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x80, 0x80, 0x05}; - setString(temp, 0x23,0); + setString(temp, 0x23, 0); setESDescriptorTypeLength(32 + init.size()); setDecoderConfigDescriptorTypeLength(18 + init.size()); setAverageBitRate(bps * 8); @@ -666,209 +666,209 @@ namespace MP4{ char temp2[] = {0x05, 0x80, 0x80, 0x10, 0x01, 0x02}; setString(temp2, 0x06, 0x23 + 32 + init.size()); } - - char ESDS::getESDescriptorType(){ + + char ESDS::getESDescriptorType() { return getInt8(4); } - - void ESDS::setESDescriptorType(char newVal){ - setInt8(newVal,4); + + void ESDS::setESDescriptorType(char newVal) { + setInt8(newVal, 4); } - - uint32_t ESDS::getExtendedESDescriptorType(){ + + uint32_t ESDS::getExtendedESDescriptorType() { return getInt24(5); } //3 bytes - void ESDS::setExtendedESDescriptorType(uint32_t newVal){ - setInt24(newVal,5); + void ESDS::setExtendedESDescriptorType(uint32_t newVal) { + setInt24(newVal, 5); } //3 bytes - char ESDS::getESDescriptorTypeLength(){ - return getInt8(8); + char ESDS::getESDescriptorTypeLength() { + return getInt8(8); } - - void ESDS::setESDescriptorTypeLength(char newVal){ - setInt8(newVal,8); + + void ESDS::setESDescriptorTypeLength(char newVal) { + setInt8(newVal, 8); } //ESID 2 bytes - uint16_t ESDS::getESID(){ + uint16_t ESDS::getESID() { return getInt16(9); } - - void ESDS::setESID(uint16_t newVal){ + + void ESDS::setESID(uint16_t newVal) { setInt16(newVal, 9); } - + //stream priority 1 byte - char ESDS::getStreamPriority(){ + char ESDS::getStreamPriority() { return getInt8(11); } - - void ESDS::setStreamPriority(char newVal){ + + void ESDS::setStreamPriority(char newVal) { setInt8(newVal, 11); } - + //decoder config descriptor tag 1byte - char ESDS::getDecoderConfigDescriptorTag(){ + char ESDS::getDecoderConfigDescriptorTag() { return getInt8(12); } - - void ESDS::setDecoderConfigDescriptorTag(char newVal){ + + void ESDS::setDecoderConfigDescriptorTag(char newVal) { setInt8(newVal, 12); } - + //extended decoder config descriptor tag 3 bytes - uint32_t ESDS::getExtendedDecoderConfigDescriptorTag(){ + uint32_t ESDS::getExtendedDecoderConfigDescriptorTag() { return getInt24(13); } //3 bytes - void ESDS::setExtendedDecoderConfigDescriptorTag(uint32_t newVal){ + void ESDS::setExtendedDecoderConfigDescriptorTag(uint32_t newVal) { setInt24(newVal, 13); } //3 bytes //decoder config descriptor type length - char ESDS::getDecoderConfigDescriptorTypeLength(){ + char ESDS::getDecoderConfigDescriptorTypeLength() { return getInt8(16); } - - void ESDS::setDecoderConfigDescriptorTypeLength(char newVal){ + + void ESDS::setDecoderConfigDescriptorTypeLength(char newVal) { setInt8(newVal, 16); } //Note: count 8 bytes extra in the next four functions - char ESDS::getByteObjectTypeID(){ - return getInt8(17); + char ESDS::getByteObjectTypeID() { + return getInt8(17); } - - void ESDS::setByteObjectTypeID(char newVal){ - setInt8(newVal,17); + + void ESDS::setByteObjectTypeID(char newVal) { + setInt8(newVal, 17); } - - char ESDS::getStreamType(){ - return getInt8(18) >> 2; + + char ESDS::getStreamType() { + return getInt8(18) >> 2; } //6 bits - void ESDS::setStreamType(char newVal){ + void ESDS::setStreamType(char newVal) { setInt8(((newVal << 2) & 0xFC) + (getInt8(18) & 0x03), 18); } //6 bits - bool ESDS::getUpstreamFlag(){ - return (((getInt8(18) >> 1) & 0x01) == 1); + bool ESDS::getUpstreamFlag() { + return (((getInt8(18) >> 1) & 0x01) == 1); } - - void ESDS::setUpstreamFlag(bool newVal){ - setInt8((getStreamType()<<2) + ((uint8_t)newVal << 1) + (uint8_t)getReservedFlag() , 18); + + void ESDS::setUpstreamFlag(bool newVal) { + setInt8((getStreamType() << 2) + ((uint8_t)newVal << 1) + (uint8_t)getReservedFlag() , 18); } - - bool ESDS::getReservedFlag(){ - return ((getInt8(18) & 0x01) == 1); + + bool ESDS::getReservedFlag() { + return ((getInt8(18) & 0x01) == 1); } - - void ESDS::setReservedFlag(bool newVal){ + + void ESDS::setReservedFlag(bool newVal) { setInt8((getInt8(18) & 0xFE) + (int)newVal, 18); } - - uint32_t ESDS::getBufferSize(){ - return getInt24(19); + + uint32_t ESDS::getBufferSize() { + return getInt24(19); } //3 bytes - void ESDS::setBufferSize(uint32_t newVal){ - setInt24(newVal,19); + void ESDS::setBufferSize(uint32_t newVal) { + setInt24(newVal, 19); } //3 bytes - uint32_t ESDS::getMaximumBitRate(){ - return getInt32(22); + uint32_t ESDS::getMaximumBitRate() { + return getInt32(22); } - - void ESDS::setMaximumBitRate(uint32_t newVal){ - setInt32(newVal,22); + + void ESDS::setMaximumBitRate(uint32_t newVal) { + setInt32(newVal, 22); } - - uint32_t ESDS::getAverageBitRate(){ - return getInt32(26); + + uint32_t ESDS::getAverageBitRate() { + return getInt32(26); } - - void ESDS::setAverageBitRate(uint32_t newVal){ - setInt32(newVal,26); + + void ESDS::setAverageBitRate(uint32_t newVal) { + setInt32(newVal, 26); } - - char ESDS::getDecoderDescriptorTypeTag(){ + + char ESDS::getDecoderDescriptorTypeTag() { return getInt8(30); } - - void ESDS::setDecoderDescriptorTypeTag(char newVal){ - setInt8(newVal,30); + + void ESDS::setDecoderDescriptorTypeTag(char newVal) { + setInt8(newVal, 30); } - - uint32_t ESDS::getExtendedDecoderDescriptorTypeTag(){ + + uint32_t ESDS::getExtendedDecoderDescriptorTypeTag() { return getInt24(31); } - + //3 bytes - void ESDS::setExtendedDecoderDescriptorTypeTag(uint32_t newVal){ + void ESDS::setExtendedDecoderDescriptorTypeTag(uint32_t newVal) { setInt24(newVal, 31); } //3 bytes - char ESDS::getConfigDescriptorTypeLength(){ + char ESDS::getConfigDescriptorTypeLength() { return getInt8(34); } - - void ESDS::setConfigDescriptorTypeLength(char newVal){ + + void ESDS::setConfigDescriptorTypeLength(char newVal) { setInt8(newVal, 34); } - - std::string ESDS::getESHeaderStartCodes(){ + + std::string ESDS::getESHeaderStartCodes() { std::string result; - for (int i = 0; i < getInt8(34); i++){ + for (int i = 0; i < getInt8(34); i++) { result += getInt8(35 + i); } return result; } - - void ESDS::setESHeaderStartCodes(std::string newVal){ + + void ESDS::setESHeaderStartCodes(std::string newVal) { setConfigDescriptorTypeLength(newVal.size()); - for (unsigned int i = 0; i < newVal.size(); i++){ - setInt8(newVal[i],35+i); + for (unsigned int i = 0; i < newVal.size(); i++) { + setInt8(newVal[i], 35 + i); } } - - char ESDS::getSLConfigDescriptorTypeTag(){ - return getInt8(35 + getInt8(34)); + + char ESDS::getSLConfigDescriptorTypeTag() { + return getInt8(35 + getInt8(34)); } - - void ESDS::setSLConfigDescriptorTypeTag(char newVal){ + + void ESDS::setSLConfigDescriptorTypeTag(char newVal) { setInt8(newVal, 35 + getInt8(34)); } - - uint32_t ESDS::getSLConfigExtendedDescriptorTypeTag(){ - return getInt24(36 + getInt8(34)); + + uint32_t ESDS::getSLConfigExtendedDescriptorTypeTag() { + return getInt24(36 + getInt8(34)); } //3 bytes - void ESDS::setSLConfigExtendedDescriptorTypeTag(uint32_t newVal){ + void ESDS::setSLConfigExtendedDescriptorTypeTag(uint32_t newVal) { setInt24(newVal, 36 + getInt8(34)); } //3 bytes - char ESDS::getSLDescriptorTypeLength(){ + char ESDS::getSLDescriptorTypeLength() { return getInt8(39 + getInt8(34)); } - - void ESDS::setSLDescriptorTypeLength(char newVal){ + + void ESDS::setSLDescriptorTypeLength(char newVal) { setInt8(newVal, 39 + getInt8(34)); } - - char ESDS::getSLValue(){ + + char ESDS::getSLValue() { return getInt8(40 + getInt8(34)); } - - void ESDS::setSLValue(char newVal){ + + void ESDS::setSLValue(char newVal) { setInt8(newVal, 40 + getInt8(34)); } - - std::string ESDS::toPrettyString(uint32_t indent){ + + std::string ESDS::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[esds] ES Descriptor Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); - r << std::string(indent + 1, ' ') << "ESDescriptorType: 0x" << std::hex << (int)getESDescriptorType() << std::dec << std::endl; + r << std::string(indent + 1, ' ') << "ESDescriptorType: 0x" << std::hex << (int)getESDescriptorType() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "ExtendedESDescriptorType: 0x" << std::hex << (int)getExtendedESDescriptorType() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "ESDescriptorTypeLength:" << (int)getESDescriptorTypeLength() << std::endl; r << std::string(indent + 1, ' ') << "ESID: 0x" << std::hex << (int)getESID() << std::dec << std::endl; @@ -886,7 +886,7 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "ExtendedDecoderDescriptorTypeTag: 0x" << std::hex << (int)getExtendedDecoderDescriptorTypeTag() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "ConfigDescriptorTypeLength: 0x" << std::hex << (int)getConfigDescriptorTypeLength() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "ESHeaderStartCodes: 0x"; - for (unsigned int i = 0; i= boxedSize()){ - if ( !reserve(payloadOffset, 0, 4)){ + + void FTYP::setMajorBrand(const char * newMajorBrand) { + if (payloadOffset + 3 >= boxedSize()) { + if (!reserve(payloadOffset, 0, 4)) { return; } } memcpy(data + payloadOffset, newMajorBrand, 4); } - - std::string FTYP::getMajorBrand(){ + + std::string FTYP::getMajorBrand() { return std::string(data + payloadOffset, 4); } - - void FTYP::setMinorVersion(const char * newMinorVersion){ - if (payloadOffset + 7 >= boxedSize()){ - if ( !reserve(payloadOffset+4, 0, 4)){ + + void FTYP::setMinorVersion(const char * newMinorVersion) { + if (payloadOffset + 7 >= boxedSize()) { + if (!reserve(payloadOffset + 4, 0, 4)) { return; } } memcpy(data + payloadOffset + 4, newMinorVersion, 4); } - - std::string FTYP::getMinorVersion(){ - return std::string(data+payloadOffset+4, 4); + + std::string FTYP::getMinorVersion() { + return std::string(data + payloadOffset + 4, 4); } - - size_t FTYP::getCompatibleBrandsCount(){ + + size_t FTYP::getCompatibleBrandsCount() { return (payloadSize() - 8) / 4; } - - void FTYP::setCompatibleBrands(const char * newCompatibleBrand, size_t index){ - if (payloadOffset + 8+index*4 + 3 >= boxedSize()){ - if ( !reserve(payloadOffset+8+index*4, 0, 4)){ + + void FTYP::setCompatibleBrands(const char * newCompatibleBrand, size_t index) { + if (payloadOffset + 8 + index * 4 + 3 >= boxedSize()) { + if (!reserve(payloadOffset + 8 + index * 4, 0, 4)) { return; } } - memcpy(data + payloadOffset+8+index*4, newCompatibleBrand, 4); + memcpy(data + payloadOffset + 8 + index * 4, newCompatibleBrand, 4); } - - std::string FTYP::getCompatibleBrands(size_t index){ - if (index >= getCompatibleBrandsCount()){ + + std::string FTYP::getCompatibleBrands(size_t index) { + if (index >= getCompatibleBrandsCount()) { return ""; } - return std::string(data+payloadOffset+8 + (index * 4), 4); + return std::string(data + payloadOffset + 8 + (index * 4), 4); } - - std::string FTYP::toPrettyString(uint32_t indent){ + + std::string FTYP::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[ftyp] File Type (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "MajorBrand: " << getMajorBrand() << std::endl; r << std::string(indent + 1, ' ') << "MinorVersion: " << getMinorVersion() << std::endl; r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl; - for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++){ + for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++) { r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: " << getCompatibleBrands(i) << std::endl; } return r.str(); } - - MOOV::MOOV(){ + + MOOV::MOOV() { memcpy(data + 4, "moov", 4); } - - MVEX::MVEX(){ + + MVEX::MVEX() { memcpy(data + 4, "mvex", 4); } - - TREX::TREX(){ + + TREX::TREX() { memcpy(data + 4, "trex", 4); } - - void TREX::setTrackID(uint32_t newTrackID){ + + void TREX::setTrackID(uint32_t newTrackID) { setInt32(newTrackID, 0); } - - uint32_t TREX::getTrackID(){ + + uint32_t TREX::getTrackID() { return getInt32(0); } - - void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex){ - setInt32(newDefaultSampleDescriptionIndex,4); + + void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex) { + setInt32(newDefaultSampleDescriptionIndex, 4); } - - uint32_t TREX::getDefaultSampleDescriptionIndex(){ + + uint32_t TREX::getDefaultSampleDescriptionIndex() { return getInt32(4); } - - void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration){ - setInt32(newDefaultSampleDuration,8); + + void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration) { + setInt32(newDefaultSampleDuration, 8); } - - uint32_t TREX::getDefaultSampleDuration(){ + + uint32_t TREX::getDefaultSampleDuration() { return getInt32(8); } - - void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize){ - setInt32(newDefaultSampleSize,12); + + void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize) { + setInt32(newDefaultSampleSize, 12); } - - uint32_t TREX::getDefaultSampleSize(){ + + uint32_t TREX::getDefaultSampleSize() { return getInt32(12); } - - void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags){ - setInt32(newDefaultSampleFlags,16); + + void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags) { + setInt32(newDefaultSampleFlags, 16); } - - uint32_t TREX::getDefaultSampleFlags(){ + + uint32_t TREX::getDefaultSampleFlags() { return getInt32(16); } - - std::string TREX::toPrettyString(uint32_t indent){ + + std::string TREX::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[trex] Track Extends (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl; @@ -1028,143 +1028,147 @@ namespace MP4{ return r.str(); } - TRAK::TRAK(){ + TRAK::TRAK() { memcpy(data + 4, "trak", 4); } - - MDIA::MDIA(){ + + MDIA::MDIA() { memcpy(data + 4, "mdia", 4); } - - MINF::MINF(){ + + MINF::MINF() { memcpy(data + 4, "minf", 4); } - - DINF::DINF(){ + + DINF::DINF() { memcpy(data + 4, "dinf", 4); } - - MFRA::MFRA(){ + + MFRA::MFRA() { memcpy(data + 4, "mfra", 4); } - - MFRO::MFRO(){ + + MFRO::MFRO() { memcpy(data + 4, "mfro", 4); } - void MFRO::setSize(uint32_t newSize){ - setInt32(newSize,0); + void MFRO::setSize(uint32_t newSize) { + setInt32(newSize, 0); } - - uint32_t MFRO::getSize(){ + + uint32_t MFRO::getSize() { return getInt32(0); } - - std::string MFRO::toPrettyString(uint32_t indent){ + + std::string MFRO::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[mfro] Movie Fragment Random Access Offset (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Size: " << getSize() << std::endl; return r.str(); } - - HDLR::HDLR(std::string & type, std::string name){ + + HDLR::HDLR(std::string & type, std::string name) { memcpy(data + 4, "hdlr", 4); //reserve an entire box, except for the string part at the end - if (!reserve(0, 8, 32)){ + if (!reserve(0, 8, 32)) { return;//on fail, cancel all the things } - memset(data+payloadOffset, 0, 24);//set all bytes (32 - 8) to zeroes - - if (type == "video"){setHandlerType("vide");} - if (type == "audio"){setHandlerType("soun");} + memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes + + if (type == "video") { + setHandlerType("vide"); + } + if (type == "audio") { + setHandlerType("soun"); + } setName(name); } - - void HDLR::setHandlerType(const char * newHandlerType){ - memcpy(data+payloadOffset+8, newHandlerType, 4); + + void HDLR::setHandlerType(const char * newHandlerType) { + memcpy(data + payloadOffset + 8, newHandlerType, 4); } - - std::string HDLR::getHandlerType(){ - return std::string(data+payloadOffset+8, 4); + + std::string HDLR::getHandlerType() { + return std::string(data + payloadOffset + 8, 4); } - - void HDLR::setName(std::string newName){ + + void HDLR::setName(std::string newName) { setString(newName, 24); } - - std::string HDLR::getName(){ + + std::string HDLR::getName() { return getString(24); } - - std::string HDLR::toPrettyString(uint32_t indent){ + + std::string HDLR::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[hdlr] Handler Reference (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Handler Type: " << getHandlerType() << std::endl; r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl; return r.str(); } - + //Note: next 4 headers inherit from fullBox, start at byte 4. - VMHD::VMHD(){ + VMHD::VMHD() { memcpy(data + 4, "vmhd", 4); setGraphicsMode(0); - setOpColor(0,0); - setOpColor(0,1); - setOpColor(0,2); + setOpColor(0, 0); + setOpColor(0, 1); + setOpColor(0, 2); } - - void VMHD::setGraphicsMode(uint16_t newGraphicsMode){ - setInt16(newGraphicsMode,4); + + void VMHD::setGraphicsMode(uint16_t newGraphicsMode) { + setInt16(newGraphicsMode, 4); } - - uint16_t VMHD::getGraphicsMode(){ + + uint16_t VMHD::getGraphicsMode() { return getInt16(4); } - - uint32_t VMHD::getOpColorCount(){ + + uint32_t VMHD::getOpColorCount() { return 3; } - - void VMHD::setOpColor(uint16_t newOpColor, size_t index){ - if (index <3){ + + void VMHD::setOpColor(uint16_t newOpColor, size_t index) { + if (index < 3) { setInt16(newOpColor, 6 + (2 * index)); } } - - uint16_t VMHD::getOpColor(size_t index){ - if (index < 3){ + + uint16_t VMHD::getOpColor(size_t index) { + if (index < 3) { return getInt16(6 + (index * 2)); - }else{ + } else { return 0; } } - - std::string VMHD::toPrettyString(uint32_t indent){ + + std::string VMHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[vmhd] Video Media Header Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "GraphicsMode: " << getGraphicsMode() << std::endl; - for (unsigned int i = 0; i < getOpColorCount(); i++){ - r << std::string(indent + 1, ' ') << "OpColor["< getEntryCount()){ + if (index + 1 > getEntryCount()) { int amount = index + 1 - getEntryCount(); - if ( !reserve(payloadOffset + offset, 0, amount * 8)){ + if (!reserve(payloadOffset + offset, 0, amount * 8)) { return; } - for (int j = 0; j < amount; ++j){ + for (int j = 0; j < amount; ++j) { memcpy(data + payloadOffset + offset + j * 8, "\000\000\000\010erro", 8); } setInt32(index + 1, 4); @@ -1345,189 +1349,189 @@ namespace MP4{ } setBox(newDataEntry, offset); } - - Box & DREF::getDataEntry(size_t index){ + + Box & DREF::getDataEntry(size_t index) { uint32_t offset = 8; - if (index > getEntryCount()){ + if (index > getEntryCount()) { static Box res; return (Box &)res; } - - for (unsigned int i=0; i < index; i++){ + + for (unsigned int i = 0; i < index; i++) { offset += getBoxLen(offset); } return (Box &)getBox(offset); } - - std::string DREF::toPrettyString(uint32_t indent){ + + std::string DREF::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[dref] Data Reference Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i< getEntryCount(); i++){ - r << getDataEntry(i).toPrettyString(indent+1); + for (unsigned int i = 0; i < getEntryCount(); i++) { + r << getDataEntry(i).toPrettyString(indent + 1); } return r.str(); } - - MVHD::MVHD(long long unsigned int duration){ + + MVHD::MVHD(long long unsigned int duration) { memcpy(data + 4, "mvhd", 4); - + //reserve an entire version 0 box - if (!reserve(0, 8, 108)){ + if (!reserve(0, 8, 108)) { return;//on fail, cancel all the things } - memset(data+payloadOffset, 0, 100);//set all bytes (108 - 8) to zeroes - + memset(data + payloadOffset, 0, 100); //set all bytes (108 - 8) to zeroes + setTimeScale(1000);//we always use milliseconds setDuration(duration);//in ms setRate(0x00010000);//playback rate 1.0X setVolume(0x0100);//volume 1.0X - setMatrix(0x00010000,0); - setMatrix(0x00010000,4); - setMatrix(0x40000000,8); + setMatrix(0x00010000, 0); + setMatrix(0x00010000, 4); + setMatrix(0x40000000, 8); setTrackID(0xFFFFFFFF);//empty track numbers is unknown - + } - - void MVHD::setCreationTime(uint64_t newCreationTime){ - if (getVersion() == 0){ + + void MVHD::setCreationTime(uint64_t newCreationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newCreationTime, 4); - }else{ + } else { setInt64(newCreationTime, 4); } } - - uint64_t MVHD::getCreationTime(){ - if (getVersion() == 0){ + + uint64_t MVHD::getCreationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(4); - }else{ + } else { return getInt64(4); } } - - void MVHD::setModificationTime(uint64_t newModificationTime){ - if (getVersion() == 0){ + + void MVHD::setModificationTime(uint64_t newModificationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newModificationTime, 8); - }else{ + } else { setInt64(newModificationTime, 12); } } - - uint64_t MVHD::getModificationTime(){ - if (getVersion() == 0){ + + uint64_t MVHD::getModificationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(8); - }else{ + } else { return getInt64(12); } } - - void MVHD::setTimeScale(uint32_t newTimeScale){ - if (getVersion() == 0){ + + void MVHD::setTimeScale(uint32_t newTimeScale) { + if (getVersion() == 0) { setInt32((uint32_t) newTimeScale, 12); - }else{ + } else { setInt32(newTimeScale, 20); } } - - uint32_t MVHD::getTimeScale(){ - if (getVersion() == 0){ + + uint32_t MVHD::getTimeScale() { + if (getVersion() == 0) { return getInt32(12); - }else{ + } else { return getInt32(20); } } - - void MVHD::setDuration(uint64_t newDuration){ - if (getVersion() == 0){ + + void MVHD::setDuration(uint64_t newDuration) { + if (getVersion() == 0) { setInt32((uint32_t) newDuration, 16); - }else{ + } else { setInt64(newDuration, 24); } } - - uint64_t MVHD::getDuration(){ - if (getVersion() == 0){ + + uint64_t MVHD::getDuration() { + if (getVersion() == 0) { return (uint64_t)getInt32(16); - }else{ + } else { return getInt64(24); } } - - void MVHD::setRate(uint32_t newRate){ - if (getVersion() == 0){ - setInt32( newRate, 20); - }else{ + + void MVHD::setRate(uint32_t newRate) { + if (getVersion() == 0) { + setInt32(newRate, 20); + } else { setInt32(newRate, 32); } } - - uint32_t MVHD::getRate(){ - if (getVersion() == 0){ + + uint32_t MVHD::getRate() { + if (getVersion() == 0) { return getInt32(20); - }else{ + } else { return getInt32(32); } } - - void MVHD::setVolume(uint16_t newVolume){ - if (getVersion() == 0){ + + void MVHD::setVolume(uint16_t newVolume) { + if (getVersion() == 0) { setInt16(newVolume, 24); - }else{ + } else { setInt16(newVolume, 36); } } - - uint16_t MVHD::getVolume(){ - if (getVersion() == 0){ + + uint16_t MVHD::getVolume() { + if (getVersion() == 0) { return getInt16(24); - }else{ + } else { return getInt16(36); } } //10 bytes reserved in between - uint32_t MVHD::getMatrixCount(){ + uint32_t MVHD::getMatrixCount() { return 9; } - - void MVHD::setMatrix(int32_t newMatrix, size_t index){ + + void MVHD::setMatrix(int32_t newMatrix, size_t index) { int offset = 0; - if (getVersion() == 0){ + if (getVersion() == 0) { offset = 24 + 2 + 10; - }else{ + } else { offset = 36 + 2 + 10; } setInt32(newMatrix, offset + index * 4); } - - int32_t MVHD::getMatrix(size_t index){ + + int32_t MVHD::getMatrix(size_t index) { int offset = 0; - if (getVersion() == 0){ + if (getVersion() == 0) { offset = 24 + 2 + 10; - }else{ + } else { offset = 36 + 2 + 10; } return getInt32(offset + index * 4); } - + //24 bytes of pre-defined in between - void MVHD::setTrackID(uint32_t newTrackID){ - if (getVersion() == 0){ + void MVHD::setTrackID(uint32_t newTrackID) { + if (getVersion() == 0) { setInt32(newTrackID, 86); - }else{ + } else { setInt32(newTrackID, 98); } } - - uint32_t MVHD::getTrackID(){ - if (getVersion() == 0){ + + uint32_t MVHD::getTrackID() { + if (getVersion() == 0) { return getInt32(86); - }else{ + } else { return getInt32(98); } } - - std::string MVHD::toPrettyString(uint32_t indent){ + + std::string MVHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[mvhd] Movie Header Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); @@ -1538,9 +1542,9 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "Rate: " << getRate() << std::endl; r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl; r << std::string(indent + 1, ' ') << "Matrix: "; - for (unsigned int i = 0; i< getMatrixCount(); i++){ + for (unsigned int i = 0; i < getMatrixCount(); i++) { r << getMatrix(i); - if (i!=getMatrixCount()-1){ + if (i != getMatrixCount() - 1) { r << ", "; } } @@ -1548,192 +1552,192 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl; return r.str(); } - - TFRA::TFRA(){ + + TFRA::TFRA() { memcpy(data + 4, "dref", 4); } - + //note, fullbox starts at byte 4 - void TFRA::setTrackID(uint32_t newTrackID){ + void TFRA::setTrackID(uint32_t newTrackID) { setInt32(newTrackID, 4); } - - uint32_t TFRA::getTrackID(){ + + uint32_t TFRA::getTrackID() { return getInt32(4); } - - void TFRA::setLengthSizeOfTrafNum(char newVal){ + + void TFRA::setLengthSizeOfTrafNum(char newVal) { char part = getInt8(11); - setInt8(((newVal & 0x03)<<4) + (part & 0xCF),11); + setInt8(((newVal & 0x03) << 4) + (part & 0xCF), 11); } - - char TFRA::getLengthSizeOfTrafNum(){ - return (getInt8(11)>>4) & 0x03; + + char TFRA::getLengthSizeOfTrafNum() { + return (getInt8(11) >> 4) & 0x03; } - - void TFRA::setLengthSizeOfTrunNum(char newVal){ + + void TFRA::setLengthSizeOfTrunNum(char newVal) { char part = getInt8(11); - setInt8(((newVal & 0x03)<<2) + (part & 0xF3),11); + setInt8(((newVal & 0x03) << 2) + (part & 0xF3), 11); } - - char TFRA::getLengthSizeOfTrunNum(){ - return (getInt8(11)>>2) & 0x03; + + char TFRA::getLengthSizeOfTrunNum() { + return (getInt8(11) >> 2) & 0x03; } - - void TFRA::setLengthSizeOfSampleNum(char newVal){ + + void TFRA::setLengthSizeOfSampleNum(char newVal) { char part = getInt8(11); - setInt8(((newVal & 0x03)) + (part & 0xFC),11); + setInt8(((newVal & 0x03)) + (part & 0xFC), 11); } - - char TFRA::getLengthSizeOfSampleNum(){ + + char TFRA::getLengthSizeOfSampleNum() { return (getInt8(11)) & 0x03; } - - void TFRA::setNumberOfEntry(uint32_t newNumberOfEntry){ - setInt32(newNumberOfEntry,12); + + void TFRA::setNumberOfEntry(uint32_t newNumberOfEntry) { + setInt32(newNumberOfEntry, 12); } - - uint32_t TFRA::getNumberOfEntry(){ + + uint32_t TFRA::getNumberOfEntry() { return getInt32(12); } - - uint32_t TFRA::getTFRAEntrySize(){ - int EntrySize= (getVersion()==1 ? 16 : 8); - EntrySize += getLengthSizeOfTrafNum()+1; - EntrySize += getLengthSizeOfTrunNum()+1; - EntrySize += getLengthSizeOfSampleNum()+1; + + uint32_t TFRA::getTFRAEntrySize() { + int EntrySize = (getVersion() == 1 ? 16 : 8); + EntrySize += getLengthSizeOfTrafNum() + 1; + EntrySize += getLengthSizeOfTrunNum() + 1; + EntrySize += getLengthSizeOfSampleNum() + 1; return EntrySize; } - - void TFRA::setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no){ - if (no + 1 > getNumberOfEntry()){//if a new entry is issued + + void TFRA::setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no) { + if (no + 1 > getNumberOfEntry()) { //if a new entry is issued uint32_t offset = 16 + getTFRAEntrySize() * getNumberOfEntry();//start of filler in bytes - uint32_t fillsize = (no + 1 - getNumberOfEntry())*getTFRAEntrySize();//filler in bytes - if ( !reserve(offset, 0, fillsize)){//filling space + uint32_t fillsize = (no + 1 - getNumberOfEntry()) * getTFRAEntrySize(); //filler in bytes + if (!reserve(offset, 0, fillsize)) {//filling space return; } - setNumberOfEntry(no+1); + setNumberOfEntry(no + 1); } uint32_t loc = 16 + no * getTFRAEntrySize(); - if (getVersion() == 1){ + if (getVersion() == 1) { setInt64(newTFRAEntry.time, loc); - setInt64(newTFRAEntry.moofOffset, loc+8); + setInt64(newTFRAEntry.moofOffset, loc + 8); loc += 16; - }else{ + } else { setInt32(newTFRAEntry.time, loc); - setInt32(newTFRAEntry.moofOffset, loc+4); + setInt32(newTFRAEntry.moofOffset, loc + 4); loc += 8; } - switch (getLengthSizeOfTrafNum()){ + switch (getLengthSizeOfTrafNum()) { case 0: - setInt8(newTFRAEntry.trafNumber, loc); + setInt8(newTFRAEntry.trafNumber, loc); break; case 1: - setInt16(newTFRAEntry.trafNumber, loc); + setInt16(newTFRAEntry.trafNumber, loc); break; case 2: - setInt24(newTFRAEntry.trafNumber, loc); + setInt24(newTFRAEntry.trafNumber, loc); break; case 3: - setInt32(newTFRAEntry.trafNumber, loc); + setInt32(newTFRAEntry.trafNumber, loc); break; } loc += getLengthSizeOfTrafNum() + 1; - switch (getLengthSizeOfTrunNum()){ + switch (getLengthSizeOfTrunNum()) { case 0: - setInt8(newTFRAEntry.trunNumber, loc); + setInt8(newTFRAEntry.trunNumber, loc); break; case 1: - setInt16(newTFRAEntry.trunNumber, loc); + setInt16(newTFRAEntry.trunNumber, loc); break; case 2: - setInt24(newTFRAEntry.trunNumber, loc); + setInt24(newTFRAEntry.trunNumber, loc); break; case 3: - setInt32(newTFRAEntry.trunNumber, loc); + setInt32(newTFRAEntry.trunNumber, loc); break; } loc += getLengthSizeOfTrunNum() + 1; - switch (getLengthSizeOfSampleNum()){ + switch (getLengthSizeOfSampleNum()) { case 0: - setInt8(newTFRAEntry.sampleNumber, loc); + setInt8(newTFRAEntry.sampleNumber, loc); break; case 1: - setInt16(newTFRAEntry.sampleNumber, loc); + setInt16(newTFRAEntry.sampleNumber, loc); break; case 2: - setInt24(newTFRAEntry.sampleNumber, loc); + setInt24(newTFRAEntry.sampleNumber, loc); break; case 3: - setInt32(newTFRAEntry.sampleNumber, loc); + setInt32(newTFRAEntry.sampleNumber, loc); break; } } - - TFRAEntry & TFRA::getTFRAEntry(uint32_t no){ + + TFRAEntry & TFRA::getTFRAEntry(uint32_t no) { static TFRAEntry retval; - if (no >= getNumberOfEntry()){ + if (no >= getNumberOfEntry()) { static TFRAEntry inval; return inval; } uint32_t loc = 16 + no * getTFRAEntrySize(); - if (getVersion() == 1){ + if (getVersion() == 1) { retval.time = getInt64(loc); retval.moofOffset = getInt64(loc + 8); loc += 16; - }else{ + } else { retval.time = getInt32(loc); retval.moofOffset = getInt32(loc + 4); loc += 8; } - switch (getLengthSizeOfTrafNum()){ + switch (getLengthSizeOfTrafNum()) { case 0: - retval.trafNumber = getInt8(loc); + retval.trafNumber = getInt8(loc); break; case 1: - retval.trafNumber = getInt16(loc); + retval.trafNumber = getInt16(loc); break; case 2: - retval.trafNumber = getInt24(loc); + retval.trafNumber = getInt24(loc); break; case 3: - retval.trafNumber = getInt32(loc); + retval.trafNumber = getInt32(loc); break; } loc += getLengthSizeOfTrafNum() + 1; - switch (getLengthSizeOfTrunNum()){ + switch (getLengthSizeOfTrunNum()) { case 0: - retval.trunNumber = getInt8(loc); + retval.trunNumber = getInt8(loc); break; case 1: - retval.trunNumber = getInt16(loc); + retval.trunNumber = getInt16(loc); break; case 2: - retval.trunNumber = getInt24(loc); + retval.trunNumber = getInt24(loc); break; case 3: - retval.trunNumber = getInt32(loc); + retval.trunNumber = getInt32(loc); break; } loc += getLengthSizeOfTrunNum() + 1; - switch (getLengthSizeOfSampleNum()){ + switch (getLengthSizeOfSampleNum()) { case 0: - retval.sampleNumber = getInt8(loc); + retval.sampleNumber = getInt8(loc); break; case 1: - retval.sampleNumber = getInt16(loc); + retval.sampleNumber = getInt16(loc); break; case 2: - retval.sampleNumber = getInt24(loc); + retval.sampleNumber = getInt24(loc); break; case 3: - retval.sampleNumber = getInt32(loc); + retval.sampleNumber = getInt32(loc); break; } return retval; } - - std::string TFRA::toPrettyString(uint32_t indent){ + + std::string TFRA::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[tfra] Track Fragment Random Access Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); @@ -1742,10 +1746,10 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "lengthSizeOfTrunNum: " << (int)getLengthSizeOfTrunNum() << std::endl; r << std::string(indent + 1, ' ') << "lengthSizeOfSampleNum: " << (int)getLengthSizeOfSampleNum() << std::endl; r << std::string(indent + 1, ' ') << "NumberOfEntry: " << getNumberOfEntry() << std::endl; - for (unsigned int i = 0; i < getNumberOfEntry(); i++){ + for (unsigned int i = 0; i < getNumberOfEntry(); i++) { static TFRAEntry temp; temp = getTFRAEntry(i); - r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl; + r << std::string(indent + 1, ' ') << "Entry[" << i << "]:" << std::endl; r << std::string(indent + 2, ' ') << "Time: " << temp.time << std::endl; r << std::string(indent + 2, ' ') << "MoofOffset: " << temp.moofOffset << std::endl; r << std::string(indent + 2, ' ') << "TrafNumber: " << temp.trafNumber << std::endl; @@ -1755,197 +1759,197 @@ namespace MP4{ return r.str(); } - TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height){ + TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height) { memcpy(data + 4, "tkhd", 4); - + //reserve an entire version 0 box - if (!reserve(0, 8, 92)){ + if (!reserve(0, 8, 92)) { return;//on fail, cancel all the things } - memset(data+payloadOffset, 0, 84);//set all bytes (92 - 8) to zeroes - + memset(data + payloadOffset, 0, 84); //set all bytes (92 - 8) to zeroes + setFlags(15);//ENABLED | IN_MOVIE | IN_PREVIEW | IN_POSTER setTrackID(trackId); setDuration(duration); - if (width == 0 || height == 0){ + if (width == 0 || height == 0) { setVolume(0x0100); } - setMatrix(0x00010000,0); - setMatrix(0x00010000,4); - setMatrix(0x40000000,8); + setMatrix(0x00010000, 0); + setMatrix(0x00010000, 4); + setMatrix(0x40000000, 8); setWidth(width << 16); setHeight(height << 16); } - - void TKHD::setCreationTime(uint64_t newCreationTime){ - if (getVersion() == 0){ + + void TKHD::setCreationTime(uint64_t newCreationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newCreationTime, 4); - }else{ + } else { setInt64(newCreationTime, 4); } } - - uint64_t TKHD::getCreationTime(){ - if (getVersion() == 0){ + + uint64_t TKHD::getCreationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(4); - }else{ + } else { return getInt64(4); } } - - void TKHD::setModificationTime(uint64_t newModificationTime){ - if (getVersion() == 0){ + + void TKHD::setModificationTime(uint64_t newModificationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newModificationTime, 8); - }else{ + } else { setInt64(newModificationTime, 12); } } - - uint64_t TKHD::getModificationTime(){ - if (getVersion() == 0){ + + uint64_t TKHD::getModificationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(8); - }else{ + } else { return getInt64(12); } } - - void TKHD::setTrackID(uint32_t newTrackID){ - if (getVersion() == 0){ + + void TKHD::setTrackID(uint32_t newTrackID) { + if (getVersion() == 0) { setInt32(newTrackID, 12); - }else{ + } else { setInt32(newTrackID, 20); } } - - uint32_t TKHD::getTrackID(){ - if (getVersion() == 0){ + + uint32_t TKHD::getTrackID() { + if (getVersion() == 0) { return getInt32(12); - }else{ + } else { return getInt32(20); } } //note 4 bytes reserved in between - void TKHD::setDuration(uint64_t newDuration){ - if (getVersion() == 0){ + void TKHD::setDuration(uint64_t newDuration) { + if (getVersion() == 0) { setInt32(newDuration, 20); - }else{ + } else { setInt64(newDuration, 28); } } - - uint64_t TKHD::getDuration(){ - if (getVersion() == 0){ + + uint64_t TKHD::getDuration() { + if (getVersion() == 0) { return (uint64_t)getInt32(20); - }else{ + } else { return getInt64(28); } } //8 bytes reserved in between - void TKHD::setLayer(uint16_t newLayer){ - if (getVersion() == 0){ + void TKHD::setLayer(uint16_t newLayer) { + if (getVersion() == 0) { setInt16(newLayer, 32); - }else{ + } else { setInt16(newLayer, 44); } } - - uint16_t TKHD::getLayer(){ - if (getVersion() == 0){ + + uint16_t TKHD::getLayer() { + if (getVersion() == 0) { return getInt16(32); - }else{ + } else { return getInt16(44); } } - - void TKHD::setAlternateGroup(uint16_t newAlternateGroup){ - if (getVersion() == 0){ + + void TKHD::setAlternateGroup(uint16_t newAlternateGroup) { + if (getVersion() == 0) { setInt16(newAlternateGroup, 34); - }else{ + } else { setInt16(newAlternateGroup, 46); } } - - uint16_t TKHD::getAlternateGroup(){ - if (getVersion() == 0){ + + uint16_t TKHD::getAlternateGroup() { + if (getVersion() == 0) { return getInt16(34); - }else{ + } else { return getInt16(46); } } - - void TKHD::setVolume(uint16_t newVolume){ - if (getVersion() == 0){ + + void TKHD::setVolume(uint16_t newVolume) { + if (getVersion() == 0) { setInt16(newVolume, 36); - }else{ + } else { setInt16(newVolume, 48); } } - - uint16_t TKHD::getVolume(){ - if (getVersion() == 0){ + + uint16_t TKHD::getVolume() { + if (getVersion() == 0) { return getInt16(36); - }else{ + } else { return getInt16(48); } } //2 bytes reserved in between - uint32_t TKHD::getMatrixCount(){ + uint32_t TKHD::getMatrixCount() { return 9; } - - void TKHD::setMatrix(int32_t newMatrix, size_t index){ + + void TKHD::setMatrix(int32_t newMatrix, size_t index) { int offset = 0; - if (getVersion() == 0){ + if (getVersion() == 0) { offset = 40; - }else{ + } else { offset = 52; } setInt32(newMatrix, offset + index * 4); } - - int32_t TKHD::getMatrix(size_t index){ + + int32_t TKHD::getMatrix(size_t index) { int offset = 0; - if (getVersion() == 0){ + if (getVersion() == 0) { offset = 40; - }else{ + } else { offset = 52; } return getInt32(offset + index * 4); } - - void TKHD::setWidth(uint32_t newWidth){ - if (getVersion() == 0){ + + void TKHD::setWidth(uint32_t newWidth) { + if (getVersion() == 0) { setInt32(newWidth, 76); - }else{ + } else { setInt32(newWidth, 88); } } - - uint32_t TKHD::getWidth(){ - if (getVersion() == 0){ + + uint32_t TKHD::getWidth() { + if (getVersion() == 0) { return getInt32(76); - }else{ + } else { return getInt32(88); } } - - void TKHD::setHeight(uint32_t newHeight){ - if (getVersion() == 0){ + + void TKHD::setHeight(uint32_t newHeight) { + if (getVersion() == 0) { setInt32(newHeight, 80); - }else{ + } else { setInt32(newHeight, 92); } } - - uint32_t TKHD::getHeight(){ - if (getVersion() == 0){ + + uint32_t TKHD::getHeight() { + if (getVersion() == 0) { return getInt32(80); - }else{ + } else { return getInt32(92); } } - - std::string TKHD::toPrettyString(uint32_t indent){ + + std::string TKHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[tkhd] Track Header Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); @@ -1957,9 +1961,9 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "AlternateGroup: " << getAlternateGroup() << std::endl; r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl; r << std::string(indent + 1, ' ') << "Matrix: "; - for (unsigned int i = 0; i< getMatrixCount(); i++){ + for (unsigned int i = 0; i < getMatrixCount(); i++) { r << getMatrix(i); - if (i!=getMatrixCount()-1){ + if (i != getMatrixCount() - 1) { r << ", "; } } @@ -1969,99 +1973,99 @@ namespace MP4{ return r.str(); } - MDHD::MDHD(uint64_t duration){ + MDHD::MDHD(uint64_t duration) { memcpy(data + 4, "mdhd", 4); //reserve an entire version 0 box - if (!reserve(0, 8, 32)){ + if (!reserve(0, 8, 32)) { return;//on fail, cancel all the things } - memset(data+payloadOffset, 0, 24);//set all bytes (32 - 8) to zeroes - + memset(data + payloadOffset, 0, 24); //set all bytes (32 - 8) to zeroes + setTimeScale(1000); setDuration(duration); } - - void MDHD::setCreationTime(uint64_t newCreationTime){ - if (getVersion() == 0){ + + void MDHD::setCreationTime(uint64_t newCreationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newCreationTime, 4); - }else{ + } else { setInt64(newCreationTime, 4); } } - - uint64_t MDHD::getCreationTime(){ - if (getVersion() == 0){ + + uint64_t MDHD::getCreationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(4); - }else{ + } else { return getInt64(4); } } - - void MDHD::setModificationTime(uint64_t newModificationTime){ - if (getVersion() == 0){ + + void MDHD::setModificationTime(uint64_t newModificationTime) { + if (getVersion() == 0) { setInt32((uint32_t) newModificationTime, 8); - }else{ + } else { setInt64(newModificationTime, 12); } } - - uint64_t MDHD::getModificationTime(){ - if (getVersion() == 0){ + + uint64_t MDHD::getModificationTime() { + if (getVersion() == 0) { return (uint64_t)getInt32(8); - }else{ + } else { return getInt64(12); } } - - void MDHD::setTimeScale(uint32_t newTimeScale){ - if (getVersion() == 0){ + + void MDHD::setTimeScale(uint32_t newTimeScale) { + if (getVersion() == 0) { setInt32((uint32_t) newTimeScale, 12); - }else{ + } else { setInt32(newTimeScale, 20); } } - - uint32_t MDHD::getTimeScale(){ - if (getVersion() == 0){ + + uint32_t MDHD::getTimeScale() { + if (getVersion() == 0) { return getInt32(12); - }else{ + } else { return getInt32(20); } } - - void MDHD::setDuration(uint64_t newDuration){ - if (getVersion() == 0){ + + void MDHD::setDuration(uint64_t newDuration) { + if (getVersion() == 0) { setInt32((uint32_t) newDuration, 16); - }else{ + } else { setInt64(newDuration, 24); } } - - uint64_t MDHD::getDuration(){ - if (getVersion() == 0){ + + uint64_t MDHD::getDuration() { + if (getVersion() == 0) { return (uint64_t)getInt32(16); - }else{ + } else { return getInt64(24); } } - void MDHD::setLanguage (uint16_t newLanguage){ - if (getVersion() == 0){ + void MDHD::setLanguage(uint16_t newLanguage) { + if (getVersion() == 0) { setInt16(newLanguage & 0x7F, 20); - }else{ + } else { setInt16(newLanguage & 0x7F, 32); } } - - uint16_t MDHD::getLanguage(){ - if (getVersion() == 0){ + + uint16_t MDHD::getLanguage() { + if (getVersion() == 0) { return getInt16(20) & 0x7F; - }else{ + } else { return getInt16(32) & 0x7F; } } - - std::string MDHD::toPrettyString(uint32_t indent){ + + std::string MDHD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[mdhd] Media Header Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); @@ -2069,39 +2073,39 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl; r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl; r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl; - r << std::string(indent + 1, ' ') << "Language: 0x" << std::hex << getLanguage() << std::dec<< std::endl; + r << std::string(indent + 1, ' ') << "Language: 0x" << std::hex << getLanguage() << std::dec << std::endl; return r.str(); } - - STTS::STTS(char v, uint32_t f){ + + STTS::STTS(char v, uint32_t f) { memcpy(data + 4, "stts", 4); setVersion(v); setFlags(f); setEntryCount(0); } - - void STTS::setEntryCount(uint32_t newEntryCount){ + + void STTS::setEntryCount(uint32_t newEntryCount) { setInt32(newEntryCount, 4); } - - uint32_t STTS::getEntryCount(){ + + uint32_t STTS::getEntryCount() { return getInt32(4); } - - void STTS::setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no){ - if(no + 1 > getEntryCount()){ + + void STTS::setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no) { + if (no + 1 > getEntryCount()) { setEntryCount(no + 1); - for (unsigned int i = getEntryCount(); i < no; i++){ + for (unsigned int i = getEntryCount(); i < no; i++) { setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits } } setInt32(newSTTSEntry.sampleCount, 8 + no * 8); setInt32(newSTTSEntry.sampleDelta, 8 + (no * 8) + 4); } - - STTSEntry STTS::getSTTSEntry(uint32_t no){ + + STTSEntry STTS::getSTTSEntry(uint32_t no) { static STTSEntry retval; - if (no >= getEntryCount()){ + if (no >= getEntryCount()) { static STTSEntry inval; return inval; } @@ -2109,48 +2113,48 @@ namespace MP4{ retval.sampleDelta = getInt32(8 + (no * 8) + 4); return retval; } - - std::string STTS::toPrettyString(uint32_t indent){ - std::stringstream r; + + std::string STTS::toPrettyString(uint32_t indent) { + std::stringstream r; r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ + for (unsigned int i = 0; i < getEntryCount(); i++) { static STTSEntry temp; temp = getSTTSEntry(i); - r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl; + r << std::string(indent + 1, ' ') << "Entry[" << i << "]:" << std::endl; r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl; r << std::string(indent + 2, ' ') << "SampleDelta: " << temp.sampleDelta << std::endl; } return r.str(); } - - CTTS::CTTS(){ + + CTTS::CTTS() { memcpy(data + 4, "ctts", 4); } - - void CTTS::setEntryCount(uint32_t newEntryCount){ + + void CTTS::setEntryCount(uint32_t newEntryCount) { setInt32(newEntryCount, 4); } - - uint32_t CTTS::getEntryCount(){ + + uint32_t CTTS::getEntryCount() { return getInt32(4); } - - void CTTS::setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no){ - if(no + 1 > getEntryCount()){ - for (unsigned int i = getEntryCount(); i < no; i++){ + + void CTTS::setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no) { + if (no + 1 > getEntryCount()) { + for (unsigned int i = getEntryCount(); i < no; i++) { setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits } } setInt32(newCTTSEntry.sampleCount, 8 + no * 8); setInt32(newCTTSEntry.sampleOffset, 8 + (no * 8) + 4); } - - CTTSEntry CTTS::getCTTSEntry(uint32_t no){ + + CTTSEntry CTTS::getCTTSEntry(uint32_t no) { static CTTSEntry retval; - if (no >= getEntryCount()){ + if (no >= getEntryCount()) { static CTTSEntry inval; return inval; } @@ -2158,16 +2162,16 @@ namespace MP4{ retval.sampleOffset = getInt32(8 + (no * 8) + 4); return retval; } - - std::string CTTS::toPrettyString(uint32_t indent){ + + std::string CTTS::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ + for (unsigned int i = 0; i < getEntryCount(); i++) { static CTTSEntry temp; temp = getCTTSEntry(i); - r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl; + r << std::string(indent + 1, ' ') << "Entry[" << i << "]:" << std::endl; r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl; r << std::string(indent + 2, ' ') << "SampleOffset: " << temp.sampleOffset << std::endl; } @@ -2175,25 +2179,25 @@ namespace MP4{ } - STSC::STSC(char v, uint32_t f){ + STSC::STSC(char v, uint32_t f) { memcpy(data + 4, "stsc", 4); setVersion(v); setFlags(f); setEntryCount(0); } - - void STSC::setEntryCount(uint32_t newEntryCount){ + + void STSC::setEntryCount(uint32_t newEntryCount) { setInt32(newEntryCount, 4); } - - uint32_t STSC::getEntryCount(){ + + uint32_t STSC::getEntryCount() { return getInt32(4); } - - void STSC::setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no){ - if(no + 1 > getEntryCount()){ - setEntryCount(no+1); - for (unsigned int i = getEntryCount(); i < no; i++){ + + void STSC::setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no) { + if (no + 1 > getEntryCount()) { + setEntryCount(no + 1); + for (unsigned int i = getEntryCount(); i < no; i++) { setInt64(0, 8 + (i * 12));//filling up undefined entries of 64 bits setInt32(0, 8 + (i * 12) + 8); } @@ -2202,10 +2206,10 @@ namespace MP4{ setInt32(newSTSCEntry.samplesPerChunk, 8 + (no * 12) + 4); setInt32(newSTSCEntry.sampleDescriptionIndex, 8 + (no * 12) + 8); } - - STSCEntry STSC::getSTSCEntry(uint32_t no){ + + STSCEntry STSC::getSTSCEntry(uint32_t no) { static STSCEntry retval; - if (no >= getEntryCount()){ + if (no >= getEntryCount()) { static STSCEntry inval; return inval; } @@ -2214,209 +2218,209 @@ namespace MP4{ retval.sampleDescriptionIndex = getInt32(8 + (no * 12) + 8); return retval; } - - std::string STSC::toPrettyString(uint32_t indent){ + + std::string STSC::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stsc] Sample To Chunk Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ + for (unsigned int i = 0; i < getEntryCount(); i++) { static STSCEntry temp; temp = getSTSCEntry(i); - r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl; + r << std::string(indent + 1, ' ') << "Entry[" << i << "]:" << std::endl; r << std::string(indent + 2, ' ') << "FirstChunk: " << temp.firstChunk << std::endl; r << std::string(indent + 2, ' ') << "SamplesPerChunk: " << temp.samplesPerChunk << std::endl; r << std::string(indent + 2, ' ') << "SampleDescriptionIndex: " << temp.sampleDescriptionIndex << std::endl; } return r.str(); } - - STCO::STCO(char v, uint32_t f){ + + STCO::STCO(char v, uint32_t f) { memcpy(data + 4, "stco", 4); setVersion(v); setFlags(f); setEntryCount(0); } - - void STCO::setEntryCount(uint32_t newEntryCount){ + + void STCO::setEntryCount(uint32_t newEntryCount) { setInt32(newEntryCount, 4); } - - uint32_t STCO::getEntryCount(){ + + uint32_t STCO::getEntryCount() { return getInt32(4); } - - void STCO::setChunkOffset(uint32_t newChunkOffset, uint32_t no){ - if (no + 1 > getEntryCount()){ - for (unsigned int i = getEntryCount(); i < no; i++){ + + void STCO::setChunkOffset(uint32_t newChunkOffset, uint32_t no) { + if (no + 1 > getEntryCount()) { + for (unsigned int i = getEntryCount(); i < no; i++) { setInt32(0, 8 + i * 4);//filling undefined entries } - setEntryCount(no+1); + setEntryCount(no + 1); } - setInt32(newChunkOffset, 8 + no * 4); + setInt32(newChunkOffset, 8 + no * 4); } - - uint32_t STCO::getChunkOffset(uint32_t no){ - if (no >= getEntryCount()){ + + uint32_t STCO::getChunkOffset(uint32_t no) { + if (no >= getEntryCount()) { return 0; } return getInt32(8 + no * 4); } - - std::string STCO::toPrettyString(uint32_t indent){ + + std::string STCO::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stco] Chunk Offset Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ - r << std::string(indent + 1, ' ') << "ChunkOffset[" << i <<"]: " << getChunkOffset(i) << std::endl; + for (unsigned int i = 0; i < getEntryCount(); i++) { + r << std::string(indent + 1, ' ') << "ChunkOffset[" << i << "]: " << getChunkOffset(i) << std::endl; } return r.str(); } - STSZ::STSZ(char v, uint32_t f){ + STSZ::STSZ(char v, uint32_t f) { memcpy(data + 4, "stsz", 4); setVersion(v); setFlags(f); setSampleCount(0); } - void STSZ::setSampleSize(uint32_t newSampleSize){ + void STSZ::setSampleSize(uint32_t newSampleSize) { setInt32(newSampleSize, 4); } - - uint32_t STSZ::getSampleSize(){ + + uint32_t STSZ::getSampleSize() { return getInt32(4); } - - void STSZ::setSampleCount(uint32_t newSampleCount){ + + void STSZ::setSampleCount(uint32_t newSampleCount) { setInt32(newSampleCount, 8); } - - uint32_t STSZ::getSampleCount(){ + + uint32_t STSZ::getSampleCount() { return getInt32(8); } - - void STSZ::setEntrySize(uint32_t newEntrySize, uint32_t no){ - if (no + 1 > getSampleCount()){ + + void STSZ::setEntrySize(uint32_t newEntrySize, uint32_t no) { + if (no + 1 > getSampleCount()) { setSampleCount(no + 1); - for (unsigned int i = getSampleCount(); i < no; i++){ + for (unsigned int i = getSampleCount(); i < no; i++) { setInt32(0, 12 + i * 4);//filling undefined entries } } setInt32(newEntrySize, 12 + no * 4); } - - uint32_t STSZ::getEntrySize(uint32_t no){ - if (no >= getSampleCount()){ + + uint32_t STSZ::getEntrySize(uint32_t no) { + if (no >= getSampleCount()) { return 0; } return getInt32(12 + no * 4); } - - std::string STSZ::toPrettyString(uint32_t indent){ + + std::string STSZ::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stsz] Sample Size Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl; r << std::string(indent + 1, ' ') << "SampleCount: " << getSampleCount() << std::endl; - for (unsigned int i = 0; i < getSampleCount(); i++){ - r << std::string(indent + 1, ' ') << "EntrySize[" << i <<"]: " << getEntrySize(i) << std::endl; + for (unsigned int i = 0; i < getSampleCount(); i++) { + r << std::string(indent + 1, ' ') << "EntrySize[" << i << "]: " << getEntrySize(i) << std::endl; } return r.str(); } - SampleEntry::SampleEntry(){ + SampleEntry::SampleEntry() { memcpy(data + 4, "erro", 4); } - - void SampleEntry::setDataReferenceIndex(uint16_t newDataReferenceIndex){ + + void SampleEntry::setDataReferenceIndex(uint16_t newDataReferenceIndex) { setInt16(newDataReferenceIndex, 6); } - - uint16_t SampleEntry::getDataReferenceIndex(){ + + uint16_t SampleEntry::getDataReferenceIndex() { return getInt16(6); } - - std::string SampleEntry::toPrettySampleString(uint32_t indent){ + + std::string SampleEntry::toPrettySampleString(uint32_t indent) { std::stringstream r; r << std::string(indent + 1, ' ') << "DataReferenceIndex: " << getDataReferenceIndex() << std::endl; - return r.str(); + return r.str(); } - CLAP::CLAP(){ + CLAP::CLAP() { memcpy(data + 4, "clap", 4); setHorizOffN(0); setHorizOffD(0); setVertOffN(0); setVertOffD(0); } - - void CLAP::setCleanApertureWidthN(uint32_t newVal){ - setInt32(newVal,0); + + void CLAP::setCleanApertureWidthN(uint32_t newVal) { + setInt32(newVal, 0); } - - uint32_t CLAP::getCleanApertureWidthN(){ + + uint32_t CLAP::getCleanApertureWidthN() { return getInt32(0); } - - void CLAP::setCleanApertureWidthD(uint32_t newVal){ - setInt32(newVal,4); + + void CLAP::setCleanApertureWidthD(uint32_t newVal) { + setInt32(newVal, 4); } - - uint32_t CLAP::getCleanApertureWidthD(){ + + uint32_t CLAP::getCleanApertureWidthD() { return getInt32(4); } - - void CLAP::setCleanApertureHeightN(uint32_t newVal){ - setInt32(newVal,8); + + void CLAP::setCleanApertureHeightN(uint32_t newVal) { + setInt32(newVal, 8); } - - uint32_t CLAP::getCleanApertureHeightN(){ + + uint32_t CLAP::getCleanApertureHeightN() { return getInt32(8); } - - void CLAP::setCleanApertureHeightD(uint32_t newVal){ + + void CLAP::setCleanApertureHeightD(uint32_t newVal) { setInt32(newVal, 12); } - - uint32_t CLAP::getCleanApertureHeightD(){ + + uint32_t CLAP::getCleanApertureHeightD() { return getInt32(12); } - - void CLAP::setHorizOffN(uint32_t newVal){ + + void CLAP::setHorizOffN(uint32_t newVal) { setInt32(newVal, 16); } - - uint32_t CLAP::getHorizOffN(){ + + uint32_t CLAP::getHorizOffN() { return getInt32(16); } - - void CLAP::setHorizOffD(uint32_t newVal){ + + void CLAP::setHorizOffD(uint32_t newVal) { setInt32(newVal, 20); } - - uint32_t CLAP::getHorizOffD(){ + + uint32_t CLAP::getHorizOffD() { return getInt32(20); } - - void CLAP::setVertOffN(uint32_t newVal){ + + void CLAP::setVertOffN(uint32_t newVal) { setInt32(newVal, 24); } - - uint32_t CLAP::getVertOffN(){ + + uint32_t CLAP::getVertOffN() { return getInt32(24); } - - void CLAP::setVertOffD(uint32_t newVal){ + + void CLAP::setVertOffD(uint32_t newVal) { setInt32(newVal, 28); } - - uint32_t CLAP::getVertOffD(){ + + uint32_t CLAP::getVertOffD() { return getInt32(32); } - - std::string CLAP::toPrettyString(uint32_t indent){ + + std::string CLAP::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[clap] Clean Aperture Box (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "CleanApertureWidthN: " << getCleanApertureWidthN() << std::endl; @@ -2429,28 +2433,28 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "VertOffD: " << getVertOffD() << std::endl; return r.str(); } - - PASP::PASP(){ + + PASP::PASP() { memcpy(data + 4, "pasp", 4); } - - void PASP::setHSpacing(uint32_t newVal){ + + void PASP::setHSpacing(uint32_t newVal) { setInt32(newVal, 0); } - - uint32_t PASP::getHSpacing(){ + + uint32_t PASP::getHSpacing() { return getInt32(0); } - - void PASP::setVSpacing(uint32_t newVal){ + + void PASP::setVSpacing(uint32_t newVal) { setInt32(newVal, 4); } - - uint32_t PASP::getVSpacing(){ + + uint32_t PASP::getVSpacing() { return getInt32(4); } - - std::string PASP::toPrettyString(uint32_t indent){ + + std::string PASP::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[pasp] Pixel Aspect Ratio Box (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "HSpacing: " << getHSpacing() << std::endl; @@ -2458,7 +2462,7 @@ namespace MP4{ return r.str(); } - VisualSampleEntry::VisualSampleEntry(){ + VisualSampleEntry::VisualSampleEntry() { memcpy(data + 4, "erro", 4); setHorizResolution(0x00480000); setVertResolution(0x00480000); @@ -2466,95 +2470,95 @@ namespace MP4{ setCompressorName(""); setDepth(0x0018); } - - void VisualSampleEntry::setCodec(const char* newCodec){ + + void VisualSampleEntry::setCodec(const char * newCodec) { memcpy(data + 4, newCodec, 4); } - - void VisualSampleEntry::setWidth(uint16_t newWidth){ - setInt16(newWidth,24); + + void VisualSampleEntry::setWidth(uint16_t newWidth) { + setInt16(newWidth, 24); } - - uint16_t VisualSampleEntry::getWidth(){ + + uint16_t VisualSampleEntry::getWidth() { return getInt16(24); } - - void VisualSampleEntry::setHeight(uint16_t newHeight){ + + void VisualSampleEntry::setHeight(uint16_t newHeight) { setInt16(newHeight, 26); } - - uint16_t VisualSampleEntry::getHeight(){ + + uint16_t VisualSampleEntry::getHeight() { return getInt16(26); } - - void VisualSampleEntry::setHorizResolution (uint32_t newHorizResolution){ + + void VisualSampleEntry::setHorizResolution(uint32_t newHorizResolution) { setInt32(newHorizResolution, 28); } - - uint32_t VisualSampleEntry::getHorizResolution(){ + + uint32_t VisualSampleEntry::getHorizResolution() { return getInt32(28); } - - void VisualSampleEntry::setVertResolution (uint32_t newVertResolution){ - setInt32(newVertResolution,32); + + void VisualSampleEntry::setVertResolution(uint32_t newVertResolution) { + setInt32(newVertResolution, 32); } - - uint32_t VisualSampleEntry::getVertResolution(){ + + uint32_t VisualSampleEntry::getVertResolution() { return getInt32(32); } - - void VisualSampleEntry::setFrameCount(uint16_t newFrameCount){ + + void VisualSampleEntry::setFrameCount(uint16_t newFrameCount) { setInt16(newFrameCount, 40); } - - uint16_t VisualSampleEntry::getFrameCount(){ + + uint16_t VisualSampleEntry::getFrameCount() { return getInt16(40); } - void VisualSampleEntry::setCompressorName(std::string newCompressorName){ + void VisualSampleEntry::setCompressorName(std::string newCompressorName) { newCompressorName.resize(32, ' '); - setString(newCompressorName,42); + setString(newCompressorName, 42); } - - std::string VisualSampleEntry::getCompressorName(){ + + std::string VisualSampleEntry::getCompressorName() { return getString(42); } - void VisualSampleEntry::setDepth(uint16_t newDepth){ + void VisualSampleEntry::setDepth(uint16_t newDepth) { setInt16(newDepth, 74); } - - uint16_t VisualSampleEntry::getDepth(){ + + uint16_t VisualSampleEntry::getDepth() { return getInt16(74); } - void VisualSampleEntry::setCLAP(Box& clap){ - setBox(clap,78); + void VisualSampleEntry::setCLAP(Box & clap) { + setBox(clap, 78); } - Box & VisualSampleEntry::getCLAP(){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP + Box & VisualSampleEntry::getCLAP() { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP return ret; } ret = getBox(78); return ret; } - - Box & VisualSampleEntry::getPASP(){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP + + Box & VisualSampleEntry::getPASP() { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (payloadSize() < 84) { //if the EntryBox is not big enough to hold a CLAP/PASP return ret; } - if (payloadSize() < 78 + getBoxLen(78) + 8){ + if (payloadSize() < 78 + getBoxLen(78) + 8) { return ret; - }else{ - return getBox(78+getBoxLen(78)); + } else { + return getBox(78 + getBoxLen(78)); } - + } - - std::string VisualSampleEntry::toPrettyVisualString(uint32_t indent, std::string name){ + + std::string VisualSampleEntry::toPrettyVisualString(uint32_t indent, std::string name) { std::stringstream r; r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl; r << toPrettySampleString(indent); @@ -2565,23 +2569,23 @@ namespace MP4{ r << std::string(indent + 1, ' ') << "FrameCount: " << getFrameCount() << std::endl; r << std::string(indent + 1, ' ') << "CompressorName: " << getCompressorName() << std::endl; r << std::string(indent + 1, ' ') << "Depth: " << getDepth() << std::endl; - if (!getCLAP().isType("erro")){ - r << getCLAP().toPrettyString(indent+1); + if (!getCLAP().isType("erro")) { + r << getCLAP().toPrettyString(indent + 1); } - if (!getPASP().isType("erro")){ - r << getPASP().toPrettyString(indent+1); + if (!getPASP().isType("erro")) { + r << getPASP().toPrettyString(indent + 1); } return r.str(); } - AudioSampleEntry::AudioSampleEntry(){ + AudioSampleEntry::AudioSampleEntry() { memcpy(data + 4, "erro", 4); setChannelCount(2); setSampleSize(16); setSampleRate(44100); } - - uint16_t AudioSampleEntry::toAACInit(){ + + uint16_t AudioSampleEntry::toAACInit() { uint16_t result = 0; result |= (2 & 0x1F) << 11; result |= (getSampleRate() & 0x0F) << 7; @@ -2589,51 +2593,51 @@ namespace MP4{ return result; } - void AudioSampleEntry::setCodec(const char* newCodec){ + void AudioSampleEntry::setCodec(const char * newCodec) { memcpy(data + 4, newCodec, 4); } - - void AudioSampleEntry::setChannelCount(uint16_t newChannelCount){ - setInt16(newChannelCount,16); + + void AudioSampleEntry::setChannelCount(uint16_t newChannelCount) { + setInt16(newChannelCount, 16); } - - uint16_t AudioSampleEntry::getChannelCount(){ + + uint16_t AudioSampleEntry::getChannelCount() { return getInt16(16); } - - void AudioSampleEntry::setSampleSize(uint16_t newSampleSize){ - setInt16(newSampleSize,18); + + void AudioSampleEntry::setSampleSize(uint16_t newSampleSize) { + setInt16(newSampleSize, 18); } - - uint16_t AudioSampleEntry::getSampleSize(){ + + uint16_t AudioSampleEntry::getSampleSize() { return getInt16(18); } - - void AudioSampleEntry::setPreDefined(uint16_t newPreDefined){ - setInt16(newPreDefined,20); + + void AudioSampleEntry::setPreDefined(uint16_t newPreDefined) { + setInt16(newPreDefined, 20); } - - uint16_t AudioSampleEntry::getPreDefined(){ + + uint16_t AudioSampleEntry::getPreDefined() { return getInt16(20); } - - void AudioSampleEntry::setSampleRate(uint32_t newSampleRate){ + + void AudioSampleEntry::setSampleRate(uint32_t newSampleRate) { setInt32(newSampleRate << 16, 24); } - - uint32_t AudioSampleEntry::getSampleRate(){ + + uint32_t AudioSampleEntry::getSampleRate() { return getInt32(24) >> 16; } - - void AudioSampleEntry::setCodecBox(Box& newBox){ + + void AudioSampleEntry::setCodecBox(Box & newBox) { setBox(newBox, 28); } - - Box & AudioSampleEntry::getCodecBox(){ + + Box & AudioSampleEntry::getCodecBox() { return getBox(28); } - - std::string AudioSampleEntry::toPrettyAudioString(uint32_t indent, std::string name){ + + std::string AudioSampleEntry::toPrettyAudioString(uint32_t indent, std::string name) { std::stringstream r; r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl; r << toPrettySampleString(indent); @@ -2645,61 +2649,61 @@ namespace MP4{ return r.str(); } - MP4A::MP4A(){ + MP4A::MP4A() { memcpy(data + 4, "mp4a", 4); } - - std::string MP4A::toPrettyString(uint32_t indent){ + + std::string MP4A::toPrettyString(uint32_t indent) { return toPrettyAudioString(indent, "[mp4a] MPEG-4 Audio"); } - AAC::AAC(){ + AAC::AAC() { memcpy(data + 4, "aac ", 4); } - - std::string AAC::toPrettyString(uint32_t indent){ + + std::string AAC::toPrettyString(uint32_t indent) { return toPrettyAudioString(indent, "[aac ] Advanced Audio Codec"); } - AVC1::AVC1(){ + AVC1::AVC1() { memcpy(data + 4, "avc1", 4); } - - std::string AVC1::toPrettyString(uint32_t indent){ + + std::string AVC1::toPrettyString(uint32_t indent) { return toPrettyVisualString(indent, "[avc1] Advanced Video Codec 1"); } - H264::H264(){ + H264::H264() { memcpy(data + 4, "h264", 4); } - - std::string H264::toPrettyString(uint32_t indent){ + + std::string H264::toPrettyString(uint32_t indent) { return toPrettyVisualString(indent, "[h264] H.264/MPEG-4 AVC"); } - STSD::STSD(char v, uint32_t f){ + STSD::STSD(char v, uint32_t f) { memcpy(data + 4, "stsd", 4); setVersion(v); setFlags(f); setEntryCount(0); } - void STSD::setEntryCount (uint32_t newEntryCount){ + void STSD::setEntryCount(uint32_t newEntryCount) { setInt32(newEntryCount, 4); } - - uint32_t STSD::getEntryCount(){ + + uint32_t STSD::getEntryCount() { return getInt32(4); } - - void STSD::setEntry(Box & newContent, uint32_t no){ - int tempLoc = 8; + + void STSD::setEntry(Box & newContent, uint32_t no) { + int tempLoc = 8; unsigned int entryCount = getEntryCount(); - for (unsigned int i = 0; i < no; i++){ - if (i < entryCount){ + for (unsigned int i = 0; i < no; i++) { + if (i < entryCount) { tempLoc += getBoxLen(tempLoc); - }else{ - if ( !reserve(tempLoc, 0, (no - entryCount) * 8)){ + } else { + if (!reserve(tempLoc, 0, (no - entryCount) * 8)) { return; } memset(data + tempLoc, 0, (no - entryCount) * 8); @@ -2708,162 +2712,162 @@ namespace MP4{ } } setBox(newContent, tempLoc); - if (getEntryCount() < no+1){ - setEntryCount(no+1); + if (getEntryCount() < no + 1) { + setEntryCount(no + 1); } } - - Box & STSD::getEntry(uint32_t no){ - static Box ret = Box((char*)"\000\000\000\010erro", false); - if (no > getEntryCount()){ + + Box & STSD::getEntry(uint32_t no) { + static Box ret = Box((char *)"\000\000\000\010erro", false); + if (no > getEntryCount()) { return ret; } unsigned int i = 0; int tempLoc = 8; - while (i < no){ + while (i < no) { tempLoc += getBoxLen(tempLoc); i++; } return getBox(tempLoc); } - std::string STSD::toPrettyString(uint32_t indent){ + std::string STSD::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stsd] Sample Description Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntrySize: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ + for (unsigned int i = 0; i < getEntryCount(); i++) { Box curBox = Box(getEntry(i).asBox(), false); r << curBox.toPrettyString(indent + 1); } return r.str(); } - EDTS::EDTS(){ + EDTS::EDTS() { memcpy(data + 4, "edts", 4); } - UDTA::UDTA(){ + UDTA::UDTA() { memcpy(data + 4, "udta", 4); } - STSS::STSS(char v, uint32_t f){ + STSS::STSS(char v, uint32_t f) { memcpy(data + 4, "stss", 4); setVersion(v); setFlags(f); setEntryCount(0); } - - void STSS::setEntryCount(uint32_t newVal){ + + void STSS::setEntryCount(uint32_t newVal) { setInt32(newVal, 4); } - - uint32_t STSS::getEntryCount(){ + + uint32_t STSS::getEntryCount() { return getInt32(4); } - - void STSS::setSampleNumber(uint32_t newVal, uint32_t index){ - if (index >= getEntryCount()){ + + void STSS::setSampleNumber(uint32_t newVal, uint32_t index) { + if (index >= getEntryCount()) { setEntryCount(index + 1); } setInt32(newVal, 8 + (index * 4)); } - - uint32_t STSS::getSampleNumber(uint32_t index){ - if (index >= getEntryCount()){ + + uint32_t STSS::getSampleNumber(uint32_t index) { + if (index >= getEntryCount()) { return 0; } return getInt32(8 + (index * 4)); } - - std::string STSS::toPrettyString(uint32_t indent){ + + std::string STSS::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[stss] Sync Sample Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl; - for (unsigned int i = 0; i < getEntryCount(); i++){ - r << std::string(indent + 1, ' ') << "SampleNumber[" << i <<"] : " << getSampleNumber(i) << std::endl; + for (unsigned int i = 0; i < getEntryCount(); i++) { + r << std::string(indent + 1, ' ') << "SampleNumber[" << i << "] : " << getSampleNumber(i) << std::endl; } return r.str(); } - META::META(){ + META::META() { memcpy(data + 4, "meta", 4); } - - std::string META::toPrettyString(uint32_t indent){ + + std::string META::toPrettyString(uint32_t indent) { return toPrettyCFBString(indent, "[meta] Meta Box"); } - ELST::ELST(){ + ELST::ELST() { memcpy(data + 4, "elst", 4); } - - void ELST::setSegmentDuration(uint64_t newVal){ - if (getVersion() == 1){ + + void ELST::setSegmentDuration(uint64_t newVal) { + if (getVersion() == 1) { setInt64(newVal, 4); - }else{ + } else { setInt32(newVal, 4); } } - - uint64_t ELST::getSegmentDuration(){ - if (getVersion() == 1){ + + uint64_t ELST::getSegmentDuration() { + if (getVersion() == 1) { return getInt64(4); - }else{ + } else { return getInt32(4); } } - - void ELST::setMediaTime(uint64_t newVal){ - if (getVersion() == 1){ + + void ELST::setMediaTime(uint64_t newVal) { + if (getVersion() == 1) { setInt64(newVal, 12); - }else{ + } else { setInt32(newVal, 8); } } - - uint64_t ELST::getMediaTime(){ - if (getVersion() == 1){ + + uint64_t ELST::getMediaTime() { + if (getVersion() == 1) { return getInt64(12); - }else{ + } else { return getInt32(8); } } - - void ELST::setMediaRateInteger(uint16_t newVal){ - if (getVersion() == 1){ + + void ELST::setMediaRateInteger(uint16_t newVal) { + if (getVersion() == 1) { setInt16(newVal, 20); - }else{ + } else { setInt16(newVal, 12); } } - - uint16_t ELST::getMediaRateInteger(){ - if (getVersion() == 1){ + + uint16_t ELST::getMediaRateInteger() { + if (getVersion() == 1) { return getInt16(20); - }else{ + } else { return getInt16(12); } } - - void ELST::setMediaRateFraction(uint16_t newVal){ - if (getVersion() == 1){ + + void ELST::setMediaRateFraction(uint16_t newVal) { + if (getVersion() == 1) { setInt16(newVal, 22); - }else{ + } else { setInt16(newVal, 14); } } - - uint16_t ELST::getMediaRateFraction(){ - if (getVersion() == 1){ + + uint16_t ELST::getMediaRateFraction() { + if (getVersion() == 1) { return getInt16(22); - }else{ + } else { return getInt16(14); } } - - std::string ELST::toPrettyString(uint32_t indent){ + + std::string ELST::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); diff --git a/lib/mp4_generic.h b/lib/mp4_generic.h index 54444d9a..c04c94c8 100644 --- a/lib/mp4_generic.h +++ b/lib/mp4_generic.h @@ -1,7 +1,7 @@ #include "mp4.h" -namespace MP4{ - class MFHD: public Box{ +namespace MP4 { + class MFHD: public Box { public: MFHD(); void setSequenceNumber(uint32_t newSequenceNumber); @@ -10,13 +10,13 @@ namespace MP4{ }; //MFHD Box - class MOOF: public containerBox{ + class MOOF: public containerBox { public: MOOF(); }; //MOOF Box - class TRAF: public Box{ + class TRAF: public Box { public: TRAF(); uint32_t getContentCount(); @@ -26,13 +26,13 @@ namespace MP4{ }; //TRAF Box - struct trunSampleInformation{ - uint32_t sampleDuration; - uint32_t sampleSize; - uint32_t sampleFlags; - uint32_t sampleOffset; + struct trunSampleInformation { + uint32_t sampleDuration; + uint32_t sampleSize; + uint32_t sampleFlags; + uint32_t sampleOffset; }; - enum trunflags{ + enum trunflags { trundataOffset = 0x00000001, trunfirstSampleFlags = 0x00000004, trunsampleDuration = 0x00000100, @@ -40,7 +40,7 @@ namespace MP4{ trunsampleFlags = 0x00000400, trunsampleOffsets = 0x00000800 }; - enum sampleflags{ + enum sampleflags { noIPicture = 0x01000000, isIPicture = 0x02000000, noDisposable = 0x00400000, @@ -52,7 +52,7 @@ namespace MP4{ MUST_BE_PRESENT = 0x1 }; std::string prettySampleFlags(uint32_t flag); - class TRUN: public Box{ + class TRUN: public Box { public: TRUN(); void setFlags(uint32_t newFlags); @@ -67,7 +67,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - enum tfhdflags{ + enum tfhdflags { tfhdBaseOffset = 0x000001, tfhdSampleDesc = 0x000002, tfhdSampleDura = 0x000008, @@ -75,7 +75,7 @@ namespace MP4{ tfhdSampleFlag = 0x000020, tfhdNoDuration = 0x010000, }; - class TFHD: public Box{ + class TFHD: public Box { public: TFHD(); void setFlags(uint32_t newFlags); @@ -96,7 +96,7 @@ namespace MP4{ }; - class AVCC: public Box{ + class AVCC: public Box { public: AVCC(); void setVersion(uint32_t newVersion); @@ -111,19 +111,19 @@ namespace MP4{ uint32_t getSPSNumber(); void setSPS(std::string newSPS); uint32_t getSPSLen(); - char* getSPS(); + char * getSPS(); void setPPSNumber(uint32_t newPPSNumber); uint32_t getPPSNumber(); void setPPS(std::string newPPS); uint32_t getPPSLen(); - char* getPPS(); + char * getPPS(); std::string asAnnexB(); void setPayload(std::string newPayload); std::string toPrettyString(uint32_t indent = 0); }; - + ///\todo : ESDS is filthy implemented, clean up when optimising - class ESDS: public fullBox{ + class ESDS: public fullBox { public: ESDS(); ESDS(std::string init, uint32_t bps); @@ -180,8 +180,8 @@ namespace MP4{ void setSLValue(char newVal); std::string toPrettyString(uint32_t indent = 0); }; - - class FTYP: public Box{ + + class FTYP: public Box { public: FTYP(); void setMajorBrand(const char * newMajorBrand); @@ -193,18 +193,18 @@ namespace MP4{ std::string getCompatibleBrands(size_t index); std::string toPrettyString(uint32_t indent = 0); }; - - class MOOV: public containerBox{ + + class MOOV: public containerBox { public: MOOV(); }; - - class MVEX: public containerBox{ + + class MVEX: public containerBox { public: MVEX(); }; - - class TREX: public Box{ + + class TREX: public Box { public: TREX(); void setTrackID(uint32_t newTrackID); @@ -219,34 +219,34 @@ namespace MP4{ uint32_t getDefaultSampleFlags(); std::string toPrettyString(uint32_t indent = 0); }; - - - class MFRA: public containerBox{ + + + class MFRA: public containerBox { public: MFRA(); }; - class TRAK: public containerBox{ + class TRAK: public containerBox { public: TRAK(); }; - - class MDIA: public containerBox{ + + class MDIA: public containerBox { public: MDIA(); }; - class MINF: public containerBox{ + class MINF: public containerBox { public: MINF(); }; - class DINF: public containerBox{ + class DINF: public containerBox { public: DINF(); }; - class MFRO: public Box{ + class MFRO: public Box { public: MFRO(); void setSize(uint32_t newSize); @@ -254,7 +254,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - class HDLR: public Box{ + class HDLR: public Box { public: HDLR(std::string & type, std::string name); void setHandlerType(const char * newHandlerType); @@ -264,7 +264,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - class VMHD: public fullBox{ + class VMHD: public fullBox { public: VMHD(); void setGraphicsMode(uint16_t newGraphicsMode); @@ -274,16 +274,16 @@ namespace MP4{ uint16_t getOpColor(size_t index); std::string toPrettyString(uint32_t indent = 0); }; - - class SMHD: public fullBox{ + + class SMHD: public fullBox { public: SMHD(); void setBalance(int16_t newBalance); int16_t getBalance(); std::string toPrettyString(uint32_t indent = 0); }; - - class HMHD: public fullBox{ + + class HMHD: public fullBox { public: HMHD(); void setMaxPDUSize(uint16_t newMaxPDUSize); @@ -296,27 +296,27 @@ namespace MP4{ uint32_t getAvgBitRate(); std::string toPrettyString(uint32_t indent = 0); }; - - class NMHD: public fullBox{ + + class NMHD: public fullBox { public: NMHD(); std::string toPrettyString(uint32_t indent = 0); }; - - class MEHD: public fullBox{ + + class MEHD: public fullBox { public: MEHD(); void setFragmentDuration(uint64_t newFragmentDuration); uint64_t getFragmentDuration(); std::string toPrettyString(uint32_t indent = 0); }; - - class STBL: public containerBox{ + + class STBL: public containerBox { public: STBL(); }; - - class URL: public fullBox{ + + class URL: public fullBox { public: URL(); void setLocation(std::string newLocation); @@ -324,7 +324,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - class URN: public fullBox{ + class URN: public fullBox { public: URN(); void setName(std::string newName); @@ -333,8 +333,8 @@ namespace MP4{ std::string getLocation(); std::string toPrettyString(uint32_t indent = 0); }; - - class DREF: public fullBox{ + + class DREF: public fullBox { public: DREF(); uint32_t getEntryCount(); @@ -342,8 +342,8 @@ namespace MP4{ Box & getDataEntry(size_t index); std::string toPrettyString(uint32_t indent = 0); }; - - class MVHD: public fullBox{ + + class MVHD: public fullBox { public: MVHD(long long unsigned int duration); void setCreationTime(uint64_t newCreationTime); @@ -365,16 +365,16 @@ namespace MP4{ uint32_t getTrackID(); std::string toPrettyString(uint32_t indent = 0); }; - - struct TFRAEntry{ + + struct TFRAEntry { uint64_t time; uint64_t moofOffset; uint32_t trafNumber; uint32_t trunNumber; uint32_t sampleNumber; }; - - class TFRA: public fullBox{ + + class TFRA: public fullBox { public: TFRA(); void setTrackID(uint32_t newTrackID); @@ -392,8 +392,8 @@ namespace MP4{ uint32_t getTFRAEntrySize(); std::string toPrettyString(uint32_t indent = 0); }; - - class TKHD: public fullBox{ + + class TKHD: public fullBox { public: TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height); void setCreationTime(uint64_t newCreationTime); @@ -422,8 +422,8 @@ namespace MP4{ uint32_t getHeight(); std::string toPrettyString(uint32_t indent = 0); }; - - class MDHD: public fullBox{ + + class MDHD: public fullBox { public: MDHD(uint64_t duration); void setCreationTime(uint64_t newCreationTime); @@ -439,13 +439,13 @@ namespace MP4{ uint16_t getLanguage(); std::string toPrettyString(uint32_t indent = 0); }; - - struct STTSEntry{ + + struct STTSEntry { uint32_t sampleCount; uint32_t sampleDelta; }; - - class STTS: public fullBox{ + + class STTS: public fullBox { public: STTS(char v = 1, uint32_t f = 0); void setEntryCount(uint32_t newEntryCount); @@ -454,13 +454,13 @@ namespace MP4{ STTSEntry getSTTSEntry(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - struct CTTSEntry{ + + struct CTTSEntry { uint32_t sampleCount; uint32_t sampleOffset; }; - class CTTS: public fullBox{ + class CTTS: public fullBox { public: CTTS(); void setEntryCount(uint32_t newEntryCount); @@ -469,14 +469,14 @@ namespace MP4{ CTTSEntry getCTTSEntry(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - struct STSCEntry{ + + struct STSCEntry { uint32_t firstChunk; uint32_t samplesPerChunk; uint32_t sampleDescriptionIndex; }; - - class STSC: public fullBox{ + + class STSC: public fullBox { public: STSC(char v = 1, uint32_t f = 0); void setEntryCount(uint32_t newEntryCount); @@ -485,8 +485,8 @@ namespace MP4{ STSCEntry getSTSCEntry(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - class STCO: public fullBox{ + + class STCO: public fullBox { public: STCO(char v = 1, uint32_t f = 0); void setEntryCount(uint32_t newEntryCount); @@ -495,8 +495,8 @@ namespace MP4{ uint32_t getChunkOffset(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - class STSZ: public fullBox{ + + class STSZ: public fullBox { public: STSZ(char v = 1, uint32_t f = 0); void setSampleSize(uint32_t newSampleSize); @@ -507,16 +507,16 @@ namespace MP4{ uint32_t getEntrySize(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - class SampleEntry: public Box{ + + class SampleEntry: public Box { public: SampleEntry(); void setDataReferenceIndex(uint16_t newDataReferenceIndex); uint16_t getDataReferenceIndex(); std::string toPrettySampleString(uint32_t index); }; - - class CLAP: public Box{//CleanApertureBox + + class CLAP: public Box { //CleanApertureBox public: CLAP(); void setCleanApertureWidthN(uint32_t newVal); @@ -538,7 +538,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - class PASP: public Box{ //PixelAspectRatioBox + class PASP: public Box { //PixelAspectRatioBox public: PASP(); void setHSpacing(uint32_t newVal); @@ -547,19 +547,19 @@ namespace MP4{ uint32_t getVSpacing(); std::string toPrettyString(uint32_t indent = 0); }; - - class VisualSampleEntry: public SampleEntry{ - ///\todo set default values + + class VisualSampleEntry: public SampleEntry { + ///\todo set default values public: VisualSampleEntry(); - void setCodec(const char* newCodec); + void setCodec(const char * newCodec); void setWidth(uint16_t newWidth); uint16_t getWidth(); void setHeight(uint16_t newHeight); uint16_t getHeight(); - void setHorizResolution (uint32_t newHorizResolution); + void setHorizResolution(uint32_t newHorizResolution); uint32_t getHorizResolution(); - void setVertResolution (uint32_t newVertResolution); + void setVertResolution(uint32_t newVertResolution); uint32_t getVertResolution(); void setFrameCount(uint16_t newFrameCount); uint16_t getFrameCount(); @@ -568,16 +568,16 @@ namespace MP4{ void setDepth(uint16_t newDepth); uint16_t getDepth(); Box & getCLAP(); - void setCLAP(Box& clap); + void setCLAP(Box & clap); Box & getPASP(); std::string toPrettyVisualString(uint32_t index = 0, std::string = ""); }; - - class AudioSampleEntry: public SampleEntry{ + + class AudioSampleEntry: public SampleEntry { public: ///\todo set default values AudioSampleEntry(); - void setCodec(const char* newCodec); + void setCodec(const char * newCodec); void setChannelCount(uint16_t newChannelCount); uint16_t getChannelCount(); void setSampleSize(uint16_t newSampleSize); @@ -587,56 +587,56 @@ namespace MP4{ void setSampleRate(uint32_t newSampleRate); uint16_t toAACInit(); uint32_t getSampleRate(); - void setCodecBox(Box& newBox); + void setCodecBox(Box & newBox); Box & getCodecBox(); std::string toPrettyAudioString(uint32_t indent = 0, std::string name = ""); }; - - class MP4A: public AudioSampleEntry{ + + class MP4A: public AudioSampleEntry { public: MP4A(); std::string toPrettyString(uint32_t indent = 0); }; - class AAC: public AudioSampleEntry{ + class AAC: public AudioSampleEntry { public: AAC(); std::string toPrettyString(uint32_t indent = 0); }; - class AVC1: public VisualSampleEntry{ + class AVC1: public VisualSampleEntry { public: AVC1(); std::string toPrettyString(uint32_t indent = 0); }; - class H264: public VisualSampleEntry{ + class H264: public VisualSampleEntry { public: H264(); std::string toPrettyString(uint32_t indent = 0); }; - - class STSD: public fullBox{ + + class STSD: public fullBox { public: STSD(char v = 1, uint32_t f = 0); - void setEntryCount (uint32_t newEntryCount); + void setEntryCount(uint32_t newEntryCount); uint32_t getEntryCount(); void setEntry(Box & newContent, uint32_t no); Box & getEntry(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; - - class EDTS: public containerBox{ + + class EDTS: public containerBox { public: EDTS(); }; - class UDTA: public containerBox{ + class UDTA: public containerBox { public: UDTA(); }; - - class STSS: public fullBox{ + + class STSS: public fullBox { public: STSS(char v = 1, uint32_t f = 0); void setEntryCount(uint32_t newVal); @@ -645,14 +645,14 @@ namespace MP4{ uint32_t getSampleNumber(uint32_t index); std::string toPrettyString(uint32_t indent = 0); }; - - class META: public containerFullBox{ + + class META: public containerFullBox { public: META(); std::string toPrettyString(uint32_t indent = 0); }; - - class ELST: public fullBox{ + + class ELST: public fullBox { public: ELST(); void setSegmentDuration(uint64_t newVal); diff --git a/lib/mp4_ms.cpp b/lib/mp4_ms.cpp index f96c346e..47424428 100644 --- a/lib/mp4_ms.cpp +++ b/lib/mp4_ms.cpp @@ -1,8 +1,8 @@ #include "mp4_ms.h" -namespace MP4{ +namespace MP4 { - static char c2hex(int c){ + static char c2hex(int c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; @@ -10,34 +10,34 @@ namespace MP4{ } - SDTP::SDTP(){ + SDTP::SDTP() { memcpy(data + 4, "sdtp", 4); } - void SDTP::setVersion(uint32_t newVersion){ + void SDTP::setVersion(uint32_t newVersion) { setInt8(newVersion, 0); } - uint32_t SDTP::getVersion(){ + uint32_t SDTP::getVersion() { return getInt8(0); } - void SDTP::setValue(uint32_t newValue, size_t index){ + void SDTP::setValue(uint32_t newValue, size_t index) { setInt8(newValue, index); } - uint32_t SDTP::getValue(size_t index){ + uint32_t SDTP::getValue(size_t index) { return getInt8(index); } - std::string SDTP::toPrettyString(uint32_t indent){ + std::string SDTP::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[sdtp] Sample Dependancy Type (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Samples: " << (boxedSize() - 12) << std::endl; - for (size_t i = 1; i <= boxedSize() - 12; ++i){ - uint32_t val = getValue(i+3); + for (size_t i = 1; i <= boxedSize() - 12; ++i) { + uint32_t val = getValue(i + 3); r << std::string(indent + 2, ' ') << "[" << i << "] = "; - switch (val & 3){ + switch (val & 3) { case 0: r << " "; break; @@ -51,7 +51,7 @@ namespace MP4{ r << "Error, "; break; } - switch (val & 12){ + switch (val & 12) { case 0: r << " "; break; @@ -65,7 +65,7 @@ namespace MP4{ r << "Error, "; break; } - switch (val & 48){ + switch (val & 48) { case 0: r << " "; break; @@ -84,48 +84,48 @@ namespace MP4{ return r.str(); } - UUID::UUID(){ + UUID::UUID() { memcpy(data + 4, "uuid", 4); setInt64(0, 0); setInt64(0, 8); } - std::string UUID::getUUID(){ + std::string UUID::getUUID() { std::stringstream r; r << std::hex; - for (int i = 0; i < 16; ++i){ - if (i == 4 || i == 6 || i == 8 || i == 10){ + for (int i = 0; i < 16; ++i) { + if (i == 4 || i == 6 || i == 8 || i == 10) { r << "-"; } - r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8+i]); + r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8 + i]); } return r.str(); } - void UUID::setUUID(const std::string & uuid_string){ + void UUID::setUUID(const std::string & uuid_string) { //reset UUID to zero - for (int i = 0; i < 4; ++i){ - ((uint32_t*)(data+8))[i] = 0; + for (int i = 0; i < 4; ++i) { + ((uint32_t *)(data + 8))[i] = 0; } //set the UUID from the string, char by char int i = 0; - for (size_t j = 0; j < uuid_string.size(); ++j){ - if (uuid_string[j] == '-'){ + for (size_t j = 0; j < uuid_string.size(); ++j) { + if (uuid_string[j] == '-') { continue; } - data[8+i/2] |= (c2hex(uuid_string[j]) << ((~i & 1) << 2)); + data[8 + i / 2] |= (c2hex(uuid_string[j]) << ((~i & 1) << 2)); ++i; } } - void UUID::setUUID(const char * raw_uuid){ - memcpy(data+8, raw_uuid, 16); + void UUID::setUUID(const char * raw_uuid) { + memcpy(data + 8, raw_uuid, 16); } - std::string UUID::toPrettyString(uint32_t indent){ + std::string UUID::toPrettyString(uint32_t indent) { std::string UUID = getUUID(); - if (UUID == "d4807ef2-ca39-4695-8e54-26cb9e46a79f"){ - return ((UUID_TrackFragmentReference*)this)->toPrettyString(indent); + if (UUID == "d4807ef2-ca39-4695-8e54-26cb9e46a79f") { + return ((UUID_TrackFragmentReference *)this)->toPrettyString(indent); } std::stringstream r; r << std::string(indent, ' ') << "[uuid] Extension box (" << boxedSize() << ")" << std::endl; @@ -134,73 +134,73 @@ namespace MP4{ return r.str(); } - UUID_TrackFragmentReference::UUID_TrackFragmentReference(){ + UUID_TrackFragmentReference::UUID_TrackFragmentReference() { setUUID((std::string)"d4807ef2-ca39-4695-8e54-26cb9e46a79f"); } - void UUID_TrackFragmentReference::setVersion(uint32_t newVersion){ + void UUID_TrackFragmentReference::setVersion(uint32_t newVersion) { setInt8(newVersion, 16); } - - uint32_t UUID_TrackFragmentReference::getVersion(){ + + uint32_t UUID_TrackFragmentReference::getVersion() { return getInt8(16); } - - void UUID_TrackFragmentReference::setFlags(uint32_t newFlags){ + + void UUID_TrackFragmentReference::setFlags(uint32_t newFlags) { setInt24(newFlags, 17); } - - uint32_t UUID_TrackFragmentReference::getFlags(){ + + uint32_t UUID_TrackFragmentReference::getFlags() { return getInt24(17); } - - void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount){ + + void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount) { setInt8(newCount, 20); } - - uint32_t UUID_TrackFragmentReference::getFragmentCount(){ + + uint32_t UUID_TrackFragmentReference::getFragmentCount() { return getInt8(20); } - - void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime){ - if (getVersion() == 0){ - setInt32(newTime, 21+(num*8)); - }else{ - setInt64(newTime, 21+(num*16)); - } - } - - uint64_t UUID_TrackFragmentReference::getTime(size_t num){ - if (getVersion() == 0){ - return getInt32(21+(num*8)); - }else{ - return getInt64(21+(num*16)); - } - } - - void UUID_TrackFragmentReference::setDuration(size_t num, uint64_t newDuration){ - if (getVersion() == 0){ - setInt32(newDuration, 21+(num*8)+4); - }else{ - setInt64(newDuration, 21+(num*16)+8); - } - } - - uint64_t UUID_TrackFragmentReference::getDuration(size_t num){ - if (getVersion() == 0){ - return getInt32(21+(num*8)+4); - }else{ - return getInt64(21+(num*16)+8); + + void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime) { + if (getVersion() == 0) { + setInt32(newTime, 21 + (num * 8)); + } else { + setInt64(newTime, 21 + (num * 16)); } } - std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent){ + uint64_t UUID_TrackFragmentReference::getTime(size_t num) { + if (getVersion() == 0) { + return getInt32(21 + (num * 8)); + } else { + return getInt64(21 + (num * 16)); + } + } + + void UUID_TrackFragmentReference::setDuration(size_t num, uint64_t newDuration) { + if (getVersion() == 0) { + setInt32(newDuration, 21 + (num * 8) + 4); + } else { + setInt64(newDuration, 21 + (num * 16) + 8); + } + } + + uint64_t UUID_TrackFragmentReference::getDuration(size_t num) { + if (getVersion() == 0) { + return getInt32(21 + (num * 8) + 4); + } else { + return getInt64(21 + (num * 16) + 8); + } + } + + std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent) { std::stringstream r; r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference (" << boxedSize() << ")" << std::endl; r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl; r << std::string(indent + 1, ' ') << "Fragments: " << getFragmentCount() << std::endl; int j = getFragmentCount(); - for (int i = 0; i < j; ++i){ + for (int i = 0; i < j; ++i) { r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i) << ", Duration = " << getDuration(i) << std::endl; } return r.str(); diff --git a/lib/mp4_ms.h b/lib/mp4_ms.h index d9c809ae..882f01dc 100644 --- a/lib/mp4_ms.h +++ b/lib/mp4_ms.h @@ -1,8 +1,8 @@ #pragma once #include "mp4.h" -namespace MP4{ - class SDTP: public Box{ +namespace MP4 { + class SDTP: public Box { public: SDTP(); void setVersion(uint32_t newVersion); @@ -11,8 +11,8 @@ namespace MP4{ uint32_t getValue(size_t index); std::string toPrettyString(uint32_t indent = 0); }; - - class UUID: public Box{ + + class UUID: public Box { public: UUID(); std::string getUUID(); @@ -21,7 +21,7 @@ namespace MP4{ std::string toPrettyString(uint32_t indent = 0); }; - class UUID_TrackFragmentReference: public UUID{ + class UUID_TrackFragmentReference: public UUID { public: UUID_TrackFragmentReference(); void setVersion(uint32_t newVersion); diff --git a/lib/nal.cpp b/lib/nal.cpp old mode 100755 new mode 100644 index e276f026..a7c430f7 --- a/lib/nal.cpp +++ b/lib/nal.cpp @@ -134,10 +134,10 @@ namespace h264 { //For calculating width unsigned int widthInMbs = 0; unsigned int cropHorizontal = 0; - + //For calculating height bool mbsOnlyFlag = 0; - unsigned int heightInMapUnits = 0; + unsigned int heightInMapUnits = 0; unsigned int cropVertical = 0; Utils::bitstream bs; @@ -177,7 +177,7 @@ namespace h264 { bs.skip(1); //Stop skipping data and start doing usefull stuff - + widthInMbs = bs.getUExpGolomb() + 1; heightInMapUnits = bs.getUExpGolomb() + 1; @@ -197,7 +197,7 @@ namespace h264 { //vuiParameters if (bs.get(1)) { //Skipping all the paramters we dont use - if (bs.get(1)){ + if (bs.get(1)) { if (bs.get(8) == 255) { bs.skip(32); } diff --git a/lib/nal.h b/lib/nal.h old mode 100755 new mode 100644 index 00a797af..16403ce0 --- a/lib/nal.h +++ b/lib/nal.h @@ -1,17 +1,17 @@ #include #include -namespace h264{ - +namespace h264 { + ///Struct containing pre-calculated metadata of an SPS nal unit. Width and height in pixels, fps in Hz - struct SPSMeta{ + struct SPSMeta { unsigned int width; unsigned int height; double fps; }; - + ///Class for analyzing generic nal units - class NAL{ + class NAL { public: NAL(); NAL(std::string & InputData); @@ -25,21 +25,21 @@ namespace h264{ std::string MyData;/// #include -namespace OGG{ - inline long long unsigned int get_64(char* data){ +namespace OGG { + inline long long unsigned int get_64(char * data) { long long unsigned int temp = 0; - for (int i = 7; i>= 0; --i){ + for (int i = 7; i >= 0; --i) { temp <<= 8; temp += data[i]; } return temp; } - - inline long unsigned int get_32(char* data){ + + inline long unsigned int get_32(char * data) { long unsigned int temp = 0; - for (int i = 3; i>= 0; --i){ + for (int i = 3; i >= 0; --i) { temp <<= 8; temp += data[i]; } return temp; } - inline void set_64(char* data, long unsigned int val){ - for (int i = 0; i< 8; ++i){ + inline void set_64(char * data, long unsigned int val) { + for (int i = 0; i < 8; ++i) { data[i] = val & 0xFF; val >>= 8; } } - inline void set_32(char* data, long unsigned int val){ - for (int i = 0; i< 4; ++i){ + inline void set_32(char * data, long unsigned int val) { + for (int i = 0; i < 4; ++i) { data[i] = val & 0xFF; val >>= 8; } } - - Page::Page(){ + + Page::Page() { data = NULL; datasize = 0; dataSum = 0; } - - Page::~Page(){ - if (data){ + + Page::~Page() { + if (data) { free(data); } } - bool Page::read(std::string & newData){ + bool Page::read(std::string & newData) { segmentTableDeque.clear(); //datasize = 0; - if (newData.size()<27){ + if (newData.size() < 27) { return false; } - if (newData.substr(0, 4) != "OggS"){ + if (newData.substr(0, 4) != "OggS") { DEBUG_MSG(DLVL_FAIL, "Invalid Ogg page encountered - cannot continue"); return false; } dataSum = 0; - if (!checkDataSize(27)){ + if (!checkDataSize(27)) { return false; } memcpy(data, newData.c_str(), 27);//copying the header, always 27 bytes - - if (newData.size() < 27u + getPageSegments()){//check input size + + if (newData.size() < 27u + getPageSegments()) { //check input size return false; } - if(!checkDataSize(27 + getPageSegments())){//check if size available in memory + if (!checkDataSize(27 + getPageSegments())) { //check if size available in memory return false; } - memcpy(data + 27, newData.c_str() + 27, getPageSegments()); + memcpy(data + 27, newData.c_str() + 27, getPageSegments()); //copying the first part of the page into data, which tells the size of the page - - for(unsigned int i = 0; i < getPageSegments(); i++){ + + for (unsigned int i = 0; i < getPageSegments(); i++) { dataSum += getSegmentTable()[i]; } - - if (newData.size() < 27 + getPageSegments() + dataSum){//check input size + + if (newData.size() < 27 + getPageSegments() + dataSum) { //check input size dataSum = 0; return false; } - if(!checkDataSize(27 + getPageSegments()+dataSum)){ + if (!checkDataSize(27 + getPageSegments() + dataSum)) { dataSum = 0; return false; } @@ -95,38 +95,38 @@ namespace OGG{ } - bool Page::read(FILE * inFile){ + bool Page::read(FILE * inFile) { segmentTableDeque.clear(); int oriPos = ftell(inFile); dataSum = 0; - if (!checkDataSize(27)){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: memory allocation"); + if (!checkDataSize(27)) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation"); return false; } - if (!fread(data, 27, 1, inFile)){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: fread"); + if (!fread(data, 27, 1, inFile)) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread"); fseek(inFile, oriPos, SEEK_SET); return false; } - if(!checkDataSize(27 + getPageSegments())){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: memory allocation1"); + if (!checkDataSize(27 + getPageSegments())) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation1"); return false; } - if (!fread(data + 27, getPageSegments(), 1, inFile)){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: fread1"); + if (!fread(data + 27, getPageSegments(), 1, inFile)) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread1"); fseek(inFile, oriPos, SEEK_SET); return false; } - for (unsigned int i = 0; i < getPageSegments(); i++){ + for (unsigned int i = 0; i < getPageSegments(); i++) { dataSum += data[27 + i]; } - if (!checkDataSize(27 + getPageSegments() + dataSum)){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: memory allocation2"); + if (!checkDataSize(27 + getPageSegments() + dataSum)) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: memory allocation2"); dataSum = 0; return false; } - if ( !fread(data + 27 + getPageSegments(), dataSum, 1, inFile)){ - DEBUG_MSG(DLVL_WARN,"Unable to read a page: fread2"); + if (!fread(data + 27 + getPageSegments(), dataSum, 1, inFile)) { + DEBUG_MSG(DLVL_WARN, "Unable to read a page: fread2"); fseek(inFile, oriPos, SEEK_SET); dataSum = 0; return false; @@ -134,143 +134,143 @@ namespace OGG{ return true; } - bool Page::getSegment(unsigned int index, char * ret, unsigned int & len){ - if (index > segmentTableDeque.size()){ + bool Page::getSegment(unsigned int index, char * ret, unsigned int & len) { + if (index > segmentTableDeque.size()) { ret = NULL; len = 0; return false; } ret = getFullPayload(); - for (unsigned int i = 0; i < index; i++){ + for (unsigned int i = 0; i < index; i++) { ret += segmentTableDeque[i]; } len = segmentTableDeque[index]; return true; } - - void Page::setMagicNumber(){ - if(checkDataSize(4)){ + + void Page::setMagicNumber() { + if (checkDataSize(4)) { memcpy(data, "OggS", 4); } } - - char Page::getVersion(){ + + char Page::getVersion() { return data[4]; } - void Page::setVersion(char newVal){ - if(checkDataSize(5)){ + void Page::setVersion(char newVal) { + if (checkDataSize(5)) { data[4] = newVal; } } - - char Page::getHeaderType(){ + + char Page::getHeaderType() { return data[5]; } - void Page::setHeaderType(char newVal){ - if(checkDataSize(6)){ + void Page::setHeaderType(char newVal) { + if (checkDataSize(6)) { data[5] = newVal; } } - - long long unsigned int Page::getGranulePosition(){ - if(checkDataSize(14)){ + + long long unsigned int Page::getGranulePosition() { + if (checkDataSize(14)) { //switching bit order upon return //return ntohl(((long unsigned*)(data+6))[1]) & ((long long unsigned)((long long unsigned)ntohl(((long unsigned*)(data+6))[0]) << 32)); //long long unsigned int temp; //temp = ((long unsigned int)(data+6)[0]); //temp = temp << 32 + ((long unsigned int)(data+6)[1]); - return get_64(data+6); + return get_64(data + 6); } return 0; } - void Page::setGranulePosition(long long unsigned int newVal){ - if(checkDataSize(14)){ - set_64(data+6, newVal); + void Page::setGranulePosition(long long unsigned int newVal) { + if (checkDataSize(14)) { + set_64(data + 6, newVal); } } - - long unsigned int Page::getBitstreamSerialNumber(){ + + long unsigned int Page::getBitstreamSerialNumber() { //return ntohl(((long unsigned int*)(data+14))[0]); - return get_32(data+14); + return get_32(data + 14); } - void Page::setBitstreamSerialNumber(long unsigned int newVal){ - if(checkDataSize(18)){ + void Page::setBitstreamSerialNumber(long unsigned int newVal) { + if (checkDataSize(18)) { //((long unsigned *)(data+14))[0] = htonl(newVal); - set_32(data+14, newVal); + set_32(data + 14, newVal); } } - - long unsigned int Page::getPageSequenceNumber(){ - return get_32(data+18); - } - void Page::setPageSequenceNumber(long unsigned int newVal){ - if(checkDataSize(22)){ + long unsigned int Page::getPageSequenceNumber() { + return get_32(data + 18); + } + + void Page::setPageSequenceNumber(long unsigned int newVal) { + if (checkDataSize(22)) { //((long unsigned *)(data+18))[0] = htonl(newVal); - set_32(data+18, newVal); + set_32(data + 18, newVal); } } - - long unsigned int Page::getCRCChecksum(){ + + long unsigned int Page::getCRCChecksum() { //return ntohl(((long unsigned int*)(data+22))[0]); - return get_32(data+22); + return get_32(data + 22); } - - void Page::setCRCChecksum(long unsigned int newVal){ - if(checkDataSize(26)){ - set_32(data+22,newVal); + + void Page::setCRCChecksum(long unsigned int newVal) { + if (checkDataSize(26)) { + set_32(data + 22, newVal); } } - - char Page::getPageSegments(){ - return data[26]; + + char Page::getPageSegments() { + return data[26]; } - - inline void Page::setPageSegments(char newVal){ - if(checkDataSize(26)){ + + inline void Page::setPageSegments(char newVal) { + if (checkDataSize(26)) { data[26] = newVal; } } - - char* Page::getSegmentTable(){ - return data+27; + + char * Page::getSegmentTable() { + return data + 27; } - - std::deque & Page::getSegmentTableDeque(){ - if ( !segmentTableDeque.size()){ + + std::deque & Page::getSegmentTableDeque() { + if (!segmentTableDeque.size()) { unsigned int temp = 0; - for (unsigned int i = 0; i < getPageSegments(); i++){ + for (unsigned int i = 0; i < getPageSegments(); i++) { temp += getSegmentTable()[i]; - if (getSegmentTable()[i] < 255){ + if (getSegmentTable()[i] < 255) { segmentTableDeque.push_back(temp); temp = 0; } } - if (temp!=0){ + if (temp != 0) { segmentTableDeque.push_back(temp); } } return segmentTableDeque; } - static void STerrMSG(){ + static void STerrMSG() { DEBUG_MSG(DLVL_ERROR, "Segment too big, create a continue page"); } - bool Page::setSegmentTable(std::vector layout){ - dataSum=0; - for (unsigned int i = 0; i < layout.size(); i++){ + bool Page::setSegmentTable(std::vector layout) { + dataSum = 0; + for (unsigned int i = 0; i < layout.size(); i++) { dataSum += layout[i]; } unsigned int place = 0; char table[256]; - for (unsigned int i = 0; i < layout.size(); i++){ - int amount = (layout[i]/255) + 1; - if (i == layout.size() - 1 && place + amount > (255 + (layout[i] % 255 == 0))){ + for (unsigned int i = 0; i < layout.size(); i++) { + int amount = (layout[i] / 255) + 1; + if (i == layout.size() - 1 && place + amount > (255 + (layout[i] % 255 == 0))) { STerrMSG(); return false; } @@ -279,141 +279,140 @@ namespace OGG{ place += amount; } //Don't send element 256, even if it was filled. - if (place > 255){ + if (place > 255) { place = 255; } setPageSegments(place); - setSegmentTable(table,place); + setSegmentTable(table, place); return true; } - - void Page::setSegmentTable(char* newVal, unsigned int length){ - if(checkDataSize(27 + length)){ + + void Page::setSegmentTable(char * newVal, unsigned int length) { + if (checkDataSize(27 + length)) { memcpy(data + 27, newVal, length); } } - - unsigned long int Page::getPageSize(){ - return 27 + getPageSegments()+dataSum; + + unsigned long int Page::getPageSize() { + return 27 + getPageSegments() + dataSum; } - - char* Page::getPage(){ + + char * Page::getPage() { return data; } - - char* Page::getFullPayload(){ + + char * Page::getFullPayload() { return data + 27 + getPageSegments(); } - - void Page::setInternalCodec(std::string myCodec){ + + void Page::setInternalCodec(std::string myCodec) { codec = myCodec; } - - std::string Page::toPrettyString(size_t indent){ + + std::string Page::toPrettyString(size_t indent) { std::stringstream r; - r << std::string(indent,' ') << "Ogg page (" << getPageSize() << ")" << std::endl; - r << std::string(indent + 2,' ') << "Version: " << (int)getVersion() << std::endl; - r << std::string(indent + 2,' ') << "Header type:"; - if ( !getHeaderType()){ + r << std::string(indent, ' ') << "Ogg page (" << getPageSize() << ")" << std::endl; + r << std::string(indent + 2, ' ') << "Version: " << (int)getVersion() << std::endl; + r << std::string(indent + 2, ' ') << "Header type:"; + if (!getHeaderType()) { r << " Normal"; - }else{ - if (getHeaderType() & Continued){ + } else { + if (getHeaderType() & Continued) { r << " Continued"; } - if (getHeaderType() & BeginOfStream){ + if (getHeaderType() & BeginOfStream) { r << " BeginOfStream"; } - if (getHeaderType() & EndOfStream){ + if (getHeaderType() & EndOfStream) { r << " EndOfStream"; } } r << " (" << (int)getHeaderType() << ")" << std::endl; - r << std::string(indent + 2,' ') << "Granule position: " << getGranulePosition() << std::endl; - r << std::string(indent + 2,' ') << "Bitstream number: " << getBitstreamSerialNumber() << std::endl; - r << std::string(indent + 2,' ') << "Sequence number: " << getPageSequenceNumber() << std::endl; - r << std::string(indent + 2,' ') << "Checksum: " << std::hex << getCRCChecksum() << std::dec << std::endl; + r << std::string(indent + 2, ' ') << "Granule position: " << getGranulePosition() << std::endl; + r << std::string(indent + 2, ' ') << "Bitstream number: " << getBitstreamSerialNumber() << std::endl; + r << std::string(indent + 2, ' ') << "Sequence number: " << getPageSequenceNumber() << std::endl; + r << std::string(indent + 2, ' ') << "Checksum: " << std::hex << getCRCChecksum() << std::dec << std::endl; //r << " Calced Checksum: " << std::hex << calcChecksum() << std::dec << std::endl; - r << std::string(indent + 2,' ') << "Payloadsize: " << dataSum << std::endl; - r << std::string(indent + 2,' ') << (int)getPageSegments() << " segments:" << std::endl; - r << std::string(indent + 3,' '); + r << std::string(indent + 2, ' ') << "Payloadsize: " << dataSum << std::endl; + r << std::string(indent + 2, ' ') << (int)getPageSegments() << " segments:" << std::endl; + r << std::string(indent + 3, ' '); std::deque temp = getSegmentTableDeque(); - for (std::deque::iterator i = temp.begin(); i != temp.end(); i++){ + for (std::deque::iterator i = temp.begin(); i != temp.end(); i++) { r << " " << (*i); } r << std::endl; return r.str(); } - - inline unsigned int crc32(unsigned int crc, const char *data, size_t len){ + + inline unsigned int crc32(unsigned int crc, const char * data, size_t len) { static const unsigned int table[256] = { - 0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U, - 0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U, - 0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U, - 0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU, - 0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U, - 0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U, - 0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U, - 0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU, - 0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U, - 0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U, - 0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U, - 0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU, - 0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U, - 0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U, - 0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U, - 0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU, - 0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU, - 0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U, - 0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U, - 0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU, - 0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU, - 0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U, - 0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U, - 0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU, - 0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU, - 0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U, - 0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U, - 0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU, - 0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU, - 0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U, - 0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U, - 0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU, - 0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U, - 0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU, - 0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU, - 0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U, - 0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U, - 0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU, - 0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU, - 0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U, - 0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U, - 0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU, - 0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU, - 0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U, - 0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U, - 0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU, - 0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU, - 0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U, - 0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U, - 0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU, - 0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U, - 0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U, - 0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U, - 0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU, - 0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U, - 0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U, - 0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U, - 0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU, - 0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U, - 0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U, - 0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U, - 0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU, - 0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U, - 0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U, + 0x00000000U, 0x04C11DB7U, 0x09823B6EU, 0x0D4326D9U, + 0x130476DCU, 0x17C56B6BU, 0x1A864DB2U, 0x1E475005U, + 0x2608EDB8U, 0x22C9F00FU, 0x2F8AD6D6U, 0x2B4BCB61U, + 0x350C9B64U, 0x31CD86D3U, 0x3C8EA00AU, 0x384FBDBDU, + 0x4C11DB70U, 0x48D0C6C7U, 0x4593E01EU, 0x4152FDA9U, + 0x5F15ADACU, 0x5BD4B01BU, 0x569796C2U, 0x52568B75U, + 0x6A1936C8U, 0x6ED82B7FU, 0x639B0DA6U, 0x675A1011U, + 0x791D4014U, 0x7DDC5DA3U, 0x709F7B7AU, 0x745E66CDU, + 0x9823B6E0U, 0x9CE2AB57U, 0x91A18D8EU, 0x95609039U, + 0x8B27C03CU, 0x8FE6DD8BU, 0x82A5FB52U, 0x8664E6E5U, + 0xBE2B5B58U, 0xBAEA46EFU, 0xB7A96036U, 0xB3687D81U, + 0xAD2F2D84U, 0xA9EE3033U, 0xA4AD16EAU, 0xA06C0B5DU, + 0xD4326D90U, 0xD0F37027U, 0xDDB056FEU, 0xD9714B49U, + 0xC7361B4CU, 0xC3F706FBU, 0xCEB42022U, 0xCA753D95U, + 0xF23A8028U, 0xF6FB9D9FU, 0xFBB8BB46U, 0xFF79A6F1U, + 0xE13EF6F4U, 0xE5FFEB43U, 0xE8BCCD9AU, 0xEC7DD02DU, + 0x34867077U, 0x30476DC0U, 0x3D044B19U, 0x39C556AEU, + 0x278206ABU, 0x23431B1CU, 0x2E003DC5U, 0x2AC12072U, + 0x128E9DCFU, 0x164F8078U, 0x1B0CA6A1U, 0x1FCDBB16U, + 0x018AEB13U, 0x054BF6A4U, 0x0808D07DU, 0x0CC9CDCAU, + 0x7897AB07U, 0x7C56B6B0U, 0x71159069U, 0x75D48DDEU, + 0x6B93DDDBU, 0x6F52C06CU, 0x6211E6B5U, 0x66D0FB02U, + 0x5E9F46BFU, 0x5A5E5B08U, 0x571D7DD1U, 0x53DC6066U, + 0x4D9B3063U, 0x495A2DD4U, 0x44190B0DU, 0x40D816BAU, + 0xACA5C697U, 0xA864DB20U, 0xA527FDF9U, 0xA1E6E04EU, + 0xBFA1B04BU, 0xBB60ADFCU, 0xB6238B25U, 0xB2E29692U, + 0x8AAD2B2FU, 0x8E6C3698U, 0x832F1041U, 0x87EE0DF6U, + 0x99A95DF3U, 0x9D684044U, 0x902B669DU, 0x94EA7B2AU, + 0xE0B41DE7U, 0xE4750050U, 0xE9362689U, 0xEDF73B3EU, + 0xF3B06B3BU, 0xF771768CU, 0xFA325055U, 0xFEF34DE2U, + 0xC6BCF05FU, 0xC27DEDE8U, 0xCF3ECB31U, 0xCBFFD686U, + 0xD5B88683U, 0xD1799B34U, 0xDC3ABDEDU, 0xD8FBA05AU, + 0x690CE0EEU, 0x6DCDFD59U, 0x608EDB80U, 0x644FC637U, + 0x7A089632U, 0x7EC98B85U, 0x738AAD5CU, 0x774BB0EBU, + 0x4F040D56U, 0x4BC510E1U, 0x46863638U, 0x42472B8FU, + 0x5C007B8AU, 0x58C1663DU, 0x558240E4U, 0x51435D53U, + 0x251D3B9EU, 0x21DC2629U, 0x2C9F00F0U, 0x285E1D47U, + 0x36194D42U, 0x32D850F5U, 0x3F9B762CU, 0x3B5A6B9BU, + 0x0315D626U, 0x07D4CB91U, 0x0A97ED48U, 0x0E56F0FFU, + 0x1011A0FAU, 0x14D0BD4DU, 0x19939B94U, 0x1D528623U, + 0xF12F560EU, 0xF5EE4BB9U, 0xF8AD6D60U, 0xFC6C70D7U, + 0xE22B20D2U, 0xE6EA3D65U, 0xEBA91BBCU, 0xEF68060BU, + 0xD727BBB6U, 0xD3E6A601U, 0xDEA580D8U, 0xDA649D6FU, + 0xC423CD6AU, 0xC0E2D0DDU, 0xCDA1F604U, 0xC960EBB3U, + 0xBD3E8D7EU, 0xB9FF90C9U, 0xB4BCB610U, 0xB07DABA7U, + 0xAE3AFBA2U, 0xAAFBE615U, 0xA7B8C0CCU, 0xA379DD7BU, + 0x9B3660C6U, 0x9FF77D71U, 0x92B45BA8U, 0x9675461FU, + 0x8832161AU, 0x8CF30BADU, 0x81B02D74U, 0x857130C3U, + 0x5D8A9099U, 0x594B8D2EU, 0x5408ABF7U, 0x50C9B640U, + 0x4E8EE645U, 0x4A4FFBF2U, 0x470CDD2BU, 0x43CDC09CU, + 0x7B827D21U, 0x7F436096U, 0x7200464FU, 0x76C15BF8U, + 0x68860BFDU, 0x6C47164AU, 0x61043093U, 0x65C52D24U, + 0x119B4BE9U, 0x155A565EU, 0x18197087U, 0x1CD86D30U, + 0x029F3D35U, 0x065E2082U, 0x0B1D065BU, 0x0FDC1BECU, + 0x3793A651U, 0x3352BBE6U, 0x3E119D3FU, 0x3AD08088U, + 0x2497D08DU, 0x2056CD3AU, 0x2D15EBE3U, 0x29D4F654U, + 0xC5A92679U, 0xC1683BCEU, 0xCC2B1D17U, 0xC8EA00A0U, + 0xD6AD50A5U, 0xD26C4D12U, 0xDF2F6BCBU, 0xDBEE767CU, + 0xE3A1CBC1U, 0xE760D676U, 0xEA23F0AFU, 0xEEE2ED18U, + 0xF0A5BD1DU, 0xF464A0AAU, 0xF9278673U, 0xFDE69BC4U, + 0x89B8FD09U, 0x8D79E0BEU, 0x803AC667U, 0x84FBDBD0U, + 0x9ABC8BD5U, 0x9E7D9662U, 0x933EB0BBU, 0x97FFAD0CU, + 0xAFB010B1U, 0xAB710D06U, 0xA6322BDFU, 0xA2F33668U, + 0xBCB4666DU, 0xB8757BDAU, 0xB5365D03U, 0xB1F740B4U, }; - - while (len > 0) - { + + while (len > 0) { crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8); data++; len--; @@ -421,39 +420,39 @@ namespace OGG{ return crc; } - long unsigned int Page::calcChecksum(){ + long unsigned int Page::calcChecksum() { long unsigned int retVal = 0; long unsigned int oldChecksum = getCRCChecksum(); - setCRCChecksum (0); + setCRCChecksum(0); retVal = crc32(0, data, getPageSize()); - setCRCChecksum (oldChecksum); + setCRCChecksum(oldChecksum); return retVal; } - - inline bool Page::checkDataSize(unsigned int size){ - if (size > datasize){ - void* tmp = realloc(data,size); - if (tmp){ - data = (char*)tmp; + + inline bool Page::checkDataSize(unsigned int size) { + if (size > datasize) { + void * tmp = realloc(data, size); + if (tmp) { + data = (char *)tmp; datasize = size; return true; - }else{ + } else { return false; } - }else{ + } else { return true; } } - int Page::getPayloadSize(){ + int Page::getPayloadSize() { return dataSum; } - - bool Page::clear(){ - if(!checkDataSize(27)){//check if size available in memory + + bool Page::clear() { + if (!checkDataSize(27)) { //check if size available in memory return false; } - memset(data,0,27); + memset(data, 0, 27); dataSum = 0; codec = ""; setMagicNumber(); @@ -461,70 +460,70 @@ namespace OGG{ return true; } - bool Page::setPayload(char* newData, unsigned int length){ - if(!checkDataSize(27 + getPageSegments() + length)){//check if size available in memory + bool Page::setPayload(char * newData, unsigned int length) { + if (!checkDataSize(27 + getPageSegments() + length)) { //check if size available in memory return false; } memcpy(data + 27 + getPageSegments(), newData, length); return true; } - - void Page::readDTSCVector(std::vector DTSCVec, unsigned int serial, unsigned int sequence){ + + void Page::readDTSCVector(std::vector DTSCVec, unsigned int serial, unsigned int sequence) { clear(); setVersion(); - if (DTSCVec[0]["OggCont"] ){//if it is a continue page, also for granule=0xFFFFFFFF + if (DTSCVec[0]["OggCont"]) {//if it is a continue page, also for granule=0xFFFFFFFF setHeaderType(1);//headertype 1 = Continue Page - }else if (DTSCVec[0]["OggEOS"]){ + } else if (DTSCVec[0]["OggEOS"]) { setHeaderType(4);//headertype 4 = end of stream - }else{ + } else { setHeaderType(0);//headertype 0 = normal } setGranulePosition(DTSCVec[0]["granule"].asInt()); - for (unsigned int i = 1; i < DTSCVec.size(); i++){ - if (DTSCVec[0]["granule"].asInt() != DTSCVec[i]["granule"].asInt()){ + for (unsigned int i = 1; i < DTSCVec.size(); i++) { + if (DTSCVec[0]["granule"].asInt() != DTSCVec[i]["granule"].asInt()) { DEBUG_MSG(DLVL_WARN, "Granule inconcistency!! %u != %u", (unsigned int)DTSCVec[0]["granule"].asInt(), (unsigned int)DTSCVec[i]["granule"].asInt()); } - if (DTSCVec[0]["trackid"].asInt() != DTSCVec[i]["trackid"].asInt()){ + if (DTSCVec[0]["trackid"].asInt() != DTSCVec[i]["trackid"].asInt()) { DEBUG_MSG(DLVL_WARN, "Track ID inconcistency!! %u != %u", (unsigned int)DTSCVec[0]["trackid"].asInt(), (unsigned int)DTSCVec[i]["trackid"].asInt()); } } setBitstreamSerialNumber(serial); setPageSequenceNumber(sequence); - + std::vector curSegTable; std::string pageBuffer; - for (unsigned int i = 0; i < DTSCVec.size(); i++){ + for (unsigned int i = 0; i < DTSCVec.size(); i++) { curSegTable.push_back(DTSCVec[i]["data"].asString().size()); pageBuffer += DTSCVec[i]["data"].asString(); } setSegmentTable(curSegTable); - setPayload((char*)pageBuffer.c_str(), pageBuffer.size()); + setPayload((char *)pageBuffer.c_str(), pageBuffer.size()); setCRCChecksum(calcChecksum()); } - - void headerPages::readDTSCHeader(DTSC::Meta & meta){ + + void headerPages::readDTSCHeader(DTSC::Meta & meta) { //pages.clear(); parsedPages = ""; Page curOggPage; - srand (Util::getMS());//randomising with milliseconds from boot + srand(Util::getMS()); //randomising with milliseconds from boot std::vector curSegTable; DTSCID2OGGSerial.clear(); DTSCID2seqNum.clear(); //Creating ID headers for theora and vorbis - for ( std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { + for (std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { curOggPage.clear(); curOggPage.setVersion(); curOggPage.setHeaderType(2);//headertype 2 = Begin of Stream curOggPage.setGranulePosition(0); - DTSCID2OGGSerial[it->second.trackID] = rand() % 0xFFFFFFFE +1; //initialising on a random not 0 number + DTSCID2OGGSerial[it->second.trackID] = rand() % 0xFFFFFFFE + 1; //initialising on a random not 0 number curOggPage.setBitstreamSerialNumber(DTSCID2OGGSerial[it->second.trackID]); DTSCID2seqNum[it->second.trackID] = 0; curOggPage.setPageSequenceNumber(DTSCID2seqNum[it->second.trackID]++); curSegTable.clear(); curSegTable.push_back(it->second.idHeader.size()); curOggPage.setSegmentTable(curSegTable); - curOggPage.setPayload((char*)it->second.idHeader.c_str(), it->second.idHeader.size()); + curOggPage.setPayload((char *)it->second.idHeader.c_str(), it->second.idHeader.size()); curOggPage.setCRCChecksum(curOggPage.calcChecksum()); //std::cout << std::string(curOggPage.getPage(), curOggPage.getPageSize()); //pages.push_back(curOggPage); @@ -533,7 +532,7 @@ namespace OGG{ //Creating remaining headers for theora and vorbis //for tracks in header //create standard page with comment (empty) en setup header(init) - for ( std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { + for (std::map::iterator it = meta.tracks.begin(); it != meta.tracks.end(); it ++) { curOggPage.clear(); curOggPage.setVersion(); curOggPage.setHeaderType(0);//headertype 0 = normal @@ -545,7 +544,7 @@ namespace OGG{ curSegTable.push_back(it->second.init.size()); curOggPage.setSegmentTable(curSegTable); std::string fullHeader = it->second.commentHeader + it->second.init; - curOggPage.setPayload((char*)fullHeader.c_str(),fullHeader.size()); + curOggPage.setPayload((char *)fullHeader.c_str(), fullHeader.size()); curOggPage.setCRCChecksum(curOggPage.calcChecksum()); //std::cout << std::string(curOggPage.getPage(), curOggPage.getPageSize()); //pages.push_back(curOggPage); diff --git a/lib/ogg.h b/lib/ogg.h index 0fe58b5d..2e396389 100644 --- a/lib/ogg.h +++ b/lib/ogg.h @@ -8,15 +8,15 @@ #include "vorbis.h" #include "json.h" -namespace OGG{ - - enum HeaderType{ +namespace OGG { + + enum HeaderType { Continued = 1, BeginOfStream = 2, EndOfStream = 4 }; - - class Page{ + + class Page { public: Page(); ~Page(); @@ -38,30 +38,30 @@ namespace OGG{ void setCRCChecksum(long unsigned int newVal); char getPageSegments(); inline void setPageSegments(char newVal); - char* getSegmentTable(); + char * getSegmentTable(); std::deque & getSegmentTableDeque(); bool setSegmentTable(std::vector layout); - void setSegmentTable(char* newVal, unsigned int length); - char* getPage();//returns complete page with header + void setSegmentTable(char * newVal, unsigned int length); + char * getPage(); //returns complete page with header unsigned long int getPageSize(); - char* getFullPayload();//returns all segments in the page + char * getFullPayload(); //returns all segments in the page int getPayloadSize(); std::string toPrettyString(size_t indent = 0); void setInternalCodec(std::string myCodec); long unsigned int calcChecksum(); bool clear(); - bool setPayload(char* newData, unsigned int length); + bool setPayload(char * newData, unsigned int length); void readDTSCVector(std::vector DTSCVec, unsigned int serial, unsigned int sequence); private: std::deque segmentTableDeque; - char* data;//pointer to the beginning of the Page data + char * data; //pointer to the beginning of the Page data unsigned int datasize;//size of the allocated memory unsigned int dataSum;//size of the total segments bool checkDataSize(unsigned int size); std::string codec;//codec in the page }; - - class headerPages{ + + class headerPages { public: void readDTSCHeader(DTSC::Meta & meta); std::map DTSCID2OGGSerial; diff --git a/lib/procs.cpp b/lib/procs.cpp index b0dd0281..209bccfd 100644 --- a/lib/procs.cpp +++ b/lib/procs.cpp @@ -25,13 +25,17 @@ std::map Util::Procs::plist; std::map Util::Procs::exitHandlers; bool Util::Procs::handler_set = false; -static bool childRunning(pid_t p){ +static bool childRunning(pid_t p) { pid_t ret = waitpid(p, 0, WNOHANG); - if (ret == p){return false;} - if (ret < 0 && errno == EINTR){ + if (ret == p) { + return false; + } + if (ret < 0 && errno == EINTR) { return childRunning(p); } - if (kill(p, 0) == 0){return true;} + if (kill(p, 0) == 0) { + return true; + } return false; } @@ -39,121 +43,129 @@ static bool childRunning(pid_t p){ /// Waits up to 1 second, then sends SIGINT signal to all managed processes. /// After that waits up to 5 seconds for children to exit, then sends SIGKILL to /// all remaining children. Waits one more second for cleanup to finish, then exits. -void Util::Procs::exit_handler(){ +void Util::Procs::exit_handler() { int waiting = 0; std::map listcopy = plist; std::map::iterator it; - if (listcopy.empty()){return;} + if (listcopy.empty()) { + return; + } - //wait up to 0.5 second for applications to shut down - while ( !listcopy.empty() && waiting <= 25){ - for (it = listcopy.begin(); it != listcopy.end(); it++){ - if ( !childRunning((*it).first)){ + //wait up to 0.5 second for applications to shut down + while (!listcopy.empty() && waiting <= 25) { + for (it = listcopy.begin(); it != listcopy.end(); it++) { + if (!childRunning((*it).first)) { listcopy.erase(it); break; } - if ( !listcopy.empty()){ + if (!listcopy.empty()) { Util::sleep(20); ++waiting; } } } - if (listcopy.empty()){return;} - + if (listcopy.empty()) { + return; + } + DEBUG_MSG(DLVL_DEVEL, "Sending SIGINT to remaining %d children", (int)listcopy.size()); //send sigint to all remaining - if ( !listcopy.empty()){ - for (it = listcopy.begin(); it != listcopy.end(); it++){ - DEBUG_MSG(DLVL_DEVEL, "SIGINT %d: %s", ( *it).first, ( *it).second.c_str()); - kill(( *it).first, SIGINT); + if (!listcopy.empty()) { + for (it = listcopy.begin(); it != listcopy.end(); it++) { + DEBUG_MSG(DLVL_DEVEL, "SIGINT %d: %s", (*it).first, (*it).second.c_str()); + kill((*it).first, SIGINT); } } - + DEBUG_MSG(DLVL_DEVEL, "Waiting up to 5 seconds for %d children to terminate.", (int)listcopy.size()); waiting = 0; - //wait up to 5 seconds for applications to shut down - while ( !listcopy.empty() && waiting <= 250){ - for (it = listcopy.begin(); it != listcopy.end(); it++){ - if ( !childRunning((*it).first)){ + //wait up to 5 seconds for applications to shut down + while (!listcopy.empty() && waiting <= 250) { + for (it = listcopy.begin(); it != listcopy.end(); it++) { + if (!childRunning((*it).first)) { listcopy.erase(it); break; } - if ( !listcopy.empty()){ + if (!listcopy.empty()) { Util::sleep(20); ++waiting; } } } - if (listcopy.empty()){return;} - + if (listcopy.empty()) { + return; + } + DEBUG_MSG(DLVL_DEVEL, "Sending SIGKILL to remaining %d children", (int)listcopy.size()); //send sigkill to all remaining - if ( !listcopy.empty()){ - for (it = listcopy.begin(); it != listcopy.end(); it++){ - DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d: %s", ( *it).first, ( *it).second.c_str()); - kill(( *it).first, SIGKILL); + if (!listcopy.empty()) { + for (it = listcopy.begin(); it != listcopy.end(); it++) { + DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d: %s", (*it).first, (*it).second.c_str()); + kill((*it).first, SIGKILL); } } DEBUG_MSG(DLVL_DEVEL, "Waiting up to a second for %d children to terminate.", (int)listcopy.size()); waiting = 0; - //wait up to 1 second for applications to shut down - while ( !listcopy.empty() && waiting <= 50){ - for (it = listcopy.begin(); it != listcopy.end(); it++){ - if ( !childRunning((*it).first)){ + //wait up to 1 second for applications to shut down + while (!listcopy.empty() && waiting <= 50) { + for (it = listcopy.begin(); it != listcopy.end(); it++) { + if (!childRunning((*it).first)) { listcopy.erase(it); break; } - if ( !listcopy.empty()){ + if (!listcopy.empty()) { Util::sleep(20); ++waiting; } } } - if (listcopy.empty()){return;} + if (listcopy.empty()) { + return; + } DEBUG_MSG(DLVL_DEVEL, "Giving up with %d children left.", (int)listcopy.size()); - + } /// Sets up exit and childsig handlers. /// Called by every Start* function. -void Util::Procs::setHandler(){ - if ( !handler_set){ +void Util::Procs::setHandler() { + if (!handler_set) { struct sigaction new_action; new_action.sa_handler = childsig_handler; - sigemptyset( &new_action.sa_mask); + sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGCHLD, &new_action, NULL); atexit(exit_handler); handler_set = true; }// else { - // DEBUG_MSG(DLVL_DEVEL, "not setting handler"); - // } + // DEBUG_MSG(DLVL_DEVEL, "not setting handler"); +// } } /// Used internally to capture child signals and update plist. -void Util::Procs::childsig_handler(int signum){ - if (signum != SIGCHLD){ +void Util::Procs::childsig_handler(int signum) { + if (signum != SIGCHLD) { DEBUG_MSG(DLVL_DEVEL, "signum != SIGCHLD"); return; } int status; pid_t ret = -1; - while (ret != 0){ - ret = waitpid( -1, &status, WNOHANG); - if (ret <= 0){ //ignore, would block otherwise - if (ret == 0 || errno != EINTR){ + while (ret != 0) { + ret = waitpid(-1, &status, WNOHANG); + if (ret <= 0) { //ignore, would block otherwise + if (ret == 0 || errno != EINTR) { return; } continue; } int exitcode; - if (WIFEXITED(status)){ + if (WIFEXITED(status)) { exitcode = WEXITSTATUS(status); - }else if (WIFSIGNALED(status)){ + } else if (WIFSIGNALED(status)) { exitcode = -WTERMSIG(status); - }else{// not possible + } else { // not possible return; } @@ -162,14 +174,14 @@ void Util::Procs::childsig_handler(int signum){ #endif plist.erase(ret); #if DEBUG >= DLVL_HIGH - if (!isActive(pname)){ + if (!isActive(pname)) { DEBUG_MSG(DLVL_HIGH, "Process %s fully terminated", pname.c_str()); - }else{ + } else { DEBUG_MSG(DLVL_HIGH, "Child process %d exited", ret); } #endif - if (exitHandlers.count(ret) > 0){ + if (exitHandlers.count(ret) > 0) { TerminationNotifier tn = exitHandlers[ret]; exitHandlers.erase(ret); tn(ret, exitcode); @@ -179,15 +191,17 @@ void Util::Procs::childsig_handler(int signum){ /// Runs the given command and returns the stdout output as a string. -std::string Util::Procs::getOutputOf(char* const* argv){ +std::string Util::Procs::getOutputOf(char * const * argv) { std::string ret; int fin = 0, fout = -1, ferr = 0; StartPiped("output_getter", argv, &fin, &fout, &ferr); - while (isActive("output_getter")){Util::sleep(100);} + while (isActive("output_getter")) { + Util::sleep(100); + } FILE * outFile = fdopen(fout, "r"); char * fileBuf = 0; size_t fileBufLen = 0; - while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){ + while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { ret += fileBuf; } fclose(outFile); @@ -196,15 +210,17 @@ std::string Util::Procs::getOutputOf(char* const* argv){ } /// Runs the given command and returns the stdout output as a string. -std::string Util::Procs::getOutputOf(std::string cmd){ +std::string Util::Procs::getOutputOf(std::string cmd) { std::string ret; int fin = 0, fout = -1, ferr = 0; StartPiped("output_getter", cmd, &fin, &fout, &ferr); - while (isActive("output_getter")){Util::sleep(100);} + while (isActive("output_getter")) { + Util::sleep(100); + } FILE * outFile = fdopen(fout, "r"); char * fileBuf = 0; size_t fileBufLen = 0; - while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){ + while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { ret += fileBuf; } free(fileBuf); @@ -217,21 +233,21 @@ std::string Util::Procs::getOutputOf(std::string cmd){ /// Replaces the current process - use after forking first! /// This function will never return - it will either run the given /// command or kill itself with return code 42. -void Util::Procs::runCmd(std::string & cmd){ +void Util::Procs::runCmd(std::string & cmd) { //split cmd into arguments //supports a maximum of 20 arguments - char * tmp = (char*)cmd.c_str(); + char * tmp = (char *)cmd.c_str(); char * tmp2 = 0; char * args[21]; int i = 0; tmp2 = strtok(tmp, " "); args[0] = tmp2; - while (tmp2 != 0 && (i < 20)){ + while (tmp2 != 0 && (i < 20)) { tmp2 = strtok(0, " "); ++i; args[i] = tmp2; } - if (i == 20){ + if (i == 20) { args[20] = 0; } //execute the command @@ -244,19 +260,19 @@ void Util::Procs::runCmd(std::string & cmd){ /// \return 0 if process was not started, process PID otherwise. /// \arg name Name for this process - only used internally. /// \arg cmd Commandline for this process. -pid_t Util::Procs::Start(std::string name, std::string cmd){ - if (isActive(name)){ +pid_t Util::Procs::Start(std::string name, std::string cmd) { + if (isActive(name)) { return getPid(name); } setHandler(); pid_t ret = fork(); - if (ret == 0){ + if (ret == 0) { runCmd(cmd); - }else{ - if (ret > 0){ + } else { + if (ret > 0) { DEBUG_MSG(DLVL_HIGH, "Process %s started, PID %d: %s", name.c_str(), ret, cmd.c_str()); plist.insert(std::pair(ret, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started: fork() failed", name.c_str()); return 0; } @@ -269,30 +285,30 @@ pid_t Util::Procs::Start(std::string name, std::string cmd){ /// \arg name Name for this process - only used internally. /// \arg cmd Commandline for sub (sending) process. /// \arg cmd2 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2){ - if (isActive(name)){ +pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2) { + if (isActive(name)) { return getPid(name); } setHandler(); int pfildes[2]; - if (pipe(pfildes) == -1){ + if (pipe(pfildes) == -1) { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); return 0; } int devnull = open("/dev/null", O_RDWR); pid_t ret = fork(); - if (ret == 0){ + if (ret == 0) { close(pfildes[0]); dup2(pfildes[1], STDOUT_FILENO); close(pfildes[1]); dup2(devnull, STDIN_FILENO); dup2(devnull, STDERR_FILENO); runCmd(cmd); - }else{ - if (ret > 0){ + } else { + if (ret > 0) { plist.insert(std::pair(ret, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); close(pfildes[1]); close(pfildes[0]); @@ -301,18 +317,18 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2){ } pid_t ret2 = fork(); - if (ret2 == 0){ + if (ret2 == 0) { close(pfildes[1]); dup2(pfildes[0], STDIN_FILENO); close(pfildes[0]); dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); runCmd(cmd2); - }else{ - if (ret2 > 0){ + } else { + if (ret2 > 0) { DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); plist.insert(std::pair(ret2, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); Stop(name); close(pfildes[1]); @@ -331,25 +347,25 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2){ /// \arg cmd Commandline for sub (sending) process. /// \arg cmd2 Commandline for sub (middle) process. /// \arg cmd3 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3){ - if (isActive(name)){ +pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3) { + if (isActive(name)) { return getPid(name); } setHandler(); int pfildes[2]; int pfildes2[2]; - if (pipe(pfildes) == -1){ + if (pipe(pfildes) == -1) { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); return 0; } - if (pipe(pfildes2) == -1){ + if (pipe(pfildes2) == -1) { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); return 0; } int devnull = open("/dev/null", O_RDWR); pid_t ret = fork(); - if (ret == 0){ + if (ret == 0) { close(pfildes[0]); dup2(pfildes[1], STDOUT_FILENO); close(pfildes[1]); @@ -358,10 +374,10 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st close(pfildes2[1]); close(pfildes2[0]); runCmd(cmd); - }else{ - if (ret > 0){ + } else { + if (ret > 0) { plist.insert(std::pair(ret, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); close(pfildes[1]); close(pfildes[0]); @@ -372,7 +388,7 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st } pid_t ret2 = fork(); - if (ret2 == 0){ + if (ret2 == 0) { close(pfildes[1]); close(pfildes2[0]); dup2(pfildes[0], STDIN_FILENO); @@ -381,11 +397,11 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st close(pfildes2[1]); dup2(devnull, STDERR_FILENO); runCmd(cmd2); - }else{ - if (ret2 > 0){ + } else { + if (ret2 > 0) { DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); plist.insert(std::pair(ret2, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); Stop(name); close(pfildes[1]); @@ -399,7 +415,7 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st close(pfildes[0]); pid_t ret3 = fork(); - if (ret3 == 0){ + if (ret3 == 0) { close(pfildes[1]); close(pfildes[0]); close(pfildes2[1]); @@ -408,11 +424,11 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); runCmd(cmd3); - }else{ - if (ret3 > 0){ + } else { + if (ret3 > 0) { DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d, %d): %s | %s | %s", name.c_str(), ret, ret2, ret3, cmd.c_str(), cmd2.c_str(), cmd3.c_str()); plist.insert(std::pair(ret3, name)); - }else{ + } else { DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); Stop(name); close(pfildes[1]); @@ -433,61 +449,61 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, st /// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. /// \arg fdout Same as fdin, but for stdout. /// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, char* const* argv, int * fdin, int * fdout, int * fderr){ - if (isActive(name)){ +pid_t Util::Procs::StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr) { + if (isActive(name)) { DEBUG_MSG(DLVL_WARN, "Process %s already active - skipping start", name.c_str()); return getPid(name); } int pidtemp = StartPiped(argv, fdin, fdout, fderr); - if (pidtemp > 0 ) { + if (pidtemp > 0) { plist.insert(std::pair(pidtemp, name)); } return pidtemp; } -pid_t Util::Procs::StartPiped(char* const* argv, int * fdin, int * fdout, int * fderr){ +pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr) { pid_t pid; int pipein[2], pipeout[2], pipeerr[2]; //DEBUG_MSG(DLVL_DEVEL, "setHandler"); setHandler(); - if (fdin && *fdin == -1 && pipe(pipein) < 0){ + if (fdin && *fdin == -1 && pipe(pipein) < 0) { DEBUG_MSG(DLVL_ERROR, "Pipe in creation failed for process %s", argv[0]); return 0; } - if (fdout && *fdout == -1 && pipe(pipeout) < 0){ + if (fdout && *fdout == -1 && pipe(pipeout) < 0) { DEBUG_MSG(DLVL_ERROR, "Pipe out creation failed for process %s", argv[0]); - if ( *fdin == -1){ + if (*fdin == -1) { close(pipein[0]); close(pipein[1]); } return 0; } - if (fderr && *fderr == -1 && pipe(pipeerr) < 0){ + if (fderr && *fderr == -1 && pipe(pipeerr) < 0) { DEBUG_MSG(DLVL_ERROR, "Pipe err creation failed for process %s", argv[0]); - if ( *fdin == -1){ + if (*fdin == -1) { close(pipein[0]); close(pipein[1]); } - if ( *fdout == -1){ + if (*fdout == -1) { close(pipeout[0]); close(pipeout[1]); } return 0; } int devnull = -1; - if ( !fdin || !fdout || !fderr){ + if (!fdin || !fdout || !fderr) { devnull = open("/dev/null", O_RDWR); - if (devnull == -1){ + if (devnull == -1) { DEBUG_MSG(DLVL_ERROR, "Could not open /dev/null for process %s: %s", argv[0], strerror(errno)); - if ( *fdin == -1){ + if (*fdin == -1) { close(pipein[0]); close(pipein[1]); } - if ( *fdout == -1){ + if (*fdout == -1) { close(pipeout[0]); close(pipeout[1]); } - if ( *fderr == -1){ + if (*fderr == -1) { close(pipeerr[0]); close(pipeerr[1]); } @@ -495,81 +511,81 @@ pid_t Util::Procs::StartPiped(char* const* argv, int * fdin, int * fdout, int * } } pid = fork(); - if (pid == 0){ //child - if ( !fdin){ + if (pid == 0) { //child + if (!fdin) { dup2(devnull, STDIN_FILENO); - }else if ( *fdin == -1){ + } else if (*fdin == -1) { close(pipein[1]); // close unused write end dup2(pipein[0], STDIN_FILENO); close(pipein[0]); - }else if ( *fdin != STDIN_FILENO){ - dup2( *fdin, STDIN_FILENO); + } else if (*fdin != STDIN_FILENO) { + dup2(*fdin, STDIN_FILENO); } - if ( !fdout){ + if (!fdout) { dup2(devnull, STDOUT_FILENO); - }else if ( *fdout == -1){ + } else if (*fdout == -1) { close(pipeout[0]); // close unused read end dup2(pipeout[1], STDOUT_FILENO); close(pipeout[1]); - }else if ( *fdout != STDOUT_FILENO){ - dup2( *fdout, STDOUT_FILENO); + } else if (*fdout != STDOUT_FILENO) { + dup2(*fdout, STDOUT_FILENO); } - if ( !fderr){ + if (!fderr) { dup2(devnull, STDERR_FILENO); - }else if ( *fderr == -1){ + } else if (*fderr == -1) { close(pipeerr[0]); // close unused read end dup2(pipeerr[1], STDERR_FILENO); close(pipeerr[1]); - }else if ( *fderr != STDERR_FILENO){ - dup2( *fderr, STDERR_FILENO); + } else if (*fderr != STDERR_FILENO) { + dup2(*fderr, STDERR_FILENO); } - if( fdin && *fdin !=-1 && *fdin != STDIN_FILENO){ - close( *fdin); + if (fdin && *fdin != -1 && *fdin != STDIN_FILENO) { + close(*fdin); } - if( fdout && *fdout !=-1 && *fdout != STDOUT_FILENO){ - close( *fdout); + if (fdout && *fdout != -1 && *fdout != STDOUT_FILENO) { + close(*fdout); } - if( fderr && *fderr !=-1 && *fderr != STDERR_FILENO){ - close( *fderr); + if (fderr && *fderr != -1 && *fderr != STDERR_FILENO) { + close(*fderr); } - if (devnull != -1){ + if (devnull != -1) { close(devnull); } execvp(argv[0], argv); DEBUG_MSG(DLVL_ERROR, "execvp() failed for process %s", argv[0]); exit(42); - }else if (pid == -1){ + } else if (pid == -1) { DEBUG_MSG(DLVL_ERROR, "fork() for pipe failed for process %s", argv[0]); - if (fdin && *fdin == -1){ + if (fdin && *fdin == -1) { close(pipein[0]); close(pipein[1]); } - if (fdout && *fdout == -1){ + if (fdout && *fdout == -1) { close(pipeout[0]); close(pipeout[1]); } - if (fderr && *fderr == -1){ + if (fderr && *fderr == -1) { close(pipeerr[0]); close(pipeerr[1]); } - if (devnull != -1){ + if (devnull != -1) { close(devnull); } return 0; - }else{ //parent + } else { //parent DEBUG_MSG(DLVL_HIGH, "Piped process %s started, PID %d", argv[0], pid); - if (devnull != -1){ + if (devnull != -1) { close(devnull); } - if (fdin && *fdin == -1){ + if (fdin && *fdin == -1) { close(pipein[0]); // close unused end end *fdin = pipein[1]; } - if (fdout && *fdout == -1){ + if (fdout && *fdout == -1) { close(pipeout[1]); // close unused write end *fdout = pipeout[0]; } - if (fderr && *fderr == -1){ + if (fderr && *fderr == -1) { close(pipeerr[1]); // close unused write end *fderr = pipeerr[0]; } @@ -584,40 +600,40 @@ pid_t Util::Procs::StartPiped(char* const* argv, int * fdin, int * fdout, int * /// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. /// \arg fdout Same as fdin, but for stdout. /// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr){ +pid_t Util::Procs::StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr) { //Convert the given command to a char * [] - char * tmp = (char*)cmd.c_str(); + char * tmp = (char *)cmd.c_str(); char * tmp2 = 0; char * args[21]; int i = 0; tmp2 = strtok(tmp, " "); args[0] = tmp2; - while (tmp2 != 0 && (i < 20)){ + while (tmp2 != 0 && (i < 20)) { tmp2 = strtok(0, " "); ++i; args[i] = tmp2; } - if (i == 20){ + if (i == 20) { args[20] = 0; } - return StartPiped(name,args,fdin,fdout,fderr); + return StartPiped(name, args, fdin, fdout, fderr); } -pid_t Util::Procs::StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2){ +pid_t Util::Procs::StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2) { int pfildes[2]; - if (pipe(pfildes) == -1){ + if (pipe(pfildes) == -1) { DEBUG_MSG(DLVL_ERROR, "Pipe creation failed for process %s", name.c_str()); return 0; } pid_t res1 = StartPiped(name, cmd1, fdin, &pfildes[1], fderr1); - if ( !res1){ + if (!res1) { close(pfildes[1]); close(pfildes[0]); return 0; } - pid_t res2 = StartPiped(name+"receiving", cmd2, &pfildes[0], fdout, fderr2); - if ( !res2){ + pid_t res2 = StartPiped(name + "receiving", cmd2, &pfildes[0], fdout, fderr2); + if (!res2) { Stop(res1); close(pfildes[1]); close(pfildes[0]); @@ -630,12 +646,12 @@ pid_t Util::Procs::StartPiped2(std::string name, std::string cmd1, std::string c } /// Stops the named process, if running. /// \arg name (Internal) name of process to stop -void Util::Procs::Stop(std::string name){ +void Util::Procs::Stop(std::string name) { int max = 5; - while (isActive(name)){ + while (isActive(name)) { Stop(getPid(name)); max--; - if (max <= 0){ + if (max <= 0) { return; } } @@ -643,36 +659,36 @@ void Util::Procs::Stop(std::string name){ /// Stops the process with this pid, if running. /// \arg name The PID of the process to stop. -void Util::Procs::Stop(pid_t name){ - if (isActive(name)){ +void Util::Procs::Stop(pid_t name) { + if (isActive(name)) { kill(name, SIGTERM); } } /// (Attempts to) stop all running child processes. -void Util::Procs::StopAll(){ +void Util::Procs::StopAll() { std::map listcopy = plist; std::map::iterator it; - for (it = listcopy.begin(); it != listcopy.end(); it++){ - Stop(( *it).first); + for (it = listcopy.begin(); it != listcopy.end(); it++) { + Stop((*it).first); } } /// Returns the number of active child processes. -int Util::Procs::Count(){ +int Util::Procs::Count() { return plist.size(); } /// Returns true if a process by this name is currently active. -bool Util::Procs::isActive(std::string name){ +bool Util::Procs::isActive(std::string name) { std::map listcopy = plist; std::map::iterator it; - for (it = listcopy.begin(); it != listcopy.end(); it++){ - if (( *it).second == name){ - if (childRunning(( *it).first)){ + for (it = listcopy.begin(); it != listcopy.end(); it++) { + if ((*it).second == name) { + if (childRunning((*it).first)) { return true; - }else{ - plist.erase(( *it).first); + } else { + plist.erase((*it).first); } } } @@ -680,17 +696,17 @@ bool Util::Procs::isActive(std::string name){ } /// Returns true if a process with this PID is currently active. -bool Util::Procs::isActive(pid_t name){ +bool Util::Procs::isActive(pid_t name) { return (plist.count(name) == 1) && (kill(name, 0) == 0); } /// Gets PID for this named process, if active. /// \return NULL if not active, process PID otherwise. -pid_t Util::Procs::getPid(std::string name){ +pid_t Util::Procs::getPid(std::string name) { std::map::iterator it; - for (it = plist.begin(); it != plist.end(); it++){ - if (( *it).second == name){ - return ( *it).first; + for (it = plist.begin(); it != plist.end(); it++) { + if ((*it).second == name) { + return (*it).first; } } return 0; @@ -698,8 +714,8 @@ pid_t Util::Procs::getPid(std::string name){ /// Gets name for this process PID, if active. /// \return Empty string if not active, name otherwise. -std::string Util::Procs::getName(pid_t name){ - if (plist.count(name) == 1){ +std::string Util::Procs::getName(pid_t name) { + if (plist.count(name) == 1) { return plist[name]; } return ""; @@ -707,8 +723,8 @@ std::string Util::Procs::getName(pid_t name){ /// Registers one notifier function for when a process indentified by PID terminates. /// \return true if the notifier could be registered, false otherwise. -bool Util::Procs::SetTerminationNotifier(pid_t pid, TerminationNotifier notifier){ - if (plist.find(pid) != plist.end()){ +bool Util::Procs::SetTerminationNotifier(pid_t pid, TerminationNotifier notifier) { + if (plist.find(pid) != plist.end()) { exitHandlers[pid] = notifier; return true; } diff --git a/lib/procs.h b/lib/procs.h index 10cd04da..ab56af53 100644 --- a/lib/procs.h +++ b/lib/procs.h @@ -13,7 +13,7 @@ namespace Util { typedef void (*TerminationNotifier)(pid_t pid, int exitCode); /// Deals with spawning, monitoring and stopping child processes - class Procs{ + class Procs { private: static std::map plist; ///< Holds active processes static std::map exitHandlers; ///< termination function, if any @@ -22,16 +22,16 @@ namespace Util { static void exit_handler(); static void runCmd(std::string & cmd); static void setHandler(); - public: - static std::string getOutputOf(char* const* argv); + public: + static std::string getOutputOf(char * const * argv); static std::string getOutputOf(std::string cmd); static pid_t Start(std::string name, std::string cmd); static pid_t Start(std::string name, std::string cmd, std::string cmd2); static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3); - - static pid_t StartPiped(char* const* argv, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped(std::string name, char* const* argv, int * fdin, int * fdout, int * fderr); - + + static pid_t StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr); + static pid_t StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr); + static pid_t StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr); static pid_t StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2); static void Stop(std::string name); diff --git a/lib/rtmpchunks.cpp b/lib/rtmpchunks.cpp index 9d61f02d..997874b5 100644 --- a/lib/rtmpchunks.cpp +++ b/lib/rtmpchunks.cpp @@ -39,59 +39,61 @@ std::map RTMPStream::lastrecv; #include #define P1024 \ -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" uint8_t genuineFMSKey[] = {0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, - 0x4d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x53, 0x65, 0x72, - 0x76, // Genuine Adobe Flash Media Server 001 - 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec, - 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae}; // 68 + 0x4d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x53, 0x65, 0x72, + 0x76, // Genuine Adobe Flash Media Server 001 + 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec, + 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae + }; // 68 uint8_t genuineFPKey[] = {0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, - 0x50, 0x6c, 0x61, - 0x79, // Genuine Adobe Flash Player 001 - 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec, - 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae}; // 62 + 0x50, 0x6c, 0x61, + 0x79, // Genuine Adobe Flash Player 001 + 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec, + 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae + }; // 62 -inline uint32_t GetDigestOffset(uint8_t *pBuffer, uint8_t scheme){ - if (scheme == 0){ +inline uint32_t GetDigestOffset(uint8_t * pBuffer, uint8_t scheme) { + if (scheme == 0) { return ((pBuffer[8] + pBuffer[9] + pBuffer[10] + pBuffer[11]) % 728) + 12; - }else{ + } else { return ((pBuffer[772] + pBuffer[773] + pBuffer[774] + pBuffer[775]) % 728) + 776; } } -inline uint32_t GetDHOffset(uint8_t *pBuffer, uint8_t scheme){ - if (scheme == 0){ +inline uint32_t GetDHOffset(uint8_t * pBuffer, uint8_t scheme) { + if (scheme == 0) { return ((pBuffer[1532] + pBuffer[1533] + pBuffer[1534] + pBuffer[1535]) % 632) + 772; - }else{ + } else { return ((pBuffer[768] + pBuffer[769] + pBuffer[770] + pBuffer[771]) % 632) + 8; } } -class DHWrapper{ +class DHWrapper { private: int32_t _bitsCount; - DH *_pDH; - uint8_t *_pSharedKey; + DH * _pDH; + uint8_t * _pSharedKey; int32_t _sharedKeyLength; - BIGNUM *_peerPublickey; + BIGNUM * _peerPublickey; public: DHWrapper(int32_t bitsCount); virtual ~DHWrapper(); bool Initialize(); - bool CopyPublicKey(uint8_t *pDst, int32_t dstLength); - bool CopyPrivateKey(uint8_t *pDst, int32_t dstLength); - bool CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length); - bool CopySharedKey(uint8_t *pDst, int32_t dstLength); + bool CopyPublicKey(uint8_t * pDst, int32_t dstLength); + bool CopyPrivateKey(uint8_t * pDst, int32_t dstLength); + bool CreateSharedKey(uint8_t * pPeerPublicKey, int32_t length); + bool CopySharedKey(uint8_t * pDst, int32_t dstLength); private: void Cleanup(); - bool CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength); + bool CopyKey(BIGNUM * pNum, uint8_t * pDst, int32_t dstLength); }; -DHWrapper::DHWrapper(int32_t bitsCount){ +DHWrapper::DHWrapper(int32_t bitsCount) { _bitsCount = bitsCount; _pDH = 0; _pSharedKey = 0; @@ -99,73 +101,73 @@ DHWrapper::DHWrapper(int32_t bitsCount){ _peerPublickey = 0; } -DHWrapper::~DHWrapper(){ +DHWrapper::~DHWrapper() { Cleanup(); } -bool DHWrapper::Initialize(){ +bool DHWrapper::Initialize() { Cleanup(); _pDH = DH_new(); - if ( !_pDH){ + if (!_pDH) { Cleanup(); return false; } _pDH->p = BN_new(); - if ( !_pDH->p){ + if (!_pDH->p) { Cleanup(); return false; } _pDH->g = BN_new(); - if ( !_pDH->g){ + if (!_pDH->g) { Cleanup(); return false; } - if (BN_hex2bn( &_pDH->p, P1024) == 0){ + if (BN_hex2bn(&_pDH->p, P1024) == 0) { Cleanup(); return false; } - if (BN_set_word(_pDH->g, 2) != 1){ + if (BN_set_word(_pDH->g, 2) != 1) { Cleanup(); return false; } _pDH->length = _bitsCount; - if (DH_generate_key(_pDH) != 1){ + if (DH_generate_key(_pDH) != 1) { Cleanup(); return false; } return true; } -bool DHWrapper::CopyPublicKey(uint8_t *pDst, int32_t dstLength){ - if ( !_pDH){ +bool DHWrapper::CopyPublicKey(uint8_t * pDst, int32_t dstLength) { + if (!_pDH) { return false; } return CopyKey(_pDH->pub_key, pDst, dstLength); } -bool DHWrapper::CopyPrivateKey(uint8_t *pDst, int32_t dstLength){ - if ( !_pDH){ +bool DHWrapper::CopyPrivateKey(uint8_t * pDst, int32_t dstLength) { + if (!_pDH) { return false; } return CopyKey(_pDH->priv_key, pDst, dstLength); } -bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length){ - if ( !_pDH){ +bool DHWrapper::CreateSharedKey(uint8_t * pPeerPublicKey, int32_t length) { + if (!_pDH) { return false; } - if (_sharedKeyLength != 0 || _pSharedKey){ + if (_sharedKeyLength != 0 || _pSharedKey) { return false; } _sharedKeyLength = DH_size(_pDH); - if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024){ + if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024) { return false; } _pSharedKey = new uint8_t[_sharedKeyLength]; _peerPublickey = BN_bin2bn(pPeerPublicKey, length, 0); - if ( !_peerPublickey){ + if (!_peerPublickey) { return false; } @@ -173,93 +175,93 @@ bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length){ return true; } -bool DHWrapper::CopySharedKey(uint8_t *pDst, int32_t dstLength){ - if ( !_pDH){ +bool DHWrapper::CopySharedKey(uint8_t * pDst, int32_t dstLength) { + if (!_pDH) { return false; } - if (dstLength != _sharedKeyLength){ + if (dstLength != _sharedKeyLength) { return false; } memcpy(pDst, _pSharedKey, _sharedKeyLength); return true; } -void DHWrapper::Cleanup(){ - if (_pDH){ - if (_pDH->p){ +void DHWrapper::Cleanup() { + if (_pDH) { + if (_pDH->p) { BN_free(_pDH->p); _pDH->p = 0; } - if (_pDH->g){ + if (_pDH->g) { BN_free(_pDH->g); _pDH->g = 0; } DH_free(_pDH); _pDH = 0; } - if (_pSharedKey){ + if (_pSharedKey) { delete[] _pSharedKey; _pSharedKey = 0; } _sharedKeyLength = 0; - if (_peerPublickey){ + if (_peerPublickey) { BN_free(_peerPublickey); _peerPublickey = 0; } } -bool DHWrapper::CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength){ +bool DHWrapper::CopyKey(BIGNUM * pNum, uint8_t * pDst, int32_t dstLength) { int32_t keySize = BN_num_bytes(pNum); - if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)){ + if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)) { return false; } - if (BN_bn2bin(pNum, pDst) != keySize){ + if (BN_bn2bin(pNum, pDst) != keySize) { return false; } return true; } -void InitRC4Encryption(uint8_t *secretKey, uint8_t *pubKeyIn, uint8_t *pubKeyOut, RC4_KEY *rc4keyIn, RC4_KEY *rc4keyOut){ +void InitRC4Encryption(uint8_t * secretKey, uint8_t * pubKeyIn, uint8_t * pubKeyOut, RC4_KEY * rc4keyIn, RC4_KEY * rc4keyOut) { uint8_t digest[SHA256_DIGEST_LENGTH]; unsigned int digestLen = 0; HMAC_CTX ctx; - HMAC_CTX_init( &ctx); - HMAC_Init_ex( &ctx, secretKey, 128, EVP_sha256(), 0); - HMAC_Update( &ctx, pubKeyIn, 128); - HMAC_Final( &ctx, digest, &digestLen); - HMAC_CTX_cleanup( &ctx); + HMAC_CTX_init(&ctx); + HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0); + HMAC_Update(&ctx, pubKeyIn, 128); + HMAC_Final(&ctx, digest, &digestLen); + HMAC_CTX_cleanup(&ctx); RC4_set_key(rc4keyOut, 16, digest); - HMAC_CTX_init( &ctx); - HMAC_Init_ex( &ctx, secretKey, 128, EVP_sha256(), 0); - HMAC_Update( &ctx, pubKeyOut, 128); - HMAC_Final( &ctx, digest, &digestLen); - HMAC_CTX_cleanup( &ctx); + HMAC_CTX_init(&ctx); + HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0); + HMAC_Update(&ctx, pubKeyOut, 128); + HMAC_Final(&ctx, digest, &digestLen); + HMAC_CTX_cleanup(&ctx); RC4_set_key(rc4keyIn, 16, digest); } -void HMACsha256(const void *pData, uint32_t dataLength, const void *pKey, uint32_t keyLength, void *pResult){ +void HMACsha256(const void * pData, uint32_t dataLength, const void * pKey, uint32_t keyLength, void * pResult) { unsigned int digestLen; HMAC_CTX ctx; - HMAC_CTX_init( &ctx); - HMAC_Init_ex( &ctx, (unsigned char*)pKey, keyLength, EVP_sha256(), 0); - HMAC_Update( &ctx, (unsigned char *)pData, dataLength); - HMAC_Final( &ctx, (unsigned char *)pResult, &digestLen); - HMAC_CTX_cleanup( &ctx); + HMAC_CTX_init(&ctx); + HMAC_Init_ex(&ctx, (unsigned char *)pKey, keyLength, EVP_sha256(), 0); + HMAC_Update(&ctx, (unsigned char *)pData, dataLength); + HMAC_Final(&ctx, (unsigned char *)pResult, &digestLen); + HMAC_CTX_cleanup(&ctx); } -bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme){ +bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme) { uint32_t clientDigestOffset = GetDigestOffset(pBuffer, scheme); - uint8_t *pTempBuffer = new uint8_t[1536 - 32]; + uint8_t * pTempBuffer = new uint8_t[1536 - 32]; memcpy(pTempBuffer, pBuffer, clientDigestOffset); memcpy(pTempBuffer + clientDigestOffset, pBuffer + clientDigestOffset + 32, 1536 - clientDigestOffset - 32); - uint8_t *pTempHash = new uint8_t[512]; + uint8_t * pTempHash = new uint8_t[512]; HMACsha256(pTempBuffer, 1536 - 32, genuineFPKey, 30, pTempHash); bool result = (memcmp(pBuffer + clientDigestOffset, pTempHash, 32) == 0); - DEBUG_MSG(DLVL_MEDIUM, "Client scheme validation %hhi %s", scheme, result?"success":"failed"); + DEBUG_MSG(DLVL_MEDIUM, "Client scheme validation %hhi %s", scheme, result ? "success" : "failed"); delete[] pTempBuffer; delete[] pTempHash; return result; @@ -268,58 +270,58 @@ bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme){ /// Packs up the chunk for sending over the network. /// \warning Do not call if you are not actually sending the resulting data! /// \returns A std::string ready to be sent. -std::string & RTMPStream::Chunk::Pack(){ +std::string & RTMPStream::Chunk::Pack() { static std::string output; output.clear(); bool allow_short = lastsend.count(cs_id); RTMPStream::Chunk prev = lastsend[cs_id]; unsigned int tmpi; unsigned char chtype = 0x00; - if (allow_short && (prev.cs_id == cs_id)){ - if (msg_stream_id == prev.msg_stream_id){ + if (allow_short && (prev.cs_id == cs_id)) { + if (msg_stream_id == prev.msg_stream_id) { chtype = 0x40; //do not send msg_stream_id - if (len == prev.len){ - if (msg_type_id == prev.msg_type_id){ + if (len == prev.len) { + if (msg_type_id == prev.msg_type_id) { chtype = 0x80; //do not send len and msg_type_id - if (timestamp == prev.timestamp){ + if (timestamp == prev.timestamp) { chtype = 0xC0; //do not send timestamp } } } } //override - we always sent type 0x00 if the timestamp has decreased since last chunk in this channel - if (timestamp < prev.timestamp){ + if (timestamp < prev.timestamp) { chtype = 0x00; } } - if (cs_id <= 63){ + if (cs_id <= 63) { output += (unsigned char)(chtype | cs_id); - }else{ - if (cs_id <= 255 + 64){ + } else { + if (cs_id <= 255 + 64) { output += (unsigned char)(chtype | 0); output += (unsigned char)(cs_id - 64); - }else{ + } else { output += (unsigned char)(chtype | 1); output += (unsigned char)((cs_id - 64) % 256); output += (unsigned char)((cs_id - 64) / 256); } } unsigned int ntime = 0; - if (chtype != 0xC0){ + if (chtype != 0xC0) { //timestamp or timestamp diff - if (chtype == 0x00){ + if (chtype == 0x00) { tmpi = timestamp; - }else{ + } else { tmpi = timestamp - prev.timestamp; } - if (tmpi >= 0x00ffffff){ + if (tmpi >= 0x00ffffff) { ntime = tmpi; tmpi = 0x00ffffff; } output += (unsigned char)((tmpi >> 16) & 0xff); output += (unsigned char)((tmpi >> 8) & 0xff); output += (unsigned char)(tmpi & 0xff); - if (chtype != 0x80){ + if (chtype != 0x80) { //len tmpi = len; output += (unsigned char)((tmpi >> 16) & 0xff); @@ -327,7 +329,7 @@ std::string & RTMPStream::Chunk::Pack(){ output += (unsigned char)(tmpi & 0xff); //msg type id output += (unsigned char)msg_type_id; - if (chtype != 0x40){ + if (chtype != 0x40) { //msg stream id output += (unsigned char)(msg_stream_id % 256); output += (unsigned char)(msg_stream_id / 256); @@ -337,28 +339,28 @@ std::string & RTMPStream::Chunk::Pack(){ } } //support for 0x00ffffff timestamps - if (ntime){ + if (ntime) { output += (unsigned char)(ntime & 0xff); output += (unsigned char)((ntime >> 8) & 0xff); output += (unsigned char)((ntime >> 16) & 0xff); output += (unsigned char)((ntime >> 24) & 0xff); } len_left = 0; - while (len_left < len){ + while (len_left < len) { tmpi = len - len_left; - if (tmpi > RTMPStream::chunk_snd_max){ + if (tmpi > RTMPStream::chunk_snd_max) { tmpi = RTMPStream::chunk_snd_max; } output.append(data, len_left, tmpi); len_left += tmpi; - if (len_left < len){ - if (cs_id <= 63){ + if (len_left < len) { + if (cs_id <= 63) { output += (unsigned char)(0xC0 + cs_id); - }else{ - if (cs_id <= 255 + 64){ + } else { + if (cs_id <= 255 + 64) { output += (unsigned char)(0xC0); output += (unsigned char)(cs_id - 64); - }else{ + } else { output += (unsigned char)(0xC1); output += (unsigned char)((cs_id - 64) % 256); output += (unsigned char)((cs_id - 64) / 256); @@ -372,7 +374,7 @@ std::string & RTMPStream::Chunk::Pack(){ } //SendChunk /// Default constructor, creates an empty chunk with all values initialized to zero. -RTMPStream::Chunk::Chunk(){ +RTMPStream::Chunk::Chunk() { headertype = 0; cs_id = 0; timestamp = 0; @@ -385,7 +387,7 @@ RTMPStream::Chunk::Chunk(){ } //constructor /// Packs up a chunk with the given arguments as properties. -std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data){ +std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data) { static RTMPStream::Chunk ch; ch.cs_id = cs_id; ch.timestamp = Util::getMS(); @@ -403,7 +405,7 @@ std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_i /// \param data Contents of the media data. /// \param len Length of the media data, in bytes. /// \param ts Timestamp of the media data, relative to current system time. -std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts){ +std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts) { static RTMPStream::Chunk ch; ch.cs_id = msg_type_id + 42; ch.timestamp = ts; @@ -412,13 +414,13 @@ std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * d ch.len_left = 0; ch.msg_type_id = msg_type_id; ch.msg_stream_id = 1; - ch.data = std::string((char*)data, (size_t)len); + ch.data = std::string((char *)data, (size_t)len); return ch.Pack(); } //SendMedia /// Packs up a chunk with media contents. /// \param tag FLV::Tag with media to send. -std::string & RTMPStream::SendMedia(FLV::Tag & tag){ +std::string & RTMPStream::SendMedia(FLV::Tag & tag) { static RTMPStream::Chunk ch; //Commented bit is more efficient and correct according to RTMP spec. //Simply passing "4" is the only thing that actually plays correctly, though. @@ -435,7 +437,7 @@ std::string & RTMPStream::SendMedia(FLV::Tag & tag){ } //SendMedia /// Packs up a chunk for a control message with 1 argument. -std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data){ +std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data) { static RTMPStream::Chunk ch; ch.cs_id = 2; ch.timestamp = Util::getMS(); @@ -445,12 +447,12 @@ std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data){ ch.msg_type_id = type; ch.msg_stream_id = 0; ch.data.resize(4); - *(int*)((char*)ch.data.c_str()) = htonl(data); + *(int *)((char *)ch.data.c_str()) = htonl(data); return ch.Pack(); } //SendCTL /// Packs up a chunk for a control message with 2 arguments. -std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigned char data2){ +std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigned char data2) { static RTMPStream::Chunk ch; ch.cs_id = 2; ch.timestamp = Util::getMS(); @@ -460,13 +462,13 @@ std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigne ch.msg_type_id = type; ch.msg_stream_id = 0; ch.data.resize(5); - *(unsigned int*)((char*)ch.data.c_str()) = htonl(data); + *(unsigned int *)((char *)ch.data.c_str()) = htonl(data); ch.data[4] = data2; return ch.Pack(); } //SendCTL /// Packs up a chunk for a user control message with 1 argument. -std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data){ +std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data) { static RTMPStream::Chunk ch; ch.cs_id = 2; ch.timestamp = Util::getMS(); @@ -476,14 +478,14 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data){ ch.msg_type_id = 4; ch.msg_stream_id = 0; ch.data.resize(6); - *(unsigned int*)(((char*)ch.data.c_str()) + 2) = htonl(data); + *(unsigned int *)(((char *)ch.data.c_str()) + 2) = htonl(data); ch.data[0] = 0; ch.data[1] = type; return ch.Pack(); } //SendUSR /// Packs up a chunk for a user control message with 2 arguments. -std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigned int data2){ +std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigned int data2) { static RTMPStream::Chunk ch; ch.cs_id = 2; ch.timestamp = Util::getMS(); @@ -493,8 +495,8 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigne ch.msg_type_id = 4; ch.msg_stream_id = 0; ch.data.resize(10); - *(unsigned int*)(((char*)ch.data.c_str()) + 2) = htonl(data); - *(unsigned int*)(((char*)ch.data.c_str()) + 6) = htonl(data2); + *(unsigned int *)(((char *)ch.data.c_str()) + 2) = htonl(data); + *(unsigned int *)(((char *)ch.data.c_str()) + 6) = htonl(data2); ch.data[0] = 0; ch.data[1] = type; return ch.Pack(); @@ -508,14 +510,14 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigne /// \param indata The input string to parse and update. /// \warning This function will destroy the current data in this chunk! /// \returns True if a whole chunk could be read, false otherwise. -bool RTMPStream::Chunk::Parse(std::string & indata){ - gettimeofday( &RTMPStream::lastrec, 0); +bool RTMPStream::Chunk::Parse(std::string & indata) { + gettimeofday(&RTMPStream::lastrec, 0); unsigned int i = 0; if (indata.size() < 1) return false; //need at least a byte unsigned char chunktype = indata[i++ ]; //read the chunkstream ID properly - switch (chunktype & 0x3F){ + switch (chunktype & 0x3F) { case 0: if (indata.size() < 2) return false; //need at least 2 bytes to continue cs_id = indata[i++ ] + 64; @@ -535,7 +537,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ //process the rest of the header, for each chunk type headertype = chunktype & 0xC0; - switch (headertype){ + switch (headertype) { case 0x00: if (indata.size() < i + 11) return false; //can't read whole header timestamp = indata[i++ ] * 256 * 256; @@ -553,13 +555,13 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ break; case 0x40: if (indata.size() < i + 7) return false; //can't read whole header - if (!allow_short){ + if (!allow_short) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!"); } timestamp = indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; - if (timestamp != 0x00ffffff){ + if (timestamp != 0x00ffffff) { timestamp += prev.timestamp; } len = indata[i++ ] * 256 * 256; @@ -571,13 +573,13 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ break; case 0x80: if (indata.size() < i + 3) return false; //can't read whole header - if (!allow_short){ + if (!allow_short) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!"); } timestamp = indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; - if (timestamp != 0x00ffffff){ + if (timestamp != 0x00ffffff) { timestamp += prev.timestamp; } len = prev.len; @@ -586,7 +588,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ msg_stream_id = prev.msg_stream_id; break; case 0xC0: - if (!allow_short){ + if (!allow_short) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!"); } timestamp = prev.timestamp; @@ -597,18 +599,18 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ break; } //calculate chunk length, real length, and length left till complete - if (len_left > 0){ + if (len_left > 0) { real_len = len_left; len_left -= real_len; - }else{ + } else { real_len = len; } - if (real_len > RTMPStream::chunk_rec_max){ + if (real_len > RTMPStream::chunk_rec_max) { len_left += real_len - RTMPStream::chunk_rec_max; real_len = RTMPStream::chunk_rec_max; } //read extended timestamp, if neccesary - if (timestamp == 0x00ffffff){ + if (timestamp == 0x00ffffff) { if (indata.size() < i + 4) return false; //can't read whole header timestamp = indata[i++ ] * 256 * 256 * 256; timestamp += indata[i++ ] * 256 * 256; @@ -617,10 +619,10 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ } //read data if length > 0, and allocate it - if (real_len > 0){ - if (prev.len_left > 0){ + if (real_len > 0) { + if (prev.len_left > 0) { data = prev.data; - }else{ + } else { data = ""; } if (indata.size() < i + real_len) return false; //can't read all data (yet) @@ -628,12 +630,12 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ indata = indata.substr(i + real_len); lastrecv[cs_id] = *this; RTMPStream::rec_cnt += i + real_len; - if (len_left == 0){ + if (len_left == 0) { return true; - }else{ + } else { return Parse(indata); } - }else{ + } else { data = ""; indata = indata.substr(i + real_len); lastrecv[cs_id] = *this; @@ -650,17 +652,17 @@ bool RTMPStream::Chunk::Parse(std::string & indata){ /// \param buffer The input to parse and update. /// \warning This function will destroy the current data in this chunk! /// \returns True if a whole chunk could be read, false otherwise. -bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ - gettimeofday( &RTMPStream::lastrec, 0); +bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer) { + gettimeofday(&RTMPStream::lastrec, 0); unsigned int i = 0; - if ( !buffer.available(3)){ + if (!buffer.available(3)) { return false; } //we want at least 3 bytes std::string indata = buffer.copy(3); unsigned char chunktype = indata[i++ ]; //read the chunkstream ID properly - switch (chunktype & 0x3F){ + switch (chunktype & 0x3F) { case 0: cs_id = indata[i++ ] + 64; break; @@ -677,9 +679,9 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ //process the rest of the header, for each chunk type headertype = chunktype & 0xC0; - switch (headertype){ + switch (headertype) { case 0x00: - if ( !buffer.available(i + 11)){ + if (!buffer.available(i + 11)) { return false; } //can't read whole header indata = buffer.copy(i + 11); @@ -697,17 +699,17 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ msg_stream_id += indata[i++ ] * 256 * 256 * 256; break; case 0x40: - if ( !buffer.available(i + 7)){ + if (!buffer.available(i + 7)) { return false; } //can't read whole header indata = buffer.copy(i + 7); - if (prev.msg_type_id == 0){ + if (prev.msg_type_id == 0) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!"); } timestamp = indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; - if (timestamp != 0x00ffffff){ + if (timestamp != 0x00ffffff) { timestamp += prev.timestamp; } len = indata[i++ ] * 256 * 256; @@ -718,17 +720,17 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ msg_stream_id = prev.msg_stream_id; break; case 0x80: - if ( !buffer.available(i + 3)){ + if (!buffer.available(i + 3)) { return false; } //can't read whole header indata = buffer.copy(i + 3); - if (prev.msg_type_id == 0){ + if (prev.msg_type_id == 0) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!"); } timestamp = indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; - if (timestamp != 0x00ffffff){ + if (timestamp != 0x00ffffff) { timestamp += prev.timestamp; } len = prev.len; @@ -737,7 +739,7 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ msg_stream_id = prev.msg_stream_id; break; case 0xC0: - if (prev.msg_type_id == 0){ + if (prev.msg_type_id == 0) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!"); } timestamp = prev.timestamp; @@ -748,19 +750,19 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ break; } //calculate chunk length, real length, and length left till complete - if (len_left > 0){ + if (len_left > 0) { real_len = len_left; len_left -= real_len; - }else{ + } else { real_len = len; } - if (real_len > RTMPStream::chunk_rec_max){ + if (real_len > RTMPStream::chunk_rec_max) { len_left += real_len - RTMPStream::chunk_rec_max; real_len = RTMPStream::chunk_rec_max; } //read extended timestamp, if neccesary - if (timestamp == 0x00ffffff){ - if ( !buffer.available(i + 4)){ + if (timestamp == 0x00ffffff) { + if (!buffer.available(i + 4)) { return false; } //can't read timestamp indata = buffer.copy(i + 4); @@ -771,24 +773,24 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ } //read data if length > 0, and allocate it - if (real_len > 0){ - if ( !buffer.available(i + real_len)){ + if (real_len > 0) { + if (!buffer.available(i + real_len)) { return false; } //can't read all data (yet) buffer.remove(i); //remove the header - if (prev.len_left > 0){ + if (prev.len_left > 0) { data = prev.data + buffer.remove(real_len); //append the data and remove from buffer - }else{ + } else { data = buffer.remove(real_len); //append the data and remove from buffer } lastrecv[cs_id] = *this; RTMPStream::rec_cnt += i + real_len; - if (len_left == 0){ + if (len_left == 0) { return true; - }else{ + } else { return Parse(buffer); } - }else{ + } else { buffer.remove(i); //remove the header data = ""; indata = indata.substr(i + real_len); @@ -802,10 +804,10 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){ /// After calling this function, don't forget to read and ignore 1536 extra bytes, /// these are the handshake response and not interesting for us because we don't do client /// verification. -bool RTMPStream::doHandshake(){ +bool RTMPStream::doHandshake() { char Version; //Read C0 - if (handshake_in.size() < 1537){ + if (handshake_in.size() < 1537) { DEBUG_MSG(DLVL_FAIL, "Handshake wasn't filled properly (%lu/1537) - aborting!", handshake_in.size()); return false; } @@ -816,9 +818,9 @@ bool RTMPStream::doHandshake(){ RTMPStream::rec_cnt += 1537; //Build S1 Packet - *((uint32_t*)Server) = 0; //time zero - *(((uint32_t*)(Server + 4))) = htonl(0x01020304); //version 1 2 3 4 - for (int i = 8; i < 3072; ++i){ + *((uint32_t *)Server) = 0; //time zero + *(((uint32_t *)(Server + 4))) = htonl(0x01020304); //version 1 2 3 4 + for (int i = 8; i < 3072; ++i) { Server[i] = FILLER_DATA[i % sizeof(FILLER_DATA)]; } //"random" data @@ -828,7 +830,7 @@ bool RTMPStream::doHandshake(){ if (ValidateClientScheme(Client, 0)) _validationScheme = 0; if (ValidateClientScheme(Client, 1)) _validationScheme = 1; - DEBUG_MSG(DLVL_HIGH, "Handshake type is %hhi, encryption is %s", _validationScheme, encrypted?"on":"off"); + DEBUG_MSG(DLVL_HIGH, "Handshake type is %hhi, encryption is %s", _validationScheme, encrypted ? "on" : "off"); //FIRST 1536 bytes from server response //compute DH key position @@ -837,34 +839,34 @@ bool RTMPStream::doHandshake(){ //generate DH key DHWrapper dhWrapper(1024); - if ( !dhWrapper.Initialize()){ + if (!dhWrapper.Initialize()) { return false; } - if ( !dhWrapper.CreateSharedKey(Client + clientDHOffset, 128)){ + if (!dhWrapper.CreateSharedKey(Client + clientDHOffset, 128)) { return false; } - if ( !dhWrapper.CopyPublicKey(Server + serverDHOffset, 128)){ + if (!dhWrapper.CopyPublicKey(Server + serverDHOffset, 128)) { return false; } - if (encrypted){ + if (encrypted) { uint8_t secretKey[128]; - if ( !dhWrapper.CopySharedKey(secretKey, sizeof(secretKey))){ + if (!dhWrapper.CopySharedKey(secretKey, sizeof(secretKey))) { return false; } RC4_KEY _pKeyIn; RC4_KEY _pKeyOut; - InitRC4Encryption(secretKey, (uint8_t*) &Client[clientDHOffset], (uint8_t*) &Server[serverDHOffset], &_pKeyIn, &_pKeyOut); + InitRC4Encryption(secretKey, (uint8_t *) &Client[clientDHOffset], (uint8_t *) &Server[serverDHOffset], &_pKeyIn, &_pKeyOut); uint8_t data[1536]; - RC4( &_pKeyIn, 1536, data, data); - RC4( &_pKeyOut, 1536, data, data); + RC4(&_pKeyIn, 1536, data, data); + RC4(&_pKeyOut, 1536, data, data); } //generate the digest uint32_t serverDigestOffset = GetDigestOffset(Server, _validationScheme); - uint8_t *pTempBuffer = new uint8_t[1536 - 32]; + uint8_t * pTempBuffer = new uint8_t[1536 - 32]; memcpy(pTempBuffer, Server, serverDigestOffset); memcpy(pTempBuffer + serverDigestOffset, Server + serverDigestOffset + 32, 1536 - serverDigestOffset - 32); - uint8_t *pTempHash = new uint8_t[512]; + uint8_t * pTempHash = new uint8_t[512]; HMACsha256(pTempBuffer, 1536 - 32, genuineFMSKey, 36, pTempHash); memcpy(Server + serverDigestOffset, pTempHash, 32); delete[] pTempBuffer; @@ -874,7 +876,7 @@ bool RTMPStream::doHandshake(){ uint32_t keyChallengeIndex = GetDigestOffset(Client, _validationScheme); pTempHash = new uint8_t[512]; HMACsha256(Client + keyChallengeIndex, 32, genuineFMSKey, 68, pTempHash); - uint8_t *pLastHash = new uint8_t[512]; + uint8_t * pLastHash = new uint8_t[512]; HMACsha256(Server + 1536, 1536 - 32, pTempHash, 32, pLastHash); memcpy(Server + 1536 * 2 - 32, pLastHash, 32); delete[] pTempHash; diff --git a/lib/rtmpchunks.h b/lib/rtmpchunks.h index 65a7ef23..6d825dbb 100644 --- a/lib/rtmpchunks.h +++ b/lib/rtmpchunks.h @@ -28,9 +28,9 @@ namespace RTMPStream { extern unsigned int snd_cnt; ///< Counter for total data sent, in bytes. extern timeval lastrec; ///< Timestamp of last time data was received. - + /// Holds a single RTMP chunk, either send or receive direction. - class Chunk{ + class Chunk { public: unsigned char headertype; ///< For input chunks, the type of header. This is calculated automatically for output chunks. unsigned int cs_id; ///< ContentStream ID @@ -51,7 +51,7 @@ namespace RTMPStream { extern std::map lastsend; extern std::map lastrecv; - + std::string & SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data); std::string & SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts); std::string & SendMedia(FLV::Tag & tag); diff --git a/lib/shared_memory.cpp b/lib/shared_memory.cpp index 1904b3fe..8227dad5 100644 --- a/lib/shared_memory.cpp +++ b/lib/shared_memory.cpp @@ -177,11 +177,11 @@ namespace IPC { ///\brief Unmaps a shared page if allowed void sharedPage::unmap() { if (mapped && len) { - #ifdef __CYGWIN__ +#ifdef __CYGWIN__ UnmapViewOfFile(mapped); - #else +#else munmap(mapped, len); - #endif +#endif mapped = 0; len = 0; } @@ -191,14 +191,14 @@ namespace IPC { void sharedPage::close() { unmap(); if (handle > 0) { - #ifdef __CYGWIN__ +#ifdef __CYGWIN__ CloseHandle(handle); - #else +#else ::close(handle); if (master && name != "") { shm_unlink(name.c_str()); } - #endif +#endif handle = 0; } } @@ -247,69 +247,69 @@ namespace IPC { master = master_; mapped = 0; if (name.size()) { - #ifdef __CYGWIN__ - if (master){ - handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, len, name.c_str()); - }else{ - int i = 0; - do { - if (i != 0){ - Util::sleep(1000); - } - handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name.c_str()); - i++; - } while(i < 10 && !handle && autoBackoff); - } - if (!handle) { - DEBUG_MSG(DLVL_FAIL, "%s for page %s failed: %s", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), strerror(errno)); - return; - } - mapped = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); - if (!mapped) { - return; - } - #else - handle = shm_open(name.c_str(), (master ? O_CREAT | O_EXCL : 0) | O_RDWR, ACCESSPERMS); - if (handle == -1) { - if (master) { - DEBUG_MSG(DLVL_HIGH, "Overwriting old page for %s", name.c_str()); - handle = shm_open(name.c_str(), O_CREAT | O_RDWR, ACCESSPERMS); - } else { - int i = 0; - while (i < 10 && handle == -1 && autoBackoff) { - i++; - Util::sleep(1000); - handle = shm_open(name.c_str(), O_RDWR, ACCESSPERMS); - } +#ifdef __CYGWIN__ + if (master) { + handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, len, name.c_str()); + } else { + int i = 0; + do { + if (i != 0) { + Util::sleep(1000); } - } - if (handle == -1) { - DEBUG_MSG(DLVL_FAIL, "shm_open for page %s failed: %s", name.c_str(), strerror(errno)); - return; - } + handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name.c_str()); + i++; + } while (i < 10 && !handle && autoBackoff); + } + if (!handle) { + DEBUG_MSG(DLVL_FAIL, "%s for page %s failed: %s", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), strerror(errno)); + return; + } + mapped = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); + if (!mapped) { + return; + } +#else + handle = shm_open(name.c_str(), (master ? O_CREAT | O_EXCL : 0) | O_RDWR, ACCESSPERMS); + if (handle == -1) { if (master) { - if (ftruncate(handle, 0) < 0) { - DEBUG_MSG(DLVL_FAIL, "truncate to zero for page %s failed: %s", name.c_str(), strerror(errno)); - return; - } - if (ftruncate(handle, len) < 0) { - DEBUG_MSG(DLVL_FAIL, "truncate to %lld for page %s failed: %s", len, name.c_str(), strerror(errno)); - return; - } + DEBUG_MSG(DLVL_HIGH, "Overwriting old page for %s", name.c_str()); + handle = shm_open(name.c_str(), O_CREAT | O_RDWR, ACCESSPERMS); } else { - struct stat buffStats; - int xRes = fstat(handle, &buffStats); - if (xRes < 0) { - return; + int i = 0; + while (i < 10 && handle == -1 && autoBackoff) { + i++; + Util::sleep(1000); + handle = shm_open(name.c_str(), O_RDWR, ACCESSPERMS); } - len = buffStats.st_size; } - mapped = (char *)mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0); - if (mapped == MAP_FAILED) { - mapped = 0; + } + if (handle == -1) { + DEBUG_MSG(DLVL_FAIL, "shm_open for page %s failed: %s", name.c_str(), strerror(errno)); + return; + } + if (master) { + if (ftruncate(handle, 0) < 0) { + DEBUG_MSG(DLVL_FAIL, "truncate to zero for page %s failed: %s", name.c_str(), strerror(errno)); return; } - #endif + if (ftruncate(handle, len) < 0) { + DEBUG_MSG(DLVL_FAIL, "truncate to %lld for page %s failed: %s", len, name.c_str(), strerror(errno)); + return; + } + } else { + struct stat buffStats; + int xRes = fstat(handle, &buffStats); + if (xRes < 0) { + return; + } + len = buffStats.st_size; + } + mapped = (char *)mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0); + if (mapped == MAP_FAILED) { + mapped = 0; + return; + } +#endif } } diff --git a/lib/shared_memory.h b/lib/shared_memory.h index 9c448203..50e52090 100644 --- a/lib/shared_memory.h +++ b/lib/shared_memory.h @@ -11,7 +11,7 @@ #endif namespace IPC { - + ///\brief A class used for the exchange of statistics over shared memory. class statExchange { public: @@ -35,13 +35,13 @@ namespace IPC { private: ///\brief The payload for the stat exchange /// - 8 byte - now (timestamp of last statistics) - /// - 4 byte - time (duration of the current connection) + /// - 4 byte - time (duration of the current connection) /// - 4 byte - lastSecond (last second of content viewed) /// - 8 byte - down (Number of bytes received from peer) /// - 8 byte - up (Number of bytes sent to peer) /// - 16 byte - host (ip address of the peer) /// - 20 byte - streamName (name of the stream peer is viewing) - /// - 20 byte - connector (name of the connector the peer is using) + /// - 20 byte - connector (name of the connector the peer is using) char * data; }; @@ -80,7 +80,7 @@ namespace IPC { #if !defined __APPLE__ ///\brief A class for managing shared memory pages. - class sharedPage{ + class sharedPage { public: sharedPage(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true); sharedPage(const sharedPage & rhs); @@ -93,13 +93,13 @@ namespace IPC { } void unmap(); void close(); - #ifdef __CYGWIN__ +#ifdef __CYGWIN__ ///\brief The handle of the opened shared memory page HANDLE handle; - #else +#else ///\brief The fd handle of the opened shared memory page int handle; - #endif +#endif ///\brief The name of the opened shared memory page std::string name; ///\brief The size in bytes of the opened shared memory page @@ -118,7 +118,7 @@ namespace IPC { #else ///\brief A class for managing shared files. #endif - class sharedFile{ + class sharedFile { public: sharedFile(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true); sharedFile(const sharedFile & rhs); @@ -146,7 +146,7 @@ namespace IPC { ///\brief A class for handling shared memory pages. /// ///Uses shared files at its backbone, defined for portability - class sharedPage: public sharedFile{ + class sharedPage: public sharedFile { public: sharedPage(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true); sharedPage(const sharedPage & rhs); @@ -163,7 +163,7 @@ namespace IPC { /// ///Clients should allocate payLen bytes at a time, possibly with the addition of a counter. ///If no such length can be allocated, the next page should be tried, and so on. - class sharedServer{ + class sharedServer { public: sharedServer(); sharedServer(std::string name, int len, bool withCounter = false); @@ -198,7 +198,7 @@ namespace IPC { /// ///Clients should allocate payLen bytes at a time, possibly with the addition of a counter. ///If no such length can be allocated, the next page should be tried, and so on. - class sharedClient{ + class sharedClient { public: sharedClient(); sharedClient(const sharedClient & rhs); diff --git a/lib/socket.cpp b/lib/socket.cpp index baac5b79..27428421 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -17,7 +17,7 @@ #define BUFFER_BLOCKSIZE 4096 //set buffer blocksize to 4KiB -std::string uint2string(unsigned int i){ +std::string uint2string(unsigned int i) { std::stringstream st; st << i; return st.str(); @@ -26,19 +26,19 @@ std::string uint2string(unsigned int i){ /// Returns the amount of elements in the internal std::deque of std::string objects. /// The back is popped as long as it is empty, first - this way this function is /// guaranteed to return 0 if the buffer is empty. -unsigned int Socket::Buffer::size(){ - while (data.size() > 0 && data.back().empty()){ +unsigned int Socket::Buffer::size() { + while (data.size() > 0 && data.back().empty()) { data.pop_back(); } return data.size(); } /// Returns either the amount of total bytes available in the buffer or max, whichever is smaller. -unsigned int Socket::Buffer::bytes(unsigned int max){ +unsigned int Socket::Buffer::bytes(unsigned int max) { unsigned int i = 0; - for (std::deque::iterator it = data.begin(); it != data.end(); ++it){ - i += ( *it).size(); - if (i >= max){ + for (std::deque::iterator it = data.begin(); it != data.end(); ++it) { + i += (*it).size(); + if (i >= max) { return max; } } @@ -47,52 +47,52 @@ unsigned int Socket::Buffer::bytes(unsigned int max){ /// Appends this string to the internal std::deque of std::string objects. /// It is automatically split every BUFFER_BLOCKSIZE bytes. -void Socket::Buffer::append(const std::string & newdata){ +void Socket::Buffer::append(const std::string & newdata) { append(newdata.c_str(), newdata.size()); } /// Appends this data block to the internal std::deque of std::string objects. /// It is automatically split every BUFFER_BLOCKSIZE bytes. -void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize){ +void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize) { unsigned int i = 0, j = 0; - while (i < newdatasize){ + while (i < newdatasize) { j = i; - while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){ + while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE) { j++; - if (newdata[j - 1] == '\n'){ + if (newdata[j - 1] == '\n') { break; } } - if (i != j){ + if (i != j) { data.push_front(std::string(newdata + i, (size_t)(j - i))); i = j; - }else{ + } else { break; } } - if (data.size() > 5000){ + if (data.size() > 5000) { DEBUG_MSG(DLVL_WARN, "Warning: After %d new bytes, buffer has %d parts!", newdatasize, (int)data.size()); } } /// Prepends this data block to the internal std::deque of std::string objects. /// It is _not_ automatically split every BUFFER_BLOCKSIZE bytes. -void Socket::Buffer::prepend(const std::string & newdata){ +void Socket::Buffer::prepend(const std::string & newdata) { data.push_back(newdata); } /// Prepends this data block to the internal std::deque of std::string objects. /// It is _not_ automatically split every BUFFER_BLOCKSIZE bytes. -void Socket::Buffer::prepend(const char * newdata, const unsigned int newdatasize){ +void Socket::Buffer::prepend(const char * newdata, const unsigned int newdatasize) { data.push_back(std::string(newdata, (size_t)newdatasize)); } /// Returns true if at least count bytes are available in this buffer. -bool Socket::Buffer::available(unsigned int count){ +bool Socket::Buffer::available(unsigned int count) { unsigned int i = 0; - for (std::deque::iterator it = data.begin(); it != data.end(); ++it){ - i += ( *it).size(); - if (i >= count){ + for (std::deque::iterator it = data.begin(); it != data.end(); ++it) { + i += (*it).size(); + if (i >= count) { return true; } } @@ -101,21 +101,21 @@ bool Socket::Buffer::available(unsigned int count){ /// Removes count bytes from the buffer, returning them by value. /// Returns an empty string if not all count bytes are available. -std::string Socket::Buffer::remove(unsigned int count){ - if ( !available(count)){ +std::string Socket::Buffer::remove(unsigned int count) { + if (!available(count)) { return ""; } unsigned int i = 0; std::string ret; ret.reserve(count); - for (std::deque::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){ - if (i + ( *it).size() < count){ - ret.append( *it); - i += ( *it).size(); - ( *it).clear(); - }else{ - ret.append( *it, 0, count - i); - ( *it).erase(0, count - i); + for (std::deque::reverse_iterator it = data.rbegin(); it != data.rend(); ++it) { + if (i + (*it).size() < count) { + ret.append(*it); + i += (*it).size(); + (*it).clear(); + } else { + ret.append(*it, 0, count - i); + (*it).erase(0, count - i); break; } } @@ -124,19 +124,19 @@ std::string Socket::Buffer::remove(unsigned int count){ /// Copies count bytes from the buffer, returning them by value. /// Returns an empty string if not all count bytes are available. -std::string Socket::Buffer::copy(unsigned int count){ - if ( !available(count)){ +std::string Socket::Buffer::copy(unsigned int count) { + if (!available(count)) { return ""; } unsigned int i = 0; std::string ret; ret.reserve(count); - for (std::deque::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){ - if (i + ( *it).size() < count){ - ret.append( *it); - i += ( *it).size(); - }else{ - ret.append( *it, 0, count - i); + for (std::deque::reverse_iterator it = data.rbegin(); it != data.rend(); ++it) { + if (i + (*it).size() < count) { + ret.append(*it); + i += (*it).size(); + } else { + ret.append(*it, 0, count - i); break; } } @@ -144,23 +144,23 @@ std::string Socket::Buffer::copy(unsigned int count){ } /// Gets a reference to the back of the internal std::deque of std::string objects. -std::string & Socket::Buffer::get(){ +std::string & Socket::Buffer::get() { static std::string empty; - if (data.size() > 0){ + if (data.size() > 0) { return data.back(); - }else{ + } else { return empty; } } /// Completely empties the buffer -void Socket::Buffer::clear(){ +void Socket::Buffer::clear() { data.clear(); } /// Create a new base socket. This is a basic constructor for converting any valid socket to a Socket::Connection. /// \param sockNo Integer representing the socket to convert. -Socket::Connection::Connection(int sockNo){ +Socket::Connection::Connection(int sockNo) { sock = sockNo; pipes[0] = -1; pipes[1] = -1; @@ -174,7 +174,7 @@ Socket::Connection::Connection(int sockNo){ /// Simulate a socket using two file descriptors. /// \param write The filedescriptor to write to. /// \param read The filedescriptor to read from. -Socket::Connection::Connection(int write, int read){ +Socket::Connection::Connection(int write, int read) { sock = -1; pipes[0] = write; pipes[1] = read; @@ -187,7 +187,7 @@ Socket::Connection::Connection(int write, int read){ /// Create a new disconnected base socket. This is a basic constructor for placeholder purposes. /// A socket created like this is always disconnected and should/could be overwritten at some point. -Socket::Connection::Connection(){ +Socket::Connection::Connection() { sock = -1; pipes[0] = -1; pipes[1] = -1; @@ -199,44 +199,44 @@ Socket::Connection::Connection(){ } //Socket::Connection basic constructor /// Internally used call to make an file descriptor blocking or not. -void setFDBlocking(int FD, bool blocking){ +void setFDBlocking(int FD, bool blocking) { int flags = fcntl(FD, F_GETFL, 0); - if ( !blocking){ + if (!blocking) { flags |= O_NONBLOCK; - }else{ + } else { flags &= !O_NONBLOCK; } fcntl(FD, F_SETFL, flags); } /// Internally used call to make an file descriptor blocking or not. -bool isFDBlocking(int FD){ +bool isFDBlocking(int FD) { int flags = fcntl(FD, F_GETFL, 0); return !(flags & O_NONBLOCK); } /// Set this socket to be blocking (true) or nonblocking (false). -void Socket::Connection::setBlocking(bool blocking){ - if (sock >= 0){ +void Socket::Connection::setBlocking(bool blocking) { + if (sock >= 0) { setFDBlocking(sock, blocking); } - if (pipes[0] >= 0){ + if (pipes[0] >= 0) { setFDBlocking(pipes[0], blocking); } - if (pipes[1] >= 0){ + if (pipes[1] >= 0) { setFDBlocking(pipes[1], blocking); } } /// Set this socket to be blocking (true) or nonblocking (false). -bool Socket::Connection::isBlocking(){ - if (sock >= 0){ +bool Socket::Connection::isBlocking() { + if (sock >= 0) { return isFDBlocking(sock); } - if (pipes[0] >= 0){ + if (pipes[0] >= 0) { return isFDBlocking(pipes[0]); } - if (pipes[1] >= 0){ + if (pipes[1] >= 0) { return isFDBlocking(pipes[1]); } return false; @@ -246,8 +246,8 @@ bool Socket::Connection::isBlocking(){ /// If the connection is already closed, nothing happens. /// This function calls shutdown, thus making the socket unusable in all other /// processes as well. Do not use on shared sockets that are still in use. -void Socket::Connection::close(){ - if (sock != -1){ +void Socket::Connection::close() { + if (sock != -1) { shutdown(sock, SHUT_RDWR); } drop(); @@ -257,24 +257,24 @@ void Socket::Connection::close(){ /// If the connection is already closed, nothing happens. /// This function does *not* call shutdown, allowing continued use in other /// processes. -void Socket::Connection::drop(){ - if (connected()){ - if (sock != -1){ +void Socket::Connection::drop() { + if (connected()) { + if (sock != -1) { DEBUG_MSG(DLVL_HIGH, "Socket %d closed", sock); errno = EINTR; - while (::close(sock) != 0 && errno == EINTR){ + while (::close(sock) != 0 && errno == EINTR) { } sock = -1; } - if (pipes[0] != -1){ + if (pipes[0] != -1) { errno = EINTR; - while (::close(pipes[0]) != 0 && errno == EINTR){ + while (::close(pipes[0]) != 0 && errno == EINTR) { } pipes[0] = -1; } - if (pipes[1] != -1){ + if (pipes[1] != -1) { errno = EINTR; - while (::close(pipes[1]) != 0 && errno == EINTR){ + while (::close(pipes[1]) != 0 && errno == EINTR) { } pipes[1] = -1; } @@ -282,24 +282,24 @@ void Socket::Connection::drop(){ } //Socket::Connection::drop /// Returns internal socket number. -int Socket::Connection::getSocket(){ +int Socket::Connection::getSocket() { return sock; } /// Returns a string describing the last error that occured. /// Only reports errors if an error actually occured - returns the host address or empty string otherwise. -std::string Socket::Connection::getError(){ +std::string Socket::Connection::getError() { return remotehost; } /// Create a new Unix Socket. This socket will (try to) connect to the given address right away. /// \param address String containing the location of the Unix socket to connect to. /// \param nonblock Whether the socket should be nonblocking. False by default. -Socket::Connection::Connection(std::string address, bool nonblock){ +Socket::Connection::Connection(std::string address, bool nonblock) { pipes[0] = -1; pipes[1] = -1; sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0){ + if (sock < 0) { remotehost = strerror(errno); DEBUG_MSG(DLVL_FAIL, "Could not create socket! Error: %s", remotehost.c_str()); return; @@ -312,14 +312,14 @@ Socket::Connection::Connection(std::string address, bool nonblock){ sockaddr_un addr; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, address.c_str(), address.size() + 1); - int r = connect(sock, (sockaddr*) &addr, sizeof(addr)); - if (r == 0){ - if (nonblock){ + int r = connect(sock, (sockaddr *) &addr, sizeof(addr)); + if (r == 0) { + if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); } - }else{ + } else { remotehost = strerror(errno); DEBUG_MSG(DLVL_FAIL, "Could not connect to %s! Error: %s", address.c_str(), remotehost.c_str()); close(); @@ -330,10 +330,10 @@ Socket::Connection::Connection(std::string address, bool nonblock){ /// \param host String containing the hostname to connect to. /// \param port String containing the port to connect to. /// \param nonblock Whether the socket should be nonblocking. -Socket::Connection::Connection(std::string host, int port, bool nonblock){ +Socket::Connection::Connection(std::string host, int port, bool nonblock) { pipes[0] = -1; pipes[1] = -1; - struct addrinfo *result, *rp, hints; + struct addrinfo * result, *rp, hints; Error = false; Blocking = false; up = 0; @@ -342,7 +342,7 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock){ std::stringstream ss; ss << port; - memset( &hints, 0, sizeof(struct addrinfo)); + memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; @@ -351,19 +351,19 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock){ hints.ai_addr = NULL; hints.ai_next = NULL; int s = getaddrinfo(host.c_str(), ss.str().c_str(), &hints, &result); - if (s != 0){ + if (s != 0) { DEBUG_MSG(DLVL_FAIL, "Could not connect to %s:%i! Error: %s", host.c_str(), port, gai_strerror(s)); close(); return; } remotehost = ""; - for (rp = result; rp != NULL; rp = rp->ai_next){ + for (rp = result; rp != NULL; rp = rp->ai_next) { sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (sock < 0){ + if (sock < 0) { continue; } - if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0){ + if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) { break; } remotehost += strerror(errno); @@ -371,11 +371,11 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock){ } freeaddrinfo(result); - if (rp == 0){ + if (rp == 0) { DEBUG_MSG(DLVL_FAIL, "Could not connect to %s! Error: %s", host.c_str(), remotehost.c_str()); close(); - }else{ - if (nonblock){ + } else { + if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); @@ -388,47 +388,47 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock){ /// The connection status is updated after every read/write attempt, when errors occur /// and when the socket is closed manually. /// \returns True if socket is connected, false otherwise. -bool Socket::Connection::connected() const{ +bool Socket::Connection::connected() const { return (sock >= 0) || ((pipes[0] >= 0) && (pipes[1] >= 0)); } /// Returns the time this socket has been connected. -unsigned int Socket::Connection::connTime(){ +unsigned int Socket::Connection::connTime() { return conntime; } /// Returns total amount of bytes sent. -unsigned int Socket::Connection::dataUp(){ +unsigned int Socket::Connection::dataUp() { return up; } /// Returns total amount of bytes received. -unsigned int Socket::Connection::dataDown(){ +unsigned int Socket::Connection::dataDown() { return down; } /// Returns a std::string of stats, ended by a newline. /// Requires the current connector name as an argument. -std::string Socket::Connection::getStats(std::string C){ +std::string Socket::Connection::getStats(std::string C) { return "S " + getHost() + " " + C + " " + uint2string(Util::epoch() - conntime) + " " + uint2string(up) + " " + uint2string(down) + "\n"; } /// Updates the downbuffer and upbuffer internal variables. /// Returns true if new data was received, false otherwise. -bool Socket::Connection::spool(){ - if (upbuffer.size() > 0){ +bool Socket::Connection::spool() { + if (upbuffer.size() > 0) { iwrite(upbuffer.get()); } /// \todo Provide better mechanism to prevent overbuffering. - if (downbuffer.size() > 10000){ + if (downbuffer.size() > 10000) { return true; - }else{ + } else { return iread(downbuffer); } } -/// -bool Socket::Connection::peek(){ +/// +bool Socket::Connection::peek() { /// clear buffer downbuffer.clear(); return iread(downbuffer, MSG_PEEK); @@ -436,40 +436,48 @@ bool Socket::Connection::peek(){ /// Updates the downbuffer and upbuffer internal variables until upbuffer is empty. /// Returns true if new data was received, false otherwise. -bool Socket::Connection::flush(){ +bool Socket::Connection::flush() { bool bing = isBlocking(); - if (!bing){setBlocking(true);} - while (upbuffer.size() > 0 && connected()){ + if (!bing) { + setBlocking(true); + } + while (upbuffer.size() > 0 && connected()) { iwrite(upbuffer.get()); } - if (!bing){setBlocking(false);} + if (!bing) { + setBlocking(false); + } /// \todo Provide better mechanism to prevent overbuffering. - if (downbuffer.size() > 1000){ + if (downbuffer.size() > 1000) { return true; - }else{ + } else { return iread(downbuffer); } } /// Returns a reference to the download buffer. -Socket::Buffer & Socket::Connection::Received(){ +Socket::Buffer & Socket::Connection::Received() { return downbuffer; } /// Will not buffer anything but always send right away. Blocks. /// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. -void Socket::Connection::SendNow(const char * data, size_t len){ +void Socket::Connection::SendNow(const char * data, size_t len) { bool bing = isBlocking(); - if (!bing){setBlocking(true);} - while (upbuffer.size() > 0 && connected()){ + if (!bing) { + setBlocking(true); + } + while (upbuffer.size() > 0 && connected()) { iwrite(upbuffer.get()); } unsigned int i = iwrite(data, std::min((long unsigned int)len, 51200ul)); - while (i < len && connected()){ + while (i < len && connected()) { i += iwrite(data + i, std::min((long unsigned int)(len - i), 51200ul)); } - if (!bing){setBlocking(false);} + if (!bing) { + setBlocking(false); + } } /// Appends data to the upbuffer. @@ -477,17 +485,17 @@ void Socket::Connection::SendNow(const char * data, size_t len){ /// If the upbuffer is empty before or after this attempt, it will attempt to send /// the data right away. Any data that could not be send will be put into the upbuffer. /// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(const char * data, size_t len){ - while (upbuffer.size() > 0){ - if ( !iwrite(upbuffer.get())){ +void Socket::Connection::Send(const char * data, size_t len) { + while (upbuffer.size() > 0) { + if (!iwrite(upbuffer.get())) { break; } } - if (upbuffer.size() > 0){ + if (upbuffer.size() > 0) { upbuffer.append(data, len); - }else{ + } else { unsigned int i = iwrite(data, len); - if (i < len){ + if (i < len) { upbuffer.append(data + i, len - i); } } @@ -496,7 +504,7 @@ void Socket::Connection::Send(const char * data, size_t len){ /// Will not buffer anything but always send right away. Blocks. /// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. -void Socket::Connection::SendNow(const char * data){ +void Socket::Connection::SendNow(const char * data) { int len = strlen(data); SendNow(data, len); } @@ -506,7 +514,7 @@ void Socket::Connection::SendNow(const char * data){ /// If the upbuffer is empty before or after this attempt, it will attempt to send /// the data right away. Any data that could not be send will be put into the upbuffer. /// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(const char * data){ +void Socket::Connection::Send(const char * data) { int len = strlen(data); Send(data, len); } @@ -514,7 +522,7 @@ void Socket::Connection::Send(const char * data){ /// Will not buffer anything but always send right away. Blocks. /// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. -void Socket::Connection::SendNow(const std::string & data){ +void Socket::Connection::SendNow(const std::string & data) { SendNow(data.data(), data.size()); } @@ -523,7 +531,7 @@ void Socket::Connection::SendNow(const std::string & data){ /// If the upbuffer is empty before or after this attempt, it will attempt to send /// the data right away. Any data that could not be send will be put into the upbuffer. /// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(std::string & data){ +void Socket::Connection::Send(std::string & data) { Send(data.c_str(), data.size()); } @@ -532,23 +540,23 @@ void Socket::Connection::Send(std::string & data){ /// \param buffer Location of the buffer to write from. /// \param len Amount of bytes to write. /// \returns The amount of bytes actually written. -unsigned int Socket::Connection::iwrite(const void * buffer, int len){ - if ( !connected() || len < 1){ +unsigned int Socket::Connection::iwrite(const void * buffer, int len) { + if (!connected() || len < 1) { return 0; } int r; - if (sock >= 0){ + if (sock >= 0) { r = send(sock, buffer, len, 0); - }else{ + } else { r = write(pipes[0], buffer, len); } - if (r < 0){ - switch (errno){ + if (r < 0) { + switch (errno) { case EWOULDBLOCK: return 0; break; default: - if (errno != EPIPE && errno != ECONNRESET){ + if (errno != EPIPE && errno != ECONNRESET) { Error = true; remotehost = strerror(errno); DEBUG_MSG(DLVL_WARN, "Could not iwrite data! Error: %s", remotehost.c_str()); @@ -558,7 +566,7 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len){ break; } } - if (r == 0 && (sock >= 0)){ + if (r == 0 && (sock >= 0)) { close(); } up += r; @@ -570,24 +578,24 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len){ /// \param buffer Location of the buffer to read to. /// \param len Amount of bytes to read. /// \returns The amount of bytes actually read. -int Socket::Connection::iread(void * buffer, int len, int flags){ - if ( !connected() || len < 1){ +int Socket::Connection::iread(void * buffer, int len, int flags) { + if (!connected() || len < 1) { return 0; } int r; - if (sock >=0 ){ - r = recv(sock, buffer, len, flags); + if (sock >= 0) { + r = recv(sock, buffer, len, flags); } else { //(pipes[1] >=0) { - r = read(pipes[1], buffer, len); + r = read(pipes[1], buffer, len); } - if (r < 0){ - switch (errno){ + if (r < 0) { + switch (errno) { case EWOULDBLOCK: return 0; break; default: - if (errno != EPIPE){ + if (errno != EPIPE) { Error = true; remotehost = strerror(errno); DEBUG_MSG(DLVL_WARN, "Could not iread data! Error: %s", remotehost.c_str()); @@ -597,7 +605,7 @@ int Socket::Connection::iread(void * buffer, int len, int flags){ break; } } - if (r == 0){ + if (r == 0) { close(); } down += r; @@ -609,10 +617,10 @@ int Socket::Connection::iread(void * buffer, int len, int flags){ /// then appended to end of buffer. /// \param buffer Socket::Buffer to append data to. /// \return True if new data arrived, false otherwise. -bool Socket::Connection::iread(Buffer & buffer, int flags){ +bool Socket::Connection::iread(Buffer & buffer, int flags) { char cbuffer[BUFFER_BLOCKSIZE]; int num = iread(cbuffer, BUFFER_BLOCKSIZE, flags); - if (num < 1){ + if (num < 1) { return false; } buffer.append(cbuffer, num); @@ -624,12 +632,12 @@ bool Socket::Connection::iread(Buffer & buffer, int flags){ /// then removed from front of buffer. /// \param buffer std::string to remove data from. /// \return True if more data was sent, false otherwise. -bool Socket::Connection::iwrite(std::string & buffer){ - if (buffer.size() < 1){ +bool Socket::Connection::iwrite(std::string & buffer) { + if (buffer.size() < 1) { return false; } - unsigned int tmp = iwrite((void*)buffer.c_str(), buffer.size()); - if ( !tmp){ + unsigned int tmp = iwrite((void *)buffer.c_str(), buffer.size()); + if (!tmp) { return false; } buffer = buffer.substr(tmp); @@ -637,39 +645,39 @@ bool Socket::Connection::iwrite(std::string & buffer){ } //iwrite /// Gets hostname for connection, if available. -std::string Socket::Connection::getHost(){ +std::string Socket::Connection::getHost() { return remotehost; } /// Sets hostname for connection manually. /// Overwrites the detected host, thus possibily making it incorrect. -void Socket::Connection::setHost(std::string host){ +void Socket::Connection::setHost(std::string host) { remotehost = host; } /// Returns true if these sockets are the same socket. /// Does not check the internal stats - only the socket itself. -bool Socket::Connection::operator==(const Connection &B) const{ +bool Socket::Connection::operator==(const Connection & B) const { return sock == B.sock && pipes[0] == B.pipes[0] && pipes[1] == B.pipes[1]; } /// Returns true if these sockets are not the same socket. /// Does not check the internal stats - only the socket itself. -bool Socket::Connection::operator!=(const Connection &B) const{ +bool Socket::Connection::operator!=(const Connection & B) const { return sock != B.sock || pipes[0] != B.pipes[0] || pipes[1] != B.pipes[1]; } /// Returns true if the socket is valid. /// Aliases for Socket::Connection::connected() -Socket::Connection::operator bool() const{ +Socket::Connection::operator bool() const { return connected(); } /// Returns true if the given address can be matched with the remote host. /// Can no longer return true after any socket error have occurred. -bool Socket::Connection::isAddress(std::string addr){ - struct addrinfo *result, *rp, hints; - memset( &hints, 0, sizeof(struct addrinfo)); +bool Socket::Connection::isAddress(std::string addr) { + struct addrinfo * result, *rp, hints; + memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED; @@ -679,26 +687,26 @@ bool Socket::Connection::isAddress(std::string addr){ hints.ai_next = NULL; int s = getaddrinfo(addr.c_str(), 0, &hints, &result); DEBUG_MSG(DLVL_DEVEL, "Meh: %s", addr.c_str()); - if (s != 0){ + if (s != 0) { return false; } - + char newaddr[INET_ADDRSTRLEN]; newaddr[0] = 0; - for (rp = result; rp != NULL; rp = rp->ai_next){ - if (rp->ai_family == AF_INET && inet_ntop(rp->ai_family, &(((sockaddr_in*)rp->ai_addr)->sin_addr), newaddr, INET_ADDRSTRLEN)){ + for (rp = result; rp != NULL; rp = rp->ai_next) { + if (rp->ai_family == AF_INET && inet_ntop(rp->ai_family, &(((sockaddr_in *)rp->ai_addr)->sin_addr), newaddr, INET_ADDRSTRLEN)) { DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr); - if (remotehost == newaddr){ + if (remotehost == newaddr) { return true; } DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '::ffff:%s'", remotehost.c_str(), newaddr); - if (remotehost == std::string("::ffff:")+newaddr){ + if (remotehost == std::string("::ffff:") + newaddr) { return true; } } - if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6*)rp->ai_addr)->sin6_addr), newaddr, INET_ADDRSTRLEN)){ + if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6 *)rp->ai_addr)->sin6_addr), newaddr, INET_ADDRSTRLEN)) { DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr); - if (remotehost == newaddr){ + if (remotehost == newaddr) { return true; } } @@ -708,7 +716,7 @@ bool Socket::Connection::isAddress(std::string addr){ } /// Create a new base Server. The socket is never connected, and a placeholder for later connections. -Socket::Server::Server(){ +Socket::Server::Server() { sock = -1; } //Socket::Server base Constructor @@ -718,8 +726,8 @@ Socket::Server::Server(){ /// \param port The TCP port to listen on /// \param hostname (optional) The interface to bind to. The default is 0.0.0.0 (all interfaces). /// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking). -Socket::Server::Server(int port, std::string hostname, bool nonblock){ - if ( !IPv6bind(port, hostname, nonblock) && !IPv4bind(port, hostname, nonblock)){ +Socket::Server::Server(int port, std::string hostname, bool nonblock) { + if (!IPv6bind(port, hostname, nonblock) && !IPv4bind(port, hostname, nonblock)) { DEBUG_MSG(DLVL_FAIL, "Could not create socket %s:%i! Error: %s", hostname.c_str(), port, errors.c_str()); sock = -1; } @@ -730,16 +738,16 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){ /// \param hostname The interface to bind to. The default is 0.0.0.0 (all interfaces). /// \param nonblock Whether accept() calls will be nonblocking. Default is false (blocking). /// \return True if successful, false otherwise. -bool Socket::Server::IPv6bind(int port, std::string hostname, bool nonblock){ +bool Socket::Server::IPv6bind(int port, std::string hostname, bool nonblock) { sock = socket(AF_INET6, SOCK_STREAM, 0); - if (sock < 0){ + if (sock < 0) { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "Could not create IPv6 socket %s:%i! Error: %s", hostname.c_str(), port, errors.c_str()); return false; } int on = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (nonblock){ + if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); @@ -748,24 +756,24 @@ bool Socket::Server::IPv6bind(int port, std::string hostname, bool nonblock){ memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = htons(port); //set port - if (hostname == "0.0.0.0" || hostname.length() == 0){ + if (hostname == "0.0.0.0" || hostname.length() == 0) { addr.sin6_addr = in6addr_any; - }else{ + } else { inet_pton(AF_INET6, hostname.c_str(), &addr.sin6_addr); //set interface, 0.0.0.0 (default) is all } - int ret = bind(sock, (sockaddr*) &addr, sizeof(addr)); //do the actual bind - if (ret == 0){ + int ret = bind(sock, (sockaddr *) &addr, sizeof(addr)); //do the actual bind + if (ret == 0) { ret = listen(sock, 100); //start listening, backlog of 100 allowed - if (ret == 0){ + if (ret == 0) { DEBUG_MSG(DLVL_DEVEL, "IPv6 socket success @ %s:%i", hostname.c_str(), port); return true; - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "IPv6 listen failed! Error: %s", errors.c_str()); close(); return false; } - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "IPv6 Binding %s:%i failed (%s)", hostname.c_str(), port, errors.c_str()); close(); @@ -778,16 +786,16 @@ bool Socket::Server::IPv6bind(int port, std::string hostname, bool nonblock){ /// \param hostname The interface to bind to. The default is 0.0.0.0 (all interfaces). /// \param nonblock Whether accept() calls will be nonblocking. Default is false (blocking). /// \return True if successful, false otherwise. -bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock){ +bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock) { sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0){ + if (sock < 0) { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "Could not create IPv4 socket %s:%i! Error: %s", hostname.c_str(), port, errors.c_str()); return false; } int on = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (nonblock){ + if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); @@ -796,24 +804,24 @@ bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock){ memset(&addr4, 0, sizeof(addr4)); addr4.sin_family = AF_INET; addr4.sin_port = htons(port); //set port - if (hostname == "0.0.0.0" || hostname.length() == 0){ + if (hostname == "0.0.0.0" || hostname.length() == 0) { addr4.sin_addr.s_addr = INADDR_ANY; - }else{ + } else { inet_pton(AF_INET, hostname.c_str(), &addr4.sin_addr); //set interface, 0.0.0.0 (default) is all } - int ret = bind(sock, (sockaddr*) &addr4, sizeof(addr4)); //do the actual bind - if (ret == 0){ + int ret = bind(sock, (sockaddr *) &addr4, sizeof(addr4)); //do the actual bind + if (ret == 0) { ret = listen(sock, 100); //start listening, backlog of 100 allowed - if (ret == 0){ + if (ret == 0) { DEBUG_MSG(DLVL_DEVEL, "IPv4 socket success @ %s:%i", hostname.c_str(), port); return true; - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "IPv4 listen failed! Error: %s", errors.c_str()); close(); return false; } - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "IPv4 Binding %s:%i failed (%s)", hostname.c_str(), port, errors.c_str()); close(); @@ -827,15 +835,15 @@ bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock){ /// The address used will first be unlinked - so it succeeds if the Unix socket already existed. Watch out for this behaviour - it will delete any file located at address! /// \param address The location of the Unix socket to bind to. /// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking). -Socket::Server::Server(std::string address, bool nonblock){ +Socket::Server::Server(std::string address, bool nonblock) { unlink(address.c_str()); sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0){ + if (sock < 0) { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "Could not create unix socket %s! Error: %s", address.c_str(), errors.c_str()); return; } - if (nonblock){ + if (nonblock) { int flags = fcntl(sock, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); @@ -843,18 +851,18 @@ Socket::Server::Server(std::string address, bool nonblock){ sockaddr_un addr; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, address.c_str(), address.size() + 1); - int ret = bind(sock, (sockaddr*) &addr, sizeof(addr)); - if (ret == 0){ + int ret = bind(sock, (sockaddr *) &addr, sizeof(addr)); + if (ret == 0) { ret = listen(sock, 100); //start listening, backlog of 100 allowed - if (ret == 0){ + if (ret == 0) { return; - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "Unix listen failed! Error: %s", errors.c_str()); close(); return; } - }else{ + } else { errors = strerror(errno); DEBUG_MSG(DLVL_ERROR, "Unix Binding %s failed (%s)", address.c_str(), errors.c_str()); close(); @@ -866,37 +874,37 @@ Socket::Server::Server(std::string address, bool nonblock){ /// If the Socket::Server is nonblocking, it might return a Socket::Connection that is not connected, so check for this. /// \param nonblock (optional) Whether the newly connected socket should be nonblocking. Default is false (blocking). /// \returns A Socket::Connection, which may or may not be connected, depending on settings and circumstances. -Socket::Connection Socket::Server::accept(bool nonblock){ - if (sock < 0){ - return Socket::Connection( -1); +Socket::Connection Socket::Server::accept(bool nonblock) { + if (sock < 0) { + return Socket::Connection(-1); } struct sockaddr_in6 addrinfo; socklen_t len = sizeof(addrinfo); static char addrconv[INET6_ADDRSTRLEN]; - int r = ::accept(sock, (sockaddr*) &addrinfo, &len); + int r = ::accept(sock, (sockaddr *) &addrinfo, &len); //set the socket to be nonblocking, if requested. //we could do this through accept4 with a flag, but that call is non-standard... - if ((r >= 0) && nonblock){ + if ((r >= 0) && nonblock) { int flags = fcntl(r, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(r, F_SETFL, flags); } Socket::Connection tmp(r); - if (r < 0){ - if ((errno != EWOULDBLOCK) && (errno != EAGAIN) && (errno != EINTR)){ + if (r < 0) { + if ((errno != EWOULDBLOCK) && (errno != EAGAIN) && (errno != EINTR)) { DEBUG_MSG(DLVL_FAIL, "Error during accept - closing server socket %d.", sock); close(); } - }else{ - if (addrinfo.sin6_family == AF_INET6){ + } else { + if (addrinfo.sin6_family == AF_INET6) { tmp.remotehost = inet_ntop(AF_INET6, &(addrinfo.sin6_addr), addrconv, INET6_ADDRSTRLEN); DEBUG_MSG(DLVL_HIGH, "IPv6 addr [%s]", tmp.remotehost.c_str()); } - if (addrinfo.sin6_family == AF_INET){ - tmp.remotehost = inet_ntop(AF_INET, &(((sockaddr_in*) &addrinfo)->sin_addr), addrconv, INET6_ADDRSTRLEN); + if (addrinfo.sin6_family == AF_INET) { + tmp.remotehost = inet_ntop(AF_INET, &(((sockaddr_in *) &addrinfo)->sin_addr), addrconv, INET6_ADDRSTRLEN); DEBUG_MSG(DLVL_HIGH, "IPv4 addr [%s]", tmp.remotehost.c_str()); } - if (addrinfo.sin6_family == AF_UNIX){ + if (addrinfo.sin6_family == AF_UNIX) { DEBUG_MSG(DLVL_HIGH, "Unix connection"); tmp.remotehost = "UNIX_SOCKET"; } @@ -905,15 +913,15 @@ Socket::Connection Socket::Server::accept(bool nonblock){ } /// Set this socket to be blocking (true) or nonblocking (false). -void Socket::Server::setBlocking(bool blocking){ - if (sock >= 0){ +void Socket::Server::setBlocking(bool blocking) { + if (sock >= 0) { setFDBlocking(sock, blocking); } } /// Set this socket to be blocking (true) or nonblocking (false). -bool Socket::Server::isBlocking(){ - if (sock >= 0){ +bool Socket::Server::isBlocking() { + if (sock >= 0) { return isFDBlocking(sock); } return false; @@ -923,8 +931,8 @@ bool Socket::Server::isBlocking(){ /// If the connection is already closed, nothing happens. /// This function calls shutdown, thus making the socket unusable in all other /// processes as well. Do not use on shared sockets that are still in use. -void Socket::Server::close(){ - if (sock != -1){ +void Socket::Server::close() { + if (sock != -1) { shutdown(sock, SHUT_RDWR); } drop(); @@ -934,12 +942,12 @@ void Socket::Server::close(){ /// If the connection is already closed, nothing happens. /// This function does *not* call shutdown, allowing continued use in other /// processes. -void Socket::Server::drop(){ - if (connected()){ - if (sock != -1){ +void Socket::Server::drop() { + if (connected()) { + if (sock != -1) { DEBUG_MSG(DLVL_HIGH, "ServerSocket %d closed", sock); errno = EINTR; - while (::close(sock) != 0 && errno == EINTR){ + while (::close(sock) != 0 && errno == EINTR) { } sock = -1; } @@ -951,12 +959,12 @@ void Socket::Server::drop(){ /// The connection status is updated after every accept attempt, when errors occur /// and when the socket is closed manually. /// \returns True if socket is connected, false otherwise. -bool Socket::Server::connected() const{ +bool Socket::Server::connected() const { return (sock >= 0); } //Socket::Server::connected /// Returns internal socket number. -int Socket::Server::getSocket(){ +int Socket::Server::getSocket() { return sock; } @@ -964,12 +972,12 @@ int Socket::Server::getSocket(){ /// Will attempt to create an IPv6 UDP socket, on fail try a IPV4 UDP socket. /// If both fail, prints an DLVL_FAIL debug message. /// \param nonblock Whether the socket should be nonblocking. -Socket::UDPConnection::UDPConnection(bool nonblock){ +Socket::UDPConnection::UDPConnection(bool nonblock) { sock = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock == -1){ + if (sock == -1) { sock = socket(AF_INET, SOCK_DGRAM, 0); } - if (sock == -1){ + if (sock == -1) { DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno)); } up = 0; @@ -979,29 +987,29 @@ Socket::UDPConnection::UDPConnection(bool nonblock){ data = 0; data_size = 0; data_len = 0; - if (nonblock){ + if (nonblock) { setBlocking(!nonblock); } } //Socket::UDPConnection UDP Contructor /// Copies a UDP socket, re-allocating local copies of any needed structures. /// The data/data_size/data_len variables are *not* copied over. -Socket::UDPConnection::UDPConnection(const UDPConnection & o){ +Socket::UDPConnection::UDPConnection(const UDPConnection & o) { sock = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock == -1){ + if (sock == -1) { sock = socket(AF_INET, SOCK_DGRAM, 0); } - if (sock == -1){ + if (sock == -1) { DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno)); } up = 0; down = 0; - if (o.destAddr && o.destAddr_size){ + if (o.destAddr && o.destAddr_size) { destAddr = malloc(o.destAddr_size); - if (destAddr){ + if (destAddr) { memcpy(destAddr, o.destAddr, o.destAddr_size); } - }else{ + } else { destAddr = 0; destAddr_size = 0; } @@ -1011,18 +1019,18 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o){ } /// Closes the UDP socket, cleans up any memory allocated by the socket. -Socket::UDPConnection::~UDPConnection(){ - if (sock != -1){ +Socket::UDPConnection::~UDPConnection() { + if (sock != -1) { errno = EINTR; - while (::close(sock) != 0 && errno == EINTR){ + while (::close(sock) != 0 && errno == EINTR) { } sock = -1; } - if (destAddr){ + if (destAddr) { free(destAddr); destAddr = 0; } - if (data){ + if (data) { free(data); data = 0; } @@ -1030,24 +1038,24 @@ Socket::UDPConnection::~UDPConnection(){ /// Stores the properties of the receiving end of this UDP socket. /// This will be the receiving end for all SendNow calls. -void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){ - if (destAddr){ +void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port) { + if (destAddr) { free(destAddr); destAddr = 0; } destAddr = malloc(sizeof(struct sockaddr_in6)); - if (destAddr){ + if (destAddr) { destAddr_size = sizeof(struct sockaddr_in6); memset(destAddr, 0, destAddr_size); - ((struct sockaddr_in6*)destAddr)->sin6_family = AF_INET6; - ((struct sockaddr_in6*)destAddr)->sin6_port = htons(port); - if(inet_pton(AF_INET6, destIp.c_str(), &(((struct sockaddr_in6*)destAddr)->sin6_addr)) == 1){ + ((struct sockaddr_in6 *)destAddr)->sin6_family = AF_INET6; + ((struct sockaddr_in6 *)destAddr)->sin6_port = htons(port); + if (inet_pton(AF_INET6, destIp.c_str(), &(((struct sockaddr_in6 *)destAddr)->sin6_addr)) == 1) { return; } memset(destAddr, 0, destAddr_size); - ((struct sockaddr_in*)destAddr)->sin_family = AF_INET; - ((struct sockaddr_in*)destAddr)->sin_port = htons(port); - if(inet_pton(AF_INET, destIp.c_str(), &(((struct sockaddr_in*)destAddr)->sin_addr)) == 1){ + ((struct sockaddr_in *)destAddr)->sin_family = AF_INET; + ((struct sockaddr_in *)destAddr)->sin_port = htons(port); + if (inet_pton(AF_INET, destIp.c_str(), &(((struct sockaddr_in *)destAddr)->sin_addr)) == 1) { return; } } @@ -1058,25 +1066,25 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){ /// Gets the properties of the receiving end of this UDP socket. /// This will be the receiving end for all SendNow calls. -void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port){ - if (!destAddr || !destAddr_size){ +void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port) { + if (!destAddr || !destAddr_size) { destIp = ""; port = 0; return; } - char addr_str[INET6_ADDRSTRLEN+1]; + char addr_str[INET6_ADDRSTRLEN + 1]; addr_str[INET6_ADDRSTRLEN] = 0;//set last byte to zero, to prevent walking out of the array - if (((struct sockaddr_in*)destAddr)->sin_family == AF_INET6){ - if (inet_ntop(AF_INET6, &(((struct sockaddr_in6*)destAddr)->sin6_addr), addr_str, INET6_ADDRSTRLEN) != 0){ + if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6) { + if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)destAddr)->sin6_addr), addr_str, INET6_ADDRSTRLEN) != 0) { destIp = addr_str; - port = ntohs(((struct sockaddr_in6*)destAddr)->sin6_port); + port = ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port); return; } } - if (((struct sockaddr_in*)destAddr)->sin_family == AF_INET){ - if (inet_ntop(AF_INET, &(((struct sockaddr_in*)destAddr)->sin_addr), addr_str, INET6_ADDRSTRLEN) != 0){ + if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET) { + if (inet_ntop(AF_INET, &(((struct sockaddr_in *)destAddr)->sin_addr), addr_str, INET6_ADDRSTRLEN) != 0) { destIp = addr_str; - port = ntohs(((struct sockaddr_in*)destAddr)->sin_port); + port = ntohs(((struct sockaddr_in *)destAddr)->sin_port); return; } } @@ -1087,22 +1095,22 @@ void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port /// Sets the socket to be blocking if the parameters is true. /// Sets the socket to be non-blocking otherwise. -void Socket::UDPConnection::setBlocking(bool blocking){ - if (sock >= 0){ +void Socket::UDPConnection::setBlocking(bool blocking) { + if (sock >= 0) { setFDBlocking(sock, blocking); } } /// Sends a UDP datagram using the buffer sdata. /// This function simply calls SendNow(const char*, size_t) -void Socket::UDPConnection::SendNow(const std::string & sdata){ +void Socket::UDPConnection::SendNow(const std::string & sdata) { SendNow(sdata.c_str(), sdata.size()); } /// Sends a UDP datagram using the buffer sdata. /// sdata is required to be NULL-terminated. /// This function simply calls SendNow(const char*, size_t) -void Socket::UDPConnection::SendNow(const char* sdata){ +void Socket::UDPConnection::SendNow(const char * sdata) { int len = strlen(sdata); SendNow(sdata, len); } @@ -1110,12 +1118,14 @@ void Socket::UDPConnection::SendNow(const char* sdata){ /// Sends a UDP datagram using the buffer sdata of length len. /// Does not do anything if len < 1. /// Prints an DLVL_FAIL level debug message if sending failed. -void Socket::UDPConnection::SendNow(const char * sdata, size_t len){ - if (len < 1){return;} - int r = sendto(sock, sdata, len, 0, (sockaddr*)destAddr, destAddr_size); - if (r > 0){ +void Socket::UDPConnection::SendNow(const char * sdata, size_t len) { + if (len < 1) { + return; + } + int r = sendto(sock, sdata, len, 0, (sockaddr *)destAddr, destAddr_size); + if (r > 0) { up += r; - }else{ + } else { DEBUG_MSG(DLVL_FAIL, "Could not send UDP data through %d: %s", sock, strerror(errno)); } } @@ -1126,21 +1136,29 @@ void Socket::UDPConnection::SendNow(const char * sdata, size_t len){ /// If that fails too, gives up and returns zero. /// Prints a debug message at DLVL_FAIL level if binding failed. /// \return Actually bound port number, or zero on error. -int Socket::UDPConnection::bind(int port){ +int Socket::UDPConnection::bind(int port) { struct sockaddr_in6 s6; s6.sin6_family = AF_INET6; s6.sin6_addr = in6addr_any; - if (port){s6.sin6_port = htons(port);} - int r = ::bind(sock, (sockaddr*)&s6, sizeof(s6)); - if (r == 0){return ntohs(s6.sin6_port);} - + if (port) { + s6.sin6_port = htons(port); + } + int r = ::bind(sock, (sockaddr *)&s6, sizeof(s6)); + if (r == 0) { + return ntohs(s6.sin6_port); + } + struct sockaddr_in s4; s4.sin_family = AF_INET; s4.sin_addr.s_addr = INADDR_ANY; - if (port){s4.sin_port = htons(port);} - r = ::bind(sock, (sockaddr*)&s4, sizeof(s4)); - if (r == 0){return ntohs(s4.sin_port);} - + if (port) { + s4.sin_port = htons(port); + } + r = ::bind(sock, (sockaddr *)&s4, sizeof(s4)); + if (r == 0) { + return ntohs(s4.sin_port); + } + DEBUG_MSG(DLVL_FAIL, "Could not bind UDP socket to port %d", port); return 0; } @@ -1149,28 +1167,28 @@ int Socket::UDPConnection::bind(int port){ /// This will automatically allocate or resize the internal data buffer if needed. /// If a packet is received, it will be placed in the "data" member, with it's length in "data_len". /// \return True if a packet was received, false otherwise. -bool Socket::UDPConnection::Receive(){ +bool Socket::UDPConnection::Receive() { int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC, 0, 0); - if (data_size < (unsigned int)r){ - data = (char*)realloc(data, r); - if (data){ + if (data_size < (unsigned int)r) { + data = (char *)realloc(data, r); + if (data) { data_size = r; - }else{ + } else { data_size = 0; } } socklen_t destsize = destAddr_size; - r = recvfrom(sock, data, data_size, 0, (sockaddr*)destAddr, &destsize); - if (r > 0){ + r = recvfrom(sock, data, data_size, 0, (sockaddr *)destAddr, &destsize); + if (r > 0) { down += r; data_len = r; return true; - }else{ + } else { data_len = 0; return false; } } -int Socket::UDPConnection::getSock(){ - return sock; +int Socket::UDPConnection::getSock() { + return sock; } diff --git a/lib/socket.h b/lib/socket.h index 4f046156..979eb6f0 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -25,7 +25,7 @@ namespace Buffer { namespace Socket { /// A buffer made out of std::string objects that can be efficiently read from and written to. - class Buffer{ + class Buffer { private: std::deque data; public: @@ -44,7 +44,7 @@ namespace Socket { //Buffer /// This class is for easy communicating through sockets, either TCP or Unix. - class Connection{ + class Connection { private: int sock; ///< Internally saved socket number. int pipes[2]; ///< Internally saved file descriptors for pipe socket simulation. @@ -98,13 +98,13 @@ namespace Socket { bool Error; ///< Set to true if a socket error happened. bool Blocking; ///< Set to true if a socket is currently or wants to be blocking. //overloaded operators - bool operator==(const Connection &B) const; - bool operator!=(const Connection &B) const; + bool operator==(const Connection & B) const; + bool operator!=(const Connection & B) const; operator bool() const; }; /// This class is for easily setting up listening socket, either TCP or Unix. - class Server{ + class Server { private: std::string errors; ///< Stores errors that may have occured. int sock; ///< Internally saved socket number. @@ -122,8 +122,8 @@ namespace Socket { void drop(); ///< Close connection without shutdown. int getSocket(); ///< Returns internal socket number. }; - - class UDPConnection{ + + class UDPConnection { private: int sock; ///< Internally saved socket number. std::string remotehost;///< Stores remote host address diff --git a/lib/stream.cpp b/lib/stream.cpp index 7de2b657..ef43cfd5 100644 --- a/lib/stream.cpp +++ b/lib/stream.cpp @@ -14,29 +14,29 @@ #include "defines.h" #include "shared_memory.h" -std::string Util::getTmpFolder(){ +std::string Util::getTmpFolder() { std::string dir; char * tmp_char = 0; - if ( !tmp_char){ + if (!tmp_char) { tmp_char = getenv("TMP"); } - if ( !tmp_char){ + if (!tmp_char) { tmp_char = getenv("TEMP"); } - if ( !tmp_char){ + if (!tmp_char) { tmp_char = getenv("TMPDIR"); } - if (tmp_char){ + if (tmp_char) { dir = tmp_char; dir += "/mist"; - }else{ + } else { #if defined(_WIN32) || defined(_CYGWIN_) dir = "C:/tmp/mist"; #else dir = "/tmp/mist"; #endif } - if (access(dir.c_str(), 0) != 0){ + if (access(dir.c_str(), 0) != 0) { mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); //attempt to create mist folder - ignore failures } return dir + "/"; @@ -46,92 +46,92 @@ std::string Util::getTmpFolder(){ /// Filters the streamname, removing invalid characters and converting all /// letters to lowercase. If a '?' character is found, everything following /// that character is deleted. The original string is modified. -void Util::Stream::sanitizeName(std::string & streamname){ +void Util::Stream::sanitizeName(std::string & streamname) { //strip anything that isn't numbers, digits or underscores - for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i){ - if ( *i == '?'){ + for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i) { + if (*i == '?') { streamname.erase(i, streamname.end()); break; } - if ( !isalpha( *i) && !isdigit( *i) && *i != '_'){ + if (!isalpha(*i) && !isdigit(*i) && *i != '_') { streamname.erase(i); - }else{ - *i = tolower( *i); + } else { + *i = tolower(*i); } } } -bool Util::Stream::getLive(std::string streamname){ +bool Util::Stream::getLive(std::string streamname) { JSON::Value ServConf = JSON::fromFile(getTmpFolder() + "streamlist"); static unsigned long long counter = 0; std::stringstream name; name << "MistInBuffer " << (counter++); std::string player_bin = Util::getMyPath() + "MistInBuffer"; DEBUG_MSG(DLVL_WARN, "Starting %s -p -s %s", player_bin.c_str(), streamname.c_str()); - char* argv[15] = {(char*)player_bin.c_str(), (char*)"-p", (char*)"-s", (char*)streamname.c_str(), (char*)0}; + char * argv[15] = {(char *)player_bin.c_str(), (char *)"-p", (char *)"-s", (char *)streamname.c_str(), (char *)0}; int argNum = 4; - if (ServConf["streams"][streamname].isMember("DVR")){ + if (ServConf["streams"][streamname].isMember("DVR")) { std::string bufferTime = ServConf["streams"][streamname]["DVR"].asString(); - argv[argNum++] = (char*)"-b"; - argv[argNum++] = (char*)bufferTime.c_str(); - argv[argNum++] = (char*)0; + argv[argNum++] = (char *)"-b"; + argv[argNum++] = (char *)bufferTime.c_str(); + argv[argNum++] = (char *)0; } int pid = fork(); - if (pid){ + if (pid) { execvp(argv[0], argv); _exit(42); - }else if(pid == -1){ + } else if (pid == -1) { perror("Could not start vod"); } return true; } /// Starts a process for a VoD stream. -bool Util::Stream::getVod(std::string filename, std::string streamname){ +bool Util::Stream::getVod(std::string filename, std::string streamname) { static unsigned long long counter = 0; std::stringstream name; name << "MistInDTSC " << (counter++); std::string player_bin = Util::getMyPath() + "MistInDTSC"; - if (filename.substr(filename.size()-5) == ".ismv"){ + if (filename.substr(filename.size() - 5) == ".ismv") { name.str("MistInISMV " + filename); player_bin = Util::getMyPath() + "MistInISMV"; } - if (filename.substr(filename.size()-4) == ".flv"){ + if (filename.substr(filename.size() - 4) == ".flv") { name.str("MistInFLV " + filename); player_bin = Util::getMyPath() + "MistInFLV"; } INFO_MSG("Starting %s -p -s %s %s", player_bin.c_str(), streamname.c_str(), filename.c_str()); - char* const argv[] = {(char*)player_bin.c_str(), (char*)"-p", (char*)"-s", (char*)streamname.c_str(), (char*)filename.c_str(), (char*)0}; + char * const argv[] = {(char *)player_bin.c_str(), (char *)"-p", (char *)"-s", (char *)streamname.c_str(), (char *)filename.c_str(), (char *)0}; int pid = fork(); - if (pid){ + if (pid) { execvp(argv[0], argv); _exit(42); - }else if(pid == -1){ + } else if (pid == -1) { perror("Could not start vod"); } return true; } /// Probe for available streams. Currently first VoD, then Live. -bool Util::Stream::getStream(std::string streamname){ +bool Util::Stream::getStream(std::string streamname) { sanitizeName(streamname); JSON::Value ServConf = JSON::fromFile(getTmpFolder() + "streamlist"); - if (ServConf["streams"].isMember(streamname)){ + if (ServConf["streams"].isMember(streamname)) { //check if the stream is already active, if yes, don't re-activate IPC::semaphore playerLock(std::string("/lock_" + streamname).c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1); - if (!playerLock.tryWait()){ + if (!playerLock.tryWait()) { playerLock.close(); DEBUG_MSG(DLVL_MEDIUM, "Playerlock for %s already active - not re-activating stream", streamname.c_str()); return true; } playerLock.post(); playerLock.close(); - if (ServConf["streams"][streamname]["source"].asString()[0] == '/'){ + if (ServConf["streams"][streamname]["source"].asString()[0] == '/') { DEBUG_MSG(DLVL_MEDIUM, "Activating VoD stream %s", streamname.c_str()); return getVod(ServConf["streams"][streamname]["source"].asString(), streamname); - }else{ + } else { DEBUG_MSG(DLVL_MEDIUM, "Activating live stream %s", streamname.c_str()); return getLive(streamname); } @@ -144,7 +144,7 @@ bool Util::Stream::getStream(std::string streamname){ /// Filters the streamname, removing invalid characters and /// converting all letters to lowercase. /// If a '?' character is found, everything following that character is deleted. -Socket::Server Util::Stream::makeLive(std::string streamname){ +Socket::Server Util::Stream::makeLive(std::string streamname) { sanitizeName(streamname); std::string loc = getTmpFolder() + "stream_" + streamname; //create and return the Socket::Server diff --git a/lib/stream.h b/lib/stream.h index 919569b6..259d39e0 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -7,7 +7,7 @@ namespace Util { std::string getTmpFolder(); - class Stream{ + class Stream { public: static void sanitizeName(std::string & streamname); static bool getLive(std::string streamname); diff --git a/lib/theora.cpp b/lib/theora.cpp index fd0bf6ea..5d7348c9 100644 --- a/lib/theora.cpp +++ b/lib/theora.cpp @@ -4,93 +4,117 @@ #include #include -namespace theora{ - bool header::checkDataSize(unsigned int size){ - if (size > datasize){ - void* tmp = realloc(data,size); - if (tmp){ - data = (char*)tmp; +namespace theora { + bool header::checkDataSize(unsigned int size) { + if (size > datasize) { + void * tmp = realloc(data, size); + if (tmp) { + data = (char *)tmp; datasize = size; return true; - }else{ + } else { return false; } - }else{ + } else { return true; } } - - uint32_t header::getInt32(size_t index){ - if (datasize >= (index + 3)){ + + uint32_t header::getInt32(size_t index) { + if (datasize >= (index + 3)) { return (data[index] << 24) + (data[index + 1] << 16) + (data[index + 2] << 8) + data[index + 3]; } return 0; } - uint32_t header::getInt24(size_t index){ - if (datasize >= (index + 2)){ + uint32_t header::getInt24(size_t index) { + if (datasize >= (index + 2)) { return 0 + (data[index] << 16) + (data[index + 1] << 8) + data[index + 2]; } return 0; } - uint16_t header::getInt16(size_t index){ - if (datasize >= (index + 1)){ + uint16_t header::getInt16(size_t index) { + if (datasize >= (index + 1)) { return 0 + (data[index] << 8) + data[index + 1]; } return 0; } - uint32_t header::commentLen(size_t index){ - if (datasize >= index + 3){ + uint32_t header::commentLen(size_t index) { + if (datasize >= index + 3) { return data[index] + (data[index + 1] << 8) + (data[index + 2] << 16) + (data[index + 3] << 24); } return 0; } - - header::header(){ + + header::header() { data = NULL; datasize = 0; } - header::header(char * newData, unsigned int length){ + header::header(char * newData, unsigned int length) { data = NULL; datasize = 0; read(newData, length); } - bool header::validateIdentificationHeader(){ - if (datasize != 42){return false;} - if (getHeaderType() != 0){return false;} - if (getVMAJ() != 3){return false;} - if (getVMIN() != 2){return false;} - if (getFMBW() == 0){return false;} - if (getFMBH() == 0){return false;} - if ((short)getPICW() > getFMBW() * 16){return false;} - if ((short)getPICH() > getFMBH() * 16){return false;} - if ((short)getPICX() > (getFMBW() * 16) - (short)getPICW()){return false;} - if ((short)getPICY() > (getFMBH() * 16) - (short)getPICH()){return false;} - if (getFRN() == 0){return false;} - if (getFRD() == 0){return false;} + bool header::validateIdentificationHeader() { + if (datasize != 42) { + return false; + } + if (getHeaderType() != 0) { + return false; + } + if (getVMAJ() != 3) { + return false; + } + if (getVMIN() != 2) { + return false; + } + if (getFMBW() == 0) { + return false; + } + if (getFMBH() == 0) { + return false; + } + if ((short)getPICW() > getFMBW() * 16) { + return false; + } + if ((short)getPICH() > getFMBH() * 16) { + return false; + } + if ((short)getPICX() > (getFMBW() * 16) - (short)getPICW()) { + return false; + } + if ((short)getPICY() > (getFMBH() * 16) - (short)getPICH()) { + return false; + } + if (getFRN() == 0) { + return false; + } + if (getFRD() == 0) { + return false; + } return true; } - - bool header::read(char* newData, unsigned int length){ - if (length < 7){ + + bool header::read(char * newData, unsigned int length) { + if (length < 7) { return false; } - if (! (newData[0] & 0x80)){ + if (!(newData[0] & 0x80)) { return false; } - if(memcmp(newData+1, "theora", 6)!=0){ + if (memcmp(newData + 1, "theora", 6) != 0) { return false; } - if (checkDataSize(length)){ + if (checkDataSize(length)) { memcpy(data, newData, length); - }else{ + } else { return false; } - switch(getHeaderType()){ + switch (getHeaderType()) { case 0: return validateIdentificationHeader(); break; @@ -103,225 +127,273 @@ namespace theora{ } return true; } - - int header::getHeaderType(){ + + int header::getHeaderType() { return (data[0] & 0x7F); } - char header::getVMAJ(){ - if (getHeaderType() == 0){return data[7];} + char header::getVMAJ() { + if (getHeaderType() == 0) { + return data[7]; + } return 0; } - char header::getVMIN(){ - if (getHeaderType() == 0){return data[8];} + char header::getVMIN() { + if (getHeaderType() == 0) { + return data[8]; + } return 0; } - char header::getVREV(){ - if (getHeaderType() == 0){return data[9];} + char header::getVREV() { + if (getHeaderType() == 0) { + return data[9]; + } return 0; } - short header::getFMBW(){ - if (getHeaderType() == 0){return getInt16(10);} + short header::getFMBW() { + if (getHeaderType() == 0) { + return getInt16(10); + } return 0; } - short header::getFMBH(){ - if (getHeaderType() == 0){return getInt16(12);} + short header::getFMBH() { + if (getHeaderType() == 0) { + return getInt16(12); + } return 0; } - char header::getPICX(){ - if (getHeaderType() == 0){return data[20];} + char header::getPICX() { + if (getHeaderType() == 0) { + return data[20]; + } return 0; } - char header::getPICY(){ - if (getHeaderType() == 0){return data[21];} - return 0; - } - - char header::getKFGShift(){ - if (getHeaderType() == 0){return (getInt16(40) >> 5) & 0x1F;} - return 0; - } - - long unsigned int header::getFRN(){ - if (getHeaderType() == 0){return getInt32(22);} - return 0; - } - - long unsigned int header::getPICH(){ - if (getHeaderType() == 0){return getInt24(17);} - return 0; - } - - long unsigned int header::getPICW(){ - if (getHeaderType() == 0){return getInt24(14);} - return 0; - } - - long unsigned int header::getFRD(){ - if (getHeaderType() == 0){return getInt32(26);} + char header::getPICY() { + if (getHeaderType() == 0) { + return data[21]; + } return 0; } - long unsigned int header::getPARN(){ - if (getHeaderType() == 0){return getInt24(30);} + char header::getKFGShift() { + if (getHeaderType() == 0) { + return (getInt16(40) >> 5) & 0x1F; + } return 0; } - long unsigned int header::getPARD(){ - if (getHeaderType() == 0){return getInt24(33);} + long unsigned int header::getFRN() { + if (getHeaderType() == 0) { + return getInt32(22); + } return 0; } - char header::getCS(){ - if (getHeaderType() == 0){return data[36];} + long unsigned int header::getPICH() { + if (getHeaderType() == 0) { + return getInt24(17); + } return 0; } - long unsigned int header::getNOMBR(){ - if (getHeaderType() == 0){return getInt24(37);} + long unsigned int header::getPICW() { + if (getHeaderType() == 0) { + return getInt24(14); + } return 0; } - char header::getQUAL(){ - if (getHeaderType() == 0){return (data[40] >> 3) & 0x1F;} + long unsigned int header::getFRD() { + if (getHeaderType() == 0) { + return getInt32(26); + } return 0; } - char header::getPF(){ - if (getHeaderType() == 0){return (data[41] >> 3) & 0x03;} + long unsigned int header::getPARN() { + if (getHeaderType() == 0) { + return getInt24(30); + } return 0; } - std::string header::getVendor(){ - if (getHeaderType() != 1){return "";} + long unsigned int header::getPARD() { + if (getHeaderType() == 0) { + return getInt24(33); + } + return 0; + } + + char header::getCS() { + if (getHeaderType() == 0) { + return data[36]; + } + return 0; + } + + long unsigned int header::getNOMBR() { + if (getHeaderType() == 0) { + return getInt24(37); + } + return 0; + } + + char header::getQUAL() { + if (getHeaderType() == 0) { + return (data[40] >> 3) & 0x1F; + } + return 0; + } + + char header::getPF() { + if (getHeaderType() == 0) { + return (data[41] >> 3) & 0x03; + } + return 0; + } + + std::string header::getVendor() { + if (getHeaderType() != 1) { + return ""; + } return std::string(data + 11, commentLen(7)); } - long unsigned int header::getNComments(){ - if (getHeaderType() != 1){return 0;} + long unsigned int header::getNComments() { + if (getHeaderType() != 1) { + return 0; + } int offset = 11 + commentLen(7); return commentLen(offset); } - char header::getLFLIMS(size_t index){ - if (getHeaderType() != 2){return 0;} - if (index >= 64){return 0;} + char header::getLFLIMS(size_t index) { + if (getHeaderType() != 2) { + return 0; + } + if (index >= 64) { + return 0; + } char NBITS = (data[0] >> 5) & 0x07; return NBITS; } - std::string header::getUserComment(size_t index){ - if (index >= getNComments()){return "";} + std::string header::getUserComment(size_t index) { + if (index >= getNComments()) { + return ""; + } int offset = 11 + commentLen(7) + 4; - for (size_t i = 0; i < index; i++){ + for (size_t i = 0; i < index; i++) { offset += 4 + commentLen(offset); } - return std::string(data + offset + 4,commentLen(offset)); + return std::string(data + offset + 4, commentLen(offset)); } - std::string header::toPrettyString(size_t indent){ + std::string header::toPrettyString(size_t indent) { std::stringstream result; - result << std::string(indent,' ') << "Theora header" << std::endl; - result << std::string(indent+2,' ') << "HeaderType: " << getHeaderType() << std::endl; - switch (getHeaderType()){ + result << std::string(indent, ' ') << "Theora header" << std::endl; + result << std::string(indent + 2, ' ') << "HeaderType: " << getHeaderType() << std::endl; + switch (getHeaderType()) { case 0: - result << std::string(indent+2,' ') << "VMAJ: " << (int)getVMAJ() << std::endl; - result << std::string(indent+2,' ') << "VMIN: " << (int)getVMIN() << std::endl; - result << std::string(indent+2,' ') << "VREV: " << (int)getVREV() << std::endl; - result << std::string(indent+2,' ') << "FMBW: " << getFMBW() << std::endl; - result << std::string(indent+2,' ') << "FMBH: " << getFMBH() << std::endl; - result << std::string(indent+2,' ') << "PICH: " << getPICH() << std::endl; - result << std::string(indent+2,' ') << "PICW: " << getPICW() << std::endl; - result << std::string(indent+2,' ') << "PICX: " << (int)getPICX() << std::endl; - result << std::string(indent+2,' ') << "PICY: " << (int)getPICY() << std::endl; - result << std::string(indent+2,' ') << "FRN: " << getFRN() << std::endl; - result << std::string(indent+2,' ') << "FRD: " << getFRD() << std::endl; - result << std::string(indent+2,' ') << "PARN: " << getPARN() << std::endl; - result << std::string(indent+2,' ') << "PARD: " << getPARD() << std::endl; - result << std::string(indent+2,' ') << "CS: " << (int)getCS() << std::endl; - result << std::string(indent+2,' ') << "NOMBR: " << getNOMBR() << std::endl; - result << std::string(indent+2,' ') << "QUAL: " << (int)getQUAL() << std::endl; - result << std::string(indent+2,' ') << "KFGShift: " << (int)getKFGShift() << std::endl; + result << std::string(indent + 2, ' ') << "VMAJ: " << (int)getVMAJ() << std::endl; + result << std::string(indent + 2, ' ') << "VMIN: " << (int)getVMIN() << std::endl; + result << std::string(indent + 2, ' ') << "VREV: " << (int)getVREV() << std::endl; + result << std::string(indent + 2, ' ') << "FMBW: " << getFMBW() << std::endl; + result << std::string(indent + 2, ' ') << "FMBH: " << getFMBH() << std::endl; + result << std::string(indent + 2, ' ') << "PICH: " << getPICH() << std::endl; + result << std::string(indent + 2, ' ') << "PICW: " << getPICW() << std::endl; + result << std::string(indent + 2, ' ') << "PICX: " << (int)getPICX() << std::endl; + result << std::string(indent + 2, ' ') << "PICY: " << (int)getPICY() << std::endl; + result << std::string(indent + 2, ' ') << "FRN: " << getFRN() << std::endl; + result << std::string(indent + 2, ' ') << "FRD: " << getFRD() << std::endl; + result << std::string(indent + 2, ' ') << "PARN: " << getPARN() << std::endl; + result << std::string(indent + 2, ' ') << "PARD: " << getPARD() << std::endl; + result << std::string(indent + 2, ' ') << "CS: " << (int)getCS() << std::endl; + result << std::string(indent + 2, ' ') << "NOMBR: " << getNOMBR() << std::endl; + result << std::string(indent + 2, ' ') << "QUAL: " << (int)getQUAL() << std::endl; + result << std::string(indent + 2, ' ') << "KFGShift: " << (int)getKFGShift() << std::endl; break; case 1: - result << std::string(indent+2,' ') << "Vendor: " << getVendor() << std::endl; - result << std::string(indent+2,' ') << "User Comments (" << getNComments() << "):" << std::endl; - for (long unsigned int i = 0; i < getNComments(); i++){ - result << std::string(indent+4,' ') << "[" << i << "] " << getUserComment(i) << std::endl; + result << std::string(indent + 2, ' ') << "Vendor: " << getVendor() << std::endl; + result << std::string(indent + 2, ' ') << "User Comments (" << getNComments() << "):" << std::endl; + for (long unsigned int i = 0; i < getNComments(); i++) { + result << std::string(indent + 4, ' ') << "[" << i << "] " << getUserComment(i) << std::endl; } break; case 2: - result << std::string(indent+2,' ') << "NBITS: " << (int)getLFLIMS(0) << std::endl; + result << std::string(indent + 2, ' ') << "NBITS: " << (int)getLFLIMS(0) << std::endl; } return result.str(); } - frame::frame(){ + frame::frame() { data = NULL; datasize = 0; } - bool frame::checkDataSize(unsigned int size){ - if (size > datasize){ - void* tmp = realloc(data,size); - if (tmp){ - data = (char*)tmp; + bool frame::checkDataSize(unsigned int size) { + if (size > datasize) { + void * tmp = realloc(data, size); + if (tmp) { + data = (char *)tmp; datasize = size; return true; - }else{ + } else { return false; } - }else{ + } else { return true; } } - bool frame::read(char* newData, unsigned int length){ - if (length < 7){ + bool frame::read(char * newData, unsigned int length) { + if (length < 7) { return false; } - if ((newData[0] & 0x80)){ + if ((newData[0] & 0x80)) { return false; } - if (checkDataSize(length)){ + if (checkDataSize(length)) { memcpy(data, newData, length); - }else{ + } else { return false; } return true; } - char frame::getFTYPE(){ + char frame::getFTYPE() { return (data[0] >> 6) & 0x01; } - char frame::getNQIS(){ + char frame::getNQIS() { return 0; } - char frame::getQIS(size_t index){ - if (index >= 3){return 0;} + char frame::getQIS(size_t index) { + if (index >= 3) { + return 0; + } return 0; } - long long unsigned int header::parseGranuleUpper(long long unsigned int granPos){ + long long unsigned int header::parseGranuleUpper(long long unsigned int granPos) { return granPos >> getKFGShift(); } - long long unsigned int header::parseGranuleLower(long long unsigned int granPos){ + long long unsigned int header::parseGranuleLower(long long unsigned int granPos) { return (granPos & ((1 << getKFGShift()) - 1)); } - std::string frame::toPrettyString(size_t indent){ + std::string frame::toPrettyString(size_t indent) { std::stringstream result; - result << std::string(indent,' ') << "Theora Frame" << std::endl; - result << std::string(indent+2,' ') << "FType: " << (int)getFTYPE() << std::endl; + result << std::string(indent, ' ') << "Theora Frame" << std::endl; + result << std::string(indent + 2, ' ') << "FType: " << (int)getFTYPE() << std::endl; return result.str(); } } diff --git a/lib/theora.h b/lib/theora.h index 5468dbca..a5f04786 100644 --- a/lib/theora.h +++ b/lib/theora.h @@ -3,12 +3,12 @@ #include #include -namespace theora{ - class header{ +namespace theora { + class header { public: header(); - header(char* newData, unsigned int length); - bool read(char* newData, unsigned int length); + header(char * newData, unsigned int length); + bool read(char * newData, unsigned int length); int getHeaderType(); char getVMAJ(); char getVMIN(); @@ -41,16 +41,16 @@ namespace theora{ uint16_t getInt16(size_t index); uint32_t commentLen(size_t index); private: - char* data; + char * data; unsigned int datasize; bool checkDataSize(unsigned int size); bool validateIdentificationHeader(); }; - class frame{ + class frame { public: frame(); - bool read(char* newData, unsigned int length); + bool read(char * newData, unsigned int length); char getFTYPE(); char getNQIS(); char getQIS(size_t index); diff --git a/lib/timing.cpp b/lib/timing.cpp index 6185603f..de51e3e1 100644 --- a/lib/timing.cpp +++ b/lib/timing.cpp @@ -11,7 +11,7 @@ #include #define CLOCK_REALTIME CALENDAR_CLOCK #define CLOCK_MONOTONIC SYSTEM_CLOCK -void clock_gettime(int ign, struct timespec * ts){ +void clock_gettime(int ign, struct timespec * ts) { clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), ign, &cclock); @@ -23,53 +23,53 @@ void clock_gettime(int ign, struct timespec * ts){ #endif /// Sleeps for the indicated amount of milliseconds or longer. -void Util::sleep(int ms){ - if (ms < 0){ +void Util::sleep(int ms) { + if (ms < 0) { return; } - if (ms > 100000){ + if (ms > 100000) { ms = 100000; } struct timespec T; T.tv_sec = ms / 1000; T.tv_nsec = 1000000 * (ms % 1000); - nanosleep( &T, 0); + nanosleep(&T, 0); } -long long Util::getNTP(){ +long long Util::getNTP() { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); - return ((((long long int)t.tv_sec) + 2208988800) << 32) + (t.tv_nsec*4.2949); + return ((((long long int)t.tv_sec) + 2208988800) << 32) + (t.tv_nsec * 4.2949); } /// Gets the current time in milliseconds. -long long int Util::getMS(){ +long long int Util::getMS() { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); return ((long long int)t.tv_sec) * 1000 + t.tv_nsec / 1000000; } -long long int Util::bootSecs(){ +long long int Util::bootSecs() { struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); return t.tv_sec; } /// Gets the current time in microseconds. -long long unsigned int Util::getMicros(){ +long long unsigned int Util::getMicros() { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); return ((long long unsigned int)t.tv_sec) * 1000000 + t.tv_nsec / 1000; } /// Gets the time difference in microseconds. -long long unsigned int Util::getMicros(long long unsigned int previous){ +long long unsigned int Util::getMicros(long long unsigned int previous) { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); return ((long long unsigned int)t.tv_sec) * 1000000 + t.tv_nsec / 1000 - previous; } /// Gets the amount of seconds since 01/01/1970. -long long int Util::epoch(){ +long long int Util::epoch() { return time(0); } diff --git a/lib/tinythread.cpp b/lib/tinythread.cpp index 98421ea4..fed3b63f 100644 --- a/lib/tinythread.cpp +++ b/lib/tinythread.cpp @@ -25,10 +25,10 @@ freely, subject to the following restrictions: #include "tinythread.h" #if defined(_TTHREAD_POSIX_) - #include - #include +#include +#include #elif defined(_TTHREAD_WIN32_) - #include +#include #endif @@ -49,74 +49,69 @@ namespace tthread { //------------------------------------------------------------------------------ #if defined(_TTHREAD_WIN32_) - #define _CONDITION_EVENT_ONE 0 - #define _CONDITION_EVENT_ALL 1 +#define _CONDITION_EVENT_ONE 0 +#define _CONDITION_EVENT_ALL 1 #endif #if defined(_TTHREAD_WIN32_) -condition_variable::condition_variable() : mWaitersCount(0) -{ - mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); - mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); - InitializeCriticalSection(&mWaitersCountLock); -} + condition_variable::condition_variable() : mWaitersCount(0) { + mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + InitializeCriticalSection(&mWaitersCountLock); + } #endif #if defined(_TTHREAD_WIN32_) -condition_variable::~condition_variable() -{ - CloseHandle(mEvents[_CONDITION_EVENT_ONE]); - CloseHandle(mEvents[_CONDITION_EVENT_ALL]); - DeleteCriticalSection(&mWaitersCountLock); -} + condition_variable::~condition_variable() { + CloseHandle(mEvents[_CONDITION_EVENT_ONE]); + CloseHandle(mEvents[_CONDITION_EVENT_ALL]); + DeleteCriticalSection(&mWaitersCountLock); + } #endif #if defined(_TTHREAD_WIN32_) -void condition_variable::_wait() -{ - // Wait for either event to become signaled due to notify_one() or - // notify_all() being called - int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE); + void condition_variable::_wait() { + // Wait for either event to become signaled due to notify_one() or + // notify_all() being called + int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE); - // Check if we are the last waiter - EnterCriticalSection(&mWaitersCountLock); - -- mWaitersCount; - bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && - (mWaitersCount == 0); - LeaveCriticalSection(&mWaitersCountLock); + // Check if we are the last waiter + EnterCriticalSection(&mWaitersCountLock); + -- mWaitersCount; + bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (mWaitersCount == 0); + LeaveCriticalSection(&mWaitersCountLock); - // If we are the last waiter to be notified to stop waiting, reset the event - if(lastWaiter) - ResetEvent(mEvents[_CONDITION_EVENT_ALL]); -} + // If we are the last waiter to be notified to stop waiting, reset the event + if (lastWaiter) + ResetEvent(mEvents[_CONDITION_EVENT_ALL]); + } #endif #if defined(_TTHREAD_WIN32_) -void condition_variable::notify_one() -{ - // Are there any waiters? - EnterCriticalSection(&mWaitersCountLock); - bool haveWaiters = (mWaitersCount > 0); - LeaveCriticalSection(&mWaitersCountLock); + void condition_variable::notify_one() { + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); - // If we have any waiting threads, send them a signal - if(haveWaiters) - SetEvent(mEvents[_CONDITION_EVENT_ONE]); -} + // If we have any waiting threads, send them a signal + if (haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ONE]); + } #endif #if defined(_TTHREAD_WIN32_) -void condition_variable::notify_all() -{ - // Are there any waiters? - EnterCriticalSection(&mWaitersCountLock); - bool haveWaiters = (mWaitersCount > 0); - LeaveCriticalSection(&mWaitersCountLock); + void condition_variable::notify_all() { + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); - // If we have any waiting threads, send them a signal - if(haveWaiters) - SetEvent(mEvents[_CONDITION_EVENT_ALL]); -} + // If we have any waiting threads, send them a signal + if (haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ALL]); + } #endif @@ -128,17 +123,16 @@ void condition_variable::notify_all() //------------------------------------------------------------------------------ #if defined(_TTHREAD_POSIX_) -static thread::id _pthread_t_to_ID(const pthread_t &aHandle) -{ - static mutex idMapLock; - static std::map idMap; - static unsigned long int idCount(1); + static thread::id _pthread_t_to_ID(const pthread_t & aHandle) { + static mutex idMapLock; + static std::map idMap; + static unsigned long int idCount(1); - lock_guard guard(idMapLock); - if(idMap.find(aHandle) == idMap.end()) - idMap[aHandle] = idCount ++; - return thread::id(idMap[aHandle]); -} + lock_guard guard(idMapLock); + if (idMap.find(aHandle) == idMap.end()) + idMap[aHandle] = idCount ++; + return thread::id(idMap[aHandle]); + } #endif // _TTHREAD_POSIX_ @@ -147,165 +141,151 @@ static thread::id _pthread_t_to_ID(const pthread_t &aHandle) //------------------------------------------------------------------------------ /// Information to pass to the new thread (what to run). -struct _thread_start_info { - void (*mFunction)(void *); ///< Pointer to the function to be executed. - void * mArg; ///< Function argument for the thread function. - thread * mThread; ///< Pointer to the thread object. -}; + struct _thread_start_info { + void (*mFunction)(void *); ///< Pointer to the function to be executed. + void * mArg; ///< Function argument for the thread function. + thread * mThread; ///< Pointer to the thread object. + }; // Thread wrapper function. #if defined(_TTHREAD_WIN32_) -unsigned WINAPI thread::wrapper_function(void * aArg) + unsigned WINAPI thread::wrapper_function(void * aArg) #elif defined(_TTHREAD_POSIX_) -void * thread::wrapper_function(void * aArg) + void * thread::wrapper_function(void * aArg) #endif -{ - // Get thread startup information - _thread_start_info * ti = (_thread_start_info *) aArg; - - try { - // Call the actual client thread function - ti->mFunction(ti->mArg); - } - catch(...) - { - // Uncaught exceptions will terminate the application (default behavior - // according to C++11) - std::terminate(); - } + // Get thread startup information + _thread_start_info * ti = (_thread_start_info *) aArg; - // The thread is no longer executing - if (ti->mThread){ - lock_guard guard(ti->mThread->mDataMutex); - ti->mThread->mNotAThread = true; - ti->mThread->ti_copy = 0; - } + try { + // Call the actual client thread function + ti->mFunction(ti->mArg); + } catch (...) { + // Uncaught exceptions will terminate the application (default behavior + // according to C++11) + std::terminate(); + } - // The thread is responsible for freeing the startup information - delete ti; + // The thread is no longer executing + if (ti->mThread) { + lock_guard guard(ti->mThread->mDataMutex); + ti->mThread->mNotAThread = true; + ti->mThread->ti_copy = 0; + } - return 0; -} - -thread::thread(void (*aFunction)(void *), void * aArg) -{ - // Serialize access to this thread structure - lock_guard guard(mDataMutex); - - // Fill out the thread startup information (passed to the thread wrapper, - // which will eventually free it) - _thread_start_info * ti = new _thread_start_info; - ti_copy = ti; - ti->mFunction = aFunction; - ti->mArg = aArg; - ti->mThread = this; - - // The thread is now alive - mNotAThread = false; - - // Create the thread -#if defined(_TTHREAD_WIN32_) - mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID); -#elif defined(_TTHREAD_POSIX_) - if(pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0) - mHandle = 0; -#endif - - // Did we fail to create the thread? - if(!mHandle) - { - mNotAThread = true; - ti_copy = 0; + // The thread is responsible for freeing the startup information delete ti; - } -} -thread::~thread() -{ - if (ti_copy){ - ((_thread_start_info *)ti_copy)->mThread = 0; + return 0; } - if(joinable()) - std::terminate(); -} -void thread::join() -{ - if(joinable()) - { + thread::thread(void (*aFunction)(void *), void * aArg) { + // Serialize access to this thread structure + lock_guard guard(mDataMutex); + + // Fill out the thread startup information (passed to the thread wrapper, + // which will eventually free it) + _thread_start_info * ti = new _thread_start_info; + ti_copy = ti; + ti->mFunction = aFunction; + ti->mArg = aArg; + ti->mThread = this; + + // The thread is now alive + mNotAThread = false; + + // Create the thread #if defined(_TTHREAD_WIN32_) - WaitForSingleObject(mHandle, INFINITE); - CloseHandle(mHandle); + mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID); #elif defined(_TTHREAD_POSIX_) - pthread_join(mHandle, NULL); + if (pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0) + mHandle = 0; +#endif + + // Did we fail to create the thread? + if (!mHandle) { + mNotAThread = true; + ti_copy = 0; + delete ti; + } + } + + thread::~thread() { + if (ti_copy) { + ((_thread_start_info *)ti_copy)->mThread = 0; + } + if (joinable()) + std::terminate(); + } + + void thread::join() { + if (joinable()) { +#if defined(_TTHREAD_WIN32_) + WaitForSingleObject(mHandle, INFINITE); + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_join(mHandle, NULL); +#endif + } + } + + bool thread::joinable() const { + mDataMutex.lock(); + bool result = !mNotAThread; + mDataMutex.unlock(); + return result; + } + + void thread::detach() { + mDataMutex.lock(); + if (!mNotAThread) { +#if defined(_TTHREAD_WIN32_) + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_detach(mHandle); +#endif + mNotAThread = true; + } + mDataMutex.unlock(); + } + + thread::id thread::get_id() const { + if (!joinable()) + return id(); +#if defined(_TTHREAD_WIN32_) + return id((unsigned long int) mWin32ThreadID); +#elif defined(_TTHREAD_POSIX_) + return _pthread_t_to_ID(mHandle); #endif } -} -bool thread::joinable() const -{ - mDataMutex.lock(); - bool result = !mNotAThread; - mDataMutex.unlock(); - return result; -} - -void thread::detach() -{ - mDataMutex.lock(); - if(!mNotAThread) - { + unsigned thread::hardware_concurrency() { #if defined(_TTHREAD_WIN32_) - CloseHandle(mHandle); -#elif defined(_TTHREAD_POSIX_) - pthread_detach(mHandle); -#endif - mNotAThread = true; - } - mDataMutex.unlock(); -} - -thread::id thread::get_id() const -{ - if(!joinable()) - return id(); -#if defined(_TTHREAD_WIN32_) - return id((unsigned long int) mWin32ThreadID); -#elif defined(_TTHREAD_POSIX_) - return _pthread_t_to_ID(mHandle); -#endif -} - -unsigned thread::hardware_concurrency() -{ -#if defined(_TTHREAD_WIN32_) - SYSTEM_INFO si; - GetSystemInfo(&si); - return (int) si.dwNumberOfProcessors; + SYSTEM_INFO si; + GetSystemInfo(&si); + return (int) si.dwNumberOfProcessors; #elif defined(_SC_NPROCESSORS_ONLN) - return (int) sysconf(_SC_NPROCESSORS_ONLN); + return (int) sysconf(_SC_NPROCESSORS_ONLN); #elif defined(_SC_NPROC_ONLN) - return (int) sysconf(_SC_NPROC_ONLN); + return (int) sysconf(_SC_NPROC_ONLN); #else - // The standard requires this function to return zero if the number of - // hardware cores could not be determined. - return 0; + // The standard requires this function to return zero if the number of + // hardware cores could not be determined. + return 0; #endif -} + } //------------------------------------------------------------------------------ // this_thread //------------------------------------------------------------------------------ -thread::id this_thread::get_id() -{ + thread::id this_thread::get_id() { #if defined(_TTHREAD_WIN32_) - return thread::id((unsigned long int) GetCurrentThreadId()); + return thread::id((unsigned long int) GetCurrentThreadId()); #elif defined(_TTHREAD_POSIX_) - return _pthread_t_to_ID(pthread_self()); + return _pthread_t_to_ID(pthread_self()); #endif -} + } } diff --git a/lib/tinythread.h b/lib/tinythread.h index e3902dd3..fdee215f 100644 --- a/lib/tinythread.h +++ b/lib/tinythread.h @@ -57,30 +57,30 @@ freely, subject to the following restrictions: // Which platform are we on? #if !defined(_TTHREAD_PLATFORM_DEFINED_) - #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) - #define _TTHREAD_WIN32_ - #else - #define _TTHREAD_POSIX_ - #endif - #define _TTHREAD_PLATFORM_DEFINED_ +#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) +#define _TTHREAD_WIN32_ +#else +#define _TTHREAD_POSIX_ +#endif +#define _TTHREAD_PLATFORM_DEFINED_ #endif // Platform specific includes #if defined(_TTHREAD_WIN32_) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #define __UNDEF_LEAN_AND_MEAN - #endif - #include - #ifdef __UNDEF_LEAN_AND_MEAN - #undef WIN32_LEAN_AND_MEAN - #undef __UNDEF_LEAN_AND_MEAN - #endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define __UNDEF_LEAN_AND_MEAN +#endif +#include +#ifdef __UNDEF_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef __UNDEF_LEAN_AND_MEAN +#endif #else - #include - #include - #include - #include +#include +#include +#include +#include #endif // Generic includes @@ -95,23 +95,23 @@ freely, subject to the following restrictions: // Do we have a fully featured C++11 compiler? #if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L)) - #define _TTHREAD_CPP11_ +#define _TTHREAD_CPP11_ #endif // ...at least partial C++11? #if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) - #define _TTHREAD_CPP11_PARTIAL_ +#define _TTHREAD_CPP11_PARTIAL_ #endif // Macro for disabling assignments of objects. #ifdef _TTHREAD_CPP11_PARTIAL_ - #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ - name(const name&) = delete; \ - name& operator=(const name&) = delete; +#define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&) = delete; \ + name& operator=(const name&) = delete; #else - #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ - name(const name&); \ - name& operator=(const name&); +#define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&); \ + name& operator=(const name&); #endif /// @def thread_local @@ -136,11 +136,11 @@ freely, subject to the following restrictions: /// @hideinitializer #if !defined(_TTHREAD_CPP11_) && !defined(thread_local) - #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) - #define thread_local __thread - #else - #define thread_local __declspec(thread) - #endif +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) +#define thread_local __thread +#else +#define thread_local __declspec(thread) +#endif #endif @@ -156,91 +156,86 @@ namespace tthread { /// program may deadlock if the thread that owns a mutex object calls lock() /// on that object). /// @see recursive_mutex -class mutex { - public: - /// Constructor. - mutex() + class mutex { + public: + /// Constructor. + mutex() #if defined(_TTHREAD_WIN32_) - : mAlreadyLocked(false) + : mAlreadyLocked(false) #endif - { -#if defined(_TTHREAD_WIN32_) - InitializeCriticalSection(&mHandle); -#else - pthread_mutex_init(&mHandle, NULL); -#endif - } - - /// Destructor. - ~mutex() - { -#if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mHandle); -#else - pthread_mutex_destroy(&mHandle); -#endif - } - - /// Lock the mutex. - /// The method will block the calling thread until a lock on the mutex can - /// be obtained. The mutex remains locked until @c unlock() is called. - /// @see lock_guard - inline void lock() - { -#if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mHandle); - while(mAlreadyLocked) Sleep(1000); // Simulate deadlock... - mAlreadyLocked = true; -#else - pthread_mutex_lock(&mHandle); -#endif - } - - /// Try to lock the mutex. - /// The method will try to lock the mutex. If it fails, the function will - /// return immediately (non-blocking). - /// @return @c true if the lock was acquired, or @c false if the lock could - /// not be acquired. - inline bool try_lock() - { -#if defined(_TTHREAD_WIN32_) - bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); - if(ret && mAlreadyLocked) { - LeaveCriticalSection(&mHandle); - ret = false; +#if defined(_TTHREAD_WIN32_) + InitializeCriticalSection(&mHandle); +#else + pthread_mutex_init(&mHandle, NULL); +#endif } - return ret; -#else - return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; -#endif - } - /// Unlock the mutex. - /// If any threads are waiting for the lock on this mutex, one of them will - /// be unblocked. - inline void unlock() - { + /// Destructor. + ~mutex() { #if defined(_TTHREAD_WIN32_) - mAlreadyLocked = false; - LeaveCriticalSection(&mHandle); + DeleteCriticalSection(&mHandle); #else - pthread_mutex_unlock(&mHandle); + pthread_mutex_destroy(&mHandle); #endif - } + } - _TTHREAD_DISABLE_ASSIGNMENT(mutex) - - private: + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() { #if defined(_TTHREAD_WIN32_) - CRITICAL_SECTION mHandle; - bool mAlreadyLocked; + EnterCriticalSection(&mHandle); + while (mAlreadyLocked) Sleep(1000); // Simulate deadlock... + mAlreadyLocked = true; #else - pthread_mutex_t mHandle; + pthread_mutex_lock(&mHandle); +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() { +#if defined(_TTHREAD_WIN32_) + bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); + if (ret && mAlreadyLocked) { + LeaveCriticalSection(&mHandle); + ret = false; + } + return ret; +#else + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() { +#if defined(_TTHREAD_WIN32_) + mAlreadyLocked = false; + LeaveCriticalSection(&mHandle); +#else + pthread_mutex_unlock(&mHandle); +#endif + } + + _TTHREAD_DISABLE_ASSIGNMENT(mutex) + + private: +#if defined(_TTHREAD_WIN32_) + CRITICAL_SECTION mHandle; + bool mAlreadyLocked; +#else + pthread_mutex_t mHandle; #endif - friend class condition_variable; -}; + friend class condition_variable; + }; /// Recursive mutex class. /// This is a mutual exclusion object for synchronizing access to shared @@ -248,81 +243,76 @@ class mutex { /// may lock the mutex several times, as long as it unlocks the mutex the same /// number of times). /// @see mutex -class recursive_mutex { - public: - /// Constructor. - recursive_mutex() - { + class recursive_mutex { + public: + /// Constructor. + recursive_mutex() { #if defined(_TTHREAD_WIN32_) - InitializeCriticalSection(&mHandle); + InitializeCriticalSection(&mHandle); #else - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mHandle, &attr); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mHandle, &attr); #endif - } + } - /// Destructor. - ~recursive_mutex() - { + /// Destructor. + ~recursive_mutex() { #if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mHandle); + DeleteCriticalSection(&mHandle); #else - pthread_mutex_destroy(&mHandle); + pthread_mutex_destroy(&mHandle); #endif - } + } - /// Lock the mutex. - /// The method will block the calling thread until a lock on the mutex can - /// be obtained. The mutex remains locked until @c unlock() is called. - /// @see lock_guard - inline void lock() - { + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() { #if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mHandle); + EnterCriticalSection(&mHandle); #else - pthread_mutex_lock(&mHandle); + pthread_mutex_lock(&mHandle); #endif - } + } - /// Try to lock the mutex. - /// The method will try to lock the mutex. If it fails, the function will - /// return immediately (non-blocking). - /// @return @c true if the lock was acquired, or @c false if the lock could - /// not be acquired. - inline bool try_lock() - { + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() { #if defined(_TTHREAD_WIN32_) - return TryEnterCriticalSection(&mHandle) ? true : false; + return TryEnterCriticalSection(&mHandle) ? true : false; #else - return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; #endif - } + } - /// Unlock the mutex. - /// If any threads are waiting for the lock on this mutex, one of them will - /// be unblocked. - inline void unlock() - { + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() { #if defined(_TTHREAD_WIN32_) - LeaveCriticalSection(&mHandle); + LeaveCriticalSection(&mHandle); #else - pthread_mutex_unlock(&mHandle); + pthread_mutex_unlock(&mHandle); #endif - } + } - _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) + _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) - private: + private: #if defined(_TTHREAD_WIN32_) - CRITICAL_SECTION mHandle; + CRITICAL_SECTION mHandle; #else - pthread_mutex_t mHandle; + pthread_mutex_t mHandle; #endif - friend class condition_variable; -}; + friend class condition_variable; + }; /// Lock guard class. /// The constructor locks the mutex, and the destructor unlocks the mutex, so @@ -339,30 +329,28 @@ class recursive_mutex { /// } /// @endcode -template -class lock_guard { - public: - typedef T mutex_type; + template + class lock_guard { + public: + typedef T mutex_type; - lock_guard() : mMutex(0) {} + lock_guard() : mMutex(0) {} - /// The constructor locks the mutex. - explicit lock_guard(mutex_type &aMutex) - { - mMutex = &aMutex; - mMutex->lock(); - } + /// The constructor locks the mutex. + explicit lock_guard(mutex_type & aMutex) { + mMutex = &aMutex; + mMutex->lock(); + } - /// The destructor unlocks the mutex. - ~lock_guard() - { - if(mMutex) - mMutex->unlock(); - } + /// The destructor unlocks the mutex. + ~lock_guard() { + if (mMutex) + mMutex->unlock(); + } - private: - mutex_type * mMutex; -}; + private: + mutex_type * mMutex; + }; /// Condition variable class. /// This is a signalling object for synchronizing the execution flow for @@ -389,323 +377,308 @@ class lock_guard { /// cond.notify_all(); /// } /// @endcode -class condition_variable { - public: - /// Constructor. + class condition_variable { + public: + /// Constructor. #if defined(_TTHREAD_WIN32_) - condition_variable(); + condition_variable(); #else - condition_variable() - { - pthread_cond_init(&mHandle, NULL); - } + condition_variable() { + pthread_cond_init(&mHandle, NULL); + } #endif - /// Destructor. + /// Destructor. #if defined(_TTHREAD_WIN32_) - ~condition_variable(); + ~condition_variable(); #else - ~condition_variable() - { - pthread_cond_destroy(&mHandle); - } + ~condition_variable() { + pthread_cond_destroy(&mHandle); + } #endif - /// Wait for the condition. - /// The function will block the calling thread until the condition variable - /// is woken by @c notify_one(), @c notify_all() or a spurious wake up. - /// @param[in] aMutex A mutex that will be unlocked when the wait operation - /// starts, an locked again as soon as the wait operation is finished. - template - inline void wait(_mutexT &aMutex) - { + /// Wait for the condition. + /// The function will block the calling thread until the condition variable + /// is woken by @c notify_one(), @c notify_all() or a spurious wake up. + /// @param[in] aMutex A mutex that will be unlocked when the wait operation + /// starts, an locked again as soon as the wait operation is finished. + template + inline void wait(_mutexT & aMutex) { #if defined(_TTHREAD_WIN32_) - // Increment number of waiters - EnterCriticalSection(&mWaitersCountLock); - ++ mWaitersCount; - LeaveCriticalSection(&mWaitersCountLock); + // Increment number of waiters + EnterCriticalSection(&mWaitersCountLock); + ++ mWaitersCount; + LeaveCriticalSection(&mWaitersCountLock); - // Release the mutex while waiting for the condition (will decrease - // the number of waiters when done)... - aMutex.unlock(); - _wait(); - aMutex.lock(); + // Release the mutex while waiting for the condition (will decrease + // the number of waiters when done)... + aMutex.unlock(); + _wait(); + aMutex.lock(); #else - pthread_cond_wait(&mHandle, &aMutex.mHandle); + pthread_cond_wait(&mHandle, &aMutex.mHandle); #endif - } + } - /// Notify one thread that is waiting for the condition. - /// If at least one thread is blocked waiting for this condition variable, - /// one will be woken up. - /// @note Only threads that started waiting prior to this call will be - /// woken up. + /// Notify one thread that is waiting for the condition. + /// If at least one thread is blocked waiting for this condition variable, + /// one will be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. #if defined(_TTHREAD_WIN32_) - void notify_one(); + void notify_one(); #else - inline void notify_one() - { - pthread_cond_signal(&mHandle); - } + inline void notify_one() { + pthread_cond_signal(&mHandle); + } #endif - /// Notify all threads that are waiting for the condition. - /// All threads that are blocked waiting for this condition variable will - /// be woken up. - /// @note Only threads that started waiting prior to this call will be - /// woken up. + /// Notify all threads that are waiting for the condition. + /// All threads that are blocked waiting for this condition variable will + /// be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. #if defined(_TTHREAD_WIN32_) - void notify_all(); + void notify_all(); #else - inline void notify_all() - { - pthread_cond_broadcast(&mHandle); - } + inline void notify_all() { + pthread_cond_broadcast(&mHandle); + } #endif - _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) + _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) - private: + private: #if defined(_TTHREAD_WIN32_) - void _wait(); - HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. - unsigned int mWaitersCount; ///< Count of the number of waiters. - CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. + void _wait(); + HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. + unsigned int mWaitersCount; ///< Count of the number of waiters. + CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. #else - pthread_cond_t mHandle; + pthread_cond_t mHandle; #endif -}; + }; /// Thread class. -class thread { - public: + class thread { + public: #if defined(_TTHREAD_WIN32_) - typedef HANDLE native_handle_type; + typedef HANDLE native_handle_type; #else - typedef pthread_t native_handle_type; + typedef pthread_t native_handle_type; #endif - class id; + class id; - /// Default constructor. - /// Construct a @c thread object without an associated thread of execution - /// (i.e. non-joinable). - thread() : mHandle(0), mNotAThread(true) + /// Default constructor. + /// Construct a @c thread object without an associated thread of execution + /// (i.e. non-joinable). + thread() : mHandle(0), mNotAThread(true) #if defined(_TTHREAD_WIN32_) - , mWin32ThreadID(0) + , mWin32ThreadID(0) #endif - {} + {} - /// Thread starting constructor. - /// Construct a @c thread object with a new thread of execution. - /// @param[in] aFunction A function pointer to a function of type: - /// void fun(void * arg) - /// @param[in] aArg Argument to the thread function. - /// @note This constructor is not fully compatible with the standard C++ - /// thread class. It is more similar to the pthread_create() (POSIX) and - /// CreateThread() (Windows) functions. - thread(void (*aFunction)(void *), void * aArg); + /// Thread starting constructor. + /// Construct a @c thread object with a new thread of execution. + /// @param[in] aFunction A function pointer to a function of type: + /// void fun(void * arg) + /// @param[in] aArg Argument to the thread function. + /// @note This constructor is not fully compatible with the standard C++ + /// thread class. It is more similar to the pthread_create() (POSIX) and + /// CreateThread() (Windows) functions. + thread(void (*aFunction)(void *), void * aArg); - /// Destructor. - /// @note If the thread is joinable upon destruction, @c std::terminate() - /// will be called, which terminates the process. It is always wise to do - /// @c join() before deleting a thread object. - ~thread(); + /// Destructor. + /// @note If the thread is joinable upon destruction, @c std::terminate() + /// will be called, which terminates the process. It is always wise to do + /// @c join() before deleting a thread object. + ~thread(); - /// Wait for the thread to finish (join execution flows). - /// After calling @c join(), the thread object is no longer associated with - /// a thread of execution (i.e. it is not joinable, and you may not join - /// with it nor detach from it). - void join(); + /// Wait for the thread to finish (join execution flows). + /// After calling @c join(), the thread object is no longer associated with + /// a thread of execution (i.e. it is not joinable, and you may not join + /// with it nor detach from it). + void join(); - /// Check if the thread is joinable. - /// A thread object is joinable if it has an associated thread of execution. - bool joinable() const; + /// Check if the thread is joinable. + /// A thread object is joinable if it has an associated thread of execution. + bool joinable() const; - /// Detach from the thread. - /// After calling @c detach(), the thread object is no longer assicated with - /// a thread of execution (i.e. it is not joinable). The thread continues - /// execution without the calling thread blocking, and when the thread - /// ends execution, any owned resources are released. - void detach(); + /// Detach from the thread. + /// After calling @c detach(), the thread object is no longer assicated with + /// a thread of execution (i.e. it is not joinable). The thread continues + /// execution without the calling thread blocking, and when the thread + /// ends execution, any owned resources are released. + void detach(); - /// Return the thread ID of a thread object. - id get_id() const; + /// Return the thread ID of a thread object. + id get_id() const; - /// Get the native handle for this thread. - /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this - /// is a @c pthread_t. - inline native_handle_type native_handle() - { - return mHandle; - } + /// Get the native handle for this thread. + /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this + /// is a @c pthread_t. + inline native_handle_type native_handle() { + return mHandle; + } - /// Determine the number of threads which can possibly execute concurrently. - /// This function is useful for determining the optimal number of threads to - /// use for a task. - /// @return The number of hardware thread contexts in the system. - /// @note If this value is not defined, the function returns zero (0). - static unsigned hardware_concurrency(); + /// Determine the number of threads which can possibly execute concurrently. + /// This function is useful for determining the optimal number of threads to + /// use for a task. + /// @return The number of hardware thread contexts in the system. + /// @note If this value is not defined, the function returns zero (0). + static unsigned hardware_concurrency(); - _TTHREAD_DISABLE_ASSIGNMENT(thread) + _TTHREAD_DISABLE_ASSIGNMENT(thread) - private: - native_handle_type mHandle; ///< Thread handle. - mutable mutex mDataMutex; ///< Serializer for access to the thread private data. - bool mNotAThread; ///< True if this object is not a thread of execution. - void * ti_copy; + private: + native_handle_type mHandle; ///< Thread handle. + mutable mutex mDataMutex; ///< Serializer for access to the thread private data. + bool mNotAThread; ///< True if this object is not a thread of execution. + void * ti_copy; #if defined(_TTHREAD_WIN32_) - unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). + unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). #endif - // This is the internal thread wrapper function. + // This is the internal thread wrapper function. #if defined(_TTHREAD_WIN32_) - static unsigned WINAPI wrapper_function(void * aArg); + static unsigned WINAPI wrapper_function(void * aArg); #else - static void * wrapper_function(void * aArg); + static void * wrapper_function(void * aArg); #endif -}; + }; /// Thread ID. /// The thread ID is a unique identifier for each thread. /// @see thread::get_id() -class thread::id { - public: - /// Default constructor. - /// The default constructed ID is that of thread without a thread of - /// execution. - id() : mId(0) {}; + class thread::id { + public: + /// Default constructor. + /// The default constructed ID is that of thread without a thread of + /// execution. + id() : mId(0) {}; - id(unsigned long int aId) : mId(aId) {}; + id(unsigned long int aId) : mId(aId) {}; - id(const id& aId) : mId(aId.mId) {}; + id(const id & aId) : mId(aId.mId) {}; - inline id & operator=(const id &aId) - { - mId = aId.mId; - return *this; - } + inline id & operator=(const id & aId) { + mId = aId.mId; + return *this; + } - inline friend bool operator==(const id &aId1, const id &aId2) - { - return (aId1.mId == aId2.mId); - } + inline friend bool operator==(const id & aId1, const id & aId2) { + return (aId1.mId == aId2.mId); + } - inline friend bool operator!=(const id &aId1, const id &aId2) - { - return (aId1.mId != aId2.mId); - } + inline friend bool operator!=(const id & aId1, const id & aId2) { + return (aId1.mId != aId2.mId); + } - inline friend bool operator<=(const id &aId1, const id &aId2) - { - return (aId1.mId <= aId2.mId); - } + inline friend bool operator<=(const id & aId1, const id & aId2) { + return (aId1.mId <= aId2.mId); + } - inline friend bool operator<(const id &aId1, const id &aId2) - { - return (aId1.mId < aId2.mId); - } + inline friend bool operator<(const id & aId1, const id & aId2) { + return (aId1.mId < aId2.mId); + } - inline friend bool operator>=(const id &aId1, const id &aId2) - { - return (aId1.mId >= aId2.mId); - } + inline friend bool operator>=(const id & aId1, const id & aId2) { + return (aId1.mId >= aId2.mId); + } - inline friend bool operator>(const id &aId1, const id &aId2) - { - return (aId1.mId > aId2.mId); - } + inline friend bool operator>(const id & aId1, const id & aId2) { + return (aId1.mId > aId2.mId); + } - inline friend std::ostream& operator <<(std::ostream &os, const id &obj) - { - os << obj.mId; - return os; - } + inline friend std::ostream & operator <<(std::ostream & os, const id & obj) { + os << obj.mId; + return os; + } - private: - unsigned long int mId; -}; + private: + unsigned long int mId; + }; // Related to - minimal to be able to support chrono. -typedef long long __intmax_t; + typedef long long __intmax_t; /// Minimal implementation of the @c ratio class. This class provides enough /// functionality to implement some basic @c chrono classes. -template <__intmax_t N, __intmax_t D = 1> class ratio { - public: - static double _as_double() { return double(N) / double(D); } -}; - -/// Minimal implementation of the @c chrono namespace. -/// The @c chrono namespace provides types for specifying time intervals. -namespace chrono { - /// Duration template class. This class provides enough functionality to - /// implement @c this_thread::sleep_for(). - template > class duration { - private: - _Rep rep_; + template <__intmax_t N, __intmax_t D = 1> class ratio { public: - typedef _Rep rep; - typedef _Period period; - - /// Construct a duration object with the given duration. - template - explicit duration(const _Rep2& r) : rep_(r) {}; - - /// Return the value of the duration object. - rep count() const - { - return rep_; + static double _as_double() { + return double(N) / double(D); } }; - // Standard duration types. - typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. - typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. - typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. - typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. - typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. - typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. -} +/// Minimal implementation of the @c chrono namespace. +/// The @c chrono namespace provides types for specifying time intervals. + namespace chrono { + /// Duration template class. This class provides enough functionality to + /// implement @c this_thread::sleep_for(). + template > class duration { + private: + _Rep rep_; + public: + typedef _Rep rep; + typedef _Period period; + + /// Construct a duration object with the given duration. + template + explicit duration(const _Rep2 & r) : rep_(r) {}; + + /// Return the value of the duration object. + rep count() const { + return rep_; + } + }; + + // Standard duration types. + typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. + typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. + typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. + typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. + typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. + typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. + } /// The namespace @c this_thread provides methods for dealing with the /// calling thread. -namespace this_thread { - /// Return the thread ID of the calling thread. - thread::id get_id(); + namespace this_thread { + /// Return the thread ID of the calling thread. + thread::id get_id(); - /// Yield execution to another thread. - /// Offers the operating system the opportunity to schedule another thread - /// that is ready to run on the current processor. - inline void yield() - { + /// Yield execution to another thread. + /// Offers the operating system the opportunity to schedule another thread + /// that is ready to run on the current processor. + inline void yield() { #if defined(_TTHREAD_WIN32_) - Sleep(0); + Sleep(0); #else - sched_yield(); + sched_yield(); #endif - } + } - /// Blocks the calling thread for a period of time. - /// @param[in] aTime Minimum time to put the thread to sleep. - /// Example usage: - /// @code - /// // Sleep for 100 milliseconds - /// this_thread::sleep_for(chrono::milliseconds(100)); - /// @endcode - /// @note Supported duration types are: nanoseconds, microseconds, - /// milliseconds, seconds, minutes and hours. - template void sleep_for(const chrono::duration<_Rep, _Period>& aTime) - { + /// Blocks the calling thread for a period of time. + /// @param[in] aTime Minimum time to put the thread to sleep. + /// Example usage: + /// @code + /// // Sleep for 100 milliseconds + /// this_thread::sleep_for(chrono::milliseconds(100)); + /// @endcode + /// @note Supported duration types are: nanoseconds, microseconds, + /// milliseconds, seconds, minutes and hours. + template void sleep_for(const chrono::duration<_Rep, _Period> & aTime) { #if defined(_TTHREAD_WIN32_) - Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); + Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); #else - usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); + usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); #endif + } } -} } diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp old mode 100755 new mode 100644 index 8057cfa9..84c04747 --- a/lib/ts_packet.cpp +++ b/lib/ts_packet.cpp @@ -36,9 +36,9 @@ namespace TS { /// It fills the content with the next 188 bytes int he file. /// \param Data The data to be read into the packet. /// \return true if it was possible to read in a full packet, false otherwise. - bool Packet::FromFile(FILE * data){ + bool Packet::FromFile(FILE * data) { strBuf.resize(188); - if (!fread((void*)strBuf.data(), 188, 1, data)){ + if (!fread((void *)strBuf.data(), 188, 1, data)) { return false; } return true; @@ -577,12 +577,12 @@ namespace TS { ///Gets the payload of this packet, as a raw char array ///\return The payload of this ts packet as a char pointer const char * Packet::getPayload() { - return strBuf.data() + (4 + (AdaptationField( ) > 1 ? AdaptationFieldLen() + 1 : 0)); + return strBuf.data() + (4 + (AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0)); } ///Gets the length of the payload for this apcket ///\return The amount of bytes payload in this packet - int Packet::getPayloadLength(){ + int Packet::getPayloadLength() { return 184 - ((AdaptationField() > 1 ? AdaptationFieldLen() + 1 : 0)); } diff --git a/lib/ts_packet.h b/lib/ts_packet.h old mode 100755 new mode 100644 index 4baa0cb0..14c3d362 --- a/lib/ts_packet.h +++ b/lib/ts_packet.h @@ -162,13 +162,14 @@ namespace TS { //0xF000 = reserved(3) = 7, network pid = 4096 //0x2AB104B2 = CRC32 static char PAT[188] = {0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xB0, 0x0D, 0x00, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x2A, 0xB1, 0x04, - 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; /// A standard Program Mapping Table, as generated by FFMPEG. /// Contains both Audio and Video mappings, works also on video- or audio-only streams. @@ -192,13 +193,14 @@ namespace TS { //0xF000 = reserved(4) = 15, es_info_len = 0 //0x2F44B99B = CRC32 static char PMT[188] = {0x47, 0x50, 0x00, 0x10, 0x00, 0x02, 0xB0, 0x17, 0x00, 0x01, 0xC1, 0x00, 0x00, 0xE1, 0x00, 0xF0, 0x00, 0x1B, 0xE1, 0x00, - 0xF0, 0x00, 0x0F, 0xE1, 0x01, 0xF0, 0x00, 0x2F, 0x44, 0xB9, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + 0xF0, 0x00, 0x0F, 0xE1, 0x01, 0xF0, 0x00, 0x2F, 0x44, 0xB9, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; } //TS namespace diff --git a/lib/vorbis.cpp b/lib/vorbis.cpp index 460429d4..72e66c58 100644 --- a/lib/vorbis.cpp +++ b/lib/vorbis.cpp @@ -10,224 +10,224 @@ #include #include -namespace vorbis{ - long long unsigned int reverseByte16(long long unsigned int input){ +namespace vorbis { + long long unsigned int reverseByte16(long long unsigned int input) { return ((input & 0xFF00) >> 8) | ((input & 0xFF) << 8); } - long long unsigned int reverseByte24(long long unsigned int input){ - return ((input & 0xFF0000) >> 16)| (input & 0xFF00) | ((input & 0xFF) << 16); + long long unsigned int reverseByte24(long long unsigned int input) { + return ((input & 0xFF0000) >> 16) | (input & 0xFF00) | ((input & 0xFF) << 16); } - long long unsigned int reverseByte32(long long unsigned int input){ - return ((input & 0xFF000000) >> 24)| ((input & 0xFF0000) >> 8) | ((input & 0xFF00) << 8) | ((input & 0xFF) << 24); + long long unsigned int reverseByte32(long long unsigned int input) { + return ((input & 0xFF000000) >> 24) | ((input & 0xFF0000) >> 8) | ((input & 0xFF00) << 8) | ((input & 0xFF) << 24); } - header::header(){ + header::header() { data = NULL; datasize = 0; } - header::header(char * newData, unsigned int length){ + header::header(char * newData, unsigned int length) { data = NULL; datasize = 0; read(newData, length); } - - int header::getHeaderType(){ + + int header::getHeaderType() { return (int)(data[0]); } - - long unsigned int header::getVorbisVersion(){ - if (getHeaderType() == 1){ + + long unsigned int header::getVorbisVersion() { + if (getHeaderType() == 1) { return getInt32(7); - }else{ + } else { return 0; } } - - char header::getAudioChannels(){ - if (getHeaderType() == 1){ + + char header::getAudioChannels() { + if (getHeaderType() == 1) { return data[11]; - }else{ + } else { return 0; } } - - long unsigned int header::getAudioSampleRate(){ - if (getHeaderType() == 1){ + + long unsigned int header::getAudioSampleRate() { + if (getHeaderType() == 1) { return ntohl(getInt32(12)); - }else{ + } else { return 0; } } - - long unsigned int header::getBitrateMaximum(){ - if (getHeaderType() == 1){ + + long unsigned int header::getBitrateMaximum() { + if (getHeaderType() == 1) { return getInt32(16); - }else{ + } else { return 0; } } - - long unsigned int header::getBitrateNominal(){ - if (getHeaderType() == 1){ + + long unsigned int header::getBitrateNominal() { + if (getHeaderType() == 1) { return getInt32(20); - }else{ + } else { return 0; } } - - long unsigned int header::getBitrateMinimum(){ - if (getHeaderType() == 1){ + + long unsigned int header::getBitrateMinimum() { + if (getHeaderType() == 1) { return getInt32(24); - }else{ + } else { return 0; } } - - char header::getBlockSize0(){ - if (getHeaderType() == 1){ + + char header::getBlockSize0() { + if (getHeaderType() == 1) { return data[28] & 0x0F; - }else{ + } else { return 0; } } - char header::getBlockSize1(){ - if (getHeaderType() == 1){ - return (data[28]>>4) & 0x0F; - }else{ + char header::getBlockSize1() { + if (getHeaderType() == 1) { + return (data[28] >> 4) & 0x0F; + } else { return 0; } } - - char header::getFramingFlag(){ - if (getHeaderType() == 1){ + + char header::getFramingFlag() { + if (getHeaderType() == 1) { return data[29]; - }else{ + } else { return 0; } } - - bool header::checkDataSize(unsigned int size){ - if (size > datasize){ - void* tmp = realloc(data,size); - if (tmp){ - data = (char*)tmp; + + bool header::checkDataSize(unsigned int size) { + if (size > datasize) { + void * tmp = realloc(data, size); + if (tmp) { + data = (char *)tmp; datasize = size; return true; - }else{ + } else { return false; } - }else{ + } else { return true; } } - bool header::validate(){ - switch(getHeaderType()){ + bool header::validate() { + switch (getHeaderType()) { case 1://ID header - if (datasize!=30){ + if (datasize != 30) { return false; } - if (getVorbisVersion()!=0){ + if (getVorbisVersion() != 0) { return false; } - if (getAudioChannels()<=0){ + if (getAudioChannels() <= 0) { return false; }; - if (getAudioSampleRate()<=0) { + if (getAudioSampleRate() <= 0) { return false; } - if (getBlockSize0()>getBlockSize1()){ + if (getBlockSize0() > getBlockSize1()) { return false; }; - if (getFramingFlag()!=1){ + if (getFramingFlag() != 1) { return false; }; - break; + break; case 3://comment header - break; + break; case 5://init header - break; + break; default: return false; - break; + break; } return true; } - bool header::read(char* newData, unsigned int length){ - if (length < 7){ + bool header::read(char * newData, unsigned int length) { + if (length < 7) { return false; } - if(memcmp(newData+1, "vorbis", 6)!=0){ + if (memcmp(newData + 1, "vorbis", 6) != 0) { return false; } - if (checkDataSize(length)){ + if (checkDataSize(length)) { memcpy(data, newData, length); - }else{ + } else { return false; } return true; } - - std::deque header::readModeDeque(char audioChannels){ + + std::deque header::readModeDeque(char audioChannels) { Utils::bitstreamLSBF stream; - stream.append(data,datasize); + stream.append(data, datasize); stream.skip(28); //skipping common header part stream.skip(28); //skipping common header part char codebook_count = stream.get(8) + 1; - for (int i = 0; i < codebook_count; i++){ + for (int i = 0; i < codebook_count; i++) { long long unsigned int CMN = stream.get(24); - if (CMN != 0x564342){ - DEBUG_MSG(DLVL_WARN,"Is dit het? VCB != %c%c%c", (char)(CMN >> 16), (char)(CMN >> 8), (char)CMN); + if (CMN != 0x564342) { + DEBUG_MSG(DLVL_WARN, "Is dit het? VCB != %c%c%c", (char)(CMN >> 16), (char)(CMN >> 8), (char)CMN); exit(1); } unsigned short codebook_dimensions = stream.get(16); unsigned int codebook_entries = stream.get(24); bool orderedFlag = stream.get(1); - if (!orderedFlag){ + if (!orderedFlag) { bool sparseFlag = stream.get(1); - if (sparseFlag){//sparse flag + if (sparseFlag) { //sparse flag //sparse handling - for (unsigned int o = 0; o < codebook_entries; o++){ - if (stream.get(1)){ + for (unsigned int o = 0; o < codebook_entries; o++) { + if (stream.get(1)) { stream.skip(5); } } - }else{ - for (unsigned int o = 0; o < codebook_entries; o++){ + } else { + for (unsigned int o = 0; o < codebook_entries; o++) { stream.skip(5); } } - }else{ + } else { //ordered handling stream.skip(5); - for (unsigned int o = 0; o < codebook_entries; o++){ - int readnow = (std::log(codebook_entries-o))/(std::log(2))+1; - o+=stream.get(readnow); - + for (unsigned int o = 0; o < codebook_entries; o++) { + int readnow = (std::log(codebook_entries - o)) / (std::log(2)) + 1; + o += stream.get(readnow); + } } char codebook_lookup_type = stream.get(4); - if (codebook_lookup_type != 0){ + if (codebook_lookup_type != 0) { stream.skip(32); stream.skip(32); char codebook_value_bits = stream.get(4) + 1; stream.skip(1); unsigned int codebook_lookup_value; - if (codebook_lookup_type == 1){ - codebook_lookup_value = std::pow(codebook_entries, (1.0/codebook_dimensions)); - }else{ + if (codebook_lookup_type == 1) { + codebook_lookup_value = std::pow(codebook_entries, (1.0 / codebook_dimensions)); + } else { codebook_lookup_value = codebook_entries * codebook_dimensions; } - for (unsigned int i = 0; i < codebook_lookup_value; i++){ + for (unsigned int i = 0; i < codebook_lookup_value; i++) { stream.skip(codebook_value_bits); } } @@ -235,140 +235,140 @@ namespace vorbis{ //end of codebooks //time domain transforms long long unsigned int TDT = stream.get(6) + 1; - for (unsigned int i = 0; i < TDT; i++){ + for (unsigned int i = 0; i < TDT; i++) { stream.skip(16); } //Floors long long unsigned int floors = stream.get(6) + 1; - for (unsigned int i = 0; i < floors; i++){ + for (unsigned int i = 0; i < floors; i++) { long long unsigned int floorType = stream.get(16); - switch(floorType){ - case 0:{ - DEBUG_MSG(DLVL_WARN, "FloorType 0 in vorbis setup header not tested!"); - stream.skip(8);//order - stream.skip(16);//rate - stream.skip(16);//bark_map_size - stream.skip(6);//amplitude bits - stream.skip(8);//amplitude offset - long long unsigned int numberOfBooks = stream.get(4)+1; - for (unsigned int o = 0; o < numberOfBooks; o++){ - stream.skip(8);//book list array - } - break; - } - case 1:{ - long long unsigned int floorPartitions = stream.get(5); - long long int max = -1; - std::deque partition_class; - for (unsigned int o = 0; o < floorPartitions; o++){ - long long int temp = stream.get(4); - partition_class.push_back(temp); - if (temp>max) max = temp; - } - std::deque class_dimensions; - for (int o = 0; o <= max; o++){ - class_dimensions.push_back(stream.get(3)+1);//class dimensions PUT IN ARRAY! - int class_subclass = stream.get(2); - if (class_subclass !=0){ - stream.skip(8);//class_master_books - } - for (int p = 0; p < (1< partition_class; + for (unsigned int o = 0; o < floorPartitions; o++) { + long long int temp = stream.get(4); + partition_class.push_back(temp); + if (temp > max) max = temp; } - } - break; - } + std::deque class_dimensions; + for (int o = 0; o <= max; o++) { + class_dimensions.push_back(stream.get(3) + 1); //class dimensions PUT IN ARRAY! + int class_subclass = stream.get(2); + if (class_subclass != 0) { + stream.skip(8);//class_master_books + } + for (int p = 0; p < (1 << class_subclass); p++) { + stream.skip(8); + } + } + stream.skip(2);//floor1_multiplier + int rangebits = stream.get(4);//rangebits + long long unsigned int count = 0; + long long unsigned int skipper = 0; + for (unsigned int o = 0; o < floorPartitions; o++) { + count += class_dimensions[(partition_class[o])]; + while (skipper < count) { + stream.skip(rangebits); + skipper ++; + } + } + break; + } default: - exit(0); + exit(0); } } //Residues long long unsigned int residues = stream.get(6) + 1; - for(unsigned int i = 0; i < residues; i++){ + for (unsigned int i = 0; i < residues; i++) { std::deque residueCascade; long long unsigned int residueType = stream.get(16); - if(residueType<=2){ + if (residueType <= 2) { stream.skip(24);//residue begin stream.skip(24);//residue end stream.skip(24);//residue partition size - long long unsigned int residueClass = stream.get(6)+1;//residue classifications + long long unsigned int residueClass = stream.get(6) + 1; //residue classifications stream.skip(8);//residue classbook - for (unsigned int o = 0; o < residueClass; o++){ + for (unsigned int o = 0; o < residueClass; o++) { char temp = stream.get(3);//low bits bool bitFlag = stream.get(1); - if (bitFlag){ + if (bitFlag) { temp += stream.get(5) << 3; } residueCascade.push_back(temp); } - for (unsigned int o = 0; o < residueClass; o++){ - for (unsigned int p = 0; p < 7; p++){ - if (((residueCascade[o] >> p) & 1) == 1){ + for (unsigned int o = 0; o < residueClass; o++) { + for (unsigned int p = 0; p < 7; p++) { + if (((residueCascade[o] >> p) & 1) == 1) { stream.skip(8); - }else{ + } else { } } } - }else{ + } else { exit(0); } } //Mappings long long unsigned int mappings = stream.get(6) + 1; - for(unsigned int i = 0; i < mappings; i++){ + for (unsigned int i = 0; i < mappings; i++) { long long unsigned int mapType = stream.get(16); - if (mapType == 0){ + if (mapType == 0) { char mappingSubmaps = 1; - if (stream.get(1)==1){ + if (stream.get(1) == 1) { mappingSubmaps = stream.get(4);//vorbis mapping submaps } long long unsigned int coupling_steps = 0; - if (stream.get(1)==1){ - coupling_steps = stream.get(8)+1; - for (unsigned int o = 0; o0){ + if (stream.get(1) == 1) { + coupling_steps = stream.get(8) + 1; + for (unsigned int o = 0; o < coupling_steps; o++) { + int temp = (std::log((audioChannels - o) - 1)) / (std::log(2)) + 1; + if (temp > 0) { stream.skip(temp);//mapping magnitude stream.skip(temp);//mapping angle } } } char meh = stream.get(2); - if (meh != 0){ + if (meh != 0) { DEBUG_MSG(DLVL_ERROR, "Sanity check ==0 : %i", (int)meh); exit(0); } - if (mappingSubmaps > 1){ - for (int o = 0; o < audioChannels; o++){ + if (mappingSubmaps > 1) { + for (int o = 0; o < audioChannels; o++) { stream.skip(4); } } - for (int o = 0; o < mappingSubmaps; o++){ + for (int o = 0; o < mappingSubmaps; o++) { stream.skip(8);//placeholder stream.skip(8);//vorbis Mapping subfloor stream.skip(8);//vorbis mapping submap residue } - - }else{ + + } else { exit(0); } } //Modes long long unsigned int modes = stream.get(6) + 1; std::deque retVal; - for (unsigned int i = 0; i < modes; i++){ + for (unsigned int i = 0; i < modes; i++) { mode temp; temp.blockFlag = stream.get(1); temp.windowType = stream.get(16); @@ -380,46 +380,46 @@ namespace vorbis{ return retVal; } - uint32_t header::getInt32(size_t index){ - if (datasize >= (index + 3)){ + uint32_t header::getInt32(size_t index) { + if (datasize >= (index + 3)) { return (data[index] << 24) + (data[index + 1] << 16) + (data[index + 2] << 8) + data[index + 3]; } return 0; } - uint32_t header::getInt24(size_t index){ - if (datasize >= (index + 2)){ + uint32_t header::getInt24(size_t index) { + if (datasize >= (index + 2)) { return 0 + (data[index] << 16) + (data[index + 1] << 8) + data[index + 2]; } return 0; } - uint16_t header::getInt16(size_t index){ - if (datasize >= (index + 1)){ + uint16_t header::getInt16(size_t index) { + if (datasize >= (index + 1)) { return 0 + (data[index] << 8) + data[index + 1]; } return 0; } - - std::string header::toPrettyString(size_t indent){ + + std::string header::toPrettyString(size_t indent) { std::stringstream r; - r << std::string(indent+1,' ') << "Vorbis Header" << std::endl; - r << std::string(indent+2,' ') << "Magic Number: " << std::string(data + 1,6) << std::endl; - r << std::string(indent+2,' ') << "Header Type: " << getHeaderType() << std::endl; - if (getHeaderType() == 1){ - r << std::string(indent+2,' ') << "ID Header" << std::endl; - r << std::string(indent+2,' ') << "VorbisVersion: " << getVorbisVersion() << std::endl; - r << std::string(indent+2,' ') << "AudioChannels: " << (int)getAudioChannels() << std::endl; - r << std::string(indent+2,' ') << "BitrateMaximum: " << std::hex << getBitrateMaximum() << std::dec << std::endl; - r << std::string(indent+2,' ') << "BitrateNominal: " << std::hex << getBitrateNominal() << std::dec << std::endl; - r << std::string(indent+2,' ') << "BitrateMinimum: " << std::hex << getBitrateMinimum() << std::dec << std::endl; - r << std::string(indent+2,' ') << "BlockSize0: " << (int)getBlockSize0() << std::endl; - r << std::string(indent+2,' ') << "BlockSize1: " << (int)getBlockSize1() << std::endl; - r << std::string(indent+2,' ') << "FramingFlag: " << (int)getFramingFlag() << std::endl; - } else if (getHeaderType() == 3){ - r << std::string(indent+2,' ') << "Comment Header" << std::endl; - } else if (getHeaderType() == 5){ - r << std::string(indent+2,' ') << "Setup Header" << std::endl; + r << std::string(indent + 1, ' ') << "Vorbis Header" << std::endl; + r << std::string(indent + 2, ' ') << "Magic Number: " << std::string(data + 1, 6) << std::endl; + r << std::string(indent + 2, ' ') << "Header Type: " << getHeaderType() << std::endl; + if (getHeaderType() == 1) { + r << std::string(indent + 2, ' ') << "ID Header" << std::endl; + r << std::string(indent + 2, ' ') << "VorbisVersion: " << getVorbisVersion() << std::endl; + r << std::string(indent + 2, ' ') << "AudioChannels: " << (int)getAudioChannels() << std::endl; + r << std::string(indent + 2, ' ') << "BitrateMaximum: " << std::hex << getBitrateMaximum() << std::dec << std::endl; + r << std::string(indent + 2, ' ') << "BitrateNominal: " << std::hex << getBitrateNominal() << std::dec << std::endl; + r << std::string(indent + 2, ' ') << "BitrateMinimum: " << std::hex << getBitrateMinimum() << std::dec << std::endl; + r << std::string(indent + 2, ' ') << "BlockSize0: " << (int)getBlockSize0() << std::endl; + r << std::string(indent + 2, ' ') << "BlockSize1: " << (int)getBlockSize1() << std::endl; + r << std::string(indent + 2, ' ') << "FramingFlag: " << (int)getFramingFlag() << std::endl; + } else if (getHeaderType() == 3) { + r << std::string(indent + 2, ' ') << "Comment Header" << std::endl; + } else if (getHeaderType() == 5) { + r << std::string(indent + 2, ' ') << "Setup Header" << std::endl; } return r.str(); } diff --git a/lib/vorbis.h b/lib/vorbis.h index 7b502276..8d2e20db 100644 --- a/lib/vorbis.h +++ b/lib/vorbis.h @@ -5,23 +5,23 @@ #include #include -namespace vorbis{ - struct mode{ +namespace vorbis { + struct mode { bool blockFlag; unsigned short windowType; unsigned short transformType; char mapping; }; - - inline unsigned int ilog(unsigned int input){ - return (std::log(input))/(std::log(2))+1; + + inline unsigned int ilog(unsigned int input) { + return (std::log(input)) / (std::log(2)) + 1; } - - class header{ + + class header { public: header(); - header(char* newData, unsigned int length); - bool read(char* newData, unsigned int length); + header(char * newData, unsigned int length); + bool read(char * newData, unsigned int length); int getHeaderType(); long unsigned int getVorbisVersion(); char getAudioChannels(); @@ -40,9 +40,9 @@ namespace vorbis{ uint16_t getInt16(size_t index); private: std::deque modes; - char* data; + char * data; unsigned int datasize; bool checkDataSize(unsigned int size); bool validate(); - }; + }; }