format: reformat project
Signed-off-by: Vyacheslav Ivanov <islavaivanov76@gmail.com>
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
#include "GLSLExtension.hpp"
|
||||
|
||||
#include "../util/stringutil.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
#include "../files/files.hpp"
|
||||
#include "../files/engine_paths.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include "../files/engine_paths.hpp"
|
||||
#include "../files/files.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
#include "../util/stringutil.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
void GLSLExtension::setVersion(std::string version) {
|
||||
@@ -21,7 +21,7 @@ void GLSLExtension::setPaths(const ResPaths* paths) {
|
||||
}
|
||||
|
||||
void GLSLExtension::loadHeader(const std::string& name) {
|
||||
fs::path file = paths->find("shaders/lib/"+name+".glsl");
|
||||
fs::path file = paths->find("shaders/lib/" + name + ".glsl");
|
||||
std::string source = files::read_string(file);
|
||||
addHeader(name, "");
|
||||
addHeader(name, process(file, source, true));
|
||||
@@ -38,7 +38,7 @@ void GLSLExtension::define(const std::string& name, std::string value) {
|
||||
const std::string& GLSLExtension::getHeader(const std::string& name) const {
|
||||
auto found = headers.find(name);
|
||||
if (found == headers.end()) {
|
||||
throw std::runtime_error("no header '"+name+"' loaded");
|
||||
throw std::runtime_error("no header '" + name + "' loaded");
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ const std::string& GLSLExtension::getHeader(const std::string& name) const {
|
||||
const std::string& GLSLExtension::getDefine(const std::string& name) const {
|
||||
auto found = defines.find(name);
|
||||
if (found == defines.end()) {
|
||||
throw std::runtime_error("name '"+name+"' is not defined");
|
||||
throw std::runtime_error("name '" + name + "' is not defined");
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
@@ -66,26 +66,29 @@ void GLSLExtension::undefine(const std::string& name) {
|
||||
}
|
||||
|
||||
inline std::runtime_error parsing_error(
|
||||
const fs::path& file,
|
||||
uint linenum,
|
||||
const std::string& message) {
|
||||
return std::runtime_error("file "+file.string()+": "+message+
|
||||
" at line "+std::to_string(linenum));
|
||||
const fs::path& file, uint linenum, const std::string& message
|
||||
) {
|
||||
return std::runtime_error(
|
||||
"file " + file.string() + ": " + message + " at line " +
|
||||
std::to_string(linenum)
|
||||
);
|
||||
}
|
||||
|
||||
inline void parsing_warning(
|
||||
const fs::path& file,
|
||||
uint linenum, const
|
||||
std::string& message) {
|
||||
std::cerr << "file "+file.string()+": warning: "+message+
|
||||
" at line "+std::to_string(linenum) << std::endl;
|
||||
const fs::path& file, uint linenum, const std::string& message
|
||||
) {
|
||||
std::cerr << "file " + file.string() + ": warning: " + message +
|
||||
" at line " + std::to_string(linenum)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
inline void source_line(std::stringstream& ss, uint linenum) {
|
||||
ss << "#line " << linenum << "\n";
|
||||
}
|
||||
|
||||
std::string GLSLExtension::process(const fs::path& file, const std::string& source, bool header) {
|
||||
std::string GLSLExtension::process(
|
||||
const fs::path& file, const std::string& source, bool header
|
||||
) {
|
||||
std::stringstream ss;
|
||||
size_t pos = 0;
|
||||
uint linenum = 1;
|
||||
@@ -103,43 +106,45 @@ std::string GLSLExtension::process(const fs::path& file, const std::string& sour
|
||||
}
|
||||
// parsing preprocessor directives
|
||||
if (source[pos] == '#') {
|
||||
std::string line = source.substr(pos+1, endline-pos);
|
||||
std::string line = source.substr(pos + 1, endline - pos);
|
||||
util::trim(line);
|
||||
// parsing 'include' directive
|
||||
if (line.find("include") != std::string::npos) {
|
||||
line = line.substr(7);
|
||||
util::trim(line);
|
||||
if (line.length() < 3) {
|
||||
throw parsing_error(file, linenum,
|
||||
"invalid 'include' syntax");
|
||||
throw parsing_error(
|
||||
file, linenum, "invalid 'include' syntax"
|
||||
);
|
||||
}
|
||||
if (line[0] != '<' || line[line.length()-1] != '>') {
|
||||
throw parsing_error(file, linenum,
|
||||
"expected '#include <filename>' syntax");
|
||||
if (line[0] != '<' || line[line.length() - 1] != '>') {
|
||||
throw parsing_error(
|
||||
file, linenum, "expected '#include <filename>' syntax"
|
||||
);
|
||||
}
|
||||
std::string name = line.substr(1, line.length()-2);
|
||||
std::string name = line.substr(1, line.length() - 2);
|
||||
if (!hasHeader(name)) {
|
||||
loadHeader(name);
|
||||
}
|
||||
source_line(ss, 1);
|
||||
ss << getHeader(name) << '\n';
|
||||
pos = endline+1;
|
||||
pos = endline + 1;
|
||||
linenum++;
|
||||
source_line(ss, linenum);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// removing extra 'include' directives
|
||||
else if (line.find("version") != std::string::npos) {
|
||||
parsing_warning(file, linenum, "removed #version directive");
|
||||
pos = endline+1;
|
||||
pos = endline + 1;
|
||||
linenum++;
|
||||
source_line(ss, linenum);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
linenum++;
|
||||
ss << source.substr(pos, endline+1-pos);
|
||||
pos = endline+1;
|
||||
ss << source.substr(pos, endline + 1 - pos);
|
||||
pos = endline + 1;
|
||||
}
|
||||
return ss.str();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef CODERS_GLSL_EXTESION_HPP_
|
||||
#define CODERS_GLSL_EXTESION_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class ResPaths;
|
||||
|
||||
@@ -30,10 +30,10 @@ public:
|
||||
bool hasDefine(const std::string& name) const;
|
||||
|
||||
std::string process(
|
||||
const std::filesystem::path& file,
|
||||
const std::filesystem::path& file,
|
||||
const std::string& source,
|
||||
bool header=false
|
||||
bool header = false
|
||||
);
|
||||
};
|
||||
|
||||
#endif // CODERS_GLSL_EXTESION_HPP_
|
||||
#endif // CODERS_GLSL_EXTESION_HPP_
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "binary_json.hpp"
|
||||
|
||||
#include "gzip.hpp"
|
||||
#include "byte_utils.hpp"
|
||||
#include "../data/dynamic.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "byte_utils.hpp"
|
||||
#include "gzip.hpp"
|
||||
|
||||
using namespace json;
|
||||
using namespace dynamic;
|
||||
|
||||
@@ -30,7 +30,7 @@ static void to_binary(ByteBuilder& builder, const Value& value) {
|
||||
if (val >= 0 && val <= 255) {
|
||||
builder.put(BJSON_TYPE_BYTE);
|
||||
builder.put(val);
|
||||
} else if (val >= INT16_MIN && val <= INT16_MAX){
|
||||
} else if (val >= INT16_MIN && val <= INT16_MAX) {
|
||||
builder.put(BJSON_TYPE_INT16);
|
||||
builder.putInt16(val);
|
||||
} else if (val >= INT32_MIN && val <= INT32_MAX) {
|
||||
@@ -115,7 +115,7 @@ static Value value_from_binary(ByteReader& reader) {
|
||||
return reader.getString();
|
||||
default:
|
||||
throw std::runtime_error(
|
||||
"type "+std::to_string(typecode)+" is not supported"
|
||||
"type " + std::to_string(typecode) + " is not supported"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef CODERS_BINARY_JSON_HPP_
|
||||
#define CODERS_BINARY_JSON_HPP_
|
||||
|
||||
#include "../data/dynamic_fwd.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "../data/dynamic_fwd.hpp"
|
||||
|
||||
namespace dynamic {
|
||||
class Map;
|
||||
@@ -26,9 +26,13 @@ namespace json {
|
||||
inline constexpr int BJSON_TYPE_NULL = 0xC;
|
||||
inline constexpr int BJSON_TYPE_CDOCUMENT = 0x1F;
|
||||
|
||||
std::vector<ubyte> to_binary(const dynamic::Map* obj, bool compress=false);
|
||||
std::vector<ubyte> to_binary(const dynamic::Value& obj, bool compress=false);
|
||||
std::vector<ubyte> to_binary(
|
||||
const dynamic::Map* obj, bool compress = false
|
||||
);
|
||||
std::vector<ubyte> to_binary(
|
||||
const dynamic::Value& obj, bool compress = false
|
||||
);
|
||||
std::shared_ptr<dynamic::Map> from_binary(const ubyte* src, size_t size);
|
||||
}
|
||||
|
||||
#endif // CODERS_BINARY_JSON_HPP_
|
||||
#endif // CODERS_BINARY_JSON_HPP_
|
||||
|
||||
+23
-22
@@ -9,7 +9,7 @@ void ByteBuilder::put(ubyte b) {
|
||||
}
|
||||
|
||||
void ByteBuilder::putCStr(const char* str) {
|
||||
size_t size = strlen(str)+1;
|
||||
size_t size = strlen(str) + 1;
|
||||
buffer.reserve(buffer.size() + size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
buffer.push_back(str[i]);
|
||||
@@ -37,21 +37,21 @@ void ByteBuilder::putInt16(int16_t val) {
|
||||
void ByteBuilder::putInt32(int32_t val) {
|
||||
buffer.reserve(buffer.size() + 4);
|
||||
buffer.push_back(static_cast<ubyte>(val >> 0 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 8 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 16 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 24 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 8 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 16 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 24 & 255));
|
||||
}
|
||||
|
||||
void ByteBuilder::putInt64(int64_t val) {
|
||||
buffer.reserve(buffer.size() + 8);
|
||||
buffer.push_back(static_cast<ubyte> (val >> 0 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 8 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 16 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 24 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 32 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 40 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 48 & 255));
|
||||
buffer.push_back(static_cast<ubyte> (val >> 56 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 0 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 8 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 16 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 24 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 32 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 40 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 48 & 255));
|
||||
buffer.push_back(static_cast<ubyte>(val >> 56 & 255));
|
||||
}
|
||||
|
||||
void ByteBuilder::putFloat32(float val) {
|
||||
@@ -102,8 +102,7 @@ ByteReader::ByteReader(const ubyte* data, size_t size)
|
||||
: data(data), size(size), pos(0) {
|
||||
}
|
||||
|
||||
ByteReader::ByteReader(const ubyte* data)
|
||||
: data(data), size(4), pos(0) {
|
||||
ByteReader::ByteReader(const ubyte* data) : data(data), size(4), pos(0) {
|
||||
size = getInt32();
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ void ByteReader::checkMagic(const char* data, size_t size) {
|
||||
throw std::runtime_error("invalid magic number");
|
||||
}
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (this->data[pos + i] != (ubyte)data[i]){
|
||||
if (this->data[pos + i] != (ubyte)data[i]) {
|
||||
throw std::runtime_error("invalid magic number");
|
||||
}
|
||||
}
|
||||
@@ -130,11 +129,11 @@ ubyte ByteReader::peek() {
|
||||
if (pos == size) {
|
||||
throw std::runtime_error("buffer underflow");
|
||||
}
|
||||
return data[pos];
|
||||
return data[pos];
|
||||
}
|
||||
|
||||
int16_t ByteReader::getInt16() {
|
||||
if (pos+2 > size) {
|
||||
if (pos + 2 > size) {
|
||||
throw std::runtime_error("buffer underflow");
|
||||
}
|
||||
pos += 2;
|
||||
@@ -143,7 +142,7 @@ int16_t ByteReader::getInt16() {
|
||||
}
|
||||
|
||||
int32_t ByteReader::getInt32() {
|
||||
if (pos+4 > size) {
|
||||
if (pos + 4 > size) {
|
||||
throw std::runtime_error("buffer underflow");
|
||||
}
|
||||
pos += 4;
|
||||
@@ -154,7 +153,7 @@ int32_t ByteReader::getInt32() {
|
||||
}
|
||||
|
||||
int64_t ByteReader::getInt64() {
|
||||
if (pos+8 > size) {
|
||||
if (pos + 8 > size) {
|
||||
throw std::runtime_error("buffer underflow");
|
||||
}
|
||||
pos += 8;
|
||||
@@ -183,18 +182,20 @@ double ByteReader::getFloat64() {
|
||||
}
|
||||
|
||||
const char* ByteReader::getCString() {
|
||||
const char* cstr = reinterpret_cast<const char*>(data+pos);
|
||||
const char* cstr = reinterpret_cast<const char*>(data + pos);
|
||||
pos += strlen(cstr) + 1;
|
||||
return cstr;
|
||||
}
|
||||
|
||||
std::string ByteReader::getString() {
|
||||
uint32_t length = (uint32_t)getInt32();
|
||||
if (pos+length > size) {
|
||||
if (pos + length > size) {
|
||||
throw std::runtime_error("buffer underflow");
|
||||
}
|
||||
pos += length;
|
||||
return std::string(reinterpret_cast<const char*>(data+pos-length), length);
|
||||
return std::string(
|
||||
reinterpret_cast<const char*>(data + pos - length), length
|
||||
);
|
||||
}
|
||||
|
||||
bool ByteReader::hasNext() const {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef CODERS_BYTE_UTILS_HPP_
|
||||
#define CODERS_BYTE_UTILS_HPP_
|
||||
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
/* byteorder: little-endian */
|
||||
class ByteBuilder {
|
||||
std::vector<ubyte> buffer;
|
||||
@@ -23,8 +23,8 @@ public:
|
||||
/* Write 32 bit floating-point number */
|
||||
void putFloat32(float val);
|
||||
/* Write 64 bit floating-point number */
|
||||
void putFloat64(double val);
|
||||
|
||||
void putFloat64(double val);
|
||||
|
||||
/* Write string (uint32 length + bytes) */
|
||||
void put(const std::string& s);
|
||||
/* Write sequence of bytes without any header */
|
||||
@@ -80,4 +80,4 @@ public:
|
||||
void skip(size_t n);
|
||||
};
|
||||
|
||||
#endif // CODERS_BYTE_UTILS_HPP_
|
||||
#endif // CODERS_BYTE_UTILS_HPP_
|
||||
|
||||
+64
-41
@@ -1,10 +1,11 @@
|
||||
#include "commons.hpp"
|
||||
|
||||
#include "../util/stringutil.hpp"
|
||||
#include <math.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <math.h>
|
||||
|
||||
#include "../util/stringutil.hpp"
|
||||
|
||||
inline double power(double base, int64_t power) {
|
||||
double result = 1.0;
|
||||
@@ -21,21 +22,25 @@ parsing_error::parsing_error(
|
||||
uint pos,
|
||||
uint line,
|
||||
uint linestart
|
||||
) : std::runtime_error(message), filename(filename),
|
||||
pos(pos), line(line), linestart(linestart)
|
||||
{
|
||||
)
|
||||
: std::runtime_error(message),
|
||||
filename(filename),
|
||||
pos(pos),
|
||||
line(line),
|
||||
linestart(linestart) {
|
||||
size_t end = source.find("\n", linestart);
|
||||
if (end == std::string::npos) {
|
||||
end = source.length();
|
||||
}
|
||||
this->source = source.substr(linestart, end-linestart);
|
||||
this->source = source.substr(linestart, end - linestart);
|
||||
}
|
||||
|
||||
std::string parsing_error::errorLog() const {
|
||||
std::stringstream ss;
|
||||
uint linepos = pos - linestart;
|
||||
ss << "parsing error in file '" << filename;
|
||||
ss << "' at " << (line+1) << ":" << linepos << ": " << this->what() << "\n";
|
||||
ss << "' at " << (line + 1) << ":" << linepos << ": " << this->what()
|
||||
<< "\n";
|
||||
ss << source << "\n";
|
||||
for (uint i = 0; i < linepos; i++) {
|
||||
ss << " ";
|
||||
@@ -44,10 +49,8 @@ std::string parsing_error::errorLog() const {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
BasicParser::BasicParser(
|
||||
std::string_view file,
|
||||
std::string_view source
|
||||
) : filename(file), source(source) {
|
||||
BasicParser::BasicParser(std::string_view file, std::string_view source)
|
||||
: filename(file), source(source) {
|
||||
}
|
||||
|
||||
void BasicParser::skipWhitespace() {
|
||||
@@ -67,7 +70,7 @@ void BasicParser::skipWhitespace() {
|
||||
}
|
||||
|
||||
void BasicParser::skip(size_t n) {
|
||||
n = std::min(n, source.length()-pos);
|
||||
n = std::min(n, source.length() - pos);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
char next = source[pos++];
|
||||
@@ -93,10 +96,10 @@ void BasicParser::skipLine() {
|
||||
bool BasicParser::skipTo(const std::string& substring) {
|
||||
size_t idx = source.find(substring, pos);
|
||||
if (idx == std::string::npos) {
|
||||
skip(source.length()-pos);
|
||||
skip(source.length() - pos);
|
||||
return false;
|
||||
} else {
|
||||
skip(idx-pos);
|
||||
skip(idx - pos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -122,17 +125,16 @@ char BasicParser::nextChar() {
|
||||
void BasicParser::expect(char expected) {
|
||||
char c = peek();
|
||||
if (c != expected) {
|
||||
throw error("'"+std::string({expected})+"' expected");
|
||||
throw error("'" + std::string({expected}) + "' expected");
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
void BasicParser::expect(const std::string& substring) {
|
||||
if (substring.empty())
|
||||
return;
|
||||
if (substring.empty()) return;
|
||||
for (uint i = 0; i < substring.length(); i++) {
|
||||
if (source.length() <= pos + i || source[pos+i] != substring[i]) {
|
||||
throw error(util::quote(substring)+" expected");
|
||||
if (source.length() <= pos + i || source[pos + i] != substring[i]) {
|
||||
throw error(util::quote(substring) + " expected");
|
||||
}
|
||||
}
|
||||
pos += substring.length();
|
||||
@@ -158,7 +160,7 @@ void BasicParser::goBack(size_t count) {
|
||||
if (pos < count) {
|
||||
throw std::runtime_error("pos < jump");
|
||||
}
|
||||
if (pos) {
|
||||
if (pos) {
|
||||
pos -= count;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +207,7 @@ std::string_view BasicParser::readUntil(char c) {
|
||||
while (hasNext() && source[pos] != c) {
|
||||
pos++;
|
||||
}
|
||||
return source.substr(start, pos-start);
|
||||
return source.substr(start, pos - start);
|
||||
}
|
||||
|
||||
std::string_view BasicParser::readUntilEOL() {
|
||||
@@ -213,7 +215,7 @@ std::string_view BasicParser::readUntilEOL() {
|
||||
while (hasNext() && source[pos] != '\r' && source[pos] != '\n') {
|
||||
pos++;
|
||||
}
|
||||
return source.substr(start, pos-start);
|
||||
return source.substr(start, pos - start);
|
||||
}
|
||||
|
||||
std::string BasicParser::parseName() {
|
||||
@@ -229,7 +231,7 @@ std::string BasicParser::parseName() {
|
||||
while (hasNext() && is_identifier_part(source[pos])) {
|
||||
pos++;
|
||||
}
|
||||
return std::string(source.substr(start, pos-start));
|
||||
return std::string(source.substr(start, pos - start));
|
||||
}
|
||||
|
||||
int64_t BasicParser::parseSimpleInt(int base) {
|
||||
@@ -272,14 +274,14 @@ dynamic::Value BasicParser::parseNumber() {
|
||||
dynamic::Value BasicParser::parseNumber(int sign) {
|
||||
char c = peek();
|
||||
int base = 10;
|
||||
if (c == '0' && pos + 1 < source.length() &&
|
||||
(base = is_box(source[pos+1])) != 10) {
|
||||
if (c == '0' && pos + 1 < source.length() &&
|
||||
(base = is_box(source[pos + 1])) != 10) {
|
||||
pos += 2;
|
||||
return parseSimpleInt(base);
|
||||
} else if (c == 'i' && pos + 2 < source.length() && source[pos+1] == 'n' && source[pos+2] == 'f') {
|
||||
} else if (c == 'i' && pos + 2 < source.length() && source[pos + 1] == 'n' && source[pos + 2] == 'f') {
|
||||
pos += 3;
|
||||
return INFINITY * sign;
|
||||
} else if (c == 'n' && pos + 2 < source.length() && source[pos+1] == 'a' && source[pos+2] == 'n') {
|
||||
} else if (c == 'n' && pos + 2 < source.length() && source[pos + 1] == 'a' && source[pos + 2] == 'n') {
|
||||
pos += 3;
|
||||
return NAN * sign;
|
||||
}
|
||||
@@ -294,7 +296,7 @@ dynamic::Value BasicParser::parseNumber(int sign) {
|
||||
if (peek() == '-') {
|
||||
s = -1;
|
||||
pos++;
|
||||
} else if (peek() == '+'){
|
||||
} else if (peek() == '+') {
|
||||
pos++;
|
||||
}
|
||||
return sign * value * power(10.0, s * parseSimpleInt(10));
|
||||
@@ -320,7 +322,7 @@ dynamic::Value BasicParser::parseNumber(int sign) {
|
||||
if (peek() == '-') {
|
||||
s = -1;
|
||||
pos++;
|
||||
} else if (peek() == '+'){
|
||||
} else if (peek() == '+') {
|
||||
pos++;
|
||||
}
|
||||
return sign * dvalue * power(10.0, s * parseSimpleInt(10));
|
||||
@@ -347,19 +349,40 @@ std::string BasicParser::parseString(char quote, bool closeRequired) {
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
case 'n': ss << '\n'; break;
|
||||
case 'r': ss << '\r'; break;
|
||||
case 'b': ss << '\b'; break;
|
||||
case 't': ss << '\t'; break;
|
||||
case 'f': ss << '\f'; break;
|
||||
case '\'': ss << '\\'; break;
|
||||
case '"': ss << '"'; break;
|
||||
case '\\': ss << '\\'; break;
|
||||
case '/': ss << '/'; break;
|
||||
case '\n': pos++; continue;
|
||||
case 'n':
|
||||
ss << '\n';
|
||||
break;
|
||||
case 'r':
|
||||
ss << '\r';
|
||||
break;
|
||||
case 'b':
|
||||
ss << '\b';
|
||||
break;
|
||||
case 't':
|
||||
ss << '\t';
|
||||
break;
|
||||
case 'f':
|
||||
ss << '\f';
|
||||
break;
|
||||
case '\'':
|
||||
ss << '\\';
|
||||
break;
|
||||
case '"':
|
||||
ss << '"';
|
||||
break;
|
||||
case '\\':
|
||||
ss << '\\';
|
||||
break;
|
||||
case '/':
|
||||
ss << '/';
|
||||
break;
|
||||
case '\n':
|
||||
pos++;
|
||||
continue;
|
||||
default:
|
||||
throw error("'\\" + std::string({c}) +
|
||||
"' is an illegal escape");
|
||||
throw error(
|
||||
"'\\" + std::string({c}) + "' is an illegal escape"
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
+13
-13
@@ -1,12 +1,12 @@
|
||||
#ifndef CODERS_COMMONS_HPP_
|
||||
#define CODERS_COMMONS_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
inline int is_box(int c) {
|
||||
switch (c) {
|
||||
case 'B':
|
||||
@@ -17,7 +17,7 @@ inline int is_box(int c) {
|
||||
return 8;
|
||||
case 'X':
|
||||
case 'x':
|
||||
return 16;
|
||||
return 16;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
@@ -31,7 +31,8 @@ inline bool is_whitespace(int c) {
|
||||
}
|
||||
|
||||
inline bool is_identifier_start(int c) {
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == '.';
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' ||
|
||||
c == '.';
|
||||
}
|
||||
|
||||
inline bool is_identifier_part(int c) {
|
||||
@@ -61,10 +62,10 @@ public:
|
||||
|
||||
parsing_error(
|
||||
const std::string& message,
|
||||
std::string_view filename,
|
||||
std::string_view source,
|
||||
uint pos,
|
||||
uint line,
|
||||
std::string_view filename,
|
||||
std::string_view source,
|
||||
uint pos,
|
||||
uint line,
|
||||
uint linestart
|
||||
);
|
||||
std::string errorLog() const;
|
||||
@@ -86,16 +87,15 @@ protected:
|
||||
void expect(const std::string& substring);
|
||||
bool isNext(const std::string& substring);
|
||||
void expectNewLine();
|
||||
void goBack(size_t count=1);
|
||||
void goBack(size_t count = 1);
|
||||
void reset();
|
||||
|
||||
int64_t parseSimpleInt(int base);
|
||||
dynamic::Value parseNumber(int sign);
|
||||
dynamic::Value parseNumber();
|
||||
std::string parseString(char chr, bool closeRequired=true);
|
||||
std::string parseString(char chr, bool closeRequired = true);
|
||||
|
||||
parsing_error error(const std::string& message);
|
||||
|
||||
public:
|
||||
std::string_view readUntil(char c);
|
||||
std::string_view readUntilEOL();
|
||||
@@ -109,4 +109,4 @@ public:
|
||||
BasicParser(std::string_view file, std::string_view source);
|
||||
};
|
||||
|
||||
#endif // CODERS_COMMONS_HPP_
|
||||
#endif // CODERS_COMMONS_HPP_
|
||||
|
||||
+14
-6
@@ -3,12 +3,13 @@
|
||||
#include "byte_utils.hpp"
|
||||
|
||||
#define ZLIB_CONST
|
||||
#include <zlib.h>
|
||||
#include <math.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
|
||||
size_t buffer_size = 23+size*1.01;
|
||||
size_t buffer_size = 23 + size * 1.01;
|
||||
std::vector<ubyte> buffer;
|
||||
buffer.resize(buffer_size);
|
||||
|
||||
@@ -23,8 +24,14 @@ std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
|
||||
defstream.next_out = buffer.data();
|
||||
|
||||
// compression
|
||||
deflateInit2(&defstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
||||
16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
|
||||
deflateInit2(
|
||||
&defstream,
|
||||
Z_DEFAULT_COMPRESSION,
|
||||
Z_DEFLATED,
|
||||
16 + MAX_WBITS,
|
||||
8,
|
||||
Z_DEFAULT_STRATEGY
|
||||
);
|
||||
deflate(&defstream, Z_FINISH);
|
||||
deflateEnd(&defstream);
|
||||
|
||||
@@ -35,7 +42,8 @@ std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
|
||||
|
||||
std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) {
|
||||
// getting uncompressed data length from gzip footer
|
||||
size_t decompressed_size = *reinterpret_cast<const uint32_t*>(src+size-4);
|
||||
size_t decompressed_size =
|
||||
*reinterpret_cast<const uint32_t*>(src + size - 4);
|
||||
std::vector<ubyte> buffer;
|
||||
buffer.resize(decompressed_size);
|
||||
|
||||
@@ -49,7 +57,7 @@ std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) {
|
||||
infstream.avail_out = decompressed_size;
|
||||
infstream.next_out = buffer.data();
|
||||
|
||||
inflateInit2(&infstream, 16+MAX_WBITS);
|
||||
inflateInit2(&infstream, 16 + MAX_WBITS);
|
||||
inflate(&infstream, Z_NO_FLUSH);
|
||||
inflateEnd(&infstream);
|
||||
|
||||
|
||||
+5
-4
@@ -1,9 +1,10 @@
|
||||
#ifndef CODERS_GZIP_HPP_
|
||||
#define CODERS_GZIP_HPP_
|
||||
|
||||
#include "../typedefs.hpp"
|
||||
#include <vector>
|
||||
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
namespace gzip {
|
||||
const unsigned char MAGIC[] = "\x1F\x8B";
|
||||
|
||||
@@ -11,11 +12,11 @@ namespace gzip {
|
||||
@param src source bytes array
|
||||
@param size length of source bytes array */
|
||||
std::vector<ubyte> compress(const ubyte* src, size_t size);
|
||||
|
||||
/* Decompress bytes array from GZIP
|
||||
|
||||
/* Decompress bytes array from GZIP
|
||||
@param src GZIP data
|
||||
@param size length of GZIP data */
|
||||
std::vector<ubyte> decompress(const ubyte* src, size_t size);
|
||||
}
|
||||
|
||||
#endif // CODERS_GZIP_HPP_
|
||||
#endif // CODERS_GZIP_HPP_
|
||||
|
||||
+11
-6
@@ -1,15 +1,16 @@
|
||||
#include "imageio.hpp"
|
||||
|
||||
#include "png.hpp"
|
||||
#include "../graphics/core/ImageData.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../graphics/core/ImageData.hpp"
|
||||
#include "png.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
using image_reader = std::function<std::unique_ptr<ImageData>(const std::string&)>;
|
||||
using image_reader =
|
||||
std::function<std::unique_ptr<ImageData>(const std::string&)>;
|
||||
using image_writer = std::function<void(const std::string&, const ImageData*)>;
|
||||
|
||||
static std::unordered_map<std::string, image_reader> readers {
|
||||
@@ -35,7 +36,9 @@ inline std::string extensionOf(const std::string& filename) {
|
||||
std::unique_ptr<ImageData> imageio::read(const std::string& filename) {
|
||||
auto found = readers.find(extensionOf(filename));
|
||||
if (found == readers.end()) {
|
||||
throw std::runtime_error("file format is not supported (read): "+filename);
|
||||
throw std::runtime_error(
|
||||
"file format is not supported (read): " + filename
|
||||
);
|
||||
}
|
||||
return std::unique_ptr<ImageData>(found->second(filename));
|
||||
}
|
||||
@@ -43,7 +46,9 @@ std::unique_ptr<ImageData> imageio::read(const std::string& filename) {
|
||||
void imageio::write(const std::string& filename, const ImageData* image) {
|
||||
auto found = writers.find(extensionOf(filename));
|
||||
if (found == writers.end()) {
|
||||
throw std::runtime_error("file format is not supported (write): "+filename);
|
||||
throw std::runtime_error(
|
||||
"file format is not supported (write): " + filename
|
||||
);
|
||||
}
|
||||
return found->second(filename, image);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef CODERS_IMAGEIO_HPP_
|
||||
#define CODERS_IMAGEIO_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class ImageData;
|
||||
|
||||
@@ -16,4 +16,4 @@ namespace imageio {
|
||||
void write(const std::string& filename, const ImageData* image);
|
||||
}
|
||||
|
||||
#endif // CODERS_IMAGEIO_HPP_
|
||||
#endif // CODERS_IMAGEIO_HPP_
|
||||
|
||||
+32
-37
@@ -1,14 +1,14 @@
|
||||
#include "json.hpp"
|
||||
|
||||
#include "commons.hpp"
|
||||
#include <math.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "../util/stringutil.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include "commons.hpp"
|
||||
|
||||
using namespace json;
|
||||
using namespace dynamic;
|
||||
@@ -19,14 +19,12 @@ class Parser : BasicParser {
|
||||
dynamic::Value parseValue();
|
||||
public:
|
||||
Parser(std::string_view filename, std::string_view source);
|
||||
|
||||
|
||||
std::unique_ptr<dynamic::Map> parse();
|
||||
};
|
||||
|
||||
inline void newline(
|
||||
std::stringstream& ss,
|
||||
bool nice, uint indent,
|
||||
const std::string& indentstr
|
||||
std::stringstream& ss, bool nice, uint indent, const std::string& indentstr
|
||||
) {
|
||||
if (nice) {
|
||||
ss << "\n";
|
||||
@@ -39,24 +37,23 @@ inline void newline(
|
||||
}
|
||||
|
||||
void stringifyObj(
|
||||
const Map* obj,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
const Map* obj,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
bool nice
|
||||
);
|
||||
|
||||
void stringifyValue(
|
||||
const Value& value,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
const Value& value,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
bool nice
|
||||
) {
|
||||
if (auto map = std::get_if<Map_sptr>(&value)) {
|
||||
stringifyObj(map->get(), ss, indent, indentstr, nice);
|
||||
}
|
||||
else if (auto listptr = std::get_if<List_sptr>(&value)) {
|
||||
} else if (auto listptr = std::get_if<List_sptr>(&value)) {
|
||||
auto list = *listptr;
|
||||
if (list->size() == 0) {
|
||||
ss << "[]";
|
||||
@@ -68,7 +65,7 @@ void stringifyValue(
|
||||
if (i > 0 || nice) {
|
||||
newline(ss, nice, indent, indentstr);
|
||||
}
|
||||
stringifyValue(value, ss, indent+1, indentstr, nice);
|
||||
stringifyValue(value, ss, indent + 1, indentstr, nice);
|
||||
if (i + 1 < list->size()) {
|
||||
ss << ',';
|
||||
}
|
||||
@@ -91,10 +88,10 @@ void stringifyValue(
|
||||
}
|
||||
|
||||
void stringifyObj(
|
||||
const Map* obj,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
const Map* obj,
|
||||
std::stringstream& ss,
|
||||
int indent,
|
||||
const std::string& indentstr,
|
||||
bool nice
|
||||
) {
|
||||
if (obj == nullptr) {
|
||||
@@ -114,22 +111,20 @@ void stringifyObj(
|
||||
}
|
||||
const Value& value = entry.second;
|
||||
ss << util::escape(key) << ": ";
|
||||
stringifyValue(value, ss, indent+1, indentstr, nice);
|
||||
stringifyValue(value, ss, indent + 1, indentstr, nice);
|
||||
index++;
|
||||
if (index < obj->values.size()) {
|
||||
ss << ',';
|
||||
}
|
||||
}
|
||||
if (nice) {
|
||||
newline(ss, true, indent-1, indentstr);
|
||||
newline(ss, true, indent - 1, indentstr);
|
||||
}
|
||||
ss << '}';
|
||||
}
|
||||
|
||||
std::string json::stringify(
|
||||
const Map* obj,
|
||||
bool nice,
|
||||
const std::string& indent
|
||||
const Map* obj, bool nice, const std::string& indent
|
||||
) {
|
||||
std::stringstream ss;
|
||||
stringifyObj(obj, ss, 1, indent, nice);
|
||||
@@ -137,17 +132,15 @@ std::string json::stringify(
|
||||
}
|
||||
|
||||
std::string json::stringify(
|
||||
const dynamic::Value& value,
|
||||
bool nice,
|
||||
const std::string& indent
|
||||
const dynamic::Value& value, bool nice, const std::string& indent
|
||||
) {
|
||||
std::stringstream ss;
|
||||
stringifyValue(value, ss, 1, indent, nice);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
Parser::Parser(std::string_view filename, std::string_view source)
|
||||
: BasicParser(filename, source) {
|
||||
Parser::Parser(std::string_view filename, std::string_view source)
|
||||
: BasicParser(filename, source) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Map> Parser::parse() {
|
||||
@@ -239,10 +232,12 @@ Value Parser::parseValue() {
|
||||
pos++;
|
||||
return parseString(next);
|
||||
}
|
||||
throw error("unexpected character '"+std::string({next})+"'");
|
||||
throw error("unexpected character '" + std::string({next}) + "'");
|
||||
}
|
||||
|
||||
dynamic::Map_sptr json::parse(std::string_view filename, std::string_view source) {
|
||||
dynamic::Map_sptr json::parse(
|
||||
std::string_view filename, std::string_view source
|
||||
) {
|
||||
Parser parser(filename, source);
|
||||
return parser.parse();
|
||||
}
|
||||
|
||||
+5
-10
@@ -1,28 +1,23 @@
|
||||
#ifndef CODERS_JSON_HPP_
|
||||
#define CODERS_JSON_HPP_
|
||||
|
||||
#include "binary_json.hpp"
|
||||
#include <string>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
#include "binary_json.hpp"
|
||||
|
||||
namespace json {
|
||||
dynamic::Map_sptr parse(std::string_view filename, std::string_view source);
|
||||
dynamic::Map_sptr parse(std::string_view source);
|
||||
|
||||
std::string stringify(
|
||||
const dynamic::Map* obj,
|
||||
bool nice,
|
||||
const std::string& indent
|
||||
const dynamic::Map* obj, bool nice, const std::string& indent
|
||||
);
|
||||
|
||||
std::string stringify(
|
||||
const dynamic::Value& value,
|
||||
bool nice,
|
||||
const std::string& indent
|
||||
const dynamic::Value& value, bool nice, const std::string& indent
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_JSON_HPP_
|
||||
#endif // CODERS_JSON_HPP_
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
#include "obj.hpp"
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "../graphics/core/Model.hpp"
|
||||
#include "commons.hpp"
|
||||
|
||||
using namespace model;
|
||||
|
||||
@@ -34,8 +34,7 @@ class ObjParser : BasicParser {
|
||||
} while (peekInLine() != '\n' && ++i < 3);
|
||||
|
||||
vertices.push_back(Vertex {
|
||||
coords[indices[0]], uvs[indices[1]], normals[indices[2]]
|
||||
});
|
||||
coords[indices[0]], uvs[indices[1]], normals[indices[2]]});
|
||||
}
|
||||
}
|
||||
if (peekInLine() != '\n' && hasNext()) {
|
||||
@@ -51,7 +50,8 @@ class ObjParser : BasicParser {
|
||||
}
|
||||
}
|
||||
public:
|
||||
ObjParser(const std::string_view file, const std::string_view src) : BasicParser(file, src) {
|
||||
ObjParser(const std::string_view file, const std::string_view src)
|
||||
: BasicParser(file, src) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Model> parse() {
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
}
|
||||
skipLine();
|
||||
}
|
||||
} while(hasNext());
|
||||
} while (hasNext());
|
||||
model->clean();
|
||||
return model;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
#ifndef CODERS_OBJ_HPP_
|
||||
#define CODERS_OBJ_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
/// Wavefont OBJ files parser
|
||||
|
||||
@@ -16,4 +16,4 @@ namespace obj {
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_OBJ_HPP_
|
||||
#endif // CODERS_OBJ_HPP_
|
||||
|
||||
+34
-20
@@ -1,13 +1,14 @@
|
||||
#include "ogg.hpp"
|
||||
|
||||
#include "../debug/Logger.hpp"
|
||||
#include "../audio/audio.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../audio/audio.hpp"
|
||||
#include "../debug/Logger.hpp"
|
||||
#include "../typedefs.hpp"
|
||||
|
||||
static debug::Logger logger("ogg");
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
@@ -15,14 +16,21 @@ using namespace audio;
|
||||
|
||||
static inline std::string vorbis_error_message(int code) {
|
||||
switch (code) {
|
||||
case 0: return "no error";
|
||||
case OV_EREAD: return "a read from media returned an error";
|
||||
case OV_ENOTVORBIS: return "the given file/data was not recognized as Ogg Vorbis data";
|
||||
case OV_EVERSION: return "vorbis version mismatch";
|
||||
case OV_EBADHEADER: return "invalid Vorbis bitstream header";
|
||||
case OV_EFAULT: return "internal logic fault";
|
||||
case OV_EINVAL: return "invalid read operation";
|
||||
case OV_EBADLINK:
|
||||
case 0:
|
||||
return "no error";
|
||||
case OV_EREAD:
|
||||
return "a read from media returned an error";
|
||||
case OV_ENOTVORBIS:
|
||||
return "the given file/data was not recognized as Ogg Vorbis data";
|
||||
case OV_EVERSION:
|
||||
return "vorbis version mismatch";
|
||||
case OV_EBADHEADER:
|
||||
return "invalid Vorbis bitstream header";
|
||||
case OV_EFAULT:
|
||||
return "internal logic fault";
|
||||
case OV_EINVAL:
|
||||
return "invalid read operation";
|
||||
case OV_EBADLINK:
|
||||
return "the given link exists in the Vorbis data stream,"
|
||||
" but is not decipherable due to garbacge or corruption";
|
||||
case OV_ENOSEEK:
|
||||
@@ -30,15 +38,17 @@ static inline std::string vorbis_error_message(int code) {
|
||||
case OV_EIMPL:
|
||||
return "feature not implemented";
|
||||
default:
|
||||
return "unknown error ["+std::to_string(code)+"]";
|
||||
return "unknown error [" + std::to_string(code) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<audio::PCM> ogg::load_pcm(const fs::path& file, bool headerOnly) {
|
||||
std::unique_ptr<audio::PCM> ogg::load_pcm(
|
||||
const fs::path& file, bool headerOnly
|
||||
) {
|
||||
OggVorbis_File vf;
|
||||
int code;
|
||||
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
||||
throw std::runtime_error("vorbis: "+vorbis_error_message(code));
|
||||
throw std::runtime_error("vorbis: " + vorbis_error_message(code));
|
||||
}
|
||||
std::vector<char> data;
|
||||
|
||||
@@ -59,9 +69,12 @@ std::unique_ptr<audio::PCM> ogg::load_pcm(const fs::path& file, bool headerOnly)
|
||||
if (ret == 0) {
|
||||
eof = true;
|
||||
} else if (ret < 0) {
|
||||
logger.error() << "ogg::load_pcm: " << vorbis_error_message(ret);
|
||||
logger.error()
|
||||
<< "ogg::load_pcm: " << vorbis_error_message(ret);
|
||||
} else {
|
||||
data.insert(data.end(), std::begin(buffer), std::begin(buffer)+ret);
|
||||
data.insert(
|
||||
data.end(), std::begin(buffer), std::begin(buffer) + ret
|
||||
);
|
||||
}
|
||||
}
|
||||
totalSamples = data.size() / channels / 2;
|
||||
@@ -103,7 +116,8 @@ public:
|
||||
int bitstream = 0;
|
||||
long bytes = ov_read(&vf, buffer, bufferSize, 0, 2, true, &bitstream);
|
||||
if (bytes < 0) {
|
||||
logger.error() << "ogg::load_pcm: " << vorbis_error_message(bytes) << " " << bytes;
|
||||
logger.error() << "ogg::load_pcm: " << vorbis_error_message(bytes)
|
||||
<< " " << bytes;
|
||||
return PCMStream::ERROR;
|
||||
}
|
||||
return bytes;
|
||||
@@ -156,7 +170,7 @@ std::unique_ptr<PCMStream> ogg::create_stream(const fs::path& file) {
|
||||
OggVorbis_File vf;
|
||||
int code;
|
||||
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
|
||||
throw std::runtime_error("vorbis: "+vorbis_error_message(code));
|
||||
throw std::runtime_error("vorbis: " + vorbis_error_message(code));
|
||||
}
|
||||
return std::make_unique<OggStream>(vf);
|
||||
}
|
||||
|
||||
+7
-3
@@ -9,8 +9,12 @@ namespace audio {
|
||||
}
|
||||
|
||||
namespace ogg {
|
||||
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly);
|
||||
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file);
|
||||
std::unique_ptr<audio::PCM> load_pcm(
|
||||
const std::filesystem::path& file, bool headerOnly
|
||||
);
|
||||
std::unique_ptr<audio::PCMStream> create_stream(
|
||||
const std::filesystem::path& file
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_OGG_HPP_
|
||||
#endif // CODERS_OGG_HPP_
|
||||
|
||||
+95
-74
@@ -1,12 +1,13 @@
|
||||
#include "png.hpp"
|
||||
|
||||
#include "../graphics/core/ImageData.hpp"
|
||||
#include "../graphics/core/GLTexture.hpp"
|
||||
#include "../files/files.hpp"
|
||||
#include "../debug/Logger.hpp"
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "../debug/Logger.hpp"
|
||||
#include "../files/files.hpp"
|
||||
#include "../graphics/core/GLTexture.hpp"
|
||||
#include "../graphics/core/ImageData.hpp"
|
||||
|
||||
static debug::Logger logger("png-coder");
|
||||
|
||||
@@ -18,7 +19,9 @@ static debug::Logger logger("png-coder");
|
||||
#include <png.h>
|
||||
|
||||
// returns 0 if all-right, 1 otherwise
|
||||
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) {
|
||||
int _png_write(
|
||||
const char* filename, uint width, uint height, const ubyte* data, bool alpha
|
||||
) {
|
||||
uint pixsize = alpha ? 4 : 3;
|
||||
|
||||
// Open file for writing (binary mode)
|
||||
@@ -30,7 +33,9 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
}
|
||||
|
||||
// Initialize write structure
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
png_structp png_ptr = png_create_write_struct(
|
||||
PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr
|
||||
);
|
||||
if (png_ptr == nullptr) {
|
||||
logger.error() << "could not allocate write struct";
|
||||
fclose(fp);
|
||||
@@ -43,9 +48,8 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
logger.error() << "could not allocate info struct";
|
||||
fclose(fp);
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)nullptr);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp) nullptr);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
// Setup Exception handling
|
||||
@@ -60,13 +64,17 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
// Write header (8 bit colour depth)
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height,
|
||||
8,
|
||||
alpha ? PNG_COLOR_TYPE_RGBA :
|
||||
PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
png_set_IHDR(
|
||||
png_ptr,
|
||||
info_ptr,
|
||||
width,
|
||||
height,
|
||||
8,
|
||||
alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE
|
||||
);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
@@ -75,7 +83,8 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
for (uint y = 0; y < height; y++) {
|
||||
for (uint x = 0; x < width; x++) {
|
||||
for (uint i = 0; i < pixsize; i++) {
|
||||
row[x * pixsize + i] = (png_byte)data[(y * width + x) * pixsize + i];
|
||||
row[x * pixsize + i] =
|
||||
(png_byte)data[(y * width + x) * pixsize + i];
|
||||
}
|
||||
}
|
||||
png_write_row(png_ptr, row.get());
|
||||
@@ -90,29 +99,31 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
std::unique_ptr<ImageData> _png_load(const char* file) {
|
||||
FILE* fp = nullptr;
|
||||
if ((fp = fopen(file, "rb")) == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
png_struct* png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
png_struct* png = png_create_read_struct(
|
||||
PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr
|
||||
);
|
||||
if (png == nullptr) {
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
png_info* info = png_create_info_struct(png);
|
||||
if (info == nullptr) {
|
||||
png_destroy_read_struct(&png, (png_info**) nullptr, (png_info**) nullptr);
|
||||
png_destroy_read_struct(&png, (png_info**)nullptr, (png_info**)nullptr);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
png_info* end_info = png_create_info_struct(png);
|
||||
if (end_info == nullptr) {
|
||||
png_destroy_read_struct(&png, (png_info**) nullptr, (png_info**) nullptr);
|
||||
png_destroy_read_struct(&png, (png_info**)nullptr, (png_info**)nullptr);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
fclose(fp);
|
||||
@@ -122,46 +133,42 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
png_init_io(png, fp);
|
||||
png_read_info(png, info);
|
||||
|
||||
int width = png_get_image_width(png, info);
|
||||
int height = png_get_image_height(png, info);
|
||||
int width = png_get_image_width(png, info);
|
||||
int height = png_get_image_height(png, info);
|
||||
png_byte color_type = png_get_color_type(png, info);
|
||||
int bit_depth = png_get_bit_depth(png, info);
|
||||
int bit_depth = png_get_bit_depth(png, info);
|
||||
|
||||
if(bit_depth == 16)
|
||||
png_set_strip_16(png);
|
||||
if (bit_depth == 16) png_set_strip_16(png);
|
||||
|
||||
if(color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb(png);
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
|
||||
|
||||
if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png);
|
||||
|
||||
if(png_get_valid(png, info, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png);
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
|
||||
|
||||
// These color_type don't have an alpha channel then fill it with 0xff.
|
||||
if(color_type == PNG_COLOR_TYPE_RGB ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
|
||||
|
||||
if(color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
|
||||
png_read_update_info(png, info);
|
||||
|
||||
int row_bytes = png_get_rowbytes(png, info);
|
||||
//color_type = png_get_color_type(png, info);
|
||||
// png_get_color_type returns 2 (RGB) but raster always have alpha channel
|
||||
// due to PNG_FILLER_AFTER
|
||||
// color_type = png_get_color_type(png, info);
|
||||
// png_get_color_type returns 2 (RGB) but raster always have alpha channel
|
||||
// due to PNG_FILLER_AFTER
|
||||
|
||||
color_type = 6;
|
||||
bit_depth = png_get_bit_depth(png, info);
|
||||
bit_depth = png_get_bit_depth(png, info);
|
||||
|
||||
auto image_data = std::make_unique<png_byte[]>(row_bytes * height);
|
||||
auto row_pointers = std::make_unique<png_byte*[]>(height);
|
||||
for (int i = 0; i < height; ++i ) {
|
||||
for (int i = 0; i < height; ++i) {
|
||||
row_pointers[height - 1 - i] = image_data.get() + i * row_bytes;
|
||||
}
|
||||
png_read_image(png, row_pointers.get());
|
||||
@@ -175,29 +182,34 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
format = ImageFormat::rgb888;
|
||||
break;
|
||||
default:
|
||||
logger.error() << "color type " << color_type << " is not supported!";
|
||||
logger.error() << "color type " << color_type
|
||||
<< " is not supported!";
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
auto image = std::make_unique<ImageData>(format, width, height, std::move(image_data));
|
||||
auto image = std::make_unique<ImageData>(
|
||||
format, width, height, std::move(image_data)
|
||||
);
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
fclose(fp);
|
||||
return image;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#include <spng.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
static const int SPNG_SUCCESS = 0;
|
||||
//returns spng result code
|
||||
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) {
|
||||
// returns spng result code
|
||||
int _png_write(
|
||||
const char* filename, uint width, uint height, const ubyte* data, bool alpha
|
||||
) {
|
||||
int fmt;
|
||||
int ret = 0;
|
||||
spng_ctx* ctx = nullptr;
|
||||
spng_ihdr ihdr = { 0 };
|
||||
spng_ihdr ihdr = {0};
|
||||
uint pixsize = alpha ? 4 : 3;
|
||||
|
||||
ctx = spng_ctx_new(SPNG_CTX_ENCODER);
|
||||
@@ -205,12 +217,19 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
|
||||
ihdr.width = width;
|
||||
ihdr.height = height;
|
||||
ihdr.color_type = alpha ? SPNG_COLOR_TYPE_TRUECOLOR_ALPHA : SPNG_COLOR_TYPE_TRUECOLOR;
|
||||
ihdr.color_type =
|
||||
alpha ? SPNG_COLOR_TYPE_TRUECOLOR_ALPHA : SPNG_COLOR_TYPE_TRUECOLOR;
|
||||
ihdr.bit_depth = 8;
|
||||
|
||||
spng_set_ihdr(ctx, &ihdr);
|
||||
fmt = SPNG_FMT_PNG;
|
||||
ret = spng_encode_image(ctx, data, (size_t)width * (size_t)height * pixsize , fmt, SPNG_ENCODE_FINALIZE);
|
||||
ret = spng_encode_image(
|
||||
ctx,
|
||||
data,
|
||||
(size_t)width * (size_t)height * pixsize,
|
||||
fmt,
|
||||
SPNG_ENCODE_FINALIZE
|
||||
);
|
||||
if (ret != SPNG_SUCCESS) {
|
||||
logger.error() << "spng_encode_image() error: " << spng_strerror(ret);
|
||||
spng_ctx_free(ctx);
|
||||
@@ -222,21 +241,20 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
|
||||
if (png_buf == nullptr) {
|
||||
logger.error() << "spng_get_png_buffer() error: " << spng_strerror(ret);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
files::write_bytes(filename, (const unsigned char*)png_buf, png_size);
|
||||
}
|
||||
spng_ctx_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
std::unique_ptr<ImageData> _png_load(const char* file) {
|
||||
int r = 0;
|
||||
FILE *png = nullptr;
|
||||
spng_ctx *ctx = nullptr;
|
||||
FILE* png = nullptr;
|
||||
spng_ctx* ctx = nullptr;
|
||||
|
||||
png = fopen(file, "rb");
|
||||
if (png == nullptr){
|
||||
if (png == nullptr) {
|
||||
logger.error() << "could not to open file " << file;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -244,31 +262,32 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
fseek(png, 0, SEEK_END);
|
||||
long siz_pngbuf = ftell(png);
|
||||
rewind(png);
|
||||
if(siz_pngbuf < 1) {
|
||||
if (siz_pngbuf < 1) {
|
||||
fclose(png);
|
||||
logger.error() << "could not to read file " << file;
|
||||
return nullptr;
|
||||
}
|
||||
auto pngbuf = std::make_unique<char[]>(siz_pngbuf);
|
||||
if(fread(pngbuf.get(), siz_pngbuf, 1, png) != 1){ //check of read elements count
|
||||
if (fread(pngbuf.get(), siz_pngbuf, 1, png) !=
|
||||
1) { // check of read elements count
|
||||
fclose(png);
|
||||
logger.error() << "fread() failed: " << file;
|
||||
return nullptr;
|
||||
}
|
||||
fclose(png); // <- finally closing file
|
||||
fclose(png); // <- finally closing file
|
||||
ctx = spng_ctx_new(0);
|
||||
if (ctx == nullptr){
|
||||
if (ctx == nullptr) {
|
||||
logger.error() << "spng_ctx_new() failed";
|
||||
return nullptr;
|
||||
}
|
||||
r = spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
|
||||
if (r != SPNG_SUCCESS){
|
||||
if (r != SPNG_SUCCESS) {
|
||||
spng_ctx_free(ctx);
|
||||
logger.error() << "spng_set_crc_action(): " << spng_strerror(r);
|
||||
return nullptr;
|
||||
}
|
||||
r = spng_set_png_buffer(ctx, pngbuf.get(), siz_pngbuf);
|
||||
if (r != SPNG_SUCCESS){
|
||||
if (r != SPNG_SUCCESS) {
|
||||
spng_ctx_free(ctx);
|
||||
logger.error() << "spng_set_png_buffer(): " << spng_strerror(r);
|
||||
return nullptr;
|
||||
@@ -276,7 +295,7 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
|
||||
spng_ihdr ihdr;
|
||||
r = spng_get_ihdr(ctx, &ihdr);
|
||||
if (r != SPNG_SUCCESS){
|
||||
if (r != SPNG_SUCCESS) {
|
||||
spng_ctx_free(ctx);
|
||||
logger.error() << "spng_get_ihdr(): " << spng_strerror(r);
|
||||
return nullptr;
|
||||
@@ -284,28 +303,30 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
|
||||
size_t out_size;
|
||||
r = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &out_size);
|
||||
if (r != SPNG_SUCCESS){
|
||||
if (r != SPNG_SUCCESS) {
|
||||
spng_ctx_free(ctx);
|
||||
logger.error() << "spng_decoded_image_size(): " << spng_strerror(r);
|
||||
return nullptr;
|
||||
}
|
||||
auto out = std::make_unique<ubyte[]>(out_size);
|
||||
r = spng_decode_image(ctx, out.get(), out_size, SPNG_FMT_RGBA8, 0);
|
||||
if (r != SPNG_SUCCESS){
|
||||
if (r != SPNG_SUCCESS) {
|
||||
spng_ctx_free(ctx);
|
||||
logger.error() << "spng_decode_image(): " << spng_strerror(r);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto flipped = std::make_unique<ubyte[]>(out_size);
|
||||
for (size_t i = 0; i < ihdr.height; i+=1){
|
||||
size_t rowsize = ihdr.width*4;
|
||||
for (size_t j = 0; j < rowsize; j++){
|
||||
flipped[(ihdr.height-i-1)*rowsize+j] = out[i*rowsize+j];
|
||||
for (size_t i = 0; i < ihdr.height; i += 1) {
|
||||
size_t rowsize = ihdr.width * 4;
|
||||
for (size_t j = 0; j < rowsize; j++) {
|
||||
flipped[(ihdr.height - i - 1) * rowsize + j] = out[i * rowsize + j];
|
||||
}
|
||||
}
|
||||
|
||||
auto image = std::make_unique<ImageData>(ImageFormat::rgba8888, ihdr.width, ihdr.height, std::move(flipped));
|
||||
auto image = std::make_unique<ImageData>(
|
||||
ImageFormat::rgba8888, ihdr.width, ihdr.height, std::move(flipped)
|
||||
);
|
||||
spng_ctx_free(ctx);
|
||||
return image;
|
||||
}
|
||||
@@ -314,7 +335,7 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
||||
std::unique_ptr<ImageData> png::load_image(const std::string& filename) {
|
||||
auto image = _png_load(filename.c_str());
|
||||
if (image == nullptr) {
|
||||
throw std::runtime_error("could not load image "+filename);
|
||||
throw std::runtime_error("could not load image " + filename);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
@@ -328,10 +349,10 @@ std::unique_ptr<Texture> png::load_texture(const std::string& filename) {
|
||||
|
||||
void png::write_image(const std::string& filename, const ImageData* image) {
|
||||
_png_write(
|
||||
filename.c_str(),
|
||||
image->getWidth(),
|
||||
image->getHeight(),
|
||||
(const ubyte*)image->getData(),
|
||||
filename.c_str(),
|
||||
image->getWidth(),
|
||||
image->getHeight(),
|
||||
(const ubyte*)image->getData(),
|
||||
image->getFormat() == ImageFormat::rgba8888
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ namespace png {
|
||||
std::unique_ptr<Texture> load_texture(const std::string& filename);
|
||||
}
|
||||
|
||||
#endif // CODERS_PNG_HPP_
|
||||
#endif // CODERS_PNG_HPP_
|
||||
|
||||
+4
-9
@@ -26,8 +26,7 @@ size_t rle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
|
||||
dst[offset++] = c;
|
||||
c = cnext;
|
||||
counter = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +35,6 @@ size_t rle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
size_t extrle::decode(const ubyte* src, size_t srclen, ubyte* dst) {
|
||||
size_t offset = 0;
|
||||
for (size_t i = 0; i < srclen;) {
|
||||
@@ -66,23 +64,20 @@ size_t extrle::encode(const ubyte* src, size_t srclen, ubyte* dst) {
|
||||
if (counter >= 0x80) {
|
||||
dst[offset++] = 0x80 | (counter & 0x7F);
|
||||
dst[offset++] = counter >> 7;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dst[offset++] = counter;
|
||||
}
|
||||
dst[offset++] = c;
|
||||
c = cnext;
|
||||
counter = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
if (counter >= 0x80) {
|
||||
dst[offset++] = 0x80 | (counter & 0x7F);
|
||||
dst[offset++] = counter >> 7;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dst[offset++] = counter;
|
||||
}
|
||||
dst[offset++] = c;
|
||||
|
||||
+1
-1
@@ -14,4 +14,4 @@ namespace extrle {
|
||||
size_t decode(const ubyte* src, size_t length, ubyte* dst);
|
||||
}
|
||||
|
||||
#endif // CODERS_RLE_HPP_
|
||||
#endif // CODERS_RLE_HPP_
|
||||
|
||||
+18
-18
@@ -1,15 +1,16 @@
|
||||
#include "toml.hpp"
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "../data/setting.hpp"
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "../util/stringutil.hpp"
|
||||
#include "../files/settings_io.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include "../data/setting.hpp"
|
||||
#include "../files/settings_io.hpp"
|
||||
#include "../util/stringutil.hpp"
|
||||
#include "commons.hpp"
|
||||
|
||||
using namespace toml;
|
||||
|
||||
@@ -48,7 +49,7 @@ class TomlReader : BasicParser {
|
||||
} else {
|
||||
rootMap = *map;
|
||||
}
|
||||
offset = index+1;
|
||||
offset = index + 1;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@@ -93,12 +94,9 @@ class TomlReader : BasicParser {
|
||||
expectNewLine();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
TomlReader(
|
||||
std::string_view file,
|
||||
std::string_view source)
|
||||
: BasicParser(file, source) {
|
||||
TomlReader(std::string_view file, std::string_view source)
|
||||
: BasicParser(file, source) {
|
||||
root = dynamic::create_map();
|
||||
}
|
||||
|
||||
@@ -129,7 +127,7 @@ void toml::parse(
|
||||
for (auto& sectionEntry : (*sectionMap)->values) {
|
||||
const auto& name = sectionEntry.first;
|
||||
auto& value = sectionEntry.second;
|
||||
auto fullname = sectionName+"."+name;
|
||||
auto fullname = sectionName + "." + name;
|
||||
if (handler.has(fullname)) {
|
||||
handler.setValue(fullname, value);
|
||||
}
|
||||
@@ -150,9 +148,11 @@ std::string toml::stringify(dynamic::Map& root, const std::string& name) {
|
||||
}
|
||||
for (auto& entry : root.values) {
|
||||
if (auto submap = std::get_if<dynamic::Map_sptr>(&entry.second)) {
|
||||
ss << "\n" << toml::stringify(
|
||||
**submap, name.empty() ? entry.first : name+"."+entry.first
|
||||
);
|
||||
ss << "\n"
|
||||
<< toml::stringify(
|
||||
**submap,
|
||||
name.empty() ? entry.first : name + "." + entry.first
|
||||
);
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
@@ -166,7 +166,7 @@ std::string toml::stringify(SettingsHandler& handler) {
|
||||
ss << "[" << section.name << "]\n";
|
||||
for (const std::string& key : section.keys) {
|
||||
ss << key << " = ";
|
||||
auto setting = handler.getSetting(section.name+"."+key);
|
||||
auto setting = handler.getSetting(section.name + "." + key);
|
||||
assert(setting != nullptr);
|
||||
if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
|
||||
ss << integer->get();
|
||||
|
||||
+5
-6
@@ -1,21 +1,20 @@
|
||||
#ifndef CODERS_TOML_HPP_
|
||||
#define CODERS_TOML_HPP_
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
#include <string>
|
||||
|
||||
#include "../data/dynamic.hpp"
|
||||
|
||||
class SettingsHandler;
|
||||
|
||||
namespace toml {
|
||||
std::string stringify(SettingsHandler& handler);
|
||||
std::string stringify(dynamic::Map& root, const std::string& name="");
|
||||
std::string stringify(dynamic::Map& root, const std::string& name = "");
|
||||
dynamic::Map_sptr parse(std::string_view file, std::string_view source);
|
||||
|
||||
void parse(
|
||||
SettingsHandler& handler,
|
||||
std::string_view file,
|
||||
std::string_view source
|
||||
SettingsHandler& handler, std::string_view file, std::string_view source
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_TOML_HPP_
|
||||
#endif // CODERS_TOML_HPP_
|
||||
|
||||
+62
-50
@@ -1,13 +1,13 @@
|
||||
#include "wav.hpp"
|
||||
|
||||
#include "../audio/audio.hpp"
|
||||
#include "../debug/Logger.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../audio/audio.hpp"
|
||||
#include "../debug/Logger.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -20,12 +20,11 @@ bool is_big_endian() {
|
||||
return bytes[0] == 1;
|
||||
}
|
||||
|
||||
std::int32_t convert_to_int(char* buffer, std::size_t len){
|
||||
std::int32_t convert_to_int(char* buffer, std::size_t len) {
|
||||
std::int32_t a = 0;
|
||||
if (!is_big_endian()) {
|
||||
std::memcpy(&a, buffer, len);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
reinterpret_cast<char*>(&a)[3 - i] = buffer[i];
|
||||
}
|
||||
@@ -44,18 +43,18 @@ class WavStream : public audio::PCMStream {
|
||||
size_t initialPosition;
|
||||
public:
|
||||
WavStream(
|
||||
std::ifstream in,
|
||||
uint channels,
|
||||
std::ifstream in,
|
||||
uint channels,
|
||||
uint bitsPerSample,
|
||||
uint sampleRate,
|
||||
size_t size,
|
||||
size_t initialPosition
|
||||
) : in(std::move(in)),
|
||||
channels(channels),
|
||||
bytesPerSample(bitsPerSample/8),
|
||||
sampleRate(sampleRate),
|
||||
totalSize(size)
|
||||
{
|
||||
)
|
||||
: in(std::move(in)),
|
||||
channels(channels),
|
||||
bytesPerSample(bitsPerSample / 8),
|
||||
sampleRate(sampleRate),
|
||||
totalSize(size) {
|
||||
totalSamples = totalSize / channels / bytesPerSample;
|
||||
this->initialPosition = initialPosition;
|
||||
}
|
||||
@@ -74,10 +73,9 @@ public:
|
||||
}
|
||||
return in.gcount();
|
||||
}
|
||||
|
||||
|
||||
void close() override {
|
||||
if (!isOpen())
|
||||
return;
|
||||
if (!isOpen()) return;
|
||||
in.close();
|
||||
}
|
||||
|
||||
@@ -110,58 +108,66 @@ public:
|
||||
}
|
||||
|
||||
void seek(size_t position) override {
|
||||
if (!isOpen())
|
||||
return;
|
||||
if (!isOpen()) return;
|
||||
position %= totalSamples;
|
||||
in.clear();
|
||||
in.seekg(initialPosition + position * channels * bytesPerSample, std::ios_base::beg);
|
||||
in.seekg(
|
||||
initialPosition + position * channels * bytesPerSample,
|
||||
std::ios_base::beg
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||
std::ifstream in(file, std::ios::binary);
|
||||
if(!in.is_open()){
|
||||
throw std::runtime_error("could not to open file '"+file.u8string()+"'");
|
||||
if (!in.is_open()) {
|
||||
throw std::runtime_error(
|
||||
"could not to open file '" + file.u8string() + "'"
|
||||
);
|
||||
}
|
||||
|
||||
char buffer[6];
|
||||
// the RIFF
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not to read RIFF");
|
||||
}
|
||||
if(std::strncmp(buffer, "RIFF", 4) != 0){
|
||||
throw std::runtime_error("file is not a valid WAVE file (header doesn't begin with RIFF)");
|
||||
if (std::strncmp(buffer, "RIFF", 4) != 0) {
|
||||
throw std::runtime_error(
|
||||
"file is not a valid WAVE file (header doesn't begin with RIFF)"
|
||||
);
|
||||
}
|
||||
// the size of the file
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read size of file");
|
||||
}
|
||||
// the WAVE
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not to read WAVE");
|
||||
}
|
||||
if(std::strncmp(buffer, "WAVE", 4) != 0){
|
||||
throw std::runtime_error("file is not a valid WAVE file (header doesn't contain WAVE)");
|
||||
if (std::strncmp(buffer, "WAVE", 4) != 0) {
|
||||
throw std::runtime_error(
|
||||
"file is not a valid WAVE file (header doesn't contain WAVE)"
|
||||
);
|
||||
}
|
||||
// "fmt/0"
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read fmt/0");
|
||||
}
|
||||
// this is always 16, the size of the fmt data chunk
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read the 16");
|
||||
}
|
||||
// PCM should be 1?
|
||||
if(!in.read(buffer, 2)){
|
||||
if (!in.read(buffer, 2)) {
|
||||
throw std::runtime_error("could not read PCM");
|
||||
}
|
||||
// the number of channels
|
||||
if(!in.read(buffer, 2)){
|
||||
if (!in.read(buffer, 2)) {
|
||||
throw std::runtime_error("could not read number of channels");
|
||||
}
|
||||
int channels = convert_to_int(buffer, 2);
|
||||
// sample rate
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read sample rate");
|
||||
}
|
||||
int sampleRate = convert_to_int(buffer, 4);
|
||||
@@ -170,16 +176,19 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||
}
|
||||
|
||||
// bitsPerSample
|
||||
if(!in.read(buffer, 2)){
|
||||
if (!in.read(buffer, 2)) {
|
||||
throw std::runtime_error("could not read bits per sample");
|
||||
}
|
||||
int bitsPerSample = convert_to_int(buffer, 2);
|
||||
if (bitsPerSample >= 24) {
|
||||
throw std::runtime_error(std::to_string(bitsPerSample)+" bit depth is not supported by OpenAL");
|
||||
throw std::runtime_error(
|
||||
std::to_string(bitsPerSample) +
|
||||
" bit depth is not supported by OpenAL"
|
||||
);
|
||||
}
|
||||
|
||||
// data chunk header "data"
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read data chunk header");
|
||||
}
|
||||
|
||||
@@ -187,7 +196,7 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||
// skip garbage in WAV
|
||||
if (std::strncmp(buffer, "LIST", 4) == 0) {
|
||||
// chunk size
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read comment chunk size");
|
||||
}
|
||||
int chunkSize = convert_to_int(buffer, 4);
|
||||
@@ -195,26 +204,28 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||
|
||||
initialOffset += chunkSize + 4;
|
||||
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read data chunk header");
|
||||
}
|
||||
}
|
||||
|
||||
if(std::strncmp(buffer, "data", 4) != 0){
|
||||
throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)");
|
||||
if (std::strncmp(buffer, "data", 4) != 0) {
|
||||
throw std::runtime_error(
|
||||
"file is not a valid WAVE file (doesn't have 'data' tag)"
|
||||
);
|
||||
}
|
||||
|
||||
// size of data
|
||||
if(!in.read(buffer, 4)){
|
||||
if (!in.read(buffer, 4)) {
|
||||
throw std::runtime_error("could not read data size");
|
||||
}
|
||||
size_t size = convert_to_int(buffer, 4);
|
||||
|
||||
/* cannot be at the end of file */
|
||||
if(in.eof()){
|
||||
if (in.eof()) {
|
||||
throw std::runtime_error("reached EOF on the file");
|
||||
}
|
||||
if(in.fail()){
|
||||
if (in.fail()) {
|
||||
throw std::runtime_error("fail state set on the file");
|
||||
}
|
||||
return std::make_unique<WavStream>(
|
||||
@@ -222,7 +233,9 @@ std::unique_ptr<audio::PCMStream> wav::create_stream(const fs::path& file) {
|
||||
);
|
||||
}
|
||||
|
||||
std::unique_ptr<audio::PCM> wav::load_pcm(const fs::path& file, bool headerOnly) {
|
||||
std::unique_ptr<audio::PCM> wav::load_pcm(
|
||||
const fs::path& file, bool headerOnly
|
||||
) {
|
||||
auto stream = wav::create_stream(file);
|
||||
|
||||
size_t totalSamples = stream->getTotalSamples();
|
||||
@@ -232,9 +245,8 @@ std::unique_ptr<audio::PCM> wav::load_pcm(const fs::path& file, bool headerOnly)
|
||||
|
||||
std::vector<char> data;
|
||||
if (!headerOnly) {
|
||||
size_t size = stream->getTotalSamples() *
|
||||
(stream->getBitsPerSample()/8) *
|
||||
stream->getChannels();
|
||||
size_t size = stream->getTotalSamples() *
|
||||
(stream->getBitsPerSample() / 8) * stream->getChannels();
|
||||
data.resize(size);
|
||||
stream->readFully(data.data(), size, false);
|
||||
}
|
||||
|
||||
+7
-3
@@ -9,8 +9,12 @@ namespace audio {
|
||||
}
|
||||
|
||||
namespace wav {
|
||||
std::unique_ptr<audio::PCM> load_pcm(const std::filesystem::path& file, bool headerOnly);
|
||||
std::unique_ptr<audio::PCMStream> create_stream(const std::filesystem::path& file);
|
||||
std::unique_ptr<audio::PCM> load_pcm(
|
||||
const std::filesystem::path& file, bool headerOnly
|
||||
);
|
||||
std::unique_ptr<audio::PCMStream> create_stream(
|
||||
const std::filesystem::path& file
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_WAV_HPP_
|
||||
#endif // CODERS_WAV_HPP_
|
||||
|
||||
+40
-48
@@ -1,17 +1,16 @@
|
||||
#include "xml.hpp"
|
||||
|
||||
#include "../util/stringutil.hpp"
|
||||
|
||||
#include <charconv>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include "../util/stringutil.hpp"
|
||||
|
||||
using namespace xml;
|
||||
|
||||
Attribute::Attribute(std::string name, std::string text)
|
||||
: name(std::move(name)),
|
||||
text(std::move(text)) {
|
||||
: name(std::move(name)), text(std::move(text)) {
|
||||
}
|
||||
|
||||
const std::string& Attribute::getName() const {
|
||||
@@ -42,7 +41,7 @@ glm::vec2 Attribute::asVec2() const {
|
||||
}
|
||||
return glm::vec2(
|
||||
util::parse_double(text, 0, pos),
|
||||
util::parse_double(text, pos+1, text.length()-pos-1)
|
||||
util::parse_double(text, pos + 1, text.length() - pos - 1)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,14 +51,14 @@ glm::vec3 Attribute::asVec3() const {
|
||||
if (pos1 == std::string::npos) {
|
||||
return glm::vec3(util::parse_double(text, 0, text.length()));
|
||||
}
|
||||
size_t pos2 = text.find(',', pos1+1);
|
||||
size_t pos2 = text.find(',', pos1 + 1);
|
||||
if (pos2 == std::string::npos) {
|
||||
throw std::runtime_error("invalid vec3 value "+util::quote(text));
|
||||
throw std::runtime_error("invalid vec3 value " + util::quote(text));
|
||||
}
|
||||
return glm::vec3(
|
||||
util::parse_double(text, 0, pos1),
|
||||
util::parse_double(text, pos1+1, pos2),
|
||||
util::parse_double(text, pos2+1, text.length()-pos2-1)
|
||||
util::parse_double(text, pos1 + 1, pos2),
|
||||
util::parse_double(text, pos2 + 1, text.length() - pos2 - 1)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,19 +68,19 @@ glm::vec4 Attribute::asVec4() const {
|
||||
if (pos1 == std::string::npos) {
|
||||
return glm::vec4(util::parse_double(text, 0, text.length()));
|
||||
}
|
||||
size_t pos2 = text.find(',', pos1+1);
|
||||
size_t pos2 = text.find(',', pos1 + 1);
|
||||
if (pos2 == std::string::npos) {
|
||||
throw std::runtime_error("invalid vec4 value "+util::quote(text));
|
||||
throw std::runtime_error("invalid vec4 value " + util::quote(text));
|
||||
}
|
||||
size_t pos3 = text.find(',', pos2+1);
|
||||
size_t pos3 = text.find(',', pos2 + 1);
|
||||
if (pos3 == std::string::npos) {
|
||||
throw std::runtime_error("invalid vec4 value "+util::quote(text));
|
||||
throw std::runtime_error("invalid vec4 value " + util::quote(text));
|
||||
}
|
||||
return glm::vec4(
|
||||
util::parse_double(text, 0, pos1),
|
||||
util::parse_double(text, pos1+1, pos2-pos1-1),
|
||||
util::parse_double(text, pos2+1, pos3-pos2-1),
|
||||
util::parse_double(text, pos3+1, text.length()-pos3-1)
|
||||
util::parse_double(text, pos1 + 1, pos2 - pos1 - 1),
|
||||
util::parse_double(text, pos2 + 1, pos3 - pos2 - 1),
|
||||
util::parse_double(text, pos3 + 1, text.length() - pos3 - 1)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ void Node::add(const xmlelement& element) {
|
||||
elements.push_back(element);
|
||||
}
|
||||
|
||||
void Node::set(const std::string& name, const std::string &text) {
|
||||
void Node::set(const std::string& name, const std::string& text) {
|
||||
attrs[name] = Attribute(name, text);
|
||||
}
|
||||
|
||||
@@ -123,7 +122,9 @@ const std::string& Node::getTag() const {
|
||||
const xmlattribute& Node::attr(const std::string& name) const {
|
||||
auto found = attrs.find(name);
|
||||
if (found == attrs.end()) {
|
||||
throw std::runtime_error("element <"+tag+" ...> missing attribute "+name);
|
||||
throw std::runtime_error(
|
||||
"element <" + tag + " ...> missing attribute " + name
|
||||
);
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
@@ -158,11 +159,10 @@ const xmlelements_map& Node::getAttributes() const {
|
||||
}
|
||||
|
||||
Document::Document(std::string version, std::string encoding)
|
||||
: version(std::move(version)),
|
||||
encoding(std::move(encoding)) {
|
||||
: version(std::move(version)), encoding(std::move(encoding)) {
|
||||
}
|
||||
|
||||
void Document::setRoot(const xmlelement &element) {
|
||||
void Document::setRoot(const xmlelement& element) {
|
||||
this->root = element;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ const std::string& Document::getEncoding() const {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
Parser::Parser(std::string_view filename, std::string_view source)
|
||||
Parser::Parser(std::string_view filename, std::string_view source)
|
||||
: BasicParser(filename, source) {
|
||||
}
|
||||
|
||||
@@ -190,15 +190,14 @@ xmlelement Parser::parseOpenTag() {
|
||||
while (true) {
|
||||
skipWhitespace();
|
||||
c = peek();
|
||||
if (c == '/' || c == '>' || c == '?')
|
||||
break;
|
||||
if (c == '/' || c == '>' || c == '?') break;
|
||||
std::string attrname = parseXMLName();
|
||||
std::string attrtext = "";
|
||||
skipWhitespace();
|
||||
if (peek() == '=') {
|
||||
nextChar();
|
||||
skipWhitespace();
|
||||
|
||||
|
||||
char quote = peek();
|
||||
if (quote != '\'' && quote != '"') {
|
||||
throw error("string literal expected");
|
||||
@@ -251,7 +250,7 @@ std::string Parser::parseText() {
|
||||
}
|
||||
nextChar();
|
||||
}
|
||||
return std::string(source.substr(start, pos-start));
|
||||
return std::string(source.substr(start, pos - start));
|
||||
}
|
||||
|
||||
inline bool is_xml_identifier_start(char c) {
|
||||
@@ -259,7 +258,7 @@ inline bool is_xml_identifier_start(char c) {
|
||||
}
|
||||
|
||||
inline bool is_xml_identifier_part(char c) {
|
||||
return is_identifier_part(c) || c == '-' || c == '.' || c == ':';
|
||||
return is_identifier_part(c) || c == '-' || c == '.' || c == ':';
|
||||
}
|
||||
|
||||
std::string Parser::parseXMLName() {
|
||||
@@ -271,7 +270,7 @@ std::string Parser::parseXMLName() {
|
||||
while (hasNext() && is_xml_identifier_part(source[pos])) {
|
||||
pos++;
|
||||
}
|
||||
return std::string(source.substr(start, pos-start));
|
||||
return std::string(source.substr(start, pos - start));
|
||||
}
|
||||
|
||||
xmlelement Parser::parseElement() {
|
||||
@@ -300,12 +299,12 @@ xmlelement Parser::parseElement() {
|
||||
|
||||
auto element = parseOpenTag();
|
||||
char c = nextChar();
|
||||
|
||||
|
||||
// <element/>
|
||||
if (c == '/') {
|
||||
expect('>');
|
||||
}
|
||||
// <element>...</element>
|
||||
// <element>...</element>
|
||||
else if (c == '>') {
|
||||
skipWhitespace();
|
||||
while (!isNext("</")) {
|
||||
@@ -319,7 +318,7 @@ xmlelement Parser::parseElement() {
|
||||
expect(element->getTag());
|
||||
expect('>');
|
||||
}
|
||||
// <element?>
|
||||
// <element?>
|
||||
else {
|
||||
throw error("invalid syntax");
|
||||
}
|
||||
@@ -343,13 +342,9 @@ xmldocument xml::parse(const std::string& filename, const std::string& source) {
|
||||
}
|
||||
|
||||
inline void newline(
|
||||
std::stringstream& ss,
|
||||
bool nice,
|
||||
const std::string& indentStr,
|
||||
int indent
|
||||
std::stringstream& ss, bool nice, const std::string& indentStr, int indent
|
||||
) {
|
||||
if (!nice)
|
||||
return;
|
||||
if (!nice) return;
|
||||
ss << '\n';
|
||||
for (int i = 0; i < indent; i++) {
|
||||
ss << indentStr;
|
||||
@@ -366,7 +361,7 @@ static void stringifyElement(
|
||||
if (element->isText()) {
|
||||
std::string text = element->attr("#").getText();
|
||||
util::replaceAll(text, "&", "&");
|
||||
util::replaceAll(text, "\"",""");
|
||||
util::replaceAll(text, "\"", """);
|
||||
util::replaceAll(text, "'", "'");
|
||||
util::replaceAll(text, "<", "<");
|
||||
util::replaceAll(text, ">", ">");
|
||||
@@ -395,32 +390,29 @@ static void stringifyElement(
|
||||
auto& elements = element->getElements();
|
||||
if (elements.size() == 1 && elements[0]->isText()) {
|
||||
ss << ">";
|
||||
stringifyElement(ss, elements[0], nice, indentStr, indent+1);
|
||||
stringifyElement(ss, elements[0], nice, indentStr, indent + 1);
|
||||
ss << "</" << tag << ">";
|
||||
return;
|
||||
}
|
||||
if (!elements.empty()) {
|
||||
ss << '>';
|
||||
for (auto& sub : elements) {
|
||||
newline(ss, nice, indentStr, indent+1);
|
||||
stringifyElement(ss, sub, nice, indentStr, indent+1);
|
||||
newline(ss, nice, indentStr, indent + 1);
|
||||
stringifyElement(ss, sub, nice, indentStr, indent + 1);
|
||||
}
|
||||
newline(ss, nice, indentStr, indent);
|
||||
ss << "</" << tag << ">";
|
||||
|
||||
|
||||
} else {
|
||||
ss << "/>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string xml::stringify(
|
||||
const xmldocument& document,
|
||||
bool nice,
|
||||
const std::string& indentStr
|
||||
const xmldocument& document, bool nice, const std::string& indentStr
|
||||
) {
|
||||
std::stringstream ss;
|
||||
|
||||
|
||||
// XML declaration
|
||||
ss << "<?xml version=\"" << document->getVersion();
|
||||
ss << "\" encoding=\"UTF-8\" ?>";
|
||||
|
||||
+23
-19
@@ -1,13 +1,13 @@
|
||||
#ifndef CODERS_XML_HPP_
|
||||
#define CODERS_XML_HPP_
|
||||
|
||||
#include "commons.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "commons.hpp"
|
||||
|
||||
namespace xml {
|
||||
class Node;
|
||||
@@ -37,7 +37,8 @@ namespace xml {
|
||||
glm::vec4 asColor() const;
|
||||
};
|
||||
|
||||
/// @brief XML element class. Text element has tag 'text' and attribute 'text'
|
||||
/// @brief XML element class. Text element has tag 'text' and attribute
|
||||
/// 'text'
|
||||
class Node {
|
||||
std::string tag;
|
||||
std::unordered_map<std::string, xmlattribute> attrs;
|
||||
@@ -51,8 +52,8 @@ namespace xml {
|
||||
/// @brief Set attribute value. Creates attribute if does not exists
|
||||
/// @param name attribute name
|
||||
/// @param text attribute value
|
||||
void set(const std::string& name, const std::string &text);
|
||||
|
||||
void set(const std::string& name, const std::string& text);
|
||||
|
||||
/// @brief Get element tag
|
||||
const std::string& getTag() const;
|
||||
|
||||
@@ -66,16 +67,17 @@ namespace xml {
|
||||
|
||||
/// @brief Get attribute by name
|
||||
/// @param name attribute name
|
||||
/// @throws std::runtime_error if element has no attribute
|
||||
/// @throws std::runtime_error if element has no attribute
|
||||
/// @return xmlattribute - {name, value}
|
||||
const xmlattribute& attr(const std::string& name) const;
|
||||
|
||||
|
||||
/// @brief Get attribute by name
|
||||
/// @param name attribute name
|
||||
/// @param def default value will be returned wrapped in xmlattribute
|
||||
/// if element has no attribute
|
||||
/// if element has no attribute
|
||||
/// @return xmlattribute - {name, value} or {name, def} if not found*/
|
||||
xmlattribute attr(const std::string& name, const std::string& def) const;
|
||||
xmlattribute attr(const std::string& name, const std::string& def)
|
||||
const;
|
||||
|
||||
/// @brief Check if element has attribute
|
||||
/// @param name attribute name
|
||||
@@ -101,7 +103,7 @@ namespace xml {
|
||||
public:
|
||||
Document(std::string version, std::string encoding);
|
||||
|
||||
void setRoot(const xmlelement &element);
|
||||
void setRoot(const xmlelement& element);
|
||||
xmlelement getRoot() const;
|
||||
|
||||
const std::string& getVersion() const;
|
||||
@@ -123,22 +125,24 @@ namespace xml {
|
||||
xmldocument parse();
|
||||
};
|
||||
|
||||
/// @brief Serialize XML Document to string
|
||||
/// @brief Serialize XML Document to string
|
||||
/// @param document serializing document
|
||||
/// @param nice use human readable format (with indents and line-separators)
|
||||
/// @param indentStr indentation characters sequence (default - 4 spaces)
|
||||
/// @return XML string
|
||||
extern std::string stringify(
|
||||
const xmldocument& document,
|
||||
bool nice=true,
|
||||
const std::string& indentStr=" "
|
||||
bool nice = true,
|
||||
const std::string& indentStr = " "
|
||||
);
|
||||
|
||||
|
||||
/// @brief Read XML Document from string
|
||||
/// @param filename file name will be shown in error messages
|
||||
/// @param source xml source code string
|
||||
/// @return xml document
|
||||
extern xmldocument parse(const std::string& filename, const std::string& source);
|
||||
extern xmldocument parse(
|
||||
const std::string& filename, const std::string& source
|
||||
);
|
||||
}
|
||||
|
||||
#endif // CODERS_XML_HPP_
|
||||
#endif // CODERS_XML_HPP_
|
||||
|
||||
Reference in New Issue
Block a user