Added DTSH versioning, made bigMeta the default
This commit is contained in:
parent
49cb493b7e
commit
7518014703
2 changed files with 65 additions and 101 deletions
49
lib/dtsc.h
49
lib/dtsc.h
|
@ -19,6 +19,12 @@
|
||||||
#define DTSC_ARR 0x0A
|
#define DTSC_ARR 0x0A
|
||||||
#define DTSC_CON 0xFF
|
#define DTSC_CON 0xFF
|
||||||
|
|
||||||
|
//Increase this value every time the DTSH file format changes in an incompatible way
|
||||||
|
//Changelog:
|
||||||
|
// Version 0-2: Undocumented changes
|
||||||
|
// Version 3: switched to bigMeta-style by default, Parts layout switched from 3/2/4 to 3/3/3 bytes
|
||||||
|
#define DTSH_VERSION 3
|
||||||
|
|
||||||
namespace DTSC {
|
namespace DTSC {
|
||||||
|
|
||||||
///\brief This enum holds all possible datatypes for DTSC packets.
|
///\brief This enum holds all possible datatypes for DTSC packets.
|
||||||
|
@ -125,6 +131,7 @@ namespace DTSC {
|
||||||
int getDataLen() const;
|
int getDataLen() const;
|
||||||
int getPayloadLen() const;
|
int getPayloadLen() const;
|
||||||
JSON::Value toJSON() const;
|
JSON::Value toJSON() const;
|
||||||
|
std::string toSummary() const;
|
||||||
Scan getScan() const;
|
Scan getScan() const;
|
||||||
protected:
|
protected:
|
||||||
bool master;
|
bool master;
|
||||||
|
@ -173,21 +180,22 @@ namespace DTSC {
|
||||||
///\brief Basic class for storage of data associated with single DTSC packets, a.k.a. parts.
|
///\brief Basic class for storage of data associated with single DTSC packets, a.k.a. parts.
|
||||||
class Part {
|
class Part {
|
||||||
public:
|
public:
|
||||||
long getSize();
|
uint32_t getSize();
|
||||||
void setSize(long newSize);
|
void setSize(uint32_t newSize);
|
||||||
short getDuration();
|
uint32_t getDuration();
|
||||||
void setDuration(short newDuration);
|
void setDuration(uint32_t newDuration);
|
||||||
long getOffset();
|
uint32_t getOffset();
|
||||||
void setOffset(long newOffset);
|
void setOffset(uint32_t newOffset);
|
||||||
char * getData();
|
char * getData();
|
||||||
void toPrettyString(std::ostream & str, int indent = 0);
|
void toPrettyString(std::ostream & str, int indent = 0);
|
||||||
private:
|
private:
|
||||||
|
#define PACKED_PART_SIZE 9
|
||||||
///\brief Data storage for this Part.
|
///\brief Data storage for this Part.
|
||||||
///
|
///
|
||||||
/// - 3 bytes: MSB storage of the payload size of this packet in bytes.
|
/// - 3 bytes: MSB storage of the payload size of this packet in bytes.
|
||||||
/// - 2 bytes: MSB storage of the duration of this packet in milliseconds.
|
/// - 3 bytes: MSB storage of the duration of this packet in milliseconds.
|
||||||
/// - 4 bytes: MSB storage of the presentation time offset of this packet in milliseconds.
|
/// - 3 bytes: MSB storage of the presentation time offset of this packet in milliseconds.
|
||||||
char data[9];
|
char data[PACKED_PART_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
///\brief Basic class for storage of data associated with keyframes.
|
///\brief Basic class for storage of data associated with keyframes.
|
||||||
|
@ -208,7 +216,6 @@ namespace DTSC {
|
||||||
char * getData();
|
char * getData();
|
||||||
void toPrettyString(std::ostream & str, int indent = 0);
|
void toPrettyString(std::ostream & str, int indent = 0);
|
||||||
private:
|
private:
|
||||||
#ifdef BIGMETA
|
|
||||||
#define PACKED_KEY_SIZE 25
|
#define PACKED_KEY_SIZE 25
|
||||||
///\brief Data storage for this Key.
|
///\brief Data storage for this Key.
|
||||||
///
|
///
|
||||||
|
@ -217,16 +224,6 @@ namespace DTSC {
|
||||||
/// - 4 bytes: MSB storage of the number of this keyframe.
|
/// - 4 bytes: MSB storage of the number of this keyframe.
|
||||||
/// - 2 bytes: MSB storage of the amount of parts in this keyframe.
|
/// - 2 bytes: MSB storage of the amount of parts in this keyframe.
|
||||||
/// - 8 bytes: MSB storage of the timestamp associated with this keyframe's first packet.
|
/// - 8 bytes: MSB storage of the timestamp associated with this keyframe's first packet.
|
||||||
#else
|
|
||||||
#define PACKED_KEY_SIZE 16
|
|
||||||
///\brief Data storage for this Key.
|
|
||||||
///
|
|
||||||
/// - 5 bytes: MSB storage of the position of the first packet of this keyframe within the file.
|
|
||||||
/// - 3 bytes: MSB storage of the duration of this keyframe.
|
|
||||||
/// - 2 bytes: MSB storage of the number of this keyframe.
|
|
||||||
/// - 2 bytes: MSB storage of the amount of parts in this keyframe.
|
|
||||||
/// - 4 bytes: MSB storage of the timestamp associated with this keyframe's first packet.
|
|
||||||
#endif
|
|
||||||
char data[PACKED_KEY_SIZE];
|
char data[PACKED_KEY_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -244,7 +241,6 @@ namespace DTSC {
|
||||||
char * getData();
|
char * getData();
|
||||||
void toPrettyString(std::ostream & str, int indent = 0);
|
void toPrettyString(std::ostream & str, int indent = 0);
|
||||||
private:
|
private:
|
||||||
#ifdef BIGMETA
|
|
||||||
#define PACKED_FRAGMENT_SIZE 13
|
#define PACKED_FRAGMENT_SIZE 13
|
||||||
///\brief Data storage for this Fragment.
|
///\brief Data storage for this Fragment.
|
||||||
///
|
///
|
||||||
|
@ -252,15 +248,6 @@ namespace DTSC {
|
||||||
/// - 1 byte: length (amount of keyframes)
|
/// - 1 byte: length (amount of keyframes)
|
||||||
/// - 4 bytes: number of first keyframe in fragment
|
/// - 4 bytes: number of first keyframe in fragment
|
||||||
/// - 4 bytes: size of fragment in bytes
|
/// - 4 bytes: size of fragment in bytes
|
||||||
#else
|
|
||||||
#define PACKED_FRAGMENT_SIZE 11
|
|
||||||
///\brief Data storage for this Fragment.
|
|
||||||
///
|
|
||||||
/// - 4 bytes: duration (in milliseconds)
|
|
||||||
/// - 1 byte: length (amount of keyframes)
|
|
||||||
/// - 2 bytes: number of first keyframe in fragment
|
|
||||||
/// - 4 bytes: size of fragment in bytes
|
|
||||||
#endif
|
|
||||||
char data[PACKED_FRAGMENT_SIZE];
|
char data[PACKED_FRAGMENT_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -335,12 +322,14 @@ namespace DTSC {
|
||||||
void writeTo(char * p);
|
void writeTo(char * p);
|
||||||
JSON::Value toJSON();
|
JSON::Value toJSON();
|
||||||
void reset();
|
void reset();
|
||||||
|
bool toFile(const std::string & fileName);
|
||||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||||
//members:
|
//members:
|
||||||
std::map<unsigned int, Track> tracks;
|
std::map<unsigned int, Track> tracks;
|
||||||
bool vod;
|
bool vod;
|
||||||
bool live;
|
bool live;
|
||||||
bool merged;
|
bool merged;
|
||||||
|
uint16_t version;
|
||||||
long long int moreheader;
|
long long int moreheader;
|
||||||
long long int bufferWindow;
|
long long int bufferWindow;
|
||||||
};
|
};
|
||||||
|
|
117
lib/dtscmeta.cpp
117
lib/dtscmeta.cpp
|
@ -4,6 +4,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#define AUDIO_KEY_INTERVAL 5000 ///< This define controls the keyframe interval for non-video tracks, such as audio and metadata tracks.
|
#define AUDIO_KEY_INTERVAL 5000 ///< This define controls the keyframe interval for non-video tracks, such as audio and metadata tracks.
|
||||||
|
|
||||||
|
@ -437,6 +438,18 @@ namespace DTSC {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Packet::toSummary() const {
|
||||||
|
std::stringstream out;
|
||||||
|
char * res = 0;
|
||||||
|
unsigned int len = 0;
|
||||||
|
getString("data", res, len);
|
||||||
|
out << getTrackId() << "@" << getTime() << ": " << len << " bytes";
|
||||||
|
if (hasMember("keyframe")){
|
||||||
|
out << " (keyframe)";
|
||||||
|
}
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
/// Create an invalid DTSC::Scan object by default.
|
/// Create an invalid DTSC::Scan object by default.
|
||||||
Scan::Scan() {
|
Scan::Scan() {
|
||||||
p = 0;
|
p = 0;
|
||||||
|
@ -840,33 +853,33 @@ namespace DTSC {
|
||||||
|
|
||||||
|
|
||||||
///\brief Returns the payloadsize of a part
|
///\brief Returns the payloadsize of a part
|
||||||
long Part::getSize() {
|
uint32_t Part::getSize() {
|
||||||
return Bit::btoh24(data);
|
return Bit::btoh24(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the payloadsize of a part
|
///\brief Sets the payloadsize of a part
|
||||||
void Part::setSize(long newSize) {
|
void Part::setSize(uint32_t newSize) {
|
||||||
Bit::htob24(data, newSize);
|
Bit::htob24(data, newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Retruns the duration of a part
|
///\brief Returns the duration of a part
|
||||||
short Part::getDuration() {
|
uint32_t Part::getDuration() {
|
||||||
return Bit::btohs(data + 3);
|
return Bit::btoh24(data + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the duration of a part
|
///\brief Sets the duration of a part
|
||||||
void Part::setDuration(short newDuration) {
|
void Part::setDuration(uint32_t newDuration) {
|
||||||
Bit::htobs(data + 3, newDuration);
|
Bit::htob24(data + 3, newDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief returns the offset of a part
|
///\brief returns the offset of a part
|
||||||
long Part::getOffset() {
|
uint32_t Part::getOffset() {
|
||||||
return Bit::btohl(data + 5);
|
return Bit::btoh24(data + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the offset of a part
|
///\brief Sets the offset of a part
|
||||||
void Part::setOffset(long newOffset) {
|
void Part::setOffset(uint32_t newOffset) {
|
||||||
Bit::htobl(data + 5, newOffset);
|
Bit::htob24(data + 6, newOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the data of a part
|
///\brief Returns the data of a part
|
||||||
|
@ -883,93 +896,49 @@ namespace DTSC {
|
||||||
|
|
||||||
///\brief Returns the byteposition of a keyframe
|
///\brief Returns the byteposition of a keyframe
|
||||||
unsigned long long Key::getBpos() {
|
unsigned long long Key::getBpos() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohll(data);
|
return Bit::btohll(data);
|
||||||
#else
|
|
||||||
return (((unsigned long long)data[0] << 32) | (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key::setBpos(unsigned long long newBpos) {
|
void Key::setBpos(unsigned long long newBpos) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobll(data, newBpos);
|
Bit::htobll(data, newBpos);
|
||||||
#else
|
|
||||||
data[4] = newBpos & 0xFF;
|
|
||||||
data[3] = (newBpos >> 8) & 0xFF;
|
|
||||||
data[2] = (newBpos >> 16) & 0xFF;
|
|
||||||
data[1] = (newBpos >> 24) & 0xFF;
|
|
||||||
data[0] = (newBpos >> 32) & 0xFF;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long Key::getLength() {
|
unsigned long Key::getLength() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btoh24(data+8);
|
return Bit::btoh24(data+8);
|
||||||
#else
|
|
||||||
return Bit::btoh24(data+5);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key::setLength(unsigned long newLength) {
|
void Key::setLength(unsigned long newLength) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htob24(data+8, newLength);
|
Bit::htob24(data+8, newLength);
|
||||||
#else
|
|
||||||
Bit::htob24(data+5, newLength);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the number of a keyframe
|
///\brief Returns the number of a keyframe
|
||||||
unsigned long Key::getNumber() {
|
unsigned long Key::getNumber() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohl(data + 11);
|
return Bit::btohl(data + 11);
|
||||||
#else
|
|
||||||
return Bit::btohs(data + 8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the number of a keyframe
|
///\brief Sets the number of a keyframe
|
||||||
void Key::setNumber(unsigned long newNumber) {
|
void Key::setNumber(unsigned long newNumber) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobl(data + 11, newNumber);
|
Bit::htobl(data + 11, newNumber);
|
||||||
#else
|
|
||||||
Bit::htobs(data + 8, newNumber);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the number of parts of a keyframe
|
///\brief Returns the number of parts of a keyframe
|
||||||
unsigned short Key::getParts() {
|
unsigned short Key::getParts() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohs(data + 15);
|
return Bit::btohs(data + 15);
|
||||||
#else
|
|
||||||
return Bit::btohs(data + 10);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the number of parts of a keyframe
|
///\brief Sets the number of parts of a keyframe
|
||||||
void Key::setParts(unsigned short newParts) {
|
void Key::setParts(unsigned short newParts) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobs(data + 15, newParts);
|
Bit::htobs(data + 15, newParts);
|
||||||
#else
|
|
||||||
Bit::htobs(data + 10, newParts);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the timestamp of a keyframe
|
///\brief Returns the timestamp of a keyframe
|
||||||
unsigned long long Key::getTime() {
|
unsigned long long Key::getTime() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohll(data + 17);
|
return Bit::btohll(data + 17);
|
||||||
#else
|
|
||||||
return Bit::btohl(data + 12);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the timestamp of a keyframe
|
///\brief Sets the timestamp of a keyframe
|
||||||
void Key::setTime(unsigned long long newTime) {
|
void Key::setTime(unsigned long long newTime) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobll(data + 17, newTime);
|
Bit::htobll(data + 17, newTime);
|
||||||
#else
|
|
||||||
Bit::htobl(data + 12, newTime);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the data of this keyframe struct
|
///\brief Returns the data of this keyframe struct
|
||||||
|
@ -1006,38 +975,22 @@ namespace DTSC {
|
||||||
|
|
||||||
///\brief Returns the number of the first keyframe in this fragment
|
///\brief Returns the number of the first keyframe in this fragment
|
||||||
unsigned long Fragment::getNumber() {
|
unsigned long Fragment::getNumber() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohl(data + 5);
|
return Bit::btohl(data + 5);
|
||||||
#else
|
|
||||||
return Bit::btohs(data + 5);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the number of the first keyframe in this fragment
|
///\brief Sets the number of the first keyframe in this fragment
|
||||||
void Fragment::setNumber(unsigned long newNumber) {
|
void Fragment::setNumber(unsigned long newNumber) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobl(data + 5, newNumber);
|
Bit::htobl(data + 5, newNumber);
|
||||||
#else
|
|
||||||
Bit::htobs(data + 5, newNumber);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns the size of a fragment
|
///\brief Returns the size of a fragment
|
||||||
unsigned long Fragment::getSize() {
|
unsigned long Fragment::getSize() {
|
||||||
#ifdef BIGMETA
|
|
||||||
return Bit::btohl(data + 9);
|
return Bit::btohl(data + 9);
|
||||||
#else
|
|
||||||
return Bit::btohl(data + 7);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Sets the size of a fragement
|
///\brief Sets the size of a fragement
|
||||||
void Fragment::setSize(unsigned long newSize) {
|
void Fragment::setSize(unsigned long newSize) {
|
||||||
#ifdef BIGMETA
|
|
||||||
Bit::htobl(data + 9, newSize);
|
Bit::htobl(data + 9, newSize);
|
||||||
#else
|
|
||||||
Bit::htobl(data + 7, newSize);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Returns thte data of this fragment structure
|
///\brief Returns thte data of this fragment structure
|
||||||
|
@ -1294,6 +1247,7 @@ namespace DTSC {
|
||||||
Meta::Meta() {
|
Meta::Meta() {
|
||||||
vod = false;
|
vod = false;
|
||||||
live = false;
|
live = false;
|
||||||
|
version = DTSH_VERSION;
|
||||||
moreheader = 0;
|
moreheader = 0;
|
||||||
merged = false;
|
merged = false;
|
||||||
bufferWindow = 0;
|
bufferWindow = 0;
|
||||||
|
@ -1307,6 +1261,7 @@ namespace DTSC {
|
||||||
tracks.clear();
|
tracks.clear();
|
||||||
vod = source.getFlag("vod");
|
vod = source.getFlag("vod");
|
||||||
live = source.getFlag("live");
|
live = source.getFlag("live");
|
||||||
|
version = source.getInt("version");
|
||||||
merged = source.getFlag("merged");
|
merged = source.getFlag("merged");
|
||||||
bufferWindow = source.getInt("buffer_window");
|
bufferWindow = source.getInt("buffer_window");
|
||||||
moreheader = source.getInt("moreheader");
|
moreheader = source.getInt("moreheader");
|
||||||
|
@ -1329,6 +1284,7 @@ namespace DTSC {
|
||||||
Meta::Meta(JSON::Value & meta) {
|
Meta::Meta(JSON::Value & meta) {
|
||||||
vod = meta.isMember("vod") && meta["vod"];
|
vod = meta.isMember("vod") && meta["vod"];
|
||||||
live = meta.isMember("live") && meta["live"];
|
live = meta.isMember("live") && meta["live"];
|
||||||
|
version = meta.isMember("version") ? meta["version"].asInt() : 0;
|
||||||
merged = meta.isMember("merged") && meta["merged"];
|
merged = meta.isMember("merged") && meta["merged"];
|
||||||
bufferWindow = 0;
|
bufferWindow = 0;
|
||||||
if (meta.isMember("buffer_window")) {
|
if (meta.isMember("buffer_window")) {
|
||||||
|
@ -1713,6 +1669,7 @@ namespace DTSC {
|
||||||
dataLen += it->second.getSendLen(skipDynamic);
|
dataLen += it->second.getSendLen(skipDynamic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (version){dataLen += 17;}
|
||||||
return dataLen + 8; //add 8 bytes header
|
return dataLen + 8; //add 8 bytes header
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1738,6 +1695,10 @@ namespace DTSC {
|
||||||
writePointer(p, "\000\006merged\001", 9);
|
writePointer(p, "\000\006merged\001", 9);
|
||||||
writePointer(p, convertLongLong(1), 8);
|
writePointer(p, convertLongLong(1), 8);
|
||||||
}
|
}
|
||||||
|
if (version) {
|
||||||
|
writePointer(p, "\000\006version\001", 9);
|
||||||
|
writePointer(p, convertLongLong(version), 8);
|
||||||
|
}
|
||||||
if (bufferWindow) {
|
if (bufferWindow) {
|
||||||
writePointer(p, "\000\015buffer_window\001", 16);
|
writePointer(p, "\000\015buffer_window\001", 16);
|
||||||
writePointer(p, convertLongLong(bufferWindow), 8);
|
writePointer(p, convertLongLong(bufferWindow), 8);
|
||||||
|
@ -1771,6 +1732,10 @@ namespace DTSC {
|
||||||
conn.SendNow("\000\006merged\001", 9);
|
conn.SendNow("\000\006merged\001", 9);
|
||||||
conn.SendNow(convertLongLong(1), 8);
|
conn.SendNow(convertLongLong(1), 8);
|
||||||
}
|
}
|
||||||
|
if (version) {
|
||||||
|
conn.SendNow("\000\006version\001", 9);
|
||||||
|
conn.SendNow(convertLongLong(version), 8);
|
||||||
|
}
|
||||||
if (bufferWindow) {
|
if (bufferWindow) {
|
||||||
conn.SendNow("\000\015buffer_window\001", 16);
|
conn.SendNow("\000\015buffer_window\001", 16);
|
||||||
conn.SendNow(convertLongLong(bufferWindow), 8);
|
conn.SendNow(convertLongLong(bufferWindow), 8);
|
||||||
|
@ -1855,10 +1820,20 @@ namespace DTSC {
|
||||||
if (bufferWindow) {
|
if (bufferWindow) {
|
||||||
result["buffer_window"] = bufferWindow;
|
result["buffer_window"] = bufferWindow;
|
||||||
}
|
}
|
||||||
|
if (version) {
|
||||||
|
result["version"] = (long long)version;
|
||||||
|
}
|
||||||
result["moreheader"] = moreheader;
|
result["moreheader"] = moreheader;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///\brief Writes metadata to a filename. Wipes existing contents, if any.
|
||||||
|
bool Meta::toFile(const std::string & fileName){
|
||||||
|
std::ofstream oFile(fileName.c_str());
|
||||||
|
oFile << toJSON().toNetPacked();
|
||||||
|
oFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
///\brief Converts a meta object to a human readable string
|
///\brief Converts a meta object to a human readable string
|
||||||
///\param str The stringstream to append to
|
///\param str The stringstream to append to
|
||||||
///\param indent the amount of indentation needed
|
///\param indent the amount of indentation needed
|
||||||
|
|
Loading…
Add table
Reference in a new issue