v101r02
This commit is contained in:
parent
6838142c9f
commit
badedce822
31 changed files with 589 additions and 361 deletions
18
atoi.hpp
18
atoi.hpp
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace nall {
|
||||
|
||||
constexpr inline auto toBinary_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto toBinary_(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? toBinary_(s + 1, (sum << 1) | *s - '0') :
|
||||
*s == '\'' ? toBinary_(s + 1, sum) :
|
||||
|
@ -12,7 +12,7 @@ constexpr inline auto toBinary_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
|||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toOctal_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto toOctal_(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s >= '0' && *s <= '7' ? toOctal_(s + 1, (sum << 3) | *s - '0') :
|
||||
*s == '\'' ? toOctal_(s + 1, sum) :
|
||||
|
@ -20,7 +20,7 @@ constexpr inline auto toOctal_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
|||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toDecimal_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto toDecimal_(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s >= '0' && *s <= '9' ? toDecimal_(s + 1, (sum * 10) + *s - '0') :
|
||||
*s == '\'' ? toDecimal_(s + 1, sum) :
|
||||
|
@ -28,7 +28,7 @@ constexpr inline auto toDecimal_(const char* s, uintmax_t sum = 0) -> uintmax_t
|
|||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toHex_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto toHex_(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s >= 'A' && *s <= 'F' ? toHex_(s + 1, (sum << 4) | *s - 'A' + 10) :
|
||||
*s >= 'a' && *s <= 'f' ? toHex_(s + 1, (sum << 4) | *s - 'a' + 10) :
|
||||
|
@ -40,21 +40,21 @@ constexpr inline auto toHex_(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
|||
|
||||
//
|
||||
|
||||
constexpr inline auto toBinary(const char* s) -> uintmax_t {
|
||||
constexpr inline auto toBinary(const char* s) -> uintmax {
|
||||
return (
|
||||
*s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) :
|
||||
*s == '%' ? toBinary_(s + 1) : toBinary_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toOctal(const char* s) -> uintmax_t {
|
||||
constexpr inline auto toOctal(const char* s) -> uintmax {
|
||||
return (
|
||||
*s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) :
|
||||
toOctal_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toHex(const char* s) -> uintmax_t {
|
||||
constexpr inline auto toHex(const char* s) -> uintmax {
|
||||
return (
|
||||
*s == '0' && (*(s + 1) == 'X' || *(s + 1) == 'x') ? toHex_(s + 2) :
|
||||
*s == '$' ? toHex_(s + 1) : toHex_(s)
|
||||
|
@ -63,7 +63,7 @@ constexpr inline auto toHex(const char* s) -> uintmax_t {
|
|||
|
||||
//
|
||||
|
||||
constexpr inline auto toNatural(const char* s) -> uintmax_t {
|
||||
constexpr inline auto toNatural(const char* s) -> uintmax {
|
||||
return (
|
||||
*s == '0' && (*(s + 1) == 'B' || *(s + 1) == 'b') ? toBinary_(s + 2) :
|
||||
*s == '0' && (*(s + 1) == 'O' || *(s + 1) == 'o') ? toOctal_(s + 2) :
|
||||
|
@ -72,7 +72,7 @@ constexpr inline auto toNatural(const char* s) -> uintmax_t {
|
|||
);
|
||||
}
|
||||
|
||||
constexpr inline auto toInteger(const char* s) -> intmax_t {
|
||||
constexpr inline auto toInteger(const char* s) -> intmax {
|
||||
return (
|
||||
*s == '+' ? +toNatural(s + 1) : *s == '-' ? -toNatural(s + 1) : toNatural(s)
|
||||
);
|
||||
|
|
32
bit.hpp
32
bit.hpp
|
@ -4,28 +4,28 @@
|
|||
|
||||
namespace nall {
|
||||
|
||||
template<uint bits> inline auto uclamp(const uintmax_t x) -> uintmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 };
|
||||
template<uint bits> inline auto uclamp(const uintmax x) -> uintmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), y = b * 2 - 1 };
|
||||
return y + ((x - y) & -(x < y)); //min(x, y);
|
||||
}
|
||||
|
||||
template<uint bits> inline auto uclip(const uintmax_t x) -> uintmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
template<uint bits> inline auto uclip(const uintmax x) -> uintmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return (x & m);
|
||||
}
|
||||
|
||||
template<uint bits> inline auto sclamp(const intmax_t x) -> intmax_t {
|
||||
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
|
||||
template<uint bits> inline auto sclamp(const intmax x) -> intmax {
|
||||
enum : intmax { b = 1ull << (bits - 1), m = b - 1 };
|
||||
return (x > m) ? m : (x < -b) ? -b : x;
|
||||
}
|
||||
|
||||
template<uint bits> inline auto sclip(const intmax_t x) -> intmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
template<uint bits> inline auto sclip(const intmax x) -> intmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return ((x & m) ^ b) - b;
|
||||
}
|
||||
|
||||
namespace bit {
|
||||
constexpr inline auto mask(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto mask(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) :
|
||||
*s == ' ' || *s == '_' ? mask(s + 1, sum) :
|
||||
|
@ -34,7 +34,7 @@ namespace bit {
|
|||
);
|
||||
}
|
||||
|
||||
constexpr inline auto test(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto test(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) :
|
||||
*s == ' ' || *s == '_' ? test(s + 1, sum) :
|
||||
|
@ -44,22 +44,22 @@ namespace bit {
|
|||
}
|
||||
|
||||
//lowest(0b1110) == 0b0010
|
||||
constexpr inline auto lowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto lowest(const uintmax x) -> uintmax {
|
||||
return x & -x;
|
||||
}
|
||||
|
||||
//clear_lowest(0b1110) == 0b1100
|
||||
constexpr inline auto clearLowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto clearLowest(const uintmax x) -> uintmax {
|
||||
return x & (x - 1);
|
||||
}
|
||||
|
||||
//set_lowest(0b0101) == 0b0111
|
||||
constexpr inline auto setLowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto setLowest(const uintmax x) -> uintmax {
|
||||
return x | (x + 1);
|
||||
}
|
||||
|
||||
//count number of bits set in a byte
|
||||
inline auto count(uintmax_t x) -> uint {
|
||||
inline auto count(uintmax x) -> uint {
|
||||
uint count = 0;
|
||||
do count += x & 1; while(x >>= 1);
|
||||
return count;
|
||||
|
@ -67,7 +67,7 @@ namespace bit {
|
|||
|
||||
//return index of the first bit set (or zero of no bits are set)
|
||||
//first(0b1000) == 3
|
||||
inline auto first(uintmax_t x) -> uint {
|
||||
inline auto first(uintmax x) -> uint {
|
||||
uint first = 0;
|
||||
while(x) { if(x & 1) break; x >>= 1; first++; }
|
||||
return first;
|
||||
|
@ -75,7 +75,7 @@ namespace bit {
|
|||
|
||||
//round up to next highest single bit:
|
||||
//round(15) == 16, round(16) == 16, round(17) == 32
|
||||
inline auto round(uintmax_t x) -> uintmax_t {
|
||||
inline auto round(uintmax x) -> uintmax {
|
||||
if((x & (x - 1)) == 0) return x;
|
||||
while(x & (x - 1)) x &= x - 1;
|
||||
return x << 1;
|
||||
|
|
134
chrono.hpp
Normal file
134
chrono.hpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall { namespace chrono { namespace {
|
||||
|
||||
//passage of time functions (from unknown epoch)
|
||||
|
||||
auto nanosecond() -> uint64_t {
|
||||
timespec tv;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
return tv.tv_sec * 1'000'000'000 + tv.tv_nsec;
|
||||
}
|
||||
|
||||
auto microsecond() -> uint64_t { return nanosecond() / 1'000; }
|
||||
auto millisecond() -> uint64_t { return nanosecond() / 1'000'000; }
|
||||
auto second() -> uint64_t { return nanosecond() / 1'000'000'000; }
|
||||
|
||||
auto benchmark(const function<void ()>& f, uint64_t times = 1) -> void {
|
||||
auto start = nanosecond();
|
||||
while(times--) f();
|
||||
auto end = nanosecond();
|
||||
print("[chrono::benchmark] ", (double)(end - start) / 1'000'000'000.0, "s\n");
|
||||
}
|
||||
|
||||
//exact date/time functions (from system epoch)
|
||||
|
||||
struct timeinfo {
|
||||
timeinfo(
|
||||
uint year = 0, uint month = 0, uint day = 0,
|
||||
uint hour = 0, uint minute = 0, uint second = 0, uint weekday = 0
|
||||
) : year(year), month(month), day(day),
|
||||
hour(hour), minute(minute), second(second), weekday(weekday) {
|
||||
}
|
||||
|
||||
explicit operator bool() const { return month; }
|
||||
|
||||
uint year; //...
|
||||
uint month; //1 - 12
|
||||
uint day; //1 - 31
|
||||
uint hour; //0 - 23
|
||||
uint minute; //0 - 59
|
||||
uint second; //0 - 60
|
||||
uint weekday; //0 - 6
|
||||
};
|
||||
|
||||
auto timestamp() -> uint64_t {
|
||||
return ::time(nullptr);
|
||||
}
|
||||
|
||||
namespace utc {
|
||||
auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
|
||||
auto stamp = time ? (time_t)time : (time_t)timestamp();
|
||||
auto info = gmtime(&stamp);
|
||||
return {
|
||||
(uint)info->tm_year + 1900,
|
||||
(uint)info->tm_mon + 1,
|
||||
(uint)info->tm_mday,
|
||||
(uint)info->tm_hour,
|
||||
(uint)info->tm_min,
|
||||
(uint)info->tm_sec,
|
||||
(uint)info->tm_wday
|
||||
};
|
||||
}
|
||||
|
||||
auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
|
||||
auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
|
||||
auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
|
||||
auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
|
||||
auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
|
||||
auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
|
||||
|
||||
auto date(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
|
||||
}
|
||||
|
||||
auto time(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
|
||||
}
|
||||
|
||||
auto datetime(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {
|
||||
pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
|
||||
pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace local {
|
||||
auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
|
||||
auto stamp = time ? (time_t)time : (time_t)timestamp();
|
||||
auto info = localtime(&stamp);
|
||||
return {
|
||||
(uint)info->tm_year + 1900,
|
||||
(uint)info->tm_mon + 1,
|
||||
(uint)info->tm_mday,
|
||||
(uint)info->tm_hour,
|
||||
(uint)info->tm_min,
|
||||
(uint)info->tm_sec,
|
||||
(uint)info->tm_wday
|
||||
};
|
||||
}
|
||||
|
||||
auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
|
||||
auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
|
||||
auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
|
||||
auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
|
||||
auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
|
||||
auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
|
||||
|
||||
auto date(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
|
||||
}
|
||||
|
||||
auto time(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
|
||||
}
|
||||
|
||||
auto datetime(uint64_t timestamp = 0) -> string {
|
||||
auto t = timeinfo(timestamp);
|
||||
return {
|
||||
pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
|
||||
pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}}}
|
110
config.hpp
110
config.hpp
|
@ -1,110 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall {
|
||||
namespace Configuration {
|
||||
|
||||
struct Node {
|
||||
string name;
|
||||
string desc;
|
||||
enum class Type : uint { Null, Boolean, Integer, Natural, Double, String } type = Type::Null;
|
||||
void* data = nullptr;
|
||||
vector<Node> children;
|
||||
|
||||
explicit operator bool() const { return data; }
|
||||
|
||||
auto get() const -> string {
|
||||
switch(type) {
|
||||
case Type::Boolean: return {*(bool*)data};
|
||||
case Type::Integer: return {*(int*)data};
|
||||
case Type::Natural: return {*(uint*)data};
|
||||
case Type::Double: return {*(double*)data};
|
||||
case Type::String: return {*(string*)data};
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
auto set(const string& value) -> void {
|
||||
switch(type) {
|
||||
case Type::Boolean: *(bool*)data = (value != "false"); break;
|
||||
case Type::Integer: *(int*)data = toInteger(value); break;
|
||||
case Type::Natural: *(uint*)data = toNatural(value); break;
|
||||
case Type::Double: *(double*)data = toReal(value); break;
|
||||
case Type::String: *(string*)data = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
auto assign() { type = Type::Null; data = nullptr; }
|
||||
auto assign(bool& bind) { type = Type::Boolean; data = (void*)&bind; }
|
||||
auto assign(int& bind) { type = Type::Integer; data = (void*)&bind; }
|
||||
auto assign(uint& bind) { type = Type::Natural; data = (void*)&bind; }
|
||||
auto assign(double& bind) { type = Type::Double; data = (void*)&bind; }
|
||||
auto assign(string& bind) { type = Type::String; data = (void*)&bind; }
|
||||
auto assign(const Node& node) { operator=(node); }
|
||||
|
||||
template<typename T> auto append(T& data, const string& name, const string& desc = "") -> void {
|
||||
Node node;
|
||||
node.assign(data);
|
||||
node.name = name;
|
||||
node.desc = desc;
|
||||
children.append(node);
|
||||
}
|
||||
|
||||
auto find(const string& path) -> maybe<Node&> {
|
||||
auto p = path.split("/");
|
||||
auto name = p.takeLeft();
|
||||
for(auto& child : children) {
|
||||
if(child.name == name) {
|
||||
if(p.size() == 0) return child;
|
||||
return child.find(p.merge("/"));
|
||||
}
|
||||
}
|
||||
return nothing;
|
||||
}
|
||||
|
||||
auto load(Markup::Node path) -> void {
|
||||
for(auto& child : children) {
|
||||
if(auto leaf = path[child.name]) {
|
||||
if(child) child.set(leaf.text());
|
||||
child.load(leaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto save(file& fp, uint depth = 0) -> void {
|
||||
for(auto& child : children) {
|
||||
if(child.desc) {
|
||||
for(auto n : range(depth)) fp.print(" ");
|
||||
fp.print("//", child.desc, "\n");
|
||||
}
|
||||
for(auto n : range(depth)) fp.print(" ");
|
||||
fp.print(child.name);
|
||||
if(child) fp.print(": ", child.get());
|
||||
fp.print("\n");
|
||||
child.save(fp, depth + 1);
|
||||
if(depth == 0) fp.print("\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Document : Node {
|
||||
auto load(const string& filename) -> bool {
|
||||
if(!file::exists(filename)) return false;
|
||||
auto document = BML::unserialize(string::read(filename));
|
||||
Node::load(document);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto save(const string& filename) -> bool {
|
||||
file fp(filename, file::mode::write);
|
||||
if(!fp.open()) return false;
|
||||
Node::save(fp);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ namespace nall { namespace Decode {
|
|||
struct BMP {
|
||||
BMP() = default;
|
||||
BMP(const string& filename) { load(filename); }
|
||||
BMP(const uint8_t* data, unsigned size) { load(data, size); }
|
||||
BMP(const uint8_t* data, uint size) { load(data, size); }
|
||||
|
||||
explicit operator bool() const { return _data; }
|
||||
|
||||
|
@ -15,28 +15,28 @@ struct BMP {
|
|||
|
||||
auto data() -> uint32_t* { return _data; }
|
||||
auto data() const -> const uint32_t* { return _data; }
|
||||
auto width() const -> unsigned { return _width; }
|
||||
auto height() const -> unsigned { return _height; }
|
||||
auto width() const -> uint { return _width; }
|
||||
auto height() const -> uint { return _height; }
|
||||
|
||||
auto load(const string& filename) -> bool {
|
||||
auto buffer = file::read(filename);
|
||||
return load(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
auto load(const uint8_t* data, unsigned size) -> bool {
|
||||
auto load(const uint8_t* data, uint size) -> bool {
|
||||
if(size < 0x36) return false;
|
||||
const uint8_t* p = data;
|
||||
if(read(p, 2) != 0x4d42) return false; //signature
|
||||
read(p, 8);
|
||||
unsigned offset = read(p, 4);
|
||||
uint offset = read(p, 4);
|
||||
if(read(p, 4) != 40) return false; //DIB size
|
||||
signed width = read(p, 4);
|
||||
int width = read(p, 4);
|
||||
if(width < 0) return false;
|
||||
signed height = read(p, 4);
|
||||
int height = read(p, 4);
|
||||
bool flip = height < 0;
|
||||
if(flip) height = -height;
|
||||
read(p, 2);
|
||||
unsigned bitsPerPixel = read(p, 2);
|
||||
uint bitsPerPixel = read(p, 2);
|
||||
if(bitsPerPixel != 24 && bitsPerPixel != 32) return false;
|
||||
if(read(p, 4) != 0) return false; //compression type
|
||||
|
||||
|
@ -44,9 +44,9 @@ struct BMP {
|
|||
_height = height;
|
||||
_data = new uint32_t[width * height];
|
||||
|
||||
unsigned bytesPerPixel = bitsPerPixel / 8;
|
||||
unsigned alignedWidth = width * bytesPerPixel;
|
||||
unsigned paddingLength = 0;
|
||||
uint bytesPerPixel = bitsPerPixel / 8;
|
||||
uint alignedWidth = width * bytesPerPixel;
|
||||
uint paddingLength = 0;
|
||||
while(alignedWidth % 4) alignedWidth++, paddingLength++;
|
||||
|
||||
p = data + offset;
|
||||
|
@ -63,12 +63,12 @@ struct BMP {
|
|||
|
||||
private:
|
||||
uint32_t* _data = nullptr;
|
||||
unsigned _width = 0;
|
||||
unsigned _height = 0;
|
||||
uint _width = 0;
|
||||
uint _height = 0;
|
||||
|
||||
auto read(const uint8_t*& buffer, unsigned length) -> uintmax_t {
|
||||
uintmax_t result = 0;
|
||||
for(auto n : range(length)) result |= (uintmax_t)*buffer++ << (n << 3);
|
||||
auto read(const uint8_t*& buffer, uint length) -> uintmax {
|
||||
uintmax result = 0;
|
||||
for(auto n : range(length)) result |= (uintmax)*buffer++ << (n << 3);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
|
28
dl.hpp
28
dl.hpp
|
@ -32,22 +32,22 @@ struct library {
|
|||
auto close() -> void;
|
||||
|
||||
private:
|
||||
uintptr_t handle = 0;
|
||||
uintptr handle = 0;
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
|
||||
inline auto library::open(const string& name, const string& path) -> bool {
|
||||
if(handle) close();
|
||||
if(path) handle = (uintptr_t)dlopen(string(path, "lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string(Path::user(), ".local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("lib", name, ".so"), RTLD_LAZY);
|
||||
if(path) handle = (uintptr)dlopen(string(path, "lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string(Path::user(), ".local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string("lib", name, ".so"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
inline auto library::openAbsolute(const string& name) -> bool {
|
||||
if(handle) close();
|
||||
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
|
||||
handle = (uintptr)dlopen(name, RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -64,16 +64,16 @@ inline auto library::close() -> void {
|
|||
#elif defined(PLATFORM_MACOSX)
|
||||
inline auto library::open(const string& name, const string& path) -> bool {
|
||||
if(handle) close();
|
||||
if(path) handle = (uintptr_t)dlopen(string(path, "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string(Path::user(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(path) handle = (uintptr)dlopen(string(path, "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string(Path::user(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr)dlopen(string("lib", name, ".dylib"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
inline auto library::openAbsolute(const string& name) -> bool {
|
||||
if(handle) close();
|
||||
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
|
||||
handle = (uintptr)dlopen(name, RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -92,18 +92,18 @@ inline auto library::open(const string& name, const string& path) -> bool {
|
|||
if(handle) close();
|
||||
if(path) {
|
||||
string filepath = {path, name, ".dll"};
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
|
||||
handle = (uintptr)LoadLibraryW(utf16_t(filepath));
|
||||
}
|
||||
if(!handle) {
|
||||
string filepath = {name, ".dll"};
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
|
||||
handle = (uintptr)LoadLibraryW(utf16_t(filepath));
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
inline auto library::openAbsolute(const string& name) -> bool {
|
||||
if(handle) close();
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(name));
|
||||
handle = (uintptr)LoadLibraryW(utf16_t(name));
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
|
18
file.hpp
18
file.hpp
|
@ -61,7 +61,7 @@ struct file : inode, varint {
|
|||
return !(data.st_mode & S_IFDIR);
|
||||
}
|
||||
|
||||
static auto size(const string& filename) -> uintmax_t {
|
||||
static auto size(const string& filename) -> uintmax {
|
||||
#if defined(API_POSIX)
|
||||
struct stat data;
|
||||
stat(filename, &data);
|
||||
|
@ -127,16 +127,16 @@ struct file : inode, varint {
|
|||
return buffer[(file_offset++) & buffer_mask];
|
||||
}
|
||||
|
||||
auto readl(uint length = 1) -> uintmax_t {
|
||||
uintmax_t data = 0;
|
||||
auto readl(uint length = 1) -> uintmax {
|
||||
uintmax data = 0;
|
||||
for(int i = 0; i < length; i++) {
|
||||
data |= (uintmax_t)read() << (i << 3);
|
||||
data |= (uintmax)read() << (i << 3);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
auto readm(uint length = 1) -> uintmax_t {
|
||||
uintmax_t data = 0;
|
||||
auto readm(uint length = 1) -> uintmax {
|
||||
uintmax data = 0;
|
||||
while(length--) {
|
||||
data <<= 8;
|
||||
data |= read();
|
||||
|
@ -164,14 +164,14 @@ struct file : inode, varint {
|
|||
if(file_offset > file_size) file_size = file_offset;
|
||||
}
|
||||
|
||||
auto writel(uintmax_t data, uint length = 1) -> void {
|
||||
auto writel(uintmax data, uint length = 1) -> void {
|
||||
while(length--) {
|
||||
write(data);
|
||||
data >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
auto writem(uintmax_t data, uint length = 1) -> void {
|
||||
auto writem(uintmax data, uint length = 1) -> void {
|
||||
for(int i = length - 1; i >= 0; i--) {
|
||||
write(data >> (i << 3));
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ struct file : inode, varint {
|
|||
if(!fp) return; //file not open
|
||||
buffer_flush();
|
||||
|
||||
intmax_t req_offset = file_offset;
|
||||
intmax req_offset = file_offset;
|
||||
switch(index_) {
|
||||
case index::absolute: req_offset = offset; break;
|
||||
case index::relative: req_offset += offset; break;
|
||||
|
|
|
@ -14,7 +14,7 @@ template<typename R, typename... P> struct function<auto (P...) -> R> {
|
|||
static constexpr bool value = decltype(exists<L>(0))::value;
|
||||
};
|
||||
|
||||
function() = default;
|
||||
function() {}
|
||||
function(const function& source) { operator=(source); }
|
||||
function(void* function) { if(function) callback = new global((auto (*)(P...) -> R)function); }
|
||||
function(auto (*function)(P...) -> R) { callback = new global(function); }
|
||||
|
|
|
@ -230,7 +230,7 @@ auto Response::setData(const vector<uint8_t>& value) -> type& {
|
|||
|
||||
auto Response::setFile(const string& value) -> type& {
|
||||
_file = value;
|
||||
string eTag = {"\"", string::datetime(file::timestamp(value, file::time::modify)), "\""};
|
||||
string eTag = {"\"", chrono::utc::datetime(file::timestamp(value, file::time::modify)), "\""};
|
||||
header.assign("Content-Length", file::size(value));
|
||||
header.assign("Cache-Control", "public");
|
||||
header.assign("ETag", eTag);
|
||||
|
|
|
@ -114,7 +114,7 @@ auto Server::ipv4_scan() -> bool {
|
|||
if(query.fd == fd4 && query.revents & POLLIN) {
|
||||
++connections;
|
||||
|
||||
thread::create([&](uintptr_t) {
|
||||
thread::create([&](uintptr) {
|
||||
thread::detach();
|
||||
|
||||
signed clientfd = -1;
|
||||
|
@ -161,7 +161,7 @@ auto Server::ipv6_scan() -> bool {
|
|||
if(query.fd == fd6 && query.revents & POLLIN) {
|
||||
++connections;
|
||||
|
||||
thread::create([&](uintptr_t) {
|
||||
thread::create([&](uintptr) {
|
||||
thread::detach();
|
||||
|
||||
signed clientfd = -1;
|
||||
|
|
|
@ -45,7 +45,7 @@ struct inode {
|
|||
return data.st_mode;
|
||||
}
|
||||
|
||||
static auto timestamp(const string& name, time mode = time::modify) -> time_t {
|
||||
static auto timestamp(const string& name, time mode = time::modify) -> uint64_t {
|
||||
struct stat data = {0};
|
||||
stat(name, &data);
|
||||
switch(mode) { default:
|
||||
|
|
2
nall.hpp
2
nall.hpp
|
@ -19,7 +19,7 @@
|
|||
#include <nall/bit.hpp>
|
||||
#include <nall/bit-field.hpp>
|
||||
#include <nall/bit-vector.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/chrono.hpp>
|
||||
#include <nall/directory.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
|
|
224
primitives.hpp
224
primitives.hpp
|
@ -12,6 +12,10 @@ struct Boolean {
|
|||
inline operator bool() const { return data; }
|
||||
template<typename T> inline auto& operator=(const T& value) { data = value; return *this; }
|
||||
|
||||
inline auto flip() { return data ^= 1; }
|
||||
inline auto raise() { return data == 0 ? data = 1, true : false; }
|
||||
inline auto lower() { return data == 1 ? data = 0, true : false; }
|
||||
|
||||
inline auto serialize(serializer& s) { s(data); }
|
||||
|
||||
private:
|
||||
|
@ -56,19 +60,36 @@ template<uint Bits> struct Natural {
|
|||
struct Reference {
|
||||
inline Reference(Natural& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {}
|
||||
|
||||
inline operator type() const {
|
||||
inline auto get() const -> type {
|
||||
const type RangeBits = Hi - Lo + 1;
|
||||
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
|
||||
return (source & RangeMask) >> Lo;
|
||||
}
|
||||
|
||||
inline auto& operator=(const type value) {
|
||||
inline auto& set(const type value) {
|
||||
const type RangeBits = Hi - Lo + 1;
|
||||
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
|
||||
source = (source & ~RangeMask) | ((value << Lo) & RangeMask);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator type() const { return get(); }
|
||||
inline auto& operator =(const type value) { return set( value); }
|
||||
inline auto& operator &=(const type value) { return set(get() & value); }
|
||||
inline auto& operator |=(const type value) { return set(get() | value); }
|
||||
inline auto& operator ^=(const type value) { return set(get() ^ value); }
|
||||
inline auto& operator<<=(const type value) { return set(get() << value); }
|
||||
inline auto& operator>>=(const type value) { return set(get() >> value); }
|
||||
inline auto& operator +=(const type value) { return set(get() + value); }
|
||||
inline auto& operator -=(const type value) { return set(get() - value); }
|
||||
inline auto& operator *=(const type value) { return set(get() * value); }
|
||||
inline auto& operator /=(const type value) { return set(get() / value); }
|
||||
inline auto& operator %=(const type value) { return set(get() % value); }
|
||||
inline auto& operator++(int) { auto value = get(); set(value + 1); return value; }
|
||||
inline auto& operator--(int) { auto value = get(); set(value - 1); return value; }
|
||||
inline auto& operator++() { return set(get() + 1); }
|
||||
inline auto& operator--() { return set(get() - 1); }
|
||||
|
||||
private:
|
||||
Natural& source;
|
||||
const type Lo;
|
||||
|
@ -79,15 +100,19 @@ template<uint Bits> struct Natural {
|
|||
inline auto bit(uint index) -> Reference { return {*this, index, index}; }
|
||||
inline auto byte(uint index) -> Reference { return {*this, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto clamp(uint bits) -> uintmax_t {
|
||||
const uintmax_t b = 1ull << (bits - 1);
|
||||
const uintmax_t m = b * 2 - 1;
|
||||
inline auto bits(uint lo, uint hi) const -> const Reference { return {(Natural&)*this, lo < hi ? lo : hi, hi > lo ? hi : lo}; }
|
||||
inline auto bit(uint index) const -> const Reference { return {(Natural&)*this, index, index}; }
|
||||
inline auto byte(uint index) const -> const Reference { return {(Natural&)*this, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto clamp(uint bits) -> uintmax {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return data < m ? data : m;
|
||||
}
|
||||
|
||||
inline auto clip(uint bits) -> uintmax_t {
|
||||
const uintmax_t b = 1ull << (bits - 1);
|
||||
const uintmax_t m = b * 2 - 1;
|
||||
inline auto clip(uint bits) -> uintmax {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return data & m;
|
||||
}
|
||||
|
||||
|
@ -138,38 +163,59 @@ template<uint Bits> struct Integer {
|
|||
struct Reference {
|
||||
inline Reference(Integer& source, uint lo, uint hi) : source(source), Lo(lo), Hi(hi) {}
|
||||
|
||||
inline operator utype() const {
|
||||
inline auto get() const -> utype {
|
||||
const type RangeBits = Hi - Lo + 1;
|
||||
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
|
||||
return ((utype)source & RangeMask) >> Lo;
|
||||
}
|
||||
|
||||
inline auto& operator=(const utype value) {
|
||||
inline auto& set(const utype value) {
|
||||
const type RangeBits = Hi - Lo + 1;
|
||||
const type RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask;
|
||||
source = ((utype)source & ~RangeMask) | ((value << Lo) & RangeMask);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator utype() const { return get(); }
|
||||
inline auto& operator =(const utype value) { return set( value); }
|
||||
inline auto& operator &=(const utype value) { return set(get() & value); }
|
||||
inline auto& operator |=(const utype value) { return set(get() | value); }
|
||||
inline auto& operator ^=(const utype value) { return set(get() ^ value); }
|
||||
inline auto& operator<<=(const utype value) { return set(get() << value); }
|
||||
inline auto& operator>>=(const utype value) { return set(get() >> value); }
|
||||
inline auto& operator +=(const utype value) { return set(get() + value); }
|
||||
inline auto& operator -=(const utype value) { return set(get() - value); }
|
||||
inline auto& operator *=(const utype value) { return set(get() * value); }
|
||||
inline auto& operator /=(const utype value) { return set(get() / value); }
|
||||
inline auto& operator %=(const utype value) { return set(get() % value); }
|
||||
inline auto& operator++(int) { auto value = get(); set(value + 1); return value; }
|
||||
inline auto& operator--(int) { auto value = get(); set(value - 1); return value; }
|
||||
inline auto& operator++() { return set(get() + 1); }
|
||||
inline auto& operator--() { return set(get() - 1); }
|
||||
|
||||
private:
|
||||
Integer& source;
|
||||
const uint Lo;
|
||||
const uint Hi;
|
||||
};
|
||||
|
||||
inline auto bits(uint lo, uint hi) -> Reference { return {*this, lo, hi}; }
|
||||
inline auto bits(uint lo, uint hi) -> Reference { return {*this, lo < hi ? lo : hi, hi > lo ? hi : lo}; }
|
||||
inline auto bit(uint index) -> Reference { return {*this, index, index}; }
|
||||
inline auto byte(uint index) -> Reference { return {*this, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto clamp(uint bits) -> intmax_t {
|
||||
const intmax_t b = 1ull << (bits - 1);
|
||||
const intmax_t m = b - 1;
|
||||
inline auto bits(uint lo, uint hi) const -> const Reference { return {(Integer&)*this, lo < hi ? lo : hi, hi > lo ? hi : lo}; }
|
||||
inline auto bit(uint index) const -> const Reference { return {(Integer&)*this, index, index}; }
|
||||
inline auto byte(uint index) const -> const Reference { return {(Integer&)*this, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto clamp(uint bits) -> intmax {
|
||||
const intmax b = 1ull << (bits - 1);
|
||||
const intmax m = b - 1;
|
||||
return data > m ? m : data < -b ? -b : data;
|
||||
}
|
||||
|
||||
inline auto clip(uint bits) -> intmax_t {
|
||||
const uintmax_t b = 1ull << (bits - 1);
|
||||
const uintmax_t m = b * 2 - 1;
|
||||
inline auto clip(uint bits) -> intmax {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return ((data & m) ^ b) - b;
|
||||
}
|
||||
|
||||
|
@ -212,13 +258,147 @@ private:
|
|||
type data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using boolean = nall::Boolean;
|
||||
using integer = nall::Integer<sizeof( int) * 8>;
|
||||
using natural = nall::Natural<sizeof(uint) * 8>;
|
||||
using integer = nall::Integer<sizeof( int) * 8>;
|
||||
using real = nall::Real<sizeof(double) * 8>;
|
||||
|
||||
using natural1 = nall::Natural< 1>;
|
||||
using natural2 = nall::Natural< 2>;
|
||||
using natural3 = nall::Natural< 3>;
|
||||
using natural4 = nall::Natural< 4>;
|
||||
using natural5 = nall::Natural< 5>;
|
||||
using natural6 = nall::Natural< 6>;
|
||||
using natural7 = nall::Natural< 7>;
|
||||
using natural8 = nall::Natural< 8>;
|
||||
using natural9 = nall::Natural< 9>;
|
||||
using natural10 = nall::Natural<10>;
|
||||
using natural11 = nall::Natural<11>;
|
||||
using natural12 = nall::Natural<12>;
|
||||
using natural13 = nall::Natural<13>;
|
||||
using natural14 = nall::Natural<14>;
|
||||
using natural15 = nall::Natural<15>;
|
||||
using natural16 = nall::Natural<16>;
|
||||
using natural17 = nall::Natural<17>;
|
||||
using natural18 = nall::Natural<18>;
|
||||
using natural19 = nall::Natural<19>;
|
||||
using natural20 = nall::Natural<20>;
|
||||
using natural21 = nall::Natural<21>;
|
||||
using natural22 = nall::Natural<22>;
|
||||
using natural23 = nall::Natural<23>;
|
||||
using natural24 = nall::Natural<24>;
|
||||
using natural25 = nall::Natural<25>;
|
||||
using natural26 = nall::Natural<26>;
|
||||
using natural27 = nall::Natural<27>;
|
||||
using natural28 = nall::Natural<28>;
|
||||
using natural29 = nall::Natural<29>;
|
||||
using natural30 = nall::Natural<30>;
|
||||
using natural31 = nall::Natural<31>;
|
||||
using natural32 = nall::Natural<32>;
|
||||
using natural33 = nall::Natural<33>;
|
||||
using natural34 = nall::Natural<34>;
|
||||
using natural35 = nall::Natural<35>;
|
||||
using natural36 = nall::Natural<36>;
|
||||
using natural37 = nall::Natural<37>;
|
||||
using natural38 = nall::Natural<38>;
|
||||
using natural39 = nall::Natural<39>;
|
||||
using natural40 = nall::Natural<40>;
|
||||
using natural41 = nall::Natural<41>;
|
||||
using natural42 = nall::Natural<42>;
|
||||
using natural43 = nall::Natural<43>;
|
||||
using natural44 = nall::Natural<44>;
|
||||
using natural45 = nall::Natural<45>;
|
||||
using natural46 = nall::Natural<46>;
|
||||
using natural47 = nall::Natural<47>;
|
||||
using natural48 = nall::Natural<48>;
|
||||
using natural49 = nall::Natural<49>;
|
||||
using natural50 = nall::Natural<50>;
|
||||
using natural51 = nall::Natural<51>;
|
||||
using natural52 = nall::Natural<52>;
|
||||
using natural53 = nall::Natural<53>;
|
||||
using natural54 = nall::Natural<54>;
|
||||
using natural55 = nall::Natural<55>;
|
||||
using natural56 = nall::Natural<56>;
|
||||
using natural57 = nall::Natural<57>;
|
||||
using natural58 = nall::Natural<58>;
|
||||
using natural59 = nall::Natural<59>;
|
||||
using natural60 = nall::Natural<60>;
|
||||
using natural61 = nall::Natural<61>;
|
||||
using natural62 = nall::Natural<62>;
|
||||
using natural63 = nall::Natural<63>;
|
||||
using natural64 = nall::Natural<64>;
|
||||
|
||||
using integer1 = nall::Integer< 1>;
|
||||
using integer2 = nall::Integer< 2>;
|
||||
using integer3 = nall::Integer< 3>;
|
||||
using integer4 = nall::Integer< 4>;
|
||||
using integer5 = nall::Integer< 5>;
|
||||
using integer6 = nall::Integer< 6>;
|
||||
using integer7 = nall::Integer< 7>;
|
||||
using integer8 = nall::Integer< 8>;
|
||||
using integer9 = nall::Integer< 9>;
|
||||
using integer10 = nall::Integer<10>;
|
||||
using integer11 = nall::Integer<11>;
|
||||
using integer12 = nall::Integer<12>;
|
||||
using integer13 = nall::Integer<13>;
|
||||
using integer14 = nall::Integer<14>;
|
||||
using integer15 = nall::Integer<15>;
|
||||
using integer16 = nall::Integer<16>;
|
||||
using integer17 = nall::Integer<17>;
|
||||
using integer18 = nall::Integer<18>;
|
||||
using integer19 = nall::Integer<19>;
|
||||
using integer20 = nall::Integer<20>;
|
||||
using integer21 = nall::Integer<21>;
|
||||
using integer22 = nall::Integer<22>;
|
||||
using integer23 = nall::Integer<23>;
|
||||
using integer24 = nall::Integer<24>;
|
||||
using integer25 = nall::Integer<25>;
|
||||
using integer26 = nall::Integer<26>;
|
||||
using integer27 = nall::Integer<27>;
|
||||
using integer28 = nall::Integer<28>;
|
||||
using integer29 = nall::Integer<29>;
|
||||
using integer30 = nall::Integer<30>;
|
||||
using integer31 = nall::Integer<31>;
|
||||
using integer32 = nall::Integer<32>;
|
||||
using integer33 = nall::Integer<33>;
|
||||
using integer34 = nall::Integer<34>;
|
||||
using integer35 = nall::Integer<35>;
|
||||
using integer36 = nall::Integer<36>;
|
||||
using integer37 = nall::Integer<37>;
|
||||
using integer38 = nall::Integer<38>;
|
||||
using integer39 = nall::Integer<39>;
|
||||
using integer40 = nall::Integer<40>;
|
||||
using integer41 = nall::Integer<41>;
|
||||
using integer42 = nall::Integer<42>;
|
||||
using integer43 = nall::Integer<43>;
|
||||
using integer44 = nall::Integer<44>;
|
||||
using integer45 = nall::Integer<45>;
|
||||
using integer46 = nall::Integer<46>;
|
||||
using integer47 = nall::Integer<47>;
|
||||
using integer48 = nall::Integer<48>;
|
||||
using integer49 = nall::Integer<49>;
|
||||
using integer50 = nall::Integer<50>;
|
||||
using integer51 = nall::Integer<51>;
|
||||
using integer52 = nall::Integer<52>;
|
||||
using integer53 = nall::Integer<53>;
|
||||
using integer54 = nall::Integer<54>;
|
||||
using integer55 = nall::Integer<55>;
|
||||
using integer56 = nall::Integer<56>;
|
||||
using integer57 = nall::Integer<57>;
|
||||
using integer58 = nall::Integer<58>;
|
||||
using integer59 = nall::Integer<59>;
|
||||
using integer60 = nall::Integer<60>;
|
||||
using integer61 = nall::Integer<61>;
|
||||
using integer62 = nall::Integer<62>;
|
||||
using integer63 = nall::Integer<63>;
|
||||
using integer64 = nall::Integer<64>;
|
||||
|
||||
using real32 = nall::Real<32>;
|
||||
using real64 = nall::Real<64>;
|
||||
//using real80 = nall::Real<80>;
|
||||
|
||||
}
|
||||
|
||||
using int1 = nall::Integer< 1>;
|
||||
using int2 = nall::Integer< 2>;
|
||||
using int3 = nall::Integer< 3>;
|
||||
|
@ -348,7 +528,3 @@ using uint61 = nall::Natural<61>;
|
|||
using uint62 = nall::Natural<62>;
|
||||
using uint63 = nall::Natural<63>;
|
||||
using uint64 = nall::Natural<64>;
|
||||
|
||||
using real32 = nall::Real<32>;
|
||||
using real64 = nall::Real<64>;
|
||||
//using real80 = nall::Real<80>;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across different implementations
|
||||
|
||||
#include <nall/range.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
@ -46,14 +47,14 @@ struct serializer {
|
|||
}
|
||||
|
||||
template<typename T> auto floatingpoint(T& value) -> serializer& {
|
||||
enum { size = sizeof(T) };
|
||||
enum : uint { size = sizeof(T) };
|
||||
//this is rather dangerous, and not cross-platform safe;
|
||||
//but there is no standardized way to export FP-values
|
||||
auto p = (uint8_t*)&value;
|
||||
if(_mode == Save) {
|
||||
for(uint n = 0; n < size; n++) _data[_size++] = p[n];
|
||||
for(uint n : range(size)) _data[_size++] = p[n];
|
||||
} else if(_mode == Load) {
|
||||
for(uint n = 0; n < size; n++) p[n] = _data[_size++];
|
||||
for(uint n : range(size)) p[n] = _data[_size++];
|
||||
} else {
|
||||
_size += size;
|
||||
}
|
||||
|
@ -61,12 +62,13 @@ struct serializer {
|
|||
}
|
||||
|
||||
template<typename T> auto integer(T& value) -> serializer& {
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
enum : uint { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(_mode == Save) {
|
||||
for(uint n = 0; n < size; n++) _data[_size++] = (uintmax_t)value >> (n << 3);
|
||||
T copy = value;
|
||||
for(uint n : range(size)) _data[_size++] = copy, copy >>= 8;
|
||||
} else if(_mode == Load) {
|
||||
value = 0;
|
||||
for(uint n = 0; n < size; n++) value |= (uintmax_t)_data[_size++] << (n << 3);
|
||||
for(uint n : range(size)) value |= (T)_data[_size++] << (n << 3);
|
||||
} else if(_mode == Size) {
|
||||
_size += size;
|
||||
}
|
||||
|
@ -74,12 +76,12 @@ struct serializer {
|
|||
}
|
||||
|
||||
template<typename T, int N> auto array(T (&array)[N]) -> serializer& {
|
||||
for(uint n = 0; n < N; n++) operator()(array[n]);
|
||||
for(uint n : range(N)) operator()(array[n]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> auto array(T array, uint size) -> serializer& {
|
||||
for(uint n = 0; n < size; n++) operator()(array[n]);
|
||||
for(uint n : range(size)) operator()(array[n]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ struct shared_pointer {
|
|||
|
||||
template<typename U, typename = enable_if<is_compatible<U>>>
|
||||
auto operator=(const shared_pointer<U>& source) -> shared_pointer& {
|
||||
if((uintptr_t)this != (uintptr_t)&source) {
|
||||
if((uintptr)this != (uintptr)&source) {
|
||||
reset();
|
||||
if((bool)source) {
|
||||
manager = source.manager;
|
||||
|
@ -122,7 +122,7 @@ struct shared_pointer {
|
|||
|
||||
template<typename U, typename = enable_if<is_compatible<U>>>
|
||||
auto operator=(shared_pointer&& source) -> shared_pointer& {
|
||||
if((uintptr_t)this != (uintptr_t)&source) {
|
||||
if((uintptr)this != (uintptr)&source) {
|
||||
reset();
|
||||
manager = source.manager;
|
||||
source.manager = nullptr;
|
||||
|
|
12
stdint.hpp
12
stdint.hpp
|
@ -26,11 +26,23 @@
|
|||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
//note: (u)intmax actually mean it: use as many bits as is possible
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
using int128_t = signed __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
|
||||
#define INTMAX_BITS 128
|
||||
using intmax = int128_t;
|
||||
using uintmax = uint128_t;
|
||||
#else
|
||||
#define INTMAX_BITS 64
|
||||
using intmax = intmax_t;
|
||||
using uintmax = uintmax_t;
|
||||
#endif
|
||||
|
||||
using intptr = intptr_t;
|
||||
using uintptr = uintptr_t;
|
||||
|
||||
using float32_t = float;
|
||||
using float64_t = double;
|
||||
//note: long double size is not reliable across platforms
|
||||
|
|
27
string.hpp
27
string.hpp
|
@ -62,12 +62,12 @@ template<typename T> struct stringify;
|
|||
//format.hpp
|
||||
template<typename... P> inline auto print(P&&...) -> void;
|
||||
template<typename... P> inline auto print(FILE*, P&&...) -> void;
|
||||
template<typename T> inline auto numeral(T value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto hex(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto octal(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto binary(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
template<typename T> inline auto pad(const T& value, long precision = 0, char padchar = ' ') -> string;
|
||||
inline auto hex(uintmax value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto octal(uintmax value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto binary(uintmax value, long precision = 0, char padchar = '0') -> string;
|
||||
template<typename T> inline auto pointer(const T* value, long precision = 0) -> string;
|
||||
inline auto pointer(uintptr_t value, long precision = 0) -> string;
|
||||
inline auto pointer(uintptr value, long precision = 0) -> string;
|
||||
|
||||
//match.hpp
|
||||
inline auto tokenize(const char* s, const char* p) -> bool;
|
||||
|
@ -75,8 +75,8 @@ inline auto tokenize(string_vector& list, const char* s, const char* p) -> bool;
|
|||
|
||||
//utility.hpp
|
||||
inline auto slice(string_view self, int offset = 0, int length = -1) -> string;
|
||||
inline auto fromInteger(char* result, intmax_t value) -> char*;
|
||||
inline auto fromNatural(char* result, uintmax_t value) -> char*;
|
||||
inline auto fromInteger(char* result, intmax value) -> char*;
|
||||
inline auto fromNatural(char* result, uintmax value) -> char*;
|
||||
inline auto fromReal(char* str, long double value) -> uint;
|
||||
|
||||
struct string {
|
||||
|
@ -168,13 +168,14 @@ public:
|
|||
auto end() const -> const char* { return &data()[size()]; }
|
||||
|
||||
//atoi.hpp
|
||||
inline auto integer() const -> intmax_t;
|
||||
inline auto natural() const -> uintmax_t;
|
||||
inline auto hex() const -> uintmax_t;
|
||||
inline auto integer() const -> intmax;
|
||||
inline auto natural() const -> uintmax;
|
||||
inline auto hex() const -> uintmax;
|
||||
inline auto real() const -> double;
|
||||
|
||||
//core.hpp
|
||||
inline auto operator[](int) const -> const char&;
|
||||
inline auto operator()(int, char) const -> char;
|
||||
template<typename... P> inline auto assign(P&&...) -> type&;
|
||||
template<typename T, typename... P> inline auto append(const T&, P&&...) -> type&;
|
||||
template<typename... P> inline auto append(const nall::string_format&, P&&...) -> type&;
|
||||
|
@ -182,11 +183,6 @@ public:
|
|||
template<typename T> inline auto _append(const stringify<T>&) -> string&;
|
||||
inline auto length() const -> uint;
|
||||
|
||||
//datetime.hpp
|
||||
inline static auto date(time_t = 0) -> string;
|
||||
inline static auto time(time_t = 0) -> string;
|
||||
inline static auto datetime(time_t = 0) -> string;
|
||||
|
||||
//find.hpp
|
||||
template<bool, bool> inline auto _find(int, string_view) const -> maybe<uint>;
|
||||
|
||||
|
@ -315,7 +311,6 @@ struct string_format : vector<string> {
|
|||
#include <nall/string/compare.hpp>
|
||||
#include <nall/string/convert.hpp>
|
||||
#include <nall/string/core.hpp>
|
||||
#include <nall/string/datetime.hpp>
|
||||
#include <nall/string/find.hpp>
|
||||
#include <nall/string/format.hpp>
|
||||
#include <nall/string/list.hpp>
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
namespace nall {
|
||||
|
||||
auto string::integer() const -> intmax_t {
|
||||
auto string::integer() const -> intmax {
|
||||
return toInteger(data());
|
||||
}
|
||||
|
||||
auto string::natural() const -> uintmax_t {
|
||||
auto string::natural() const -> uintmax {
|
||||
return toNatural(data());
|
||||
}
|
||||
|
||||
auto string::hex() const -> uintmax_t {
|
||||
auto string::hex() const -> uintmax {
|
||||
return toHex(data());
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,15 @@ template<> struct stringify<signed long long> {
|
|||
char _data[2 + sizeof(signed long long) * 3];
|
||||
};
|
||||
|
||||
#if INTMAX_BITS >= 128
|
||||
template<> struct stringify<int128_t> {
|
||||
stringify(int128_t source) { fromInteger(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
auto size() const -> uint { return strlen(_data); }
|
||||
char _data[2 + sizeof(int128_t) * 3];
|
||||
};
|
||||
#endif
|
||||
|
||||
template<uint Bits> struct stringify<Integer<Bits>> {
|
||||
stringify(Integer<Bits> source) { fromInteger(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
|
@ -111,6 +120,15 @@ template<> struct stringify<unsigned long long> {
|
|||
char _data[1 + sizeof(unsigned long long) * 3];
|
||||
};
|
||||
|
||||
#if INTMAX_BITS >= 128
|
||||
template<> struct stringify<uint128_t> {
|
||||
stringify(uint128_t source) { fromNatural(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
auto size() const -> uint { return strlen(_data); }
|
||||
char _data[1 + sizeof(uint128_t) * 3];
|
||||
};
|
||||
#endif
|
||||
|
||||
template<uint Bits> struct stringify<Natural<Bits>> {
|
||||
stringify(Natural<Bits> source) { fromNatural(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
|
|
|
@ -20,6 +20,11 @@ auto string::operator[](int position) const -> const char& {
|
|||
return data()[position];
|
||||
}
|
||||
|
||||
auto string::operator()(int position, char fallback) const -> char {
|
||||
if(position > size() + 1) return fallback;
|
||||
return data()[position];
|
||||
}
|
||||
|
||||
template<typename... P> auto string::assign(P&&... p) -> string& {
|
||||
resize(0);
|
||||
return append(forward<P>(p)...);
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace nall {
|
||||
|
||||
auto string::date(time_t timestamp) -> string {
|
||||
if(timestamp == 0) timestamp = ::time(nullptr);
|
||||
tm* info = localtime(×tamp);
|
||||
return {
|
||||
numeral(1900 + info->tm_year, 4L), "-",
|
||||
numeral(1 + info->tm_mon, 2L), "-",
|
||||
numeral(info->tm_mday, 2L)
|
||||
};
|
||||
}
|
||||
|
||||
auto string::time(time_t timestamp) -> string {
|
||||
if(timestamp == 0) timestamp = ::time(nullptr);
|
||||
tm* info = localtime(×tamp);
|
||||
return {
|
||||
numeral(info->tm_hour, 2L), ":",
|
||||
numeral(info->tm_min, 2L), ":",
|
||||
numeral(info->tm_sec, 2L)
|
||||
};
|
||||
}
|
||||
|
||||
auto string::datetime(time_t timestamp) -> string {
|
||||
if(timestamp == 0) timestamp = ::time(nullptr);
|
||||
return {string::date(timestamp), " ", string::time(timestamp)};
|
||||
}
|
||||
|
||||
}
|
|
@ -78,52 +78,15 @@ template<typename... P> auto print(FILE* fp, P&&... p) -> void {
|
|||
fwrite(s.data(), 1, s.size(), fp);
|
||||
}
|
||||
|
||||
/*
|
||||
auto integer(intmax_t value, long precision, char padchar) -> string {
|
||||
string buffer;
|
||||
buffer.resize(1 + sizeof(intmax_t) * 3);
|
||||
char* p = buffer.get();
|
||||
|
||||
bool negative = value < 0;
|
||||
if(negative) value = -value; //make positive
|
||||
uint size = 0;
|
||||
do {
|
||||
p[size++] = '0' + (value % 10);
|
||||
value /= 10;
|
||||
} while(value);
|
||||
if(negative) p[size++] = '-';
|
||||
buffer.resize(size);
|
||||
buffer.reverse();
|
||||
if(precision) buffer.size(precision, padchar);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
auto natural(uintmax_t value, long precision, char padchar) -> string {
|
||||
string buffer;
|
||||
buffer.resize(sizeof(uintmax_t) * 3);
|
||||
char* p = buffer.get();
|
||||
|
||||
uint size = 0;
|
||||
do {
|
||||
p[size++] = '0' + (value % 10);
|
||||
value /= 10;
|
||||
} while(value);
|
||||
buffer.resize(size);
|
||||
buffer.reverse();
|
||||
if(precision) buffer.size(precision, padchar);
|
||||
return buffer;
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename T> auto numeral(T value, long precision, char padchar) -> string {
|
||||
template<typename T> auto pad(const T& value, long precision, char padchar) -> string {
|
||||
string buffer{value};
|
||||
if(precision) buffer.size(precision, padchar);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
auto hex(uintmax_t value, long precision, char padchar) -> string {
|
||||
auto hex(uintmax value, long precision, char padchar) -> string {
|
||||
string buffer;
|
||||
buffer.resize(sizeof(uintmax_t) * 2);
|
||||
buffer.resize(sizeof(uintmax) * 2);
|
||||
char* p = buffer.get();
|
||||
|
||||
uint size = 0;
|
||||
|
@ -138,9 +101,9 @@ auto hex(uintmax_t value, long precision, char padchar) -> string {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
auto octal(uintmax_t value, long precision, char padchar) -> string {
|
||||
auto octal(uintmax value, long precision, char padchar) -> string {
|
||||
string buffer;
|
||||
buffer.resize(sizeof(uintmax_t) * 3);
|
||||
buffer.resize(sizeof(uintmax) * 3);
|
||||
char* p = buffer.get();
|
||||
|
||||
uint size = 0;
|
||||
|
@ -154,9 +117,9 @@ auto octal(uintmax_t value, long precision, char padchar) -> string {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
auto binary(uintmax_t value, long precision, char padchar) -> string {
|
||||
auto binary(uintmax value, long precision, char padchar) -> string {
|
||||
string buffer;
|
||||
buffer.resize(sizeof(uintmax_t) * 8);
|
||||
buffer.resize(sizeof(uintmax) * 8);
|
||||
char* p = buffer.get();
|
||||
|
||||
uint size = 0;
|
||||
|
@ -172,10 +135,10 @@ auto binary(uintmax_t value, long precision, char padchar) -> string {
|
|||
|
||||
template<typename T> auto pointer(const T* value, long precision) -> string {
|
||||
if(value == nullptr) return "(nullptr)";
|
||||
return {"0x", hex((uintptr_t)value, precision)};
|
||||
return {"0x", hex((uintptr)value, precision)};
|
||||
}
|
||||
|
||||
auto pointer(uintptr_t value, long precision) -> string {
|
||||
auto pointer(uintptr value, long precision) -> string {
|
||||
if(value == 0) return "(nullptr)";
|
||||
return {"0x", hex(value, precision)};
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ struct ManagedNode {
|
|||
protected:
|
||||
string _name;
|
||||
string _value;
|
||||
uintptr_t _metadata = 0;
|
||||
uintptr _metadata = 0;
|
||||
vector<SharedNode> _children;
|
||||
|
||||
inline auto _evaluate(string query) const -> bool;
|
||||
|
@ -59,8 +59,8 @@ struct Node {
|
|||
|
||||
auto text() const -> string { return value().strip(); }
|
||||
auto boolean() const -> bool { return text() == "true"; }
|
||||
auto integer() const -> intmax_t { return text().integer(); }
|
||||
auto natural() const -> uintmax_t { return text().natural(); }
|
||||
auto integer() const -> intmax { return text().integer(); }
|
||||
auto natural() const -> uintmax { return text().natural(); }
|
||||
auto real() const -> double { return text().real(); }
|
||||
|
||||
auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
/* Document Markup Language (DML) v1.0 parser
|
||||
* revision 0.03
|
||||
* revision 0.04
|
||||
*/
|
||||
|
||||
#include <nall/location.hpp>
|
||||
|
@ -87,7 +87,7 @@ auto DML::parseBlock(string& block, const string& pathname, uint depth) -> bool
|
|||
if(state.sections++) state.output.append("</section>");
|
||||
state.output.append("<section>");
|
||||
}
|
||||
auto content = lines.takeLeft().trimLeft("# ", 1L).split(" => ", 1L);
|
||||
auto content = lines.takeLeft().trimLeft("# ", 1L).split("::", 1L);
|
||||
auto data = markup(content[0]);
|
||||
auto name = escape(content(1, data.hash()));
|
||||
state.output.append("<header id=\"", name, "\">", data);
|
||||
|
@ -100,7 +100,7 @@ auto DML::parseBlock(string& block, const string& pathname, uint depth) -> bool
|
|||
|
||||
//header
|
||||
else if(auto depth = count(block, '=')) {
|
||||
auto content = slice(lines.takeLeft(), depth + 1).split(" => ", 1L);
|
||||
auto content = slice(lines.takeLeft(), depth + 1).split("::", 1L);
|
||||
auto data = markup(content[0]);
|
||||
auto name = escape(content(1, data.hash()));
|
||||
if(depth <= 6) {
|
||||
|
@ -121,7 +121,7 @@ auto DML::parseBlock(string& block, const string& pathname, uint depth) -> bool
|
|||
if(auto depth = count(line, '-')) {
|
||||
while(level < depth) level++, state.output.append("<ul>\n");
|
||||
while(level > depth) level--, state.output.append("</ul>\n");
|
||||
auto content = slice(line, depth + 1).split(" => ", 1L);
|
||||
auto content = slice(line, depth + 1).split("::", 1L);
|
||||
auto data = markup(content[0]);
|
||||
auto name = escape(content(1, data.hash()));
|
||||
state.output.append("<li><a href=\"#", name, "\">", data, "</a></li>\n");
|
||||
|
@ -204,6 +204,7 @@ auto DML::escape(const string& text) -> string {
|
|||
return output;
|
||||
}
|
||||
|
||||
/* //revision 0.03 parser
|
||||
auto DML::markup(const string& text) -> string {
|
||||
string output;
|
||||
|
||||
|
@ -264,6 +265,68 @@ auto DML::markup(const string& text) -> string {
|
|||
}
|
||||
|
||||
return output;
|
||||
} */
|
||||
|
||||
auto DML::markup(const string& s) -> string {
|
||||
string t;
|
||||
|
||||
boolean strong;
|
||||
boolean emphasis;
|
||||
boolean insertion;
|
||||
boolean deletion;
|
||||
boolean code;
|
||||
|
||||
natural link, linkBase;
|
||||
natural embed, embedBase;
|
||||
|
||||
for(uint n = 0; n < s.size();) {
|
||||
char a = s[n];
|
||||
char b = s[n + 1];
|
||||
|
||||
if(!link && !embed) {
|
||||
if(a == '*' && b == '*') { t.append(strong.flip() ? "<strong>" : "</strong>"); n += 2; continue; }
|
||||
if(a == '/' && b == '/') { t.append(emphasis.flip() ? "<em>" : "</em>"); n += 2; continue; }
|
||||
if(a == '_' && b == '_') { t.append(insertion.flip() ? "<ins>" : "</ins>"); n += 2; continue; }
|
||||
if(a == '~' && b == '~') { t.append(deletion.flip() ? "<del>" : "</del>"); n += 2; continue; }
|
||||
if(a == '|' && b == '|') { t.append(code.flip() ? "<code>" : "</code>"); n += 2; continue; }
|
||||
if(a =='\\' && b =='\\') { t.append("<br>"); n += 2; continue; }
|
||||
}
|
||||
|
||||
if(!embed) {
|
||||
if(link == 0 && a == '[' && b == '[') { t.append("<a href=\""); link = 1; linkBase = n += 2; continue; }
|
||||
if(link == 1 && a == ':' && b == ':') { t.append("\">"); link = 2; n += 2; continue; }
|
||||
if(link == 1 && a == ']' && b == ']') { t.append("\">", slice(s, linkBase, n - linkBase), "</a>"); n += 2; link = 0; continue; }
|
||||
if(link == 2 && a == ']' && b == ']') { t.append("</a>"); n += 2; link = 0; continue; }
|
||||
if(link == 1 && a == '@' && b == '/') { t.append(settings.host); n += 2; continue; }
|
||||
}
|
||||
|
||||
if(!link) {
|
||||
if(embed == 0 && a == '{' && b == '{') { t.append("<img src=\""); embed = 1; embedBase = n += 2; continue; }
|
||||
if(embed == 1 && a == ':' && b == ':') { t.append("\" alt=\""); embed = 2; n += 2; continue; }
|
||||
if(embed != 0 && a == '}' && b == '}') { t.append("\">"); embed = 0; n += 2; continue; }
|
||||
if(embed == 1 && a == '@' && b == '/') { t.append(settings.host); n += 2; continue; }
|
||||
}
|
||||
|
||||
if(a =='\\') { t.append(b); n += 2; continue; }
|
||||
if(a == '&') { t.append("&"); n++; continue; }
|
||||
if(a == '<') { t.append("<"); n++; continue; }
|
||||
if(a == '>') { t.append(">"); n++; continue; }
|
||||
if(a == '"') { t.append("""); n++; continue; }
|
||||
|
||||
t.append(a);
|
||||
n++;
|
||||
}
|
||||
|
||||
if(strong) t.append("</strong>");
|
||||
if(emphasis) t.append("</em>");
|
||||
if(insertion) t.append("</ins>");
|
||||
if(deletion) t.append("</del>");
|
||||
if(code) t.append("</code>");
|
||||
if(link == 1) t.append("\">", slice(s, linkBase, s.size() - linkBase), "</a>");
|
||||
if(link == 2) t.append("</a>");
|
||||
if(embed != 0) t.append("\">");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
|
@ -92,7 +92,7 @@ auto slice(string_view self, int offset, int length) -> string {
|
|||
return result;
|
||||
}
|
||||
|
||||
auto fromInteger(char* result, intmax_t value) -> char* {
|
||||
auto fromInteger(char* result, intmax value) -> char* {
|
||||
bool negative = value < 0;
|
||||
if(negative) value = -value;
|
||||
|
||||
|
@ -111,7 +111,7 @@ auto fromInteger(char* result, intmax_t value) -> char* {
|
|||
return result;
|
||||
}
|
||||
|
||||
auto fromNatural(char* result, uintmax_t value) -> char* {
|
||||
auto fromNatural(char* result, uintmax value) -> char* {
|
||||
char buffer[64];
|
||||
uint size = 0;
|
||||
|
||||
|
|
16
thread.hpp
16
thread.hpp
|
@ -19,13 +19,13 @@ namespace nall {
|
|||
struct thread {
|
||||
inline auto join() -> void;
|
||||
|
||||
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto detach() -> void;
|
||||
static inline auto exit() -> void;
|
||||
|
||||
struct context {
|
||||
function<auto (uintptr_t) -> void> callback;
|
||||
uintptr_t parameter = 0;
|
||||
function<auto (uintptr) -> void> callback;
|
||||
uintptr parameter = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -43,7 +43,7 @@ auto thread::join() -> void {
|
|||
pthread_join(handle, nullptr);
|
||||
}
|
||||
|
||||
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, uint stacksize) -> thread {
|
||||
auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
|
||||
thread instance;
|
||||
|
||||
auto context = new thread::context;
|
||||
|
@ -76,13 +76,13 @@ struct thread {
|
|||
inline ~thread();
|
||||
inline auto join() -> void;
|
||||
|
||||
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto detach() -> void;
|
||||
static inline auto exit() -> void;
|
||||
|
||||
struct context {
|
||||
function<auto (uintptr_t) -> void> callback;
|
||||
uintptr_t parameter = 0;
|
||||
function<auto (uintptr) -> void> callback;
|
||||
uintptr parameter = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -111,7 +111,7 @@ auto thread::join() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, uint stacksize) -> thread {
|
||||
auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
|
||||
thread instance;
|
||||
|
||||
auto context = new thread::context;
|
||||
|
|
12
varint.hpp
12
varint.hpp
|
@ -10,8 +10,8 @@ struct varint {
|
|||
virtual auto read() -> uint8_t = 0;
|
||||
virtual auto write(uint8_t) -> void = 0;
|
||||
|
||||
auto readvu() -> uintmax_t {
|
||||
uintmax_t data = 0, shift = 1;
|
||||
auto readvu() -> uintmax {
|
||||
uintmax data = 0, shift = 1;
|
||||
while(true) {
|
||||
uint8_t x = read();
|
||||
data += (x & 0x7f) * shift;
|
||||
|
@ -22,15 +22,15 @@ struct varint {
|
|||
return data;
|
||||
}
|
||||
|
||||
auto readvs() -> intmax_t {
|
||||
uintmax_t data = readvu();
|
||||
auto readvs() -> intmax {
|
||||
uintmax data = readvu();
|
||||
bool negate = data & 1;
|
||||
data >>= 1;
|
||||
if(negate) data = ~data;
|
||||
return data;
|
||||
}
|
||||
|
||||
auto writevu(uintmax_t data) -> void {
|
||||
auto writevu(uintmax data) -> void {
|
||||
while(true) {
|
||||
uint8_t x = data & 0x7f;
|
||||
data >>= 7;
|
||||
|
@ -40,7 +40,7 @@ struct varint {
|
|||
}
|
||||
}
|
||||
|
||||
auto writevs(intmax_t data) -> void {
|
||||
auto writevs(intmax data) -> void {
|
||||
bool negate = data < 0;
|
||||
if(negate) data = ~data;
|
||||
data = (data << 1) | negate;
|
||||
|
|
|
@ -11,15 +11,15 @@ struct file : vfs::file {
|
|||
return instance;
|
||||
}
|
||||
|
||||
auto size() const -> uintmax_t override {
|
||||
auto size() const -> uintmax override {
|
||||
return _fp.size();
|
||||
}
|
||||
|
||||
auto offset() const -> uintmax_t override {
|
||||
auto offset() const -> uintmax override {
|
||||
return _fp.offset();
|
||||
}
|
||||
|
||||
auto seek(intmax_t offset_, index index_) -> void override {
|
||||
auto seek(intmax offset_, index index_) -> void override {
|
||||
_fp.seek(offset_, (nall::file::index)index_);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,18 +5,18 @@ namespace nall { namespace vfs { namespace memory {
|
|||
struct file : vfs::file {
|
||||
~file() { delete[] _data; }
|
||||
|
||||
static auto open(const uint8_t* data, uintmax_t size) -> vfs::shared::file {
|
||||
static auto open(const uint8_t* data, uintmax size) -> vfs::shared::file {
|
||||
auto instance = shared_pointer<file>{new file};
|
||||
instance->_open(data, size);
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto size() const -> uintmax_t override { return _size; }
|
||||
auto offset() const -> uintmax_t override { return _offset; }
|
||||
auto size() const -> uintmax override { return _size; }
|
||||
auto offset() const -> uintmax override { return _offset; }
|
||||
|
||||
auto seek(intmax_t offset, index mode) -> void override {
|
||||
if(mode == index::absolute) _offset = (uintmax_t)offset;
|
||||
if(mode == index::relative) _offset += (intmax_t)offset;
|
||||
auto seek(intmax offset, index mode) -> void override {
|
||||
if(mode == index::absolute) _offset = (uintmax)offset;
|
||||
if(mode == index::relative) _offset += (intmax)offset;
|
||||
}
|
||||
|
||||
auto read() -> uint8_t override {
|
||||
|
@ -34,15 +34,15 @@ private:
|
|||
file(const file&) = delete;
|
||||
auto operator=(const file&) -> file& = delete;
|
||||
|
||||
auto _open(const uint8_t* data, uintmax_t size) -> void {
|
||||
auto _open(const uint8_t* data, uintmax size) -> void {
|
||||
_size = size;
|
||||
_data = new uint8_t[size];
|
||||
nall::memory::copy(_data, data, size);
|
||||
}
|
||||
|
||||
uint8_t* _data = nullptr;
|
||||
uintmax_t _size = 0;
|
||||
uintmax_t _offset = 0;
|
||||
uintmax _size = 0;
|
||||
uintmax _offset = 0;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
|
24
vfs/vfs.hpp
24
vfs/vfs.hpp
|
@ -11,10 +11,10 @@ struct file {
|
|||
|
||||
virtual ~file() = default;
|
||||
|
||||
virtual auto size() const -> uintmax_t = 0;
|
||||
virtual auto offset() const -> uintmax_t = 0;
|
||||
virtual auto size() const -> uintmax = 0;
|
||||
virtual auto offset() const -> uintmax = 0;
|
||||
|
||||
virtual auto seek(intmax_t offset, index = index::absolute) -> void = 0;
|
||||
virtual auto seek(intmax offset, index = index::absolute) -> void = 0;
|
||||
virtual auto read() -> uint8_t = 0;
|
||||
virtual auto write(uint8_t data) -> void = 0;
|
||||
virtual auto flush() -> void {}
|
||||
|
@ -23,19 +23,19 @@ struct file {
|
|||
return offset() >= size();
|
||||
}
|
||||
|
||||
auto read(void* vdata, uintmax_t bytes) -> void {
|
||||
auto read(void* vdata, uintmax bytes) -> void {
|
||||
auto data = (uint8_t*)vdata;
|
||||
while(bytes--) *data++ = read();
|
||||
}
|
||||
|
||||
auto readl(uint bytes) -> uintmax_t {
|
||||
uintmax_t data = 0;
|
||||
for(auto n : range(bytes)) data |= (uintmax_t)read() << n * 8;
|
||||
auto readl(uint bytes) -> uintmax {
|
||||
uintmax data = 0;
|
||||
for(auto n : range(bytes)) data |= (uintmax)read() << n * 8;
|
||||
return data;
|
||||
}
|
||||
|
||||
auto readm(uint bytes) -> uintmax_t {
|
||||
uintmax_t data = 0;
|
||||
auto readm(uint bytes) -> uintmax {
|
||||
uintmax data = 0;
|
||||
for(auto n : range(bytes)) data = data << 8 | read();
|
||||
return data;
|
||||
}
|
||||
|
@ -47,16 +47,16 @@ struct file {
|
|||
return s;
|
||||
}
|
||||
|
||||
auto write(const void* vdata, uintmax_t bytes) -> void {
|
||||
auto write(const void* vdata, uintmax bytes) -> void {
|
||||
auto data = (const uint8_t*)vdata;
|
||||
while(bytes--) write(*data++);
|
||||
}
|
||||
|
||||
auto writel(uintmax_t data, uint bytes) -> void {
|
||||
auto writel(uintmax data, uint bytes) -> void {
|
||||
for(auto n : range(bytes)) write(data), data >>= 8;
|
||||
}
|
||||
|
||||
auto writem(uintmax_t data, uint bytes) -> void {
|
||||
auto writem(uintmax data, uint bytes) -> void {
|
||||
for(auto n : rrange(bytes)) write(data >> n * 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ auto detour::insert(const string& moduleName, const string& functionName, void*&
|
|||
DWORD privileges;
|
||||
VirtualProtect((void*)mirrorData, 512, PAGE_EXECUTE_READWRITE, &privileges);
|
||||
VirtualProtect((void*)sourceData, 256, PAGE_EXECUTE_READWRITE, &privileges);
|
||||
uintmax address = (uintmax)target - ((uintmax)sourceData + 5);
|
||||
uint64_t address = (uint64_t)target - ((uint64_t)sourceData + 5);
|
||||
sourceData[0] = 0xe9; //jmp target
|
||||
sourceData[1] = address >> 0;
|
||||
sourceData[2] = address >> 8;
|
||||
|
@ -157,11 +157,11 @@ auto detour::mirror(uint8* target, const uint8* source) -> uint {
|
|||
break;
|
||||
case RelNear: {
|
||||
source++;
|
||||
uintmax sourceAddress = (uintmax)source + 1 + (int8)*source;
|
||||
uint64_t sourceAddress = (uint64_t)source + 1 + (int8)*source;
|
||||
*target++ = opcode->modify;
|
||||
if(opcode->modify >> 8) *target++ = opcode->modify >> 8;
|
||||
uintmax targetAddress = (uintmax)target + 4;
|
||||
uintmax address = sourceAddress - targetAddress;
|
||||
uint64_t targetAddress = (uint64_t)target + 4;
|
||||
uint64_t address = sourceAddress - targetAddress;
|
||||
*target++ = address >> 0;
|
||||
*target++ = address >> 8;
|
||||
*target++ = address >> 16;
|
||||
|
@ -173,7 +173,7 @@ auto detour::mirror(uint8* target, const uint8* source) -> uint {
|
|||
size -= opcode->length;
|
||||
}
|
||||
|
||||
uintmax address = (entryPoint + detour::length(entryPoint)) - (target + 5);
|
||||
uint64_t address = (entryPoint + detour::length(entryPoint)) - (target + 5);
|
||||
*target++ = 0xe9; //jmp entryPoint
|
||||
*target++ = address >> 0;
|
||||
*target++ = address >> 8;
|
||||
|
|
Loading…
Reference in a new issue