filedat: rework
format improvement code cleaning
This commit is contained in:
parent
8d01a18f3a
commit
d6a308bdbc
3 changed files with 453 additions and 413 deletions
|
|
@ -105,7 +105,7 @@ namespace ztd
|
||||||
//! @brief Constructor with initial value
|
//! @brief Constructor with initial value
|
||||||
chunkdat(const char* in);
|
chunkdat(const char* in);
|
||||||
//! @brief Constructor with initial value
|
//! @brief Constructor with initial value
|
||||||
chunkdat(std::string const& in);
|
chunkdat(std::string const& in, int offset=0, filedat* parent=nullptr);
|
||||||
//! @brief Constructor with initial value
|
//! @brief Constructor with initial value
|
||||||
chunkdat(const char* in, const int in_size, int offset=0, filedat* parent=nullptr);
|
chunkdat(const char* in, const int in_size, int offset=0, filedat* parent=nullptr);
|
||||||
//! @brief Constructor with copy
|
//! @brief Constructor with copy
|
||||||
|
|
@ -127,6 +127,13 @@ namespace ztd
|
||||||
inline int offset() const { return m_offset; }
|
inline int offset() const { return m_offset; }
|
||||||
|
|
||||||
|
|
||||||
|
//! @brief Set data
|
||||||
|
/*!
|
||||||
|
@param in String data
|
||||||
|
@param offset Used for debugging
|
||||||
|
@param data Used for debugging
|
||||||
|
*/
|
||||||
|
void set(std::string const& in, int offset=0, filedat* parent=nullptr);
|
||||||
//! @brief Set data
|
//! @brief Set data
|
||||||
/*!
|
/*!
|
||||||
@param in C string data
|
@param in C string data
|
||||||
|
|
@ -134,14 +141,7 @@ namespace ztd
|
||||||
@param offset Used for debugging
|
@param offset Used for debugging
|
||||||
@param parent Used for debugging
|
@param parent Used for debugging
|
||||||
*/
|
*/
|
||||||
void set(const char* in, const int in_size, int offset=0, filedat* parent=nullptr);
|
inline void set(const char* in, const int in_size, int offset=0, filedat* parent=nullptr) { this->set(std::string(in, in_size), offset, parent);}
|
||||||
//! @brief Set data
|
|
||||||
/*!
|
|
||||||
@param in String data
|
|
||||||
@param offset Used for debugging
|
|
||||||
@param data Used for debugging
|
|
||||||
*/
|
|
||||||
inline void set(std::string const& in, int offset=0, filedat* parent=nullptr) { this->set(in.c_str(), in.size(), offset, parent); }
|
|
||||||
//! @brief Copy chunk data
|
//! @brief Copy chunk data
|
||||||
void set(chunkdat const& in);
|
void set(chunkdat const& in);
|
||||||
|
|
||||||
|
|
@ -337,6 +337,8 @@ namespace ztd
|
||||||
@param aligner String used to align subchunks
|
@param aligner String used to align subchunks
|
||||||
*/
|
*/
|
||||||
std::string strval(std::string const& aligner="\t") const;
|
std::string strval(std::string const& aligner="\t") const;
|
||||||
|
//! @brief Alias for strval()
|
||||||
|
inline std::string str(std::string const& aligner="\t") const { return this->strval(aligner); }
|
||||||
|
|
||||||
//! @brief Get reference to chunk data
|
//! @brief Get reference to chunk data
|
||||||
inline chunkdat& data() const { return *m_dataChunk; }
|
inline chunkdat& data() const { return *m_dataChunk; }
|
||||||
|
|
@ -362,25 +364,13 @@ namespace ztd
|
||||||
//! @see chunkdat::operator[](const unsigned int a) const
|
//! @see chunkdat::operator[](const unsigned int a) const
|
||||||
inline chunkdat& operator[](const unsigned int index) const { return m_dataChunk->subChunkRef(index); }
|
inline chunkdat& operator[](const unsigned int index) const { return m_dataChunk->subChunkRef(index); }
|
||||||
|
|
||||||
//! @brief add data and return *this
|
|
||||||
//! @see chunkdat::operator+=(std::pair<std::string, chunkdat> const& a)
|
|
||||||
inline filedat& operator+=(std::pair<std::string, chunkdat> const& a) { *m_dataChunk += a; return *this; }
|
|
||||||
//! @brief add data and return *this
|
|
||||||
//! @see chunkdat::operator+=(std::vector<std::pair<std::string, chunkdat>> const& a)
|
|
||||||
inline filedat& operator+=(std::vector<std::pair<std::string, chunkdat>> const& a) { *m_dataChunk += a; return *this; }
|
|
||||||
//! @brief add data and return *this
|
|
||||||
//! @see chunkdat::operator+=(chunkdat const& a)
|
|
||||||
inline filedat& operator+=(chunkdat const& a) { *m_dataChunk += a; return *this; }
|
|
||||||
//! @brief add() and return *this
|
|
||||||
//! @see chunkdat::operator+=(std::vector<chunkdat> const& a)
|
|
||||||
inline filedat& operator+=(std::vector<chunkdat> const& a) { *m_dataChunk += a; return *this; }
|
|
||||||
|
|
||||||
//! @brief set_data() and return *this
|
//! @brief set_data() and return *this
|
||||||
//! @see chunkdat::operator+=(std::vector<chunkdat> const& a)
|
//! @see chunkdat::operator+=(std::vector<chunkdat> const& a)
|
||||||
inline filedat& operator=(chunkdat const& a) { set_data(a); return *this; }
|
inline filedat& operator=(chunkdat const& a) { set_data(a); return *this; }
|
||||||
|
|
||||||
//! @brief Is a read char
|
//! @brief Is a read char
|
||||||
static bool isRead(char in);
|
static bool isRead(char in);
|
||||||
|
static std::string removeComments(std::string str);
|
||||||
|
|
||||||
inline operator chunkdat() const { return *m_dataChunk; }
|
inline operator chunkdat() const { return *m_dataChunk; }
|
||||||
// inline operator std::string() const { if(m_dataChunk!=nullptr) return m_dataChunk->strval(); else return ""; }
|
// inline operator std::string() const { if(m_dataChunk!=nullptr) return m_dataChunk->strval(); else return ""; }
|
||||||
|
|
@ -388,6 +378,7 @@ namespace ztd
|
||||||
private:
|
private:
|
||||||
//functions
|
//functions
|
||||||
void generateChunk();
|
void generateChunk();
|
||||||
|
|
||||||
//attributes
|
//attributes
|
||||||
std::string m_filePath;
|
std::string m_filePath;
|
||||||
std::string m_data;
|
std::string m_data;
|
||||||
|
|
@ -428,7 +419,7 @@ namespace ztd
|
||||||
If origin is known, displays location and discriminating line\n
|
If origin is known, displays location and discriminating line\n
|
||||||
If origin is unknown, displays whole data up to discriminating line
|
If origin is unknown, displays whole data up to discriminating line
|
||||||
*/
|
*/
|
||||||
void printFormatException(format_error& exc);
|
inline void printFormatException(format_error& exc) {printErrorIndex(exc.data(), exc.where(), exc.what(), exc.origin());}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,37 +5,42 @@ ZFD is composed of infinitely concatenable "chunks". There a three types of chun
|
||||||
- List chunk : between brackets []
|
- List chunk : between brackets []
|
||||||
- String value
|
- String value
|
||||||
|
|
||||||
Formatting is ignored, all spaces will be ignored unless they are part of a value.
|
All spaces will be ignored unless they are part of a value.
|
||||||
Comments can be written with //, ends at end of line
|
Comments can be written with // or #, ends at end of line.
|
||||||
|
Only supports ASCII
|
||||||
|
|
||||||
ZFD treats everything as a string, there is no number or boolean types
|
Everything is a string, there are no number or boolean types
|
||||||
|
|
||||||
### Map Chunk
|
### Map Chunk
|
||||||
|
|
||||||
A map chunk consists of pairs of keys and values. Format is as follows:
|
A map chunk consists of pairs of keys and values.
|
||||||
|
Key separators are \n and ;
|
||||||
|
Format is as follows:
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
//no concatenator: value ends at end of line. /!\ Comments on these lines will be part of the value
|
|
||||||
key1=value
|
key1=value
|
||||||
//concatenators: value ends at end of concatenation
|
|
||||||
key2 = " value "
|
key2 = " value "
|
||||||
key3 = ' value '
|
key3 = ' value '
|
||||||
key4=[ //list ]
|
// brace and brackets have to be the first valid chars for list and maps
|
||||||
key5={ //chunk }
|
key4 = [ //list ]
|
||||||
|
key5 = { //map }
|
||||||
|
// multiple values in a single line
|
||||||
|
key6=foo; key7=bar
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### List Chunk
|
### List Chunk
|
||||||
|
|
||||||
A list chunk consists of a linear list of values separated by commas. Format is as follows:
|
A list chunk consists of a linear list of values separated by commas.
|
||||||
|
Value separators are , and ;
|
||||||
|
Format is as follows:
|
||||||
```
|
```
|
||||||
[
|
[
|
||||||
//comments cannot be written between a value and the separating comma
|
|
||||||
value,
|
value,
|
||||||
" value ",
|
" value ",
|
||||||
' value ',
|
' value ',
|
||||||
{ //chunk },
|
{ //chunk },
|
||||||
[ //list ]
|
[ //list ],
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
802
src/filedat.cpp
802
src/filedat.cpp
|
|
@ -1,5 +1,7 @@
|
||||||
#include "filedat.hpp"
|
#include "filedat.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// Function code
|
// Function code
|
||||||
bool ztd::filedat::isRead(char in)
|
bool ztd::filedat::isRead(char in)
|
||||||
{
|
{
|
||||||
|
|
@ -14,6 +16,17 @@ static std::string repeatString(const std::string& str, const unsigned int n)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string escape(std::string str, const char c)
|
||||||
|
{
|
||||||
|
size_t pos = str.find(c);
|
||||||
|
while(pos != std::string::npos)
|
||||||
|
{
|
||||||
|
str.insert(pos, "\\");
|
||||||
|
pos += 2;
|
||||||
|
pos = str.find(c, pos);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
void ztd::printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin)
|
void ztd::printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin)
|
||||||
{
|
{
|
||||||
|
|
@ -55,11 +68,52 @@ void ztd::printErrorIndex(const char* in, const int index, const std::string& me
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ztd::printFormatException(ztd::format_error& exc)
|
std::string ztd::filedat::removeComments(std::string str)
|
||||||
{
|
{
|
||||||
ztd::printErrorIndex(exc.data(), exc.where(), exc.what(), exc.origin());
|
uint32_t i=0;
|
||||||
}
|
while(i < str.size())
|
||||||
|
{
|
||||||
|
if( str[i] == '"') // double quotes
|
||||||
|
{
|
||||||
|
uint32_t j=i;
|
||||||
|
i++;
|
||||||
|
while(i < str.size() && str[i]!='"') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '"') //escaped quote
|
||||||
|
i++; //ignore backslash
|
||||||
|
|
||||||
|
i++; // add char and increment
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Double quote doesn't close", "", str, j);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if( str[i] == '\'') // single quotes
|
||||||
|
{
|
||||||
|
uint32_t j=i;
|
||||||
|
i++;
|
||||||
|
while(i < str.size() && str[i]!='\'') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '\'') //escaped quote
|
||||||
|
i++; //ignore backslash
|
||||||
|
|
||||||
|
i++; // add char
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Single quote doesn't close", "", str, j);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if(str[i] == '#' || (i+1 < str.size() && str.substr(i,2) == "//")) // comment
|
||||||
|
{
|
||||||
|
uint32_t j=i;
|
||||||
|
i = str.find('\n', i);
|
||||||
|
str.erase(j,i-j);
|
||||||
|
i=j;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
ztd::filedat::filedat()
|
ztd::filedat::filedat()
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +129,7 @@ ztd::filedat::filedat(std::string const& in)
|
||||||
ztd::filedat::~filedat()
|
ztd::filedat::~filedat()
|
||||||
{
|
{
|
||||||
if(m_dataChunk!=nullptr)
|
if(m_dataChunk!=nullptr)
|
||||||
delete m_dataChunk;
|
delete m_dataChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ztd::filedat::clear()
|
void ztd::filedat::clear()
|
||||||
|
|
@ -92,18 +146,18 @@ bool ztd::filedat::readTest() const
|
||||||
{
|
{
|
||||||
std::ifstream stream(m_filePath);
|
std::ifstream stream(m_filePath);
|
||||||
if(!stream)
|
if(!stream)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ztd::filedat::import_file(const std::string& path)
|
void ztd::filedat::import_file(const std::string& path)
|
||||||
{
|
{
|
||||||
if(path != "")
|
if(path != "")
|
||||||
m_filePath=path;
|
m_filePath=path;
|
||||||
std::ifstream st(m_filePath);
|
std::ifstream st(m_filePath);
|
||||||
if(!st)
|
if(!st)
|
||||||
throw std::runtime_error("Cannot read file '" + m_filePath + '\'');
|
throw std::runtime_error("Cannot read file '" + m_filePath + '\'');
|
||||||
|
|
||||||
this->clear();
|
this->clear();
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
@ -141,11 +195,11 @@ bool ztd::filedat::export_file(std::string const& path, std::string const& align
|
||||||
{
|
{
|
||||||
std::ofstream stream;
|
std::ofstream stream;
|
||||||
if(path=="")
|
if(path=="")
|
||||||
stream.open(m_filePath);
|
stream.open(m_filePath);
|
||||||
else
|
else
|
||||||
stream.open(path);
|
stream.open(path);
|
||||||
if(!stream)
|
if(!stream)
|
||||||
return false;
|
return false;
|
||||||
stream << this->strval(aligner);
|
stream << this->strval(aligner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -153,9 +207,9 @@ bool ztd::filedat::export_file(std::string const& path, std::string const& align
|
||||||
std::string ztd::filedat::strval(std::string const& aligner) const
|
std::string ztd::filedat::strval(std::string const& aligner) const
|
||||||
{
|
{
|
||||||
if(m_dataChunk == nullptr)
|
if(m_dataChunk == nullptr)
|
||||||
return "";
|
return "";
|
||||||
else
|
else
|
||||||
return m_dataChunk->strval(0, aligner);
|
return m_dataChunk->strval(0, aligner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ztd::filedat::generateChunk()
|
void ztd::filedat::generateChunk()
|
||||||
|
|
@ -163,436 +217,402 @@ void ztd::filedat::generateChunk()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(m_dataChunk != nullptr)
|
if(m_dataChunk != nullptr)
|
||||||
delete m_dataChunk;
|
delete m_dataChunk;
|
||||||
m_dataChunk = new ztd::chunkdat(m_data.c_str(), m_data.size(), 0, this);
|
m_data = this->removeComments(m_data);
|
||||||
|
m_dataChunk = new ztd::chunkdat(m_data, 0, nullptr);
|
||||||
}
|
}
|
||||||
catch(ztd::format_error& e)
|
catch(ztd::format_error& e)
|
||||||
{
|
{
|
||||||
|
m_dataChunk = nullptr;
|
||||||
throw ztd::format_error(e.what(), m_filePath, m_data, e.where());
|
throw ztd::format_error(e.what(), m_filePath, m_data, e.where());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string _getname(const char* in, const int in_size, int* start, int* val_size, int* end)
|
std::pair<std::string, size_t> _skip(const std::string& str)
|
||||||
{
|
{
|
||||||
int i=0;
|
size_t i=0;
|
||||||
|
|
||||||
*start = in_size; //default no value
|
//skip to val start
|
||||||
*end = in_size; //default end
|
while( i < str.size() )
|
||||||
*val_size=0; //default no value
|
|
||||||
|
|
||||||
while(i<in_size)
|
|
||||||
{
|
{
|
||||||
if(i+1<in_size && in[i] == '/' && in[i+1] == '/')
|
// start of value
|
||||||
while(i<in_size && in[i] != '\n')
|
if(ztd::filedat::isRead(str[i]))
|
||||||
i++;
|
break;
|
||||||
|
|
||||||
if(ztd::filedat::isRead(in[i]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if(i >= in_size) //ends without value
|
|
||||||
return "";
|
|
||||||
|
|
||||||
int j=i; //name start
|
|
||||||
while(i<in_size && in[i] != '=') //skip to =
|
|
||||||
i++;
|
|
||||||
if(i >= in_size) //no =
|
|
||||||
throw ztd::format_error("Tag has no value", "", std::string(in, in_size), j);
|
|
||||||
|
|
||||||
if(i == j) //nothing preceding =
|
|
||||||
throw ztd::format_error("Value has no tag", "", std::string(in, in_size), i);
|
|
||||||
|
|
||||||
int k=i-1; //name end
|
|
||||||
while( !ztd::filedat::isRead(in[k]) )
|
|
||||||
k--;
|
|
||||||
std::string name=std::string(in+j, k-j+1);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
while(i < in_size && !ztd::filedat::isRead(in[i]))
|
|
||||||
i++;
|
|
||||||
if(i >= in_size) //no value
|
|
||||||
{
|
|
||||||
*start=i;
|
|
||||||
*val_size=0;
|
|
||||||
*end=i;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
if(in[i] == '\"') //"" val
|
|
||||||
{
|
|
||||||
*start=i; //value starts
|
|
||||||
j=1; //size
|
|
||||||
while(i+j < in_size && in[i+j]!='\"')
|
|
||||||
{
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) // no closing "
|
|
||||||
throw ztd::format_error("Double quote does not close", "", std::string(in, in_size), i-1);
|
|
||||||
j++;
|
|
||||||
*val_size=j;
|
|
||||||
*end=i+j;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
if(in[i] == '\'') //"" val
|
|
||||||
{
|
|
||||||
*start=i; //value starts
|
|
||||||
j=1; //size
|
|
||||||
while(i+j < in_size && in[i+j]!='\'')
|
|
||||||
{
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) // no closing '
|
|
||||||
throw ztd::format_error("Single quote does not close", "", std::string(in, in_size), i-1);
|
|
||||||
j++;
|
|
||||||
*val_size=j;
|
|
||||||
*end=i+j;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
if(in[i] == '{')
|
|
||||||
{
|
|
||||||
*start=i;
|
|
||||||
j=1;
|
|
||||||
int counter=0;
|
|
||||||
while( i+j < in_size && !( counter == 0 && in[i+j]=='}') )
|
|
||||||
{
|
|
||||||
if(i+j+1<in_size && in[i+j] == '/' && in[i+j+1] == '/')
|
|
||||||
while(i+j<in_size && in[i+j] != '\n')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='{')
|
|
||||||
counter++;
|
|
||||||
if(in[i+j]=='}')
|
|
||||||
counter--;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) //reached end without closing
|
|
||||||
throw ztd::format_error("Brace does not close", "", std::string(in, in_size), i);
|
|
||||||
j++;
|
|
||||||
*val_size=j;
|
|
||||||
*end=i+j;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
if(in[i] == '[')
|
|
||||||
{
|
|
||||||
*start=i;
|
|
||||||
j=1;
|
|
||||||
int counter=0;
|
|
||||||
while( i+j < in_size && !( counter == 0 && in[i+j]==']') )
|
|
||||||
{
|
|
||||||
if(i+j+1<in_size && in[i+j] == '/' && in[i+j+1] == '/')
|
|
||||||
while(i+j<in_size && in[i+j] != '\n')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='[')
|
|
||||||
counter++;
|
|
||||||
if(in[i+j]==']')
|
|
||||||
counter--;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) //reached end without closing
|
|
||||||
throw ztd::format_error("Bracket does not close", "", std::string(in, in_size), i);
|
|
||||||
j++;
|
|
||||||
*val_size=j;
|
|
||||||
*end=i+j;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
{ // no encapsulation: go to end of line
|
|
||||||
*start=i; //value starts
|
|
||||||
j=0; //size
|
|
||||||
while(i+j < in_size && in[i+j]!='\n')
|
|
||||||
{
|
|
||||||
if(in[i]+j=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
while( !ztd::filedat::isRead(in[i+j]) )
|
|
||||||
j--;
|
|
||||||
*val_size=j+1;
|
|
||||||
*end=i+j+1;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string _getlist(const char* in, const int in_size, int* start, int* end)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
if(i < str.size())
|
||||||
while(i<in_size)
|
ret = str.substr(i);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(i+1<in_size && in[i] == '/' && in[i+1] == '/')
|
i=str.size();
|
||||||
while(i<in_size && in[i] != '\n')
|
ret="";
|
||||||
i++;
|
}
|
||||||
|
return std::make_pair(ret, i);
|
||||||
|
}
|
||||||
|
|
||||||
if(ztd::filedat::isRead(in[i]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
i++;
|
// TODO TODO TODO
|
||||||
|
// value, rest, start of rest, start of value, delim found
|
||||||
|
static std::tuple<std::string, std::string, int, int, bool> _getstrval(const std::string& str, const char delim=0, const char altdelim=0)
|
||||||
|
{
|
||||||
|
std::string val;
|
||||||
|
|
||||||
|
//skip to start of val
|
||||||
|
size_t i = _skip(str).second;
|
||||||
|
int st = i;
|
||||||
|
bool delim_found=false;
|
||||||
|
|
||||||
|
// no value
|
||||||
|
if(i >= str.size())
|
||||||
|
return std::make_tuple("","",0,0,false);
|
||||||
|
|
||||||
|
while(i < str.size())
|
||||||
|
{
|
||||||
|
if( str[i] == '"') // double quotes
|
||||||
|
{
|
||||||
|
uint32_t j=i;
|
||||||
|
i++;
|
||||||
|
while(i < str.size() && str[i]!='"') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '"') //escaped quote
|
||||||
|
i++; //ignore backslash
|
||||||
|
|
||||||
|
val.push_back(str[i++]); // add char and increment
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Double quote doesn't close", "", str, j);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if( str[i] == '\'') // single quotes
|
||||||
|
{
|
||||||
|
uint32_t j=i;
|
||||||
|
i++;
|
||||||
|
while(i < str.size() && str[i]!='\'') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '\'') //escaped quote
|
||||||
|
i++; //ignore backslash
|
||||||
|
|
||||||
|
val += str[i++]; // add char
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Single quote doesn't close", "", str, j);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(str[i] == '{') // {} map
|
||||||
|
{
|
||||||
|
uint32_t counter=0;
|
||||||
|
uint32_t j=i;
|
||||||
|
val += str[i++]; // add the bracket to the value
|
||||||
|
while(i < str.size() && !(counter == 0 && str[i] == '}') )
|
||||||
|
{
|
||||||
|
if(str[i] == '}')
|
||||||
|
counter--;
|
||||||
|
else if(str[i] == '{')
|
||||||
|
counter++;
|
||||||
|
else if( str[i] == '"') // double quotes
|
||||||
|
{
|
||||||
|
uint32_t k=i;
|
||||||
|
val += str[i++];
|
||||||
|
while(i < str.size() && str[i]!='"') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '"') //escaped quote
|
||||||
|
val += str[i++];
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Double quote does not close", "", str, k);
|
||||||
|
}
|
||||||
|
else if( str[i] == '\'') // single quotes
|
||||||
|
{
|
||||||
|
uint32_t k=i;
|
||||||
|
val += str[i++];
|
||||||
|
while(i < str.size() && str[i]!='\'') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '\'') //escaped quote
|
||||||
|
val += str[i++];
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Single quote does not close", "", str, k);
|
||||||
|
}
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i >= str.size()) //didn't close
|
||||||
|
throw ztd::format_error("Brace does not close", "", str, j);
|
||||||
|
|
||||||
|
val += str[i++]; // add brace
|
||||||
|
}
|
||||||
|
else if(str[i] == '[') // [] list
|
||||||
|
{
|
||||||
|
uint32_t counter=0;
|
||||||
|
uint32_t j=i;
|
||||||
|
val += str[i++]; // add the bracket to the value
|
||||||
|
while(i < str.size() && !(counter == 0 && str[i] == ']') )
|
||||||
|
{
|
||||||
|
if(str[i] == '[')
|
||||||
|
counter--;
|
||||||
|
else if(str[i] == ']')
|
||||||
|
counter++;
|
||||||
|
else if( str[i] == '"') // double quotes
|
||||||
|
{
|
||||||
|
uint32_t k=i;
|
||||||
|
val += str[i++];
|
||||||
|
while(i < str.size() && str[i]!='"') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '"') //escaped quote
|
||||||
|
val += str[i++];
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Double quote does not close", "", str, k);
|
||||||
|
}
|
||||||
|
else if( str[i] == '\'') // single quotes
|
||||||
|
{
|
||||||
|
uint32_t k=i;
|
||||||
|
val += str[i++];
|
||||||
|
while(i < str.size() && str[i]!='\'') // until end of quote
|
||||||
|
{
|
||||||
|
if(i+1 < str.size() && str[i] == '\\' && str[i+1] == '\'') //escaped quote
|
||||||
|
val += str[i++];
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
if(i >= str.size()) // quote didn't end
|
||||||
|
throw ztd::format_error("Single quote does not close", "", str, k);
|
||||||
|
}
|
||||||
|
val += str[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i >= str.size()) //didn't close
|
||||||
|
throw ztd::format_error("Brace does not close", "", str, j);
|
||||||
|
|
||||||
|
val += str[i++]; // add bracket
|
||||||
|
}
|
||||||
|
else if(!ztd::filedat::isRead(str[i])) // non read char
|
||||||
|
{
|
||||||
|
std::string tval="";
|
||||||
|
if(delim == 0) // delim=0: stop at non read
|
||||||
|
break;
|
||||||
|
while(!ztd::filedat::isRead(str[i]) && !(str[i] == delim || str[i] == altdelim) ) // until read or delim
|
||||||
|
tval += str[i++];
|
||||||
|
if(str[i] == delim || str[i] == altdelim) // delim: stop
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val += tval;
|
||||||
|
}
|
||||||
|
else // read char
|
||||||
|
{
|
||||||
|
if(str[i] == delim || str[i] == altdelim) // delim: stop without adding delim
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
val.push_back(str[i++]); //add char and increment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ret;
|
||||||
|
if(i < str.size())
|
||||||
|
{
|
||||||
|
ret = str.substr(i);
|
||||||
|
delim_found=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while( val.size() > 0 && !ztd::filedat::isRead(val[val.size()-1]) )
|
||||||
|
val.pop_back();
|
||||||
|
ret = "";
|
||||||
|
delim_found=false;
|
||||||
|
i=str.size();
|
||||||
|
}
|
||||||
|
return std::make_tuple(val, ret, i, st, delim_found); // return
|
||||||
|
}
|
||||||
|
|
||||||
|
// key, value, rest, start of rest, start of value, start of key
|
||||||
|
static std::tuple<std::string, std::string, std::string, int, int, int> _getkeyval(const std::string& in)
|
||||||
|
{
|
||||||
|
std::string key, value, rstr;
|
||||||
|
std::tuple<std::string, std::string, int, int, bool> tup;
|
||||||
|
int dpos=-1, rpos=-1, valstart=-1, keystart=-1;
|
||||||
|
bool eq_found=false;
|
||||||
|
|
||||||
|
try // get key
|
||||||
|
{
|
||||||
|
tup=_getstrval(in, '=');
|
||||||
|
key=std::get<0>(tup);
|
||||||
|
rstr=std::get<1>(tup);
|
||||||
|
dpos=std::get<2>(tup);
|
||||||
|
keystart=std::get<3>(tup);
|
||||||
|
eq_found=std::get<4>(tup);
|
||||||
|
}
|
||||||
|
catch(ztd::format_error& e)
|
||||||
|
{
|
||||||
|
ztd::format_error(e.what(), e.origin(), in, e.where());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if(key.size() > 0 && key[0] == ';') // ignore ; : new value
|
||||||
|
{
|
||||||
|
key.erase(key.begin());
|
||||||
|
return std::make_tuple("", "", key+value+rstr, keystart+1, -1, -1);
|
||||||
|
}
|
||||||
|
if(key == "" && _skip(rstr).first != "") // key is empty
|
||||||
|
throw ztd::format_error("Value has no Key", "", in, in.find(dpos) );
|
||||||
|
if(key != "" && !eq_found) // no delim
|
||||||
|
throw ztd::format_error("Key '"+key+"' has no value", "", in, keystart+key.size());
|
||||||
|
|
||||||
|
try // get value
|
||||||
|
{
|
||||||
|
tup=_getstrval(rstr, ';', '\n');
|
||||||
|
value=std::get<0>(tup);
|
||||||
|
rstr=std::get<1>(tup);
|
||||||
|
rpos=std::get<2>(tup);
|
||||||
|
valstart = std::get<3>(tup);
|
||||||
|
}
|
||||||
|
catch(ztd::format_error& e)
|
||||||
|
{
|
||||||
|
ztd::format_error(e.what(), e.origin(), in, dpos+1+e.where());
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
*start=i;
|
int rr=-1;
|
||||||
if(i >= in_size) //ends without value
|
if(rpos >= 0)
|
||||||
{
|
rr = dpos+rpos;
|
||||||
*end = in_size;
|
else
|
||||||
return "";
|
rr = in.size();
|
||||||
}
|
|
||||||
if(in[i] == ',') //value is empty
|
|
||||||
{
|
|
||||||
*end=i+1;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
int j=0;
|
return std::make_tuple(key, value, rstr, rr, valstart, keystart);
|
||||||
if(in[i] == '\"') //"" val
|
|
||||||
{
|
|
||||||
j=1; //size
|
|
||||||
while(i+j < in_size && in[i+j]!='\"')
|
|
||||||
{
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) // no closing "
|
|
||||||
throw ztd::format_error("Double quote does not close", "", std::string(in, in_size), i-1);
|
|
||||||
j++;
|
|
||||||
ret = std::string(in+i, j);
|
|
||||||
*end=i+j;
|
|
||||||
}
|
|
||||||
else if(in[i] == '\'') //"" val
|
|
||||||
{
|
|
||||||
j=1; //size
|
|
||||||
while(i+j < in_size && in[i+j]!='\'')
|
|
||||||
{
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) // no closing '
|
|
||||||
throw ztd::format_error("Single quote does not close", "", std::string(in, in_size), i-1);
|
|
||||||
j++;
|
|
||||||
ret = std::string(in+i, j);
|
|
||||||
*end=i+j;
|
|
||||||
}
|
|
||||||
else if(in[i] == '{')
|
|
||||||
{
|
|
||||||
j=1;
|
|
||||||
int counter=0;
|
|
||||||
while( i+j < in_size && !( counter == 0 && in[i+j]=='}') )
|
|
||||||
{
|
|
||||||
if(i+j+1<in_size && in[i+j] == '/' && in[i+j+1] == '/')
|
|
||||||
while(i+j<in_size && in[i+j] != '\n')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='{')
|
|
||||||
counter++;
|
|
||||||
if(in[i+j]=='}')
|
|
||||||
counter--;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) //reached end without closing
|
|
||||||
throw ztd::format_error("Brace does not close", "", std::string(in, in_size), i);
|
|
||||||
j++;
|
|
||||||
ret = std::string(in+i, j);
|
|
||||||
*end=i+j;
|
|
||||||
}
|
|
||||||
else if(in[i] == '[')
|
|
||||||
{
|
|
||||||
j=1;
|
|
||||||
int counter=0;
|
|
||||||
while( i+j < in_size && !( counter == 0 && in[i+j]==']') )
|
|
||||||
{
|
|
||||||
if(i+j+1<in_size && in[i+j] == '/' && in[i+j+1] == '/')
|
|
||||||
while(i+j<in_size && in[i+j] != '\n')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
if(in[i+j]=='[')
|
|
||||||
counter++;
|
|
||||||
if(in[i+j]==']')
|
|
||||||
counter--;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j >= in_size) //reached end without closing
|
|
||||||
throw ztd::format_error("Bracket does not close", "", std::string(in, in_size), i);
|
|
||||||
j++;
|
|
||||||
ret = std::string(in+i, j);
|
|
||||||
*end=i+j;
|
|
||||||
}
|
|
||||||
else // no encapsulation: go to next ,
|
|
||||||
{
|
|
||||||
j=0; //size
|
|
||||||
while(i+j < in_size && in[i+j]!=',')
|
|
||||||
{
|
|
||||||
if(in[i+j]=='\\')
|
|
||||||
j++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if(i+j < in_size)
|
|
||||||
{
|
|
||||||
while( !ztd::filedat::isRead(in[i+j]) )
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
ret = std::string(in+i,j);
|
|
||||||
*end=i+j;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = *end;
|
|
||||||
while(i < in_size && !ztd::filedat::isRead(in[i]))
|
|
||||||
i++;
|
|
||||||
if( i>= in_size ) //last char
|
|
||||||
{
|
|
||||||
*end=i;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else if(in[i] ==',') //comma as expected
|
|
||||||
{
|
|
||||||
*end=i+1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else //Unexpected char
|
|
||||||
throw ztd::format_error("Expecting comma", "", std::string(in, in_size), i);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ztd::chunkdat::set(const char* in, const int in_size, int offset, filedat* parent)
|
void ztd::chunkdat::set(const std::string& in, int offset, ztd::filedat* parent)
|
||||||
{
|
{
|
||||||
this->clear(); //reset everything
|
this->clear();
|
||||||
this->m_parent=parent;
|
this->m_parent=parent;
|
||||||
this->m_offset=offset;
|
this->m_offset=offset;
|
||||||
|
|
||||||
int i=0;
|
// isolate value
|
||||||
|
auto tup = _getstrval(in); // any exception here is caught upwards
|
||||||
|
std::string str = std::get<0>(tup);
|
||||||
|
std::string rest = std::get<1>(tup);
|
||||||
|
int i = std::get<2>(tup);
|
||||||
|
int j = std::get<3>(tup);
|
||||||
|
|
||||||
while(i<in_size && !ztd::filedat::isRead(in[i])) //skip unread char
|
if(str == "") //empty: make an empty strval
|
||||||
i++;
|
|
||||||
|
|
||||||
if(i >= in_size) //empty: make an empty strval
|
|
||||||
{
|
{
|
||||||
ztd::chunk_string* cv = new ztd::chunk_string();
|
ztd::chunk_string* cv = new ztd::chunk_string();
|
||||||
m_achunk=cv;
|
m_achunk=cv;
|
||||||
cv->val = "";
|
cv->val = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( in[i] == '{')
|
if ( str[0] == '{') // map
|
||||||
{
|
{
|
||||||
i++;
|
auto p = _skip(rest);
|
||||||
int val_end=in_size-1;
|
if( p.first != "") //rest is not empty
|
||||||
while(!ztd::filedat::isRead(in[val_end])) //skip unread char
|
throw ztd::format_error("Unexpected char", "", in, i+p.second);
|
||||||
val_end--;
|
|
||||||
if(in[val_end] != '}')
|
|
||||||
throw ztd::format_error("Expecting closing brace", "", std::string(in, in_size), val_end+1);
|
|
||||||
|
|
||||||
|
str.erase(str.begin()); // remove first char '{'
|
||||||
|
i = j+1;
|
||||||
|
str.pop_back(); // remove last char '}'
|
||||||
|
|
||||||
|
// create chunk
|
||||||
ztd::chunk_map* tch = new ztd::chunk_map();
|
ztd::chunk_map* tch = new ztd::chunk_map();
|
||||||
m_achunk = tch;
|
m_achunk = tch;
|
||||||
|
|
||||||
std::string name;
|
if(_skip(str).first == "") // empty map
|
||||||
std::string val;
|
return;
|
||||||
while(i < val_end)
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
int start=0;
|
int keystart, valstart;
|
||||||
int _size=0;
|
std::string key, value;
|
||||||
int end=0;
|
p = _skip(str);
|
||||||
|
if(p.first[0] == '=')
|
||||||
while(!ztd::filedat::isRead(in[i]))
|
throw ztd::format_error("Value has no key", "", in, i+p.second);
|
||||||
i++;
|
try // get one value
|
||||||
|
|
||||||
std::string newstr=std::string(in+i, val_end-i);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
name = _getname(newstr.c_str(), newstr.size(), &start, &_size, &end);
|
auto tup2 = _getkeyval(str);
|
||||||
val = newstr.substr(start, _size);
|
key=std::get<0>(tup2); // key
|
||||||
|
value=std::get<1>(tup2); // value
|
||||||
|
str=std::get<2>(tup2); // rest
|
||||||
|
valstart = i + std::get<4>(tup2); // start of value
|
||||||
|
keystart = i + std::get<5>(tup2); // start of key
|
||||||
|
i+=std::get<3>(tup2); // add start of rest
|
||||||
}
|
}
|
||||||
catch(ztd::format_error& e)
|
catch(ztd::format_error& e)
|
||||||
{
|
{
|
||||||
throw ztd::format_error(e.what(), "", std::string(in, in_size), e.where()+i);
|
throw ztd::format_error(e.what(), e.origin(), in, i+e.where());
|
||||||
}
|
}
|
||||||
|
if(key != "") // good value
|
||||||
if( name == "" ) //no more values
|
|
||||||
break;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
ztd::chunkdat* chk = new ztd::chunkdat(val.c_str(),val.size(), offset + start+i, m_parent);
|
try // insert value
|
||||||
if(!tch->values.insert( std::make_pair(name, chk ) ).second)
|
|
||||||
{
|
{
|
||||||
delete chk;
|
ztd::chunkdat* chk = new ztd::chunkdat(value, offset + valstart, m_parent);
|
||||||
throw ztd::format_error("Key '" + name + "' already present", "", std::string(in, in_size), 0 - start );
|
if(!tch->values.insert( std::make_pair(key, chk ) ).second) // failed to insert
|
||||||
|
{
|
||||||
|
delete chk;
|
||||||
|
throw ztd::format_error("Key '" + key + "' already present", "", in, keystart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ztd::format_error& e)
|
||||||
|
{
|
||||||
|
throw ztd::format_error(e.what(), "", in, e.where() + valstart );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(ztd::format_error& e)
|
|
||||||
{
|
|
||||||
throw ztd::format_error(e.what(), "", std::string(in, in_size), e.where() + start + i );
|
|
||||||
}
|
|
||||||
|
|
||||||
i += end;
|
|
||||||
}
|
}
|
||||||
|
while(str != "");
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( in[i] == '[')
|
else if ( str[0] == '[') // map
|
||||||
{
|
{
|
||||||
i++;
|
auto p = _skip(rest);
|
||||||
int val_end=in_size-1;
|
if( p.first != "") //rest is not empty
|
||||||
while(!ztd::filedat::isRead(in[val_end])) //skip unread char
|
throw ztd::format_error("Unexpected char", "", in, i+p.second);
|
||||||
val_end--;
|
|
||||||
if(in[val_end] != ']')
|
|
||||||
throw ztd::format_error("Expecting closing bracket", "", std::string(in, in_size), val_end+1);
|
|
||||||
|
|
||||||
|
str.erase(str.begin()); // remove first char '['
|
||||||
|
i = j+1;
|
||||||
|
str.pop_back(); // remove last char ']'
|
||||||
|
|
||||||
|
// create chunk
|
||||||
ztd::chunk_list* tch = new ztd::chunk_list();
|
ztd::chunk_list* tch = new ztd::chunk_list();
|
||||||
m_achunk = tch;
|
m_achunk = tch;
|
||||||
|
|
||||||
int end=0,start=0;
|
if(_skip(str).first == "") // empty list
|
||||||
while( i < val_end )
|
return;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
std::string val;
|
int valstart;
|
||||||
std::string newstr=std::string(in+i, val_end-i);
|
std::string value;
|
||||||
try
|
try // get one value
|
||||||
{
|
{
|
||||||
val = _getlist(newstr.c_str(), newstr.size(), &start, &end);
|
auto tup2 = _getstrval(str, ',', ';');
|
||||||
|
value=std::get<0>(tup2); // value
|
||||||
|
str=std::get<1>(tup2); // rest
|
||||||
|
valstart = i + std::get<3>(tup2); // start of value
|
||||||
|
i+=std::get<2>(tup2); // add start of rest
|
||||||
}
|
}
|
||||||
catch(ztd::format_error& e)
|
catch(ztd::format_error& e)
|
||||||
{
|
{
|
||||||
throw ztd::format_error(e.what(), "", std::string(in, in_size), e.where()+i);
|
throw ztd::format_error(e.what(), e.origin(), in, e.where() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tch->list.push_back(new ztd::chunkdat(val.c_str(),val.size(), offset + start+i, m_parent) );
|
tch->list.push_back(new ztd::chunkdat(value, offset + valstart, m_parent) );
|
||||||
}
|
}
|
||||||
catch(ztd::format_error& e)
|
catch(ztd::format_error& e)
|
||||||
{
|
{
|
||||||
throw ztd::format_error(e.what(), "", std::string(in, in_size), e.where() + start + i );
|
throw ztd::format_error(e.what(), e.origin(), in, e.where() + valstart );
|
||||||
}
|
}
|
||||||
|
|
||||||
i+=end;
|
|
||||||
}
|
}
|
||||||
|
while(str != "");
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else // string value
|
else
|
||||||
{
|
{
|
||||||
int val_end=in_size;
|
ztd::chunk_string* cv = new ztd::chunk_string();
|
||||||
val_end--;
|
m_achunk=cv;
|
||||||
while(!ztd::filedat::isRead(in[val_end])) //skip unread char
|
cv->val = in;
|
||||||
val_end--;
|
|
||||||
|
|
||||||
ztd::chunk_string* tch = new ztd::chunk_string();
|
|
||||||
m_achunk = tch;
|
|
||||||
|
|
||||||
tch->val = std::string(in+i,val_end-i+1);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -776,6 +796,8 @@ std::string ztd::chunkdat::strval(unsigned int alignment, std::string const& ali
|
||||||
else if(this->type()==ztd::chunk_abstract::map)
|
else if(this->type()==ztd::chunk_abstract::map)
|
||||||
{
|
{
|
||||||
ztd::chunk_map* cp = dynamic_cast<chunk_map*>(m_achunk);
|
ztd::chunk_map* cp = dynamic_cast<chunk_map*>(m_achunk);
|
||||||
|
if(cp->values.size() <= 0)
|
||||||
|
return "{}";
|
||||||
std::string ret="{\n";
|
std::string ret="{\n";
|
||||||
for(auto it : cp->values)
|
for(auto it : cp->values)
|
||||||
{
|
{
|
||||||
|
|
@ -783,7 +805,16 @@ std::string ztd::chunkdat::strval(unsigned int alignment, std::string const& ali
|
||||||
ret += it.first;
|
ret += it.first;
|
||||||
ret += " = ";
|
ret += " = ";
|
||||||
if(it.second!=nullptr)
|
if(it.second!=nullptr)
|
||||||
ret += it.second->strval(alignment+1, aligner);
|
{
|
||||||
|
if(it.second->type() == ztd::chunk_abstract::string)
|
||||||
|
{
|
||||||
|
ret += "\"" + escape(it.second->strval(), '"') + "\"";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret += it.second->strval(alignment+1, aligner);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret += '\n';
|
ret += '\n';
|
||||||
}
|
}
|
||||||
ret += repeatString(aligner, alignment);
|
ret += repeatString(aligner, alignment);
|
||||||
|
|
@ -793,12 +824,23 @@ std::string ztd::chunkdat::strval(unsigned int alignment, std::string const& ali
|
||||||
else if(this->type()==ztd::chunk_abstract::list)
|
else if(this->type()==ztd::chunk_abstract::list)
|
||||||
{
|
{
|
||||||
ztd::chunk_list* lp = dynamic_cast<chunk_list*>(m_achunk);
|
ztd::chunk_list* lp = dynamic_cast<chunk_list*>(m_achunk);
|
||||||
|
if(lp->list.size() <= 0)
|
||||||
|
return "[]";
|
||||||
std::string ret="[\n";
|
std::string ret="[\n";
|
||||||
for(auto it : lp->list)
|
for(auto it : lp->list)
|
||||||
{
|
{
|
||||||
ret += repeatString(aligner, alignment+1);
|
ret += repeatString(aligner, alignment+1);
|
||||||
if(it!=nullptr)
|
if(it!=nullptr)
|
||||||
ret += it->strval(alignment+1, aligner);
|
{
|
||||||
|
if(it->type() == ztd::chunk_abstract::string)
|
||||||
|
{
|
||||||
|
ret += '"' + escape(it->strval(), '"') + '"';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret += it->strval(alignment+1, aligner);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret += ",\n";
|
ret += ",\n";
|
||||||
}
|
}
|
||||||
ret.erase(ret.end()-2);
|
ret.erase(ret.end()-2);
|
||||||
|
|
@ -909,21 +951,23 @@ ztd::chunkdat& ztd::chunkdat::subChunkRef(const unsigned int a) const
|
||||||
ztd::chunkdat::chunkdat()
|
ztd::chunkdat::chunkdat()
|
||||||
{
|
{
|
||||||
m_achunk=nullptr;
|
m_achunk=nullptr;
|
||||||
|
m_parent=nullptr;
|
||||||
|
m_offset=0;
|
||||||
}
|
}
|
||||||
ztd::chunkdat::chunkdat(const char* in)
|
ztd::chunkdat::chunkdat(const char* in)
|
||||||
{
|
{
|
||||||
m_achunk=nullptr;
|
m_achunk=nullptr;
|
||||||
set(in, strlen(in), 0, nullptr);
|
set(in, strlen(in), 0, nullptr);
|
||||||
}
|
}
|
||||||
ztd::chunkdat::chunkdat(std::string const& in)
|
ztd::chunkdat::chunkdat(std::string const& in, int offset, filedat* parent)
|
||||||
{
|
{
|
||||||
m_achunk=nullptr;
|
m_achunk=nullptr;
|
||||||
set(in, 0, nullptr);
|
set(in, offset, parent);
|
||||||
}
|
}
|
||||||
ztd::chunkdat::chunkdat(const char* in, const int in_size, int offset, filedat* data)
|
ztd::chunkdat::chunkdat(const char* in, const int in_size, int offset, filedat* parent)
|
||||||
{
|
{
|
||||||
m_achunk=nullptr;
|
m_achunk=nullptr;
|
||||||
set(in, in_size, offset, data);
|
set(in, in_size, offset, parent);
|
||||||
}
|
}
|
||||||
ztd::chunkdat::chunkdat(chunkdat const& in)
|
ztd::chunkdat::chunkdat(chunkdat const& in)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue