Update to v092r08 release.

byuu says:

Changelog:
- fixed cartridge load window focus on Windows
- lots of updates to nall, ruby and phoenix
- ethos and Emulator::Interface updated from "foo &bar" to "foo& bar"
  syntax (work-in-progress)

Before I had mixed the two ways to declare variables/arguments all over
the place, so the goal is to unify them all for consistency. So the
changelog for this release will be massive (750KB >.>) due to the syntax
change. Yeah, that's what I spent the last three days working on ...
This commit is contained in:
Tim Allen 2013-05-02 21:25:45 +10:00
parent 177e222ca7
commit 75dab443b4
394 changed files with 4989 additions and 4745 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "higan";
static const char Version[] = "092.07";
static const char Version[] = "092.08";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
static const char Website[] = "http://byuu.org/";
@ -59,11 +59,11 @@ template<typename R, typename... P> struct hook<R (P...)> {
}
hook() {}
hook(const hook &hook) { callback = hook.callback; }
hook(void *function) { callback = function; }
hook(const hook& hook) { callback = hook.callback; }
hook(void* function) { callback = function; }
hook(R (*function)(P...)) { callback = function; }
template<typename C> hook(R (C::*function)(P...), C *object) { callback = {function, object}; }
template<typename C> hook(R (C::*function)(P...) const, C *object) { callback = {function, object}; }
template<typename C> hook(R (C::*function)(P...), C* object) { callback = {function, object}; }
template<typename C> hook(R (C::*function)(P...) const, C* object) { callback = {function, object}; }
template<typename L> hook(const L& function) { callback = function; }
hook& operator=(const hook& hook) { callback = hook.callback; return *this; }

View File

@ -23,7 +23,6 @@ struct Interface {
string type;
bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges)
};
vector<Media> media;
struct Device {
@ -58,21 +57,22 @@ struct Interface {
virtual unsigned dipSettings(const Markup::Node&) { return 0; }
virtual string path(unsigned) { return ""; }
virtual string server() { return ""; }
virtual void notify(const string &text) { print(text, "\n"); }
} *bind;
virtual void notify(const string& text) { print(text, "\n"); }
};
Bind* bind = nullptr;
//callback bindings (provided by user interface)
void loadRequest(unsigned id, const string &name, const string &type) { return bind->loadRequest(id, name, type); }
void loadRequest(unsigned id, const string &path) { return bind->loadRequest(id, path); }
void saveRequest(unsigned id, const string &path) { return bind->saveRequest(id, path); }
void loadRequest(unsigned id, const string& name, const string& type) { return bind->loadRequest(id, name, type); }
void loadRequest(unsigned id, const string& path) { return bind->loadRequest(id, path); }
void saveRequest(unsigned id, const string& path) { return bind->saveRequest(id, path); }
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { return bind->videoColor(source, red, green, blue); }
void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
void videoRefresh(const uint32_t* data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
void audioSample(int16_t lsample, int16_t rsample) { return bind->audioSample(lsample, rsample); }
int16_t inputPoll(unsigned port, unsigned device, unsigned input) { return bind->inputPoll(port, device, input); }
unsigned dipSettings(const Markup::Node &node) { return bind->dipSettings(node); }
unsigned dipSettings(const Markup::Node& node) { return bind->dipSettings(node); }
string path(unsigned group) { return bind->path(group); }
string server() { return bind->server(); }
template<typename... Args> void notify(Args&... args) { return bind->notify({std::forward<Args>(args)...}); }
template<typename... Args> void notify(Args&&... args) { return bind->notify({std::forward<Args>(args)...}); }
//information
virtual string title() = 0;
@ -85,8 +85,8 @@ struct Interface {
virtual unsigned group(unsigned id) = 0;
virtual void load(unsigned id) {}
virtual void save() {}
virtual void load(unsigned id, const stream &memory) {}
virtual void save(unsigned id, const stream &memory) {}
virtual void load(unsigned id, const stream& memory) {}
virtual void save(unsigned id, const stream& memory) {}
virtual void unload() {}
//system interface
@ -112,8 +112,6 @@ struct Interface {
//debugger functions
virtual bool tracerEnable(bool) { return false; }
virtual void exportMemory() {}
Interface() : bind(nullptr) {}
};
}

View File

@ -11,8 +11,12 @@ void CPU::serialize(serializer &s) {
s.integer(status.irq_apu_line);
s.integer(status.rdy_line);
s.integer(status.rdy_addr.valid);
s.integer(status.rdy_addr.value);
bool rdy_addr_valid = status.rdy_addr;
unsigned rdy_addr_value = 0;
if(rdy_addr_valid) rdy_addr_value = status.rdy_addr();
s.integer(rdy_addr_valid);
s.integer(rdy_addr_value);
if(rdy_addr_valid) status.rdy_addr = rdy_addr_value;
s.integer(status.oam_dma_pending);
s.integer(status.oam_dma_page);

View File

@ -2,7 +2,7 @@
namespace Famicom {
Interface *interface = nullptr;
Interface* interface = nullptr;
string Interface::title() {
return cartridge.title();
@ -42,12 +42,12 @@ void Interface::load(unsigned id) {
}
void Interface::save() {
for(auto &memory : cartridge.memory) {
for(auto& memory : cartridge.memory) {
saveRequest(memory.id, memory.name);
}
}
void Interface::load(unsigned id, const stream &stream) {
void Interface::load(unsigned id, const stream& stream) {
if(id == ID::Manifest) cartridge.information.markup = stream.text();
if(id == ID::ProgramROM) {
@ -67,7 +67,7 @@ void Interface::load(unsigned id, const stream &stream) {
}
}
void Interface::save(unsigned id, const stream &stream) {
void Interface::save(unsigned id, const stream& stream) {
if(id == ID::ProgramRAM) {
stream.write(cartridge.board->prgram.data, cartridge.board->prgram.size);
}
@ -99,15 +99,15 @@ serializer Interface::serialize() {
return system.serialize();
}
bool Interface::unserialize(serializer &s) {
bool Interface::unserialize(serializer& s) {
return system.unserialize(s);
}
void Interface::cheatSet(const lstring &list) {
void Interface::cheatSet(const lstring& list) {
cheat.reset();
for(auto &code : list) {
for(auto& code : list) {
lstring codelist = code.split("+");
for(auto &part : codelist) {
for(auto& part : codelist) {
unsigned addr, data, comp;
if(Cheat::decode(part, addr, data, comp)) cheat.append({addr, data, comp});
}
@ -150,8 +150,8 @@ Interface::Interface() {
port.append({0, "Port 1"});
port.append({1, "Port 2"});
for(auto &device : this->device) {
for(auto &port : this->port) {
for(auto& device : this->device) {
for(auto& port : this->port) {
if(device.portmask & (1 << port.id)) {
port.device.append(device);
}

View File

@ -32,8 +32,8 @@ struct Interface : Emulator::Interface {
unsigned group(unsigned id);
void load(unsigned id);
void save();
void load(unsigned id, const stream &stream);
void save(unsigned id, const stream &stream);
void load(unsigned id, const stream& stream);
void save(unsigned id, const stream& stream);
void unload();
void power();
@ -53,7 +53,7 @@ private:
vector<Device> device;
};
extern Interface *interface;
extern Interface* interface;
#ifndef FC_HPP
}

View File

@ -2,7 +2,7 @@
namespace GameBoy {
Interface *interface = nullptr;
Interface* interface = nullptr;
void Interface::lcdScanline() {
if(hook) hook->lcdScanline();
@ -62,7 +62,7 @@ void Interface::save() {
}
}
void Interface::load(unsigned id, const stream &stream) {
void Interface::load(unsigned id, const stream& stream) {
if(id == ID::GameBoyBootROM) {
stream.read(system.bootROM.dmg, min( 256u, stream.size()));
}
@ -86,7 +86,7 @@ void Interface::load(unsigned id, const stream &stream) {
}
}
void Interface::save(unsigned id, const stream &stream) {
void Interface::save(unsigned id, const stream& stream) {
if(id == ID::RAM) {
stream.write(cartridge.ramdata, cartridge.ramsize);
}
@ -114,15 +114,15 @@ serializer Interface::serialize() {
return system.serialize();
}
bool Interface::unserialize(serializer &s) {
bool Interface::unserialize(serializer& s) {
return system.unserialize(s);
}
void Interface::cheatSet(const lstring &list) {
void Interface::cheatSet(const lstring& list) {
cheat.reset();
for(auto &code : list) {
for(auto& code : list) {
lstring codelist = code.split("+");
for(auto &part : codelist) {
for(auto& part : codelist) {
unsigned addr, data, comp;
if(Cheat::decode(part, addr, data, comp)) cheat.append({addr, data, comp});
}

View File

@ -30,7 +30,8 @@ struct Interface : Emulator::Interface {
struct Hook {
virtual void lcdScanline() {}
virtual void joypWrite(bool p15, bool p14) {}
} *hook;
};
Hook* hook = nullptr;
void lcdScanline();
void joypWrite(bool p15, bool p14);
@ -44,8 +45,8 @@ struct Interface : Emulator::Interface {
unsigned group(unsigned id);
void load(unsigned id);
void save();
void load(unsigned id, const stream &stream);
void save(unsigned id, const stream &stream);
void load(unsigned id, const stream& stream);
void save(unsigned id, const stream& stream);
void unload();
void power();
@ -65,7 +66,7 @@ private:
vector<Device> device;
};
extern Interface *interface;
extern Interface* interface;
#ifndef GB_HPP
}

View File

@ -2,7 +2,7 @@
namespace GameBoyAdvance {
Interface *interface = nullptr;
Interface* interface = nullptr;
string Interface::title() {
return cartridge.title();
@ -40,12 +40,12 @@ void Interface::load(unsigned id) {
}
void Interface::save() {
for(auto &memory : cartridge.memory) {
for(auto& memory : cartridge.memory) {
interface->saveRequest(memory.id, memory.name);
}
}
void Interface::load(unsigned id, const stream &stream) {
void Interface::load(unsigned id, const stream& stream) {
if(id == ID::BIOS) {
stream.read(bios.data, min(bios.size, stream.size()));
}
@ -69,7 +69,7 @@ void Interface::load(unsigned id, const stream &stream) {
}
}
void Interface::save(unsigned id, const stream &stream) {
void Interface::save(unsigned id, const stream& stream) {
if(id == ID::RAM) {
stream.write(cartridge.ram.data, cartridge.ram.size);
}
@ -105,7 +105,7 @@ serializer Interface::serialize() {
return system.serialize();
}
bool Interface::unserialize(serializer &s) {
bool Interface::unserialize(serializer& s) {
return system.unserialize(s);
}

View File

@ -32,8 +32,8 @@ struct Interface : Emulator::Interface {
unsigned group(unsigned id);
void load(unsigned id);
void save();
void load(unsigned id, const stream &stream);
void save(unsigned id, const stream &stream);
void load(unsigned id, const stream& stream);
void save(unsigned id, const stream& stream);
void unload();
void power();
@ -51,7 +51,7 @@ private:
vector<Device> device;
};
extern Interface *interface;
extern Interface* interface;
#ifndef GBA_HPP
}

View File

@ -5,13 +5,15 @@
#undef max
namespace nall {
template<typename T, typename U> T min(const T &t, const U &u) {
return t < u ? t : u;
}
template<typename T, typename U> T max(const T &t, const U &u) {
return t > u ? t : u;
}
template<typename T, typename U> T min(const T& t, const U& u) {
return t < u ? t : u;
}
template<typename T, typename U> T max(const T& t, const U& u) {
return t > u ? t : u;
}
}
#endif

View File

@ -5,69 +5,73 @@
#include <nall/traits.hpp>
namespace nall {
struct any {
bool empty() const { return container; }
const std::type_info& type() const { return container ? container->type() : typeid(void); }
template<typename T> any& operator=(const T& value_) {
typedef typename type_if<
std::is_array<T>::value,
typename std::remove_extent<typename std::add_const<T>::type>::type*,
T
>::type auto_t;
struct any {
bool empty() const { return container; }
const std::type_info& type() const { return container ? container->type() : typeid(void); }
if(type() == typeid(auto_t)) {
static_cast<holder<auto_t>*>(container)->value = (auto_t)value_;
} else {
if(container) delete container;
container = new holder<auto_t>((auto_t)value_);
}
template<typename T> any& operator=(const T& value) {
typedef typename type_if<
std::is_array<T>::value,
typename std::remove_extent<typename std::add_const<T>::type>::type*,
T
>::type auto_t;
return *this;
if(type() == typeid(auto_t)) {
static_cast<holder<auto_t>*>(container)->value = (auto_t)value;
} else {
if(container) delete container;
container = new holder<auto_t>((auto_t)value);
}
any() : container(nullptr) {}
~any() { if(container) delete container; }
template<typename T> any(const T& value_) : container(nullptr) { operator=(value_); }
return *this;
}
private:
struct placeholder {
virtual const std::type_info& type() const = 0;
} *container;
any() = default;
template<typename T> any(const T& value) { operator=(value); }
~any() { if(container) delete container; }
template<typename T> struct holder : placeholder {
T value;
const std::type_info& type() const { return typeid(T); }
holder(const T& value_) : value(value_) {}
};
template<typename T> friend T any_cast(any&);
template<typename T> friend T any_cast(const any&);
template<typename T> friend T* any_cast(any*);
template<typename T> friend const T* any_cast(const any*);
private:
struct placeholder {
virtual const std::type_info& type() const = 0;
};
template<typename T> T any_cast(any &value) {
typedef typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
placeholder* container = nullptr;
template<typename T> T any_cast(const any &value) {
typedef const typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
template<typename T> struct holder : placeholder {
T value;
const std::type_info& type() const { return typeid(T); }
holder(const T& value) : value(value) {}
};
template<typename T> T* any_cast(any *value) {
if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value;
}
template<typename T> friend T any_cast(any&);
template<typename T> friend T any_cast(const any&);
template<typename T> friend T* any_cast(any*);
template<typename T> friend const T* any_cast(const any*);
};
template<typename T> T any_cast(any& value) {
typedef typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
template<typename T> T any_cast(const any& value) {
typedef const typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
template<typename T> T* any_cast(any* value) {
if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value;
}
template<typename T> const T* any_cast(const any* value) {
if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value;
}
template<typename T> const T* any_cast(const any *value) {
if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value;
}
}
#endif

View File

@ -5,34 +5,28 @@
namespace nall {
//note: this header is intended to form the base for user-defined literals;
//once they are supported by GCC. eg:
//unsigned operator "" b(const char *s) { return binary(s); }
//-> signed data = 1001b;
//(0b1001 is nicer, but is not part of the C++ standard)
constexpr inline uintmax_t binary_(const char *s, uintmax_t sum = 0) {
constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
sum
);
}
constexpr inline uintmax_t octal_(const char *s, uintmax_t sum = 0) {
constexpr inline uintmax_t octal_(const char* s, uintmax_t sum = 0) {
return (
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
sum
);
}
constexpr inline uintmax_t decimal_(const char *s, uintmax_t sum = 0) {
constexpr inline uintmax_t decimal_(const char* s, uintmax_t sum = 0) {
return (
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') :
sum
);
}
constexpr inline uintmax_t hex_(const char *s, uintmax_t sum = 0) {
constexpr inline uintmax_t hex_(const char* s, uintmax_t sum = 0) {
return (
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) :
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) :
@ -43,7 +37,7 @@ constexpr inline uintmax_t hex_(const char *s, uintmax_t sum = 0) {
//
constexpr inline uintmax_t binary(const char *s) {
constexpr inline uintmax_t binary(const char* s) {
return (
*s == '0' && *(s + 1) == 'B' ? binary_(s + 2) :
*s == '0' && *(s + 1) == 'b' ? binary_(s + 2) :
@ -52,13 +46,13 @@ constexpr inline uintmax_t binary(const char *s) {
);
}
constexpr inline uintmax_t octal(const char *s) {
constexpr inline uintmax_t octal(const char* s) {
return (
octal_(s)
);
}
constexpr inline intmax_t integer(const char *s) {
constexpr inline intmax_t integer(const char* s) {
return (
*s == '+' ? +decimal_(s + 1) :
*s == '-' ? -decimal_(s + 1) :
@ -66,13 +60,13 @@ constexpr inline intmax_t integer(const char *s) {
);
}
constexpr inline uintmax_t decimal(const char *s) {
constexpr inline uintmax_t decimal(const char* s) {
return (
decimal_(s)
);
}
constexpr inline uintmax_t hex(const char *s) {
constexpr inline uintmax_t hex(const char* s) {
return (
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
*s == '0' && *(s + 1) == 'x' ? hex_(s + 2) :
@ -81,7 +75,7 @@ constexpr inline uintmax_t hex(const char *s) {
);
}
constexpr inline intmax_t numeral(const char *s) {
constexpr inline intmax_t numeral(const char* s) {
return (
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
*s == '0' && *(s + 1) == 'x' ? hex_(s + 2) :
@ -94,7 +88,7 @@ constexpr inline intmax_t numeral(const char *s) {
);
}
inline double fp(const char *s) {
inline double fp(const char* s) {
return atof(s);
}

View File

@ -5,114 +5,116 @@
#include <nall/string.hpp>
namespace nall {
struct base64 {
static bool encode(char *&output, const uint8_t* input, unsigned inlength) {
output = new char[inlength * 8 / 6 + 8]();
unsigned i = 0, o = 0;
while(i < inlength) {
switch(i % 3) {
struct base64 {
static bool encode(char*& output, const uint8_t* input, unsigned inlength) {
output = new char[inlength * 8 / 6 + 8]();
case 0: {
output[o++] = enc(input[i] >> 2);
output[o] = enc((input[i] & 3) << 4);
break;
}
unsigned i = 0, o = 0;
while(i < inlength) {
switch(i % 3) {
case 1: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 4));
output[o] = enc((input[i] & 15) << 2);
break;
}
case 2: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 6));
output[o++] = enc(input[i] & 63);
break;
}
}
i++;
case 0: {
output[o++] = enc(input[i] >> 2);
output[o] = enc((input[i] & 3) << 4);
break;
}
return true;
}
static string encode(const string &data) {
char *buffer = nullptr;
encode(buffer, (const uint8_t*)(const char*)data, data.length());
string result = buffer;
delete[] buffer;
return result;
}
static bool decode(uint8_t *&output, unsigned &outlength, const char *input) {
unsigned inlength = strlen(input), infix = 0;
output = new uint8_t[inlength + 1]();
unsigned i = 0, o = 0;
while(i < inlength) {
uint8_t x = dec(input[i]);
switch(i++ & 3) {
case 0: {
output[o] = x << 2;
break;
}
case 1: {
output[o++] |= x >> 4;
output[o] = (x & 15) << 4;
break;
}
case 2: {
output[o++] |= x >> 2;
output[o] = (x & 3) << 6;
break;
}
case 3: {
output[o++] |= x;
break;
}
}
case 1: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 4));
output[o] = enc((input[i] & 15) << 2);
break;
}
outlength = o;
return true;
case 2: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 6));
output[o++] = enc(input[i] & 63);
break;
}
}
i++;
}
static string decode(const string &data) {
uint8_t *buffer = nullptr;
unsigned size = 0;
decode(buffer, size, (const char*)data);
string result = (const char*)buffer;
delete[] buffer;
return result;
return true;
}
static string encode(const string& data) {
char* buffer = nullptr;
encode(buffer, (const uint8_t*)(const char*)data, data.length());
string result = buffer;
delete[] buffer;
return result;
}
static bool decode(uint8_t*& output, unsigned& outlength, const char* input) {
unsigned inlength = strlen(input), infix = 0;
output = new uint8_t[inlength + 1]();
unsigned i = 0, o = 0;
while(i < inlength) {
uint8_t x = dec(input[i]);
switch(i++ & 3) {
case 0: {
output[o] = x << 2;
break;
}
case 1: {
output[o++] |= x >> 4;
output[o] = (x & 15) << 4;
break;
}
case 2: {
output[o++] |= x >> 2;
output[o] = (x & 3) << 6;
break;
}
case 3: {
output[o++] |= x;
break;
}
}
}
private:
static char enc(uint8_t n) {
//base64 for URL encodings (URL = -_, MIME = +/)
static char lookup_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
return lookup_table[n & 63];
}
outlength = o;
return true;
}
static string decode(const string& data) {
uint8_t* buffer = nullptr;
unsigned size = 0;
decode(buffer, size, (const char*)data);
string result = (const char*)buffer;
delete[] buffer;
return result;
}
private:
static char enc(uint8_t n) {
//base64 for URL encodings (URL = -_, MIME = +/)
static char lookup_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
return lookup_table[n & 63];
}
static uint8_t dec(char n) {
if(n >= 'A' && n <= 'Z') return n - 'A';
if(n >= 'a' && n <= 'z') return n - 'a' + 26;
if(n >= '0' && n <= '9') return n - '0' + 52;
if(n == '-') return 62;
if(n == '_') return 63;
return 0;
}
};
static uint8_t dec(char n) {
if(n >= 'A' && n <= 'Z') return n - 'A';
if(n >= 'a' && n <= 'z') return n - 'a' + 26;
if(n >= '0' && n <= '9') return n - '0' + 52;
if(n == '-') return 62;
if(n == '_') return 63;
return 0;
}
};
}
#endif

View File

@ -6,7 +6,7 @@
namespace nall {
struct beatArchive : beatBase {
bool create(const string &beatname, string pathname, const string &metadata = "") {
bool create(const string& beatname, string pathname, const string& metadata = "") {
if(fp.open(beatname, file::mode::write) == false) return false;
if(pathname.endswith("/") == false) pathname.append("/");
@ -44,7 +44,7 @@ struct beatArchive : beatBase {
return true;
}
bool unpack(const string &beatname, string pathname) {
bool unpack(const string& beatname, string pathname) {
if(fp.open(beatname, file::mode::read) == false) return false;
if(pathname.endswith("/") == false) pathname.append("/");

View File

@ -8,15 +8,15 @@ protected:
file fp;
uint32_t checksum;
void ls(lstring &list, const string &path, const string &basepath) {
void ls(lstring& list, const string& path, const string& basepath) {
lstring paths = directory::folders(path);
for(auto &pathname : paths) {
for(auto& pathname : paths) {
list.append(string{path, pathname}.ltrim<1>(basepath));
ls(list, {path, pathname}, basepath);
}
lstring files = directory::files(path);
for(auto &filename : files) {
for(auto& filename : files) {
list.append(string{path, filename}.ltrim<1>(basepath));
}
}
@ -36,7 +36,7 @@ protected:
}
}
void writeString(const string &text) {
void writeString(const string& text) {
unsigned length = text.length();
for(unsigned n = 0; n < length; n++) write(text[n]);
}

View File

@ -10,56 +10,56 @@
namespace nall {
struct bpsdelta {
inline void source(const uint8_t *data, unsigned size);
inline void target(const uint8_t *data, unsigned size);
inline void source(const uint8_t* data, unsigned size);
inline void target(const uint8_t* data, unsigned size);
inline bool source(const string &filename);
inline bool target(const string &filename);
inline bool create(const string &filename, const string &metadata = "");
inline bool source(const string& filename);
inline bool target(const string& filename);
inline bool create(const string& filename, const string& metadata = "");
protected:
enum : unsigned { SourceRead, TargetRead, SourceCopy, TargetCopy };
enum : unsigned { Granularity = 1 };
struct Node {
unsigned offset;
Node *next;
inline Node() : offset(0), next(nullptr) {}
inline ~Node() { if(next) delete next; }
unsigned offset = 0;
Node* next = nullptr;
Node() = default;
~Node() { if(next) delete next; }
};
filemap sourceFile;
const uint8_t *sourceData;
const uint8_t* sourceData;
unsigned sourceSize;
filemap targetFile;
const uint8_t *targetData;
const uint8_t* targetData;
unsigned targetSize;
};
void bpsdelta::source(const uint8_t *data, unsigned size) {
void bpsdelta::source(const uint8_t* data, unsigned size) {
sourceData = data;
sourceSize = size;
}
void bpsdelta::target(const uint8_t *data, unsigned size) {
void bpsdelta::target(const uint8_t* data, unsigned size) {
targetData = data;
targetSize = size;
}
bool bpsdelta::source(const string &filename) {
bool bpsdelta::source(const string& filename) {
if(sourceFile.open(filename, filemap::mode::read) == false) return false;
source(sourceFile.data(), sourceFile.size());
return true;
}
bool bpsdelta::target(const string &filename) {
bool bpsdelta::target(const string& filename) {
if(targetFile.open(filename, filemap::mode::read) == false) return false;
target(targetFile.data(), targetFile.size());
return true;
}
bool bpsdelta::create(const string &filename, const string &metadata) {
bool bpsdelta::create(const string& filename, const string& metadata) {
file modifyFile;
if(modifyFile.open(filename, file::mode::write) == false) return false;
@ -96,7 +96,8 @@ bool bpsdelta::create(const string &filename, const string &metadata) {
encode(markupSize);
for(unsigned n = 0; n < markupSize; n++) write(metadata[n]);
Node *sourceTree[65536], *targetTree[65536];
Node* sourceTree[65536];
Node* targetTree[65536];
for(unsigned n = 0; n < 65536; n++) sourceTree[n] = nullptr, targetTree[n] = nullptr;
//source tree creation
@ -136,7 +137,7 @@ bool bpsdelta::create(const string &filename, const string &metadata) {
}
{ //source copy
Node *node = sourceTree[symbol];
Node* node = sourceTree[symbol];
while(node) {
unsigned length = 0, x = node->offset, y = outputOffset;
while(x < sourceSize && y < targetSize && sourceData[x++] == targetData[y++]) length++;
@ -146,7 +147,7 @@ bool bpsdelta::create(const string &filename, const string &metadata) {
}
{ //target copy
Node *node = targetTree[symbol];
Node* node = targetTree[symbol];
while(node) {
unsigned length = 0, x = node->offset, y = outputOffset;
while(y < targetSize && targetData[x++] == targetData[y++]) length++;

View File

@ -10,49 +10,49 @@
namespace nall {
struct bpslinear {
inline void source(const uint8_t *data, unsigned size);
inline void target(const uint8_t *data, unsigned size);
inline void source(const uint8_t* data, unsigned size);
inline void target(const uint8_t* data, unsigned size);
inline bool source(const string &filename);
inline bool target(const string &filename);
inline bool create(const string &filename, const string &metadata = "");
inline bool source(const string& filename);
inline bool target(const string& filename);
inline bool create(const string& filename, const string& metadata = "");
protected:
enum : unsigned { SourceRead, TargetRead, SourceCopy, TargetCopy };
enum : unsigned { Granularity = 1 };
filemap sourceFile;
const uint8_t *sourceData;
const uint8_t* sourceData;
unsigned sourceSize;
filemap targetFile;
const uint8_t *targetData;
const uint8_t* targetData;
unsigned targetSize;
};
void bpslinear::source(const uint8_t *data, unsigned size) {
void bpslinear::source(const uint8_t* data, unsigned size) {
sourceData = data;
sourceSize = size;
}
void bpslinear::target(const uint8_t *data, unsigned size) {
void bpslinear::target(const uint8_t* data, unsigned size) {
targetData = data;
targetSize = size;
}
bool bpslinear::source(const string &filename) {
bool bpslinear::source(const string& filename) {
if(sourceFile.open(filename, filemap::mode::read) == false) return false;
source(sourceFile.data(), sourceFile.size());
return true;
}
bool bpslinear::target(const string &filename) {
bool bpslinear::target(const string& filename) {
if(targetFile.open(filename, filemap::mode::read) == false) return false;
target(targetFile.data(), targetFile.size());
return true;
}
bool bpslinear::create(const string &filename, const string &metadata) {
bool bpslinear::create(const string& filename, const string& metadata) {
file modifyFile;
if(modifyFile.open(filename, file::mode::write) == false) return false;

View File

@ -10,8 +10,8 @@
namespace nall {
struct bpsmetadata {
inline bool load(const string &filename);
inline bool save(const string &filename, const string &metadata);
inline bool load(const string& filename);
inline bool save(const string& filename, const string& metadata);
inline string metadata() const;
protected:
@ -19,7 +19,7 @@ protected:
string metadataString;
};
bool bpsmetadata::load(const string &filename) {
bool bpsmetadata::load(const string& filename) {
if(sourceFile.open(filename, file::mode::read) == false) return false;
auto read = [&]() -> uint8_t {
@ -53,7 +53,7 @@ bool bpsmetadata::load(const string &filename) {
return true;
}
bool bpsmetadata::save(const string &filename, const string &metadata) {
bool bpsmetadata::save(const string& filename, const string& metadata) {
file targetFile;
if(targetFile.open(filename, file::mode::write) == false) return false;
if(sourceFile.open() == false) return false;

View File

@ -20,7 +20,7 @@ struct bpsmulti {
OriginTarget = 1,
};
bool create(const string &patchName, const string &sourcePath, const string &targetPath, bool delta = false, const string &metadata = "") {
bool create(const string& patchName, const string& sourcePath, const string& targetPath, bool delta = false, const string& metadata = "") {
if(fp.open()) fp.close();
fp.open(patchName, file::mode::write);
checksum = ~0;
@ -33,7 +33,7 @@ struct bpsmulti {
ls(sourceList, sourcePath, sourcePath);
ls(targetList, targetPath, targetPath);
for(auto &targetName : targetList) {
for(auto& targetName : targetList) {
if(targetName.endswith("/")) {
targetName.rtrim<1>("/");
writeNumber(CreatePath | ((targetName.length() - 1) << 2));
@ -94,7 +94,7 @@ struct bpsmulti {
return true;
}
bool apply(const string &patchName, const string &sourcePath, const string &targetPath) {
bool apply(const string& patchName, const string& sourcePath, const string& targetPath) {
directory::remove(targetPath); //start with a clean directory
directory::create(targetPath);
@ -157,15 +157,15 @@ protected:
uint32_t checksum;
//create() functions
void ls(lstring &list, const string &path, const string &basepath) {
void ls(lstring& list, const string& path, const string& basepath) {
lstring paths = directory::folders(path);
for(auto &pathname : paths) {
for(auto& pathname : paths) {
list.append(string{path, pathname}.ltrim<1>(basepath));
ls(list, {path, pathname}, basepath);
}
lstring files = directory::files(path);
for(auto &filename : files) {
for(auto& filename : files) {
list.append(string{path, filename}.ltrim<1>(basepath));
}
}
@ -188,7 +188,7 @@ protected:
}
}
void writeString(const string &text) {
void writeString(const string& text) {
unsigned length = text.length();
for(unsigned n = 0; n < length; n++) write(text[n]);
}

View File

@ -10,13 +10,13 @@
namespace nall {
struct bpspatch {
inline bool modify(const uint8_t *data, unsigned size);
inline void source(const uint8_t *data, unsigned size);
inline void target(uint8_t *data, unsigned size);
inline bool modify(const uint8_t* data, unsigned size);
inline void source(const uint8_t* data, unsigned size);
inline void target(uint8_t* data, unsigned size);
inline bool modify(const string &filename);
inline bool source(const string &filename);
inline bool target(const string &filename);
inline bool modify(const string& filename);
inline bool source(const string& filename);
inline bool target(const string& filename);
inline string metadata() const;
inline unsigned size() const;
@ -39,15 +39,15 @@ protected:
enum : unsigned { SourceRead, TargetRead, SourceCopy, TargetCopy };
filemap modifyFile;
const uint8_t *modifyData;
const uint8_t* modifyData;
unsigned modifySize;
filemap sourceFile;
const uint8_t *sourceData;
const uint8_t* sourceData;
unsigned sourceSize;
filemap targetFile;
uint8_t *targetData;
uint8_t* targetData;
unsigned targetSize;
unsigned modifySourceSize;
@ -56,7 +56,7 @@ protected:
string metadataString;
};
bool bpspatch::modify(const uint8_t *data, unsigned size) {
bool bpspatch::modify(const uint8_t* data, unsigned size) {
if(size < 19) return false;
modifyData = data;
modifySize = size;
@ -86,28 +86,28 @@ bool bpspatch::modify(const uint8_t *data, unsigned size) {
return true;
}
void bpspatch::source(const uint8_t *data, unsigned size) {
void bpspatch::source(const uint8_t* data, unsigned size) {
sourceData = data;
sourceSize = size;
}
void bpspatch::target(uint8_t *data, unsigned size) {
void bpspatch::target(uint8_t* data, unsigned size) {
targetData = data;
targetSize = size;
}
bool bpspatch::modify(const string &filename) {
bool bpspatch::modify(const string& filename) {
if(modifyFile.open(filename, filemap::mode::read) == false) return false;
return modify(modifyFile.data(), modifyFile.size());
}
bool bpspatch::source(const string &filename) {
bool bpspatch::source(const string& filename) {
if(sourceFile.open(filename, filemap::mode::read) == false) return false;
source(sourceFile.data(), sourceFile.size());
return true;
}
bool bpspatch::target(const string &filename) {
bool bpspatch::target(const string& filename) {
file fp;
if(fp.open(filename, file::mode::write) == false) return false;
fp.truncate(modifyTargetSize);

View File

@ -4,79 +4,77 @@
#include <nall/stdint.hpp>
namespace nall {
template<unsigned bits>
inline uintmax_t uclamp(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 };
return y + ((x - y) & -(x < y)); //min(x, y);
template<unsigned bits> inline uintmax_t uclamp(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 };
return y + ((x - y) & -(x < y)); //min(x, y);
}
template<unsigned bits> inline uintmax_t uclip(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return (x & m);
}
template<unsigned bits> inline intmax_t sclamp(const intmax_t x) {
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
return (x > m) ? m : (x < -b) ? -b : x;
}
template<unsigned bits> inline intmax_t sclip(const intmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return ((x & m) ^ b) - b;
}
namespace bit {
constexpr inline uintmax_t mask(const char* s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) :
*s == ' ' || *s == '_' ? mask(s + 1, sum) :
*s ? mask(s + 1, sum << 1) :
sum
);
}
template<unsigned bits>
inline uintmax_t uclip(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return (x & m);
constexpr inline uintmax_t test(const char* s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) :
*s == ' ' || *s == '_' ? test(s + 1, sum) :
*s ? test(s + 1, sum << 1) :
sum
);
}
template<unsigned bits>
inline intmax_t sclamp(const intmax_t x) {
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
return (x > m) ? m : (x < -b) ? -b : x;
//lowest(0b1110) == 0b0010
constexpr inline uintmax_t lowest(const uintmax_t x) {
return x & -x;
}
template<unsigned bits>
inline intmax_t sclip(const intmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return ((x & m) ^ b) - b;
//clear_lowest(0b1110) == 0b1100
constexpr inline uintmax_t clear_lowest(const uintmax_t x) {
return x & (x - 1);
}
namespace bit {
constexpr inline uintmax_t mask(const char *s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) :
*s == ' ' || *s == '_' ? mask(s + 1, sum) :
*s ? mask(s + 1, sum << 1) :
sum
);
}
//set_lowest(0b0101) == 0b0111
constexpr inline uintmax_t set_lowest(const uintmax_t x) {
return x | (x + 1);
}
constexpr inline uintmax_t test(const char *s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) :
*s == ' ' || *s == '_' ? test(s + 1, sum) :
*s ? test(s + 1, sum << 1) :
sum
);
}
//count number of bits set in a byte
inline unsigned count(uintmax_t x) {
unsigned count = 0;
do count += x & 1; while(x >>= 1);
return count;
}
//lowest(0b1110) == 0b0010
constexpr inline uintmax_t lowest(const uintmax_t x) {
return x & -x;
}
//clear_lowest(0b1110) == 0b1100
constexpr inline uintmax_t clear_lowest(const uintmax_t x) {
return x & (x - 1);
}
//set_lowest(0b0101) == 0b0111
constexpr inline uintmax_t set_lowest(const uintmax_t x) {
return x | (x + 1);
}
//count number of bits set in a byte
inline unsigned count(uintmax_t x) {
unsigned count = 0;
do count += x & 1; while(x >>= 1);
return count;
}
//round up to next highest single bit:
//round(15) == 16, round(16) == 16, round(17) == 32
inline uintmax_t round(uintmax_t x) {
if((x & (x - 1)) == 0) return x;
while(x & (x - 1)) x &= x - 1;
return x << 1;
}
//round up to next highest single bit:
//round(15) == 16, round(16) == 16, round(17) == 32
inline uintmax_t round(uintmax_t x) {
if((x & (x - 1)) == 0) return x;
while(x & (x - 1)) x &= x - 1;
return x << 1;
}
}
}
#endif

View File

@ -9,11 +9,11 @@
namespace nall {
struct bmp {
inline static bool read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height);
inline static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha = false);
inline static bool read(const string& filename, uint32_t*& data, unsigned& width, unsigned& height);
inline static bool write(const string& filename, const uint32_t* data, unsigned width, unsigned height, unsigned pitch, bool alpha = false);
};
bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height) {
bool bmp::read(const string& filename, uint32_t*& data, unsigned& width, unsigned& height) {
file fp;
if(fp.open(filename, file::mode::read) == false) return false;
if(fp.size() < 0x36) return false;
@ -43,7 +43,7 @@ bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigne
while(alignedWidth % 4) alignedWidth++, paddingLength++;
for(unsigned y = 0; y < height; y++) {
uint32_t *p = noFlip ? data + y * width : data + (height - 1 - y) * width;
uint32_t* p = noFlip ? data + y * width : data + (height - 1 - y) * width;
for(unsigned x = 0; x < width; x++, p++) {
*p = fp.readl(bytesPerPixel);
if(bytesPerPixel == 3) *p |= 255 << 24;
@ -55,7 +55,7 @@ bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigne
return true;
}
bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha) {
bool bmp::write(const string& filename, const uint32_t* data, unsigned width, unsigned height, unsigned pitch, bool alpha) {
file fp;
if(fp.open(filename, file::mode::write) == false) return false;
@ -86,7 +86,7 @@ bool bmp::write(const string &filename, const uint32_t *data, unsigned width, un
fp.writel(0, 4); //important color count
for(unsigned y = 0; y < height; y++) {
const uint32_t *p = (const uint32_t*)((const uint8_t*)data + y * pitch);
const uint32_t* p = (const uint32_t*)((const uint8_t*)data + y * pitch);
for(unsigned x = 0; x < width; x++) fp.writel(*p++, bytesPerPixel);
if(paddingLength) fp.writel(0, paddingLength);
}

View File

@ -26,7 +26,7 @@ struct compositor {
//Metacity
bool compositor::enabled_metacity() {
FILE *fp = popen("gconftool-2 --get /apps/metacity/general/compositing_manager", "r");
FILE* fp = popen("gconftool-2 --get /apps/metacity/general/compositing_manager", "r");
if(!fp) return false;
char buffer[512];
@ -37,7 +37,7 @@ bool compositor::enabled_metacity() {
}
bool compositor::enable_metacity(bool status) {
FILE *fp;
FILE* fp;
if(status) {
fp = popen("gconftool-2 --set --type bool /apps/metacity/general/compositing_manager true", "r");
} else {
@ -51,7 +51,7 @@ bool compositor::enable_metacity(bool status) {
//Xfwm4
bool compositor::enabled_xfwm4() {
FILE *fp = popen("xfconf-query -c xfwm4 -p '/general/use_compositing'", "r");
FILE* fp = popen("xfconf-query -c xfwm4 -p '/general/use_compositing'", "r");
if(!fp) return false;
char buffer[512];
@ -62,7 +62,7 @@ bool compositor::enabled_xfwm4() {
}
bool compositor::enable_xfwm4(bool status) {
FILE *fp;
FILE* fp;
if(status) {
fp = popen("xfconf-query -c xfwm4 -p '/general/use_compositing' -t 'bool' -s 'true'", "r");
} else {
@ -78,7 +78,7 @@ bool compositor::enable_xfwm4(bool status) {
compositor::Compositor compositor::detect() {
Compositor result = Compositor::Unknown;
FILE *fp;
FILE* fp;
char buffer[512];
fp = popen("pidof metacity", "r");

View File

@ -4,22 +4,24 @@
#include <nall/stdint.hpp>
namespace nall {
inline uint16_t crc16_adjust(uint16_t crc16, uint8_t data) {
for(unsigned n = 0; n < 8; n++) {
if((crc16 & 1) ^ (data & 1)) crc16 = (crc16 >> 1) ^ 0x8408;
else crc16 >>= 1;
data >>= 1;
}
return crc16;
}
inline uint16_t crc16_calculate(const uint8_t *data, unsigned length) {
uint16_t crc16 = ~0;
for(unsigned n = 0; n < length; n++) {
crc16 = crc16_adjust(crc16, data[n]);
}
return ~crc16;
inline uint16_t crc16_adjust(uint16_t crc16, uint8_t data) {
for(unsigned n = 0; n < 8; n++) {
if((crc16 & 1) ^ (data & 1)) crc16 = (crc16 >> 1) ^ 0x8408;
else crc16 >>= 1;
data >>= 1;
}
return crc16;
}
inline uint16_t crc16_calculate(const uint8_t* data, unsigned length) {
uint16_t crc16 = ~0;
for(unsigned n = 0; n < length; n++) {
crc16 = crc16_adjust(crc16, data[n]);
}
return ~crc16;
}
}
#endif

View File

@ -4,63 +4,65 @@
#include <nall/stdint.hpp>
namespace nall {
const uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline uint32_t crc32_adjust(uint32_t crc32, uint8_t input) {
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
}
const uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline uint32_t crc32_calculate(const uint8_t *data, unsigned length) {
uint32_t crc32 = ~0;
for(unsigned i = 0; i < length; i++) {
crc32 = crc32_adjust(crc32, data[i]);
}
return ~crc32;
inline uint32_t crc32_adjust(uint32_t crc32, uint8_t input) {
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
}
inline uint32_t crc32_calculate(const uint8_t* data, unsigned length) {
uint32_t crc32 = ~0;
for(unsigned i = 0; i < length; i++) {
crc32 = crc32_adjust(crc32, data[i]);
}
return ~crc32;
}
}
#endif

View File

@ -18,80 +18,80 @@
namespace nall {
struct directory {
static bool create(const string &pathname, unsigned permissions = 0755); //recursive
static bool remove(const string &pathname); //recursive
static bool exists(const string &pathname);
static bool create(const string& pathname, unsigned permissions = 0755); //recursive
static bool remove(const string& pathname); //recursive
static bool exists(const string& pathname);
static lstring folders(const string &pathname, const string &pattern = "*") {
static lstring folders(const string& pathname, const string& pattern = "*") {
lstring folders = directory::ufolders(pathname, pattern);
folders.sort();
return folders;
}
static lstring files(const string &pathname, const string &pattern = "*") {
static lstring files(const string& pathname, const string& pattern = "*") {
lstring files = directory::ufiles(pathname, pattern);
files.sort();
return files;
}
static lstring contents(const string &pathname, const string &pattern = "*") {
static lstring contents(const string& pathname, const string& pattern = "*") {
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
lstring files = directory::ufiles(pathname, pattern);
folders.sort();
files.sort();
for(auto &file : files) folders.append(file);
for(auto& file : files) folders.append(file);
return folders;
}
static lstring ifolders(const string &pathname, const string &pattern = "*") {
static lstring ifolders(const string& pathname, const string& pattern = "*") {
lstring folders = ufolders(pathname, pattern);
folders.isort();
return folders;
}
static lstring ifiles(const string &pathname, const string &pattern = "*") {
static lstring ifiles(const string& pathname, const string& pattern = "*") {
lstring files = ufiles(pathname, pattern);
files.isort();
return files;
}
static lstring icontents(const string &pathname, const string &pattern = "*") {
static lstring icontents(const string& pathname, const string& pattern = "*") {
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
lstring files = directory::ufiles(pathname, pattern);
folders.isort();
files.isort();
for(auto &file : files) folders.append(file);
for(auto& file : files) folders.append(file);
return folders;
}
private:
//internal functions; these return unsorted lists
static lstring ufolders(const string &pathname, const string &pattern = "*");
static lstring ufiles(const string &pathname, const string &pattern = "*");
static lstring ufolders(const string& pathname, const string& pattern = "*");
static lstring ufiles(const string& pathname, const string& pattern = "*");
};
#if defined(PLATFORM_WINDOWS)
inline bool directory::create(const string &pathname, unsigned permissions) {
inline bool directory::create(const string& pathname, unsigned permissions) {
string path;
lstring list = string{pathname}.transform("\\", "/").rtrim<1>("/").split("/");
bool result = true;
for(auto &part : list) {
for(auto& part : list) {
path.append(part, "/");
result &= (_wmkdir(utf16_t(path)) == 0);
}
return result;
}
inline bool directory::remove(const string &pathname) {
inline bool directory::remove(const string& pathname) {
lstring list = directory::contents(pathname);
for(auto &name : list) {
for(auto& name : list) {
if(name.endswith("/")) directory::remove({pathname, name});
else file::remove({pathname, name});
}
return _wrmdir(utf16_t(pathname)) == 0;
}
inline bool directory::exists(const string &pathname) {
inline bool directory::exists(const string& pathname) {
string name = pathname;
name.trim<1>("\"");
DWORD result = GetFileAttributes(utf16_t(name));
@ -99,7 +99,7 @@ private:
return (result & FILE_ATTRIBUTE_DIRECTORY);
}
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
inline lstring directory::ufolders(const string& pathname, const string& pattern) {
lstring list;
string path = pathname;
path.transform("/", "\\");
@ -125,11 +125,11 @@ private:
}
FindClose(handle);
}
for(auto &name : list) name.append("/"); //must append after sorting
for(auto& name : list) name.append("/"); //must append after sorting
return list;
}
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
inline lstring directory::ufiles(const string& pathname, const string& pattern) {
lstring list;
string path = pathname;
path.transform("/", "\\");
@ -154,37 +154,37 @@ private:
return list;
}
#else
inline bool directory::create(const string &pathname, unsigned permissions) {
inline bool directory::create(const string& pathname, unsigned permissions) {
string path;
lstring list = string{pathname}.rtrim<1>("/").split("/");
bool result = true;
for(auto &part : list) {
for(auto& part : list) {
path.append(part, "/");
result &= (mkdir(path, permissions) == 0);
}
return result;
}
inline bool directory::remove(const string &pathname) {
inline bool directory::remove(const string& pathname) {
lstring list = directory::contents(pathname);
for(auto &name : list) {
for(auto& name : list) {
if(name.endswith("/")) directory::remove({pathname, name});
else file::remove({pathname, name});
}
return rmdir(pathname) == 0;
}
inline bool directory::exists(const string &pathname) {
inline bool directory::exists(const string& pathname) {
DIR *dp = opendir(pathname);
if(!dp) return false;
closedir(dp);
return true;
}
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
inline lstring directory::ufolders(const string& pathname, const string& pattern) {
lstring list;
DIR *dp;
struct dirent *ep;
DIR* dp;
struct dirent* ep;
dp = opendir(pathname);
if(dp) {
while(ep = readdir(dp)) {
@ -196,14 +196,14 @@ private:
}
closedir(dp);
}
for(auto &name : list) name.append("/"); //must append after sorting
for(auto& name : list) name.append("/"); //must append after sorting
return list;
}
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
inline lstring directory::ufiles(const string& pathname, const string& pattern) {
lstring list;
DIR *dp;
struct dirent *ep;
DIR* dp;
struct dirent* ep;
dp = opendir(pathname);
if(dp) {
while(ep = readdir(dp)) {

View File

@ -16,102 +16,104 @@
#endif
namespace nall {
struct library {
explicit operator bool() const { return open(); }
bool open() const { return handle; }
bool open(const char*, const char* = "");
bool open_absolute(const char*);
void* sym(const char*);
void close();
library() : handle(0) {}
~library() { close(); }
struct library {
explicit operator bool() const { return open(); }
bool open() const { return handle; }
bool open(const string&, const string& = "");
bool open_absolute(const string&);
void* sym(const string&);
void close();
library& operator=(const library&) = delete;
library(const library&) = delete;
library() = default;
~library() { close(); }
private:
uintptr_t handle;
};
library& operator=(const library&) = delete;
library(const library&) = delete;
#if defined(PLATFORM_X)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const char *name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_OSX)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const char *name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_WINDOWS)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
return handle;
}
inline bool library::open_absolute(const char *name) {
if(handle) close();
handle = (uintptr_t)LoadLibraryW(utf16_t(name));
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return nullptr;
return (void*)GetProcAddress((HMODULE)handle, name);
}
inline void library::close() {
if(!handle) return;
FreeLibrary((HMODULE)handle);
handle = 0;
}
#else
inline bool library::open(const char*, const char*) { return false; }
inline bool library::open_absolute(const char*) { return false; }
inline void* library::sym(const char*) { return nullptr; }
inline void library::close() {}
#endif
private:
uintptr_t handle = 0;
};
#if defined(PLATFORM_X)
inline bool library::open(const string& name, const string& path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_OSX)
inline bool library::open(const string& name, const string& path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_WINDOWS)
inline bool library::open(const string& name, const string& path) {
if(handle) close();
string filepath(path, !path.empty() && !path.endswith("/") && !path.endswith("\\") ? "/" : "", name, ".dll");
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
return handle;
}
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)LoadLibraryW(utf16_t(name));
return handle;
}
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return (void*)GetProcAddress((HMODULE)handle, name);
}
inline void library::close() {
if(!handle) return;
FreeLibrary((HMODULE)handle);
handle = 0;
}
#else
inline bool library::open(const string&, const string&) { return false; }
inline bool library::open_absolute(const string&) { return false; }
inline void* library::sym(const string&) { return nullptr; }
inline void library::close() {}
#endif
}
#endif

View File

@ -1,7 +1,7 @@
#ifdef NALL_DSP_INTERNAL_HPP
struct Buffer {
double **sample = nullptr;
double** sample = nullptr;
uint16_t rdoffset = 0;
uint16_t wroffset = 0;
unsigned channels = 0;

View File

@ -12,13 +12,13 @@ namespace nall {
struct DSP;
struct Resampler {
DSP &dsp;
DSP& dsp;
real frequency;
virtual void setFrequency() = 0;
virtual void clear() = 0;
virtual void sample() = 0;
Resampler(DSP &dsp) : dsp(dsp) {}
Resampler(DSP& dsp) : dsp(dsp) {}
};
struct DSP {
@ -70,7 +70,7 @@ protected:
real intensityInverse;
} settings;
Resampler *resampler = nullptr;
Resampler* resampler = nullptr;
inline void write(real channel[]);
#include "buffer.hpp"

View File

@ -5,7 +5,7 @@ struct ResampleAverage : Resampler {
inline void clear();
inline void sample();
inline void sampleLinear();
ResampleAverage(DSP &dsp) : Resampler(dsp) {}
ResampleAverage(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -4,7 +4,7 @@ struct ResampleCosine : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
ResampleCosine(DSP &dsp) : Resampler(dsp) {}
ResampleCosine(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -4,7 +4,7 @@ struct ResampleCubic : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
ResampleCubic(DSP &dsp) : Resampler(dsp) {}
ResampleCubic(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -4,7 +4,7 @@ struct ResampleHermite : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
ResampleHermite(DSP &dsp) : Resampler(dsp) {}
ResampleHermite(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -4,7 +4,7 @@ struct ResampleLinear : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
ResampleLinear(DSP &dsp) : Resampler(dsp) {}
ResampleLinear(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -4,7 +4,7 @@ struct ResampleNearest : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
ResampleNearest(DSP &dsp) : Resampler(dsp) {}
ResampleNearest(DSP& dsp) : Resampler(dsp) {}
real fraction;
real step;

View File

@ -6,11 +6,11 @@ struct ResampleSinc : Resampler {
inline void setFrequency();
inline void clear();
inline void sample();
inline ResampleSinc(DSP &dsp);
inline ResampleSinc(DSP& dsp);
private:
inline void remakeSinc();
SincResample *sinc_resampler[8];
SincResample* sinc_resampler[8];
};
void ResampleSinc::setFrequency() {
@ -38,7 +38,7 @@ void ResampleSinc::sample() {
dsp.buffer.rdoffset++;
}
ResampleSinc::ResampleSinc(DSP &dsp) : Resampler(dsp) {
ResampleSinc::ResampleSinc(DSP& dsp) : Resampler(dsp) {
for(unsigned n = 0; n < 8; n++) sinc_resampler[n] = nullptr;
}

View File

@ -83,7 +83,7 @@ static void sigint(int) {
usart_sigint = true;
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
setpriority(PRIO_PROCESS, 0, -20); //requires superuser privileges; otherwise priority = +0
signal(SIGINT, sigint);

View File

@ -9,346 +9,348 @@
#include <nall/stream/memory.hpp>
namespace nall {
inline FILE* fopen_utf8(const string &utf8_filename, const char *mode) {
inline FILE* fopen_utf8(const string& filename, const string& mode) {
#if !defined(_WIN32)
return fopen(filename, mode);
#else
return _wfopen(utf16_t(filename), utf16_t(mode));
#endif
}
struct file {
enum class mode : unsigned { read, write, modify, append, readwrite = modify, writeread = append };
enum class index : unsigned { absolute, relative };
enum class time : unsigned { create, modify, access };
static bool copy(const string& sourcename, const string& targetname) {
file rd, wr;
if(rd.open(sourcename, mode::read) == false) return false;
if(wr.open(targetname, mode::write) == false) return false;
for(unsigned n = 0; n < rd.size(); n++) wr.write(rd.read());
return true;
}
static bool move(const string& sourcename, const string& targetname) {
#if !defined(_WIN32)
return fopen(utf8_filename, mode);
return rename(sourcename, targetname) == 0;
#else
return _wfopen(utf16_t(utf8_filename), utf16_t(mode));
return _wrename(utf16_t(sourcename), utf16_t(targetname)) == 0;
#endif
}
struct file {
enum class mode : unsigned { read, write, modify, append, readwrite = modify, writeread = append };
enum class index : unsigned { absolute, relative };
enum class time : unsigned { create, modify, access };
static bool remove(const string& filename) {
return unlink(filename) == 0;
}
static bool copy(const string &sourcename, const string &targetname) {
file rd, wr;
if(rd.open(sourcename, mode::read) == false) return false;
if(wr.open(targetname, mode::write) == false) return false;
for(unsigned n = 0; n < rd.size(); n++) wr.write(rd.read());
return true;
}
static bool move(const string &sourcename, const string &targetname) {
#if !defined(_WIN32)
return rename(sourcename, targetname) == 0;
#else
return _wrename(utf16_t(sourcename), utf16_t(targetname)) == 0;
#endif
}
static bool remove(const string &filename) {
return unlink(filename) == 0;
}
static bool truncate(const string &filename, unsigned size) {
#if !defined(_WIN32)
return truncate(filename, size) == 0;
#else
bool result = false;
FILE *fp = fopen(filename, "rb+");
if(fp) {
result = _chsize(fileno(fp), size) == 0;
fclose(fp);
}
return result;
#endif
}
static vector<uint8_t> read(const string &filename) {
vector<uint8_t> memory;
file fp;
if(fp.open(filename, mode::read)) {
memory.resize(fp.size());
fp.read(memory.data(), memory.size());
}
return memory;
}
static bool read(const string &filename, uint8_t *data, unsigned size) {
file fp;
if(fp.open(filename, mode::read) == false) return false;
fp.read(data, size);
fp.close();
return true;
}
static bool write(const string &filename, const string &text) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.print(text);
fp.close();
return true;
}
static bool write(const string &filename, const vector<uint8_t> &buffer) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.write(buffer.data(), buffer.size());
fp.close();
return true;
}
static bool write(const string &filename, const uint8_t *data, unsigned size) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.write(data, size);
fp.close();
return true;
}
static bool create(const string &filename) {
//create an empty file (will replace existing files)
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.close();
return true;
}
static string sha256(const string &filename) {
auto buffer = read(filename);
return nall::sha256(buffer.data(), buffer.size());
}
uint8_t read() {
if(!fp) return 0xff; //file not open
if(file_mode == mode::write) return 0xff; //reads not permitted
if(file_offset >= file_size) return 0xff; //cannot read past end of file
buffer_sync();
return buffer[(file_offset++) & buffer_mask];
}
uintmax_t readl(unsigned length = 1) {
uintmax_t data = 0;
for(int i = 0; i < length; i++) {
data |= (uintmax_t)read() << (i << 3);
}
return data;
}
uintmax_t readm(unsigned length = 1) {
uintmax_t data = 0;
while(length--) {
data <<= 8;
data |= read();
}
return data;
}
void read(uint8_t *buffer, unsigned length) {
while(length--) *buffer++ = read();
}
void write(uint8_t data) {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //writes not permitted
buffer_sync();
buffer[(file_offset++) & buffer_mask] = data;
buffer_dirty = true;
if(file_offset > file_size) file_size = file_offset;
}
void writel(uintmax_t data, unsigned length = 1) {
while(length--) {
write(data);
data >>= 8;
}
}
void writem(uintmax_t data, unsigned length = 1) {
for(int i = length - 1; i >= 0; i--) {
write(data >> (i << 3));
}
}
void write(const uint8_t *buffer, unsigned length) {
while(length--) write(*buffer++);
}
template<typename... Args> void print(Args... args) {
string data(args...);
const char *p = data;
while(*p) write(*p++);
}
void flush() {
buffer_flush();
fflush(fp);
}
void seek(int offset, index index_ = index::absolute) {
if(!fp) return; //file not open
buffer_flush();
uintmax_t req_offset = file_offset;
switch(index_) {
case index::absolute: req_offset = offset; break;
case index::relative: req_offset += offset; break;
}
if(req_offset < 0) req_offset = 0; //cannot seek before start of file
if(req_offset > file_size) {
if(file_mode == mode::read) { //cannot seek past end of file
req_offset = file_size;
} else { //pad file to requested location
file_offset = file_size;
while(file_size < req_offset) write(0x00);
}
}
file_offset = req_offset;
}
unsigned offset() const {
if(!fp) return 0; //file not open
return file_offset;
}
unsigned size() const {
if(!fp) return 0; //file not open
return file_size;
}
bool truncate(unsigned size) {
if(!fp) return false; //file not open
#if !defined(_WIN32)
return ftruncate(fileno(fp), size) == 0;
#else
return _chsize(fileno(fp), size) == 0;
#endif
}
bool end() {
if(!fp) return true; //file not open
return file_offset >= file_size;
}
static bool exists(const string &filename) {
#if !defined(_WIN32)
struct stat64 data;
if(stat64(filename, &data) != 0) return false;
#else
struct __stat64 data;
if(_wstat64(utf16_t(filename), &data) != 0) return false;
#endif
//return true if this is a file, and false if this is a directory
return !(data.st_mode & S_IFDIR);
}
static uintmax_t size(const string &filename) {
#if !defined(_WIN32)
struct stat64 data;
stat64(filename, &data);
#else
struct __stat64 data;
_wstat64(utf16_t(filename), &data);
#endif
return S_ISREG(data.st_mode) ? data.st_size : 0u;
}
static time_t timestamp(const string &filename, file::time mode = file::time::create) {
#if !defined(_WIN32)
struct stat64 data;
stat64(filename, &data);
#else
struct __stat64 data;
_wstat64(utf16_t(filename), &data);
#endif
switch(mode) { default:
case file::time::create: return data.st_ctime;
case file::time::modify: return data.st_mtime;
case file::time::access: return data.st_atime;
}
}
bool open() const {
return fp;
}
explicit operator bool() const {
return open();
}
bool open(const string &filename, mode mode_) {
if(fp) return false;
switch(file_mode = mode_) {
#if !defined(_WIN32)
case mode::read: fp = fopen(filename, "rb" ); break;
case mode::write: fp = fopen(filename, "wb+"); break; //need read permission for buffering
case mode::readwrite: fp = fopen(filename, "rb+"); break;
case mode::writeread: fp = fopen(filename, "wb+"); break;
#else
case mode::read: fp = _wfopen(utf16_t(filename), L"rb" ); break;
case mode::write: fp = _wfopen(utf16_t(filename), L"wb+"); break;
case mode::readwrite: fp = _wfopen(utf16_t(filename), L"rb+"); break;
case mode::writeread: fp = _wfopen(utf16_t(filename), L"wb+"); break;
#endif
}
if(!fp) return false;
buffer_offset = -1; //invalidate buffer
file_offset = 0;
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
return true;
}
void close() {
if(!fp) return;
buffer_flush();
static bool truncate(const string& filename, unsigned size) {
#if !defined(_WIN32)
return truncate(filename, size) == 0;
#else
bool result = false;
FILE* fp = fopen(filename, "rb+");
if(fp) {
result = _chsize(fileno(fp), size) == 0;
fclose(fp);
fp = nullptr;
}
return result;
#endif
}
static vector<uint8_t> read(const string& filename) {
vector<uint8_t> memory;
file fp;
if(fp.open(filename, mode::read)) {
memory.resize(fp.size());
fp.read(memory.data(), memory.size());
}
return memory;
}
static bool read(const string& filename, uint8_t* data, unsigned size) {
file fp;
if(fp.open(filename, mode::read) == false) return false;
fp.read(data, size);
fp.close();
return true;
}
static bool write(const string& filename, const string& text) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.print(text);
fp.close();
return true;
}
static bool write(const string& filename, const vector<uint8_t>& buffer) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.write(buffer.data(), buffer.size());
fp.close();
return true;
}
static bool write(const string& filename, const uint8_t* data, unsigned size) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.write(data, size);
fp.close();
return true;
}
static bool create(const string& filename) {
//create an empty file (will replace existing files)
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.close();
return true;
}
static string sha256(const string& filename) {
auto buffer = read(filename);
return nall::sha256(buffer.data(), buffer.size());
}
uint8_t read() {
if(!fp) return 0xff; //file not open
if(file_mode == mode::write) return 0xff; //reads not permitted
if(file_offset >= file_size) return 0xff; //cannot read past end of file
buffer_sync();
return buffer[(file_offset++) & buffer_mask];
}
uintmax_t readl(unsigned length = 1) {
uintmax_t data = 0;
for(int i = 0; i < length; i++) {
data |= (uintmax_t)read() << (i << 3);
}
return data;
}
uintmax_t readm(unsigned length = 1) {
uintmax_t data = 0;
while(length--) {
data <<= 8;
data |= read();
}
return data;
}
void read(uint8_t* buffer, unsigned length) {
while(length--) *buffer++ = read();
}
void write(uint8_t data) {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //writes not permitted
buffer_sync();
buffer[(file_offset++) & buffer_mask] = data;
buffer_dirty = true;
if(file_offset > file_size) file_size = file_offset;
}
void writel(uintmax_t data, unsigned length = 1) {
while(length--) {
write(data);
data >>= 8;
}
}
void writem(uintmax_t data, unsigned length = 1) {
for(int i = length - 1; i >= 0; i--) {
write(data >> (i << 3));
}
}
void write(const uint8_t* buffer, unsigned length) {
while(length--) write(*buffer++);
}
template<typename... Args> void print(Args... args) {
string data(args...);
const char* p = data;
while(*p) write(*p++);
}
void flush() {
buffer_flush();
fflush(fp);
}
void seek(int offset, index index_ = index::absolute) {
if(!fp) return; //file not open
buffer_flush();
uintmax_t req_offset = file_offset;
switch(index_) {
case index::absolute: req_offset = offset; break;
case index::relative: req_offset += offset; break;
}
file() {
}
file(const string &filename, mode mode_) {
open(filename, mode_);
}
~file() {
close();
}
file& operator=(const file&) = delete;
file(const file&) = delete;
private:
enum { buffer_size = 1 << 12, buffer_mask = buffer_size - 1 };
char buffer[buffer_size] = {0};
int buffer_offset = -1; //invalidate buffer
bool buffer_dirty = false;
FILE *fp = nullptr;
unsigned file_offset = 0;
unsigned file_size = 0;
mode file_mode = mode::read;
void buffer_sync() {
if(!fp) return; //file not open
if(buffer_offset != (file_offset & ~buffer_mask)) {
buffer_flush();
buffer_offset = file_offset & ~buffer_mask;
fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fread(buffer, 1, length, fp);
if(req_offset < 0) req_offset = 0; //cannot seek before start of file
if(req_offset > file_size) {
if(file_mode == mode::read) { //cannot seek past end of file
req_offset = file_size;
} else { //pad file to requested location
file_offset = file_size;
while(file_size < req_offset) write(0x00);
}
}
void buffer_flush() {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //buffer cannot be written to
if(buffer_offset < 0) return; //buffer unused
if(buffer_dirty == false) return; //buffer unmodified since read
file_offset = req_offset;
}
unsigned offset() const {
if(!fp) return 0; //file not open
return file_offset;
}
unsigned size() const {
if(!fp) return 0; //file not open
return file_size;
}
bool truncate(unsigned size) {
if(!fp) return false; //file not open
#if !defined(_WIN32)
return ftruncate(fileno(fp), size) == 0;
#else
return _chsize(fileno(fp), size) == 0;
#endif
}
bool end() {
if(!fp) return true; //file not open
return file_offset >= file_size;
}
static bool exists(const string& filename) {
#if !defined(_WIN32)
struct stat64 data;
if(stat64(filename, &data) != 0) return false;
#else
struct __stat64 data;
if(_wstat64(utf16_t(filename), &data) != 0) return false;
#endif
//return true if this is a file, and false if this is a directory
return !(data.st_mode & S_IFDIR);
}
static uintmax_t size(const string& filename) {
#if !defined(_WIN32)
struct stat64 data;
stat64(filename, &data);
#else
struct __stat64 data;
_wstat64(utf16_t(filename), &data);
#endif
return S_ISREG(data.st_mode) ? data.st_size : 0u;
}
static time_t timestamp(const string& filename, file::time mode = file::time::create) {
#if !defined(_WIN32)
struct stat64 data;
stat64(filename, &data);
#else
struct __stat64 data;
_wstat64(utf16_t(filename), &data);
#endif
switch(mode) { default:
case file::time::create: return data.st_ctime;
case file::time::modify: return data.st_mtime;
case file::time::access: return data.st_atime;
}
}
bool open() const {
return fp;
}
explicit operator bool() const {
return open();
}
bool open(const string& filename, mode mode_) {
if(fp) return false;
switch(file_mode = mode_) {
#if !defined(_WIN32)
case mode::read: fp = fopen(filename, "rb" ); break;
case mode::write: fp = fopen(filename, "wb+"); break; //need read permission for buffering
case mode::readwrite: fp = fopen(filename, "rb+"); break;
case mode::writeread: fp = fopen(filename, "wb+"); break;
#else
case mode::read: fp = _wfopen(utf16_t(filename), L"rb" ); break;
case mode::write: fp = _wfopen(utf16_t(filename), L"wb+"); break;
case mode::readwrite: fp = _wfopen(utf16_t(filename), L"rb+"); break;
case mode::writeread: fp = _wfopen(utf16_t(filename), L"wb+"); break;
#endif
}
if(!fp) return false;
buffer_offset = -1; //invalidate buffer
file_offset = 0;
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
return true;
}
void close() {
if(!fp) return;
buffer_flush();
fclose(fp);
fp = nullptr;
}
file() {
}
file(const string& filename, mode mode_) {
open(filename, mode_);
}
~file() {
close();
}
file& operator=(const file&) = delete;
file(const file&) = delete;
private:
enum { buffer_size = 1 << 12, buffer_mask = buffer_size - 1 };
char buffer[buffer_size] = {0};
int buffer_offset = -1; //invalidate buffer
bool buffer_dirty = false;
FILE *fp = nullptr;
unsigned file_offset = 0;
unsigned file_size = 0;
mode file_mode = mode::read;
void buffer_sync() {
if(!fp) return; //file not open
if(buffer_offset != (file_offset & ~buffer_mask)) {
buffer_flush();
buffer_offset = file_offset & ~buffer_mask;
fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fwrite(buffer, 1, length, fp);
buffer_offset = -1; //invalidate buffer
buffer_dirty = false;
if(length) unsigned unused = fread(buffer, 1, length, fp);
}
};
}
void buffer_flush() {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //buffer cannot be written to
if(buffer_offset < 0) return; //buffer unused
if(buffer_dirty == false) return; //buffer unmodified since read
fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fwrite(buffer, 1, length, fp);
buffer_offset = -1; //invalidate buffer
buffer_dirty = false;
}
};
}
#endif

View File

@ -18,197 +18,198 @@
#endif
namespace nall {
class filemap {
public:
enum class mode : unsigned { read, write, readwrite, writeread };
explicit operator bool() const { return open(); }
bool open() const { return p_open(); }
bool open(const char *filename, mode mode_) { return p_open(filename, mode_); }
void close() { return p_close(); }
unsigned size() const { return p_size; }
uint8_t* data() { return p_handle; }
const uint8_t* data() const { return p_handle; }
filemap() : p_size(0), p_handle(nullptr) { p_ctor(); }
filemap(const char *filename, mode mode_) : p_size(0), p_handle(nullptr) { p_ctor(); p_open(filename, mode_); }
~filemap() { p_dtor(); }
struct filemap {
enum class mode : unsigned { read, write, readwrite, writeread };
private:
unsigned p_size;
uint8_t *p_handle;
explicit operator bool() const { return open(); }
bool open() const { return p_open(); }
bool open(const string& filename, mode mode_) { return p_open(filename, mode_); }
void close() { return p_close(); }
unsigned size() const { return p_size; }
uint8_t* data() { return p_handle; }
const uint8_t* data() const { return p_handle; }
filemap() { p_ctor(); }
filemap(const string& filename, mode mode_) { p_ctor(); p_open(filename, mode_); }
~filemap() { p_dtor(); }
#if defined(_WIN32)
//=============
//MapViewOfFile
//=============
private:
uint8_t *p_handle = nullptr;
unsigned p_size = 0;
HANDLE p_filehandle, p_maphandle;
#if defined(_WIN32)
//=============
//MapViewOfFile
//=============
bool p_open() const {
return p_handle;
HANDLE p_filehandle, p_maphandle;
bool p_open() const {
return p_handle;
}
bool p_open(const string& filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
return true;
}
bool p_open(const char *filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
return true;
}
int desired_access, creation_disposition, flprotect, map_access;
int desired_access, creation_disposition, flprotect, map_access;
switch(mode_) {
default: return false;
case mode::read:
desired_access = GENERIC_READ;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READONLY;
map_access = FILE_MAP_READ;
break;
case mode::write:
//write access requires read access
desired_access = GENERIC_WRITE;
creation_disposition = CREATE_ALWAYS;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::readwrite:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::writeread:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = CREATE_NEW;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
}
p_filehandle = CreateFileW(utf16_t(filename), desired_access, FILE_SHARE_READ, nullptr,
creation_disposition, FILE_ATTRIBUTE_NORMAL, nullptr);
if(p_filehandle == INVALID_HANDLE_VALUE) return false;
p_size = GetFileSize(p_filehandle, nullptr);
p_maphandle = CreateFileMapping(p_filehandle, nullptr, flprotect, 0, p_size, nullptr);
if(p_maphandle == INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
return false;
}
p_handle = (uint8_t*)MapViewOfFile(p_maphandle, map_access, 0, 0, p_size);
return p_handle;
switch(mode_) {
default: return false;
case mode::read:
desired_access = GENERIC_READ;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READONLY;
map_access = FILE_MAP_READ;
break;
case mode::write:
//write access requires read access
desired_access = GENERIC_WRITE;
creation_disposition = CREATE_ALWAYS;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::readwrite:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::writeread:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = CREATE_NEW;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
}
void p_close() {
if(p_handle) {
UnmapViewOfFile(p_handle);
p_handle = nullptr;
}
p_filehandle = CreateFileW(utf16_t(filename), desired_access, FILE_SHARE_READ, nullptr,
creation_disposition, FILE_ATTRIBUTE_NORMAL, nullptr);
if(p_filehandle == INVALID_HANDLE_VALUE) return false;
if(p_maphandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_maphandle);
p_maphandle = INVALID_HANDLE_VALUE;
}
p_size = GetFileSize(p_filehandle, nullptr);
if(p_filehandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
}
}
void p_ctor() {
p_maphandle = CreateFileMapping(p_filehandle, nullptr, flprotect, 0, p_size, nullptr);
if(p_maphandle == INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
p_maphandle = INVALID_HANDLE_VALUE;
return false;
}
void p_dtor() {
close();
p_handle = (uint8_t*)MapViewOfFile(p_maphandle, map_access, 0, 0, p_size);
return p_handle;
}
void p_close() {
if(p_handle) {
UnmapViewOfFile(p_handle);
p_handle = nullptr;
}
#else
//====
//mmap
//====
int p_fd;
bool p_open() const {
return p_handle;
if(p_maphandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_maphandle);
p_maphandle = INVALID_HANDLE_VALUE;
}
bool p_open(const char *filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
return true;
}
if(p_filehandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
}
}
int open_flags, mmap_flags;
void p_ctor() {
p_filehandle = INVALID_HANDLE_VALUE;
p_maphandle = INVALID_HANDLE_VALUE;
}
switch(mode_) {
default: return false;
case mode::read:
open_flags = O_RDONLY;
mmap_flags = PROT_READ;
break;
case mode::write:
open_flags = O_RDWR | O_CREAT; //mmap() requires read access
mmap_flags = PROT_WRITE;
break;
case mode::readwrite:
open_flags = O_RDWR;
mmap_flags = PROT_READ | PROT_WRITE;
break;
case mode::writeread:
open_flags = O_RDWR | O_CREAT;
mmap_flags = PROT_READ | PROT_WRITE;
break;
}
void p_dtor() {
close();
}
p_fd = ::open(filename, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if(p_fd < 0) return false;
#else
//====
//mmap
//====
struct stat p_stat;
fstat(p_fd, &p_stat);
p_size = p_stat.st_size;
int p_fd;
p_handle = (uint8_t*)mmap(nullptr, p_size, mmap_flags, MAP_SHARED, p_fd, 0);
if(p_handle == MAP_FAILED) {
p_handle = nullptr;
::close(p_fd);
p_fd = -1;
return false;
}
bool p_open() const {
return p_handle;
}
return p_handle;
bool p_open(const string& filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
return true;
}
void p_close() {
if(p_handle) {
munmap(p_handle, p_size);
p_handle = nullptr;
}
int open_flags, mmap_flags;
if(p_fd >= 0) {
::close(p_fd);
p_fd = -1;
}
switch(mode_) {
default: return false;
case mode::read:
open_flags = O_RDONLY;
mmap_flags = PROT_READ;
break;
case mode::write:
open_flags = O_RDWR | O_CREAT; //mmap() requires read access
mmap_flags = PROT_WRITE;
break;
case mode::readwrite:
open_flags = O_RDWR;
mmap_flags = PROT_READ | PROT_WRITE;
break;
case mode::writeread:
open_flags = O_RDWR | O_CREAT;
mmap_flags = PROT_READ | PROT_WRITE;
break;
}
void p_ctor() {
p_fd = ::open(filename, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if(p_fd < 0) return false;
struct stat p_stat;
fstat(p_fd, &p_stat);
p_size = p_stat.st_size;
p_handle = (uint8_t*)mmap(nullptr, p_size, mmap_flags, MAP_SHARED, p_fd, 0);
if(p_handle == MAP_FAILED) {
p_handle = nullptr;
::close(p_fd);
p_fd = -1;
return false;
}
return p_handle;
}
void p_close() {
if(p_handle) {
munmap(p_handle, p_size);
p_handle = nullptr;
}
if(p_fd >= 0) {
::close(p_fd);
p_fd = -1;
}
}
void p_dtor() {
p_close();
}
void p_ctor() {
p_fd = -1;
}
void p_dtor() {
p_close();
}
#endif
};
#endif
};
}
#endif

View File

@ -2,59 +2,63 @@
#define NALL_FUNCTION_HPP
namespace nall {
template<typename T> class function;
template<typename R, typename... P> class function<R (P...)> {
struct container {
virtual R operator()(P... p) const = 0;
virtual container* copy() const = 0;
virtual ~container() {}
} *callback;
template<typename T> class function;
struct global : container {
R (*function)(P...);
R operator()(P... p) const { return function(std::forward<P>(p)...); }
container* copy() const { return new global(function); }
global(R (*function)(P...)) : function(function) {}
};
template<typename C> struct member : container {
R (C::*function)(P...);
C *object;
R operator()(P... p) const { return (object->*function)(std::forward<P>(p)...); }
container* copy() const { return new member(function, object); }
member(R (C::*function)(P...), C *object) : function(function), object(object) {}
};
template<typename L> struct lambda : container {
mutable L object;
R operator()(P... p) const { return object(std::forward<P>(p)...); }
container* copy() const { return new lambda(object); }
lambda(const L& object) : object(object) {}
};
public:
explicit operator bool() const { return callback; }
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
void reset() { if(callback) { delete callback; callback = nullptr; } }
function& operator=(const function &source) {
if(this != &source) {
if(callback) { delete callback; callback = nullptr; }
if(source.callback) callback = source.callback->copy();
}
return *this;
}
function(const function &source) : callback(nullptr) { operator=(source); }
function() : callback(nullptr) {}
function(void *function) : callback(nullptr) { if(function) callback = new global((R (*)(P...))function); }
function(R (*function)(P...)) { callback = new global(function); }
template<typename C> function(R (C::*function)(P...), C *object) { callback = new member<C>(function, object); }
template<typename C> function(R (C::*function)(P...) const, C *object) { callback = new member<C>((R (C::*)(P...))function, object); }
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
~function() { if(callback) delete callback; }
template<typename R, typename... P> class function<R (P...)> {
struct container {
virtual R operator()(P... p) const = 0;
virtual container* copy() const = 0;
virtual ~container() {}
};
container* callback = nullptr;
struct global : container {
R (*function)(P...);
R operator()(P... p) const { return function(std::forward<P>(p)...); }
container* copy() const { return new global(function); }
global(R (*function)(P...)) : function(function) {}
};
template<typename C> struct member : container {
R (C::*function)(P...);
C* object;
R operator()(P... p) const { return (object->*function)(std::forward<P>(p)...); }
container* copy() const { return new member(function, object); }
member(R (C::*function)(P...), C* object) : function(function), object(object) {}
};
template<typename L> struct lambda : container {
mutable L object;
R operator()(P... p) const { return object(std::forward<P>(p)...); }
container* copy() const { return new lambda(object); }
lambda(const L& object) : object(object) {}
};
public:
explicit operator bool() const { return callback; }
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
void reset() { if(callback) { delete callback; callback = nullptr; } }
function& operator=(const function& source) {
if(this != &source) {
if(callback) { delete callback; callback = nullptr; }
if(source.callback) callback = source.callback->copy();
}
return *this;
}
function() = default;
function(const function &source) { operator=(source); }
function(void* function) { if(function) callback = new global((R (*)(P...))function); }
function(R (*function)(P...)) { callback = new global(function); }
template<typename C> function(R (C::*function)(P...), C* object) { callback = new member<C>(function, object); }
template<typename C> function(R (C::*function)(P...) const, C* object) { callback = new member<C>((R (C::*)(P...))function, object); }
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
~function() { if(callback) delete callback; }
};
}
#endif

View File

@ -1,132 +1,62 @@
#ifndef NALL_GROUP_HPP
#define NALL_GROUP_HPP
//group: a vector of unique references
//group
//vector of unique references
#include <stdlib.h>
#include <algorithm>
#include <initializer_list>
#include <utility>
#include <nall/bit.hpp>
#include <nall/traits.hpp>
#include <nall/vector.hpp>
namespace nall {
template<typename TR> struct group {
struct exception_out_of_bounds{};
typedef typename std::remove_reference<TR>::type T;
template<typename T> struct group : protected vector<T*> {
group& operator=(const group& source) { vector<T*>::operator=(source); return *this; }
group& operator=(group&& source) { vector<T*>::operator=(std::move(source)); return *this; }
template<typename... Args> group(Args&&... args) { construct(std::forward<Args>(args)...); }
protected:
T** pool = nullptr;
unsigned poolsize = 0;
unsigned objectsize = 0;
bool empty() const { return vector<T*>::empty(); }
unsigned size() const { return vector<T*>::size(); }
void reset() { vector<T*>::reset(); }
public:
unsigned size() const { return objectsize; }
unsigned capacity() const { return poolsize; }
T& first() const { return *vector<T*>::operator[](0); }
void reset() {
if(pool) free(pool);
pool = nullptr;
poolsize = 0;
objectsize = 0;
//return true if at least one item was appended
template<typename... Args> bool append(T& value, Args&&... args) {
bool result = append(value);
return append(std::forward<Args>(args)...) | result;
}
void reserve(unsigned size) {
if(size == poolsize) return;
pool = (T**)realloc(pool, sizeof(T*) * size);
poolsize = size;
objectsize = min(objectsize, size);
bool append(T& value) {
if(vector<T*>::find(&value)) return false;
return vector<T*>::append(&value), true;
}
void resize(unsigned size) {
if(size > poolsize) reserve(bit::round(size)); //amortize growth
objectsize = size;
//return true if at least one item was removed
template<typename... Args> bool remove(T& value, Args&&... args) {
bool result = remove(value);
return remove(std::forward<Args>(args)...) | result;
}
bool append(T& data) {
if(find(data)) return false;
unsigned offset = objectsize++;
if(offset >= poolsize) resize(offset + 1);
pool[offset] = &data;
return true;
}
template<typename... Args>
bool append(T& data, Args&&... args) {
bool result = append(data);
append(std::forward<Args>(args)...);
return result;
}
bool remove(T& data) {
if(auto position = find(data)) {
for(signed i = position(); i < objectsize - 1; i++) pool[i] = pool[i + 1];
resize(objectsize - 1);
return true;
}
bool remove(T& value) {
if(auto position = vector<T*>::find(&value)) return vector<T*>::remove(position()), true;
return false;
}
optional<unsigned> find(const T& data) {
for(unsigned n = 0; n < objectsize; n++) if(pool[n] == &data) return {true, n};
return {false, 0u};
}
template<typename... Args> group(Args&&... args) {
construct(std::forward<Args>(args)...);
}
~group() {
reset();
}
group& operator=(const group& source) {
if(&source == this) return *this;
reset();
reserve(source.poolsize);
resize(source.objectsize);
memcpy(pool, source.pool, sizeof(T*) * objectsize);
return *this;
}
group& operator=(const group&& source) {
if(&source == this) return *this;
reset();
pool = source.pool;
poolsize = source.poolsize;
objectsize = source.objectsize;
source.pool = nullptr;
source.reset();
return *this;
}
T& operator[](unsigned position) const {
if(position >= objectsize) throw exception_out_of_bounds();
return *pool[position];
}
struct iterator {
bool operator!=(const iterator& source) const { return position != source.position; }
T& operator*() { return source.operator[](position); }
iterator& operator++() { position++; return *this; }
iterator(const group& source, unsigned position) : source(source), position(position) {}
private:
const group& source;
unsigned position;
struct iterator : protected vector<T*>::const_iterator {
T& operator*() const { return *vector<T*>::const_iterator::operator*(); }
bool operator!=(const iterator& source) const { return vector<T*>::const_iterator::operator!=(source); }
iterator& operator++() { vector<T*>::const_iterator::operator++(); return *this; }
iterator(const group& source, unsigned position) : vector<T*>::const_iterator(source, position) {}
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, objectsize); }
const iterator begin() const { return iterator(*this, 0); }
const iterator end() const { return iterator(*this, objectsize); }
const iterator end() const { return iterator(*this, size()); }
private:
void construct() {}
void construct(const group& source) { operator=(source); }
void construct(const group&& source) { operator=(std::move(source)); }
template<typename... Args> void construct(T& data, Args&&... args) {
append(data);
void construct(const group& source) { vector<T*>::operator=(source); }
void construct(group&& source) { vector<T*>::operator=(std::move(source)); }
template<typename... Args> void construct(T& value, Args&&... args) {
append(value);
construct(std::forward<Args>(args)...);
}
};

View File

@ -8,24 +8,24 @@ namespace nall {
struct gzip {
string filename;
uint8_t *data;
unsigned size;
uint8_t* data = nullptr;
unsigned size = 0;
inline bool decompress(const string &filename);
inline bool decompress(const uint8_t *data, unsigned size);
inline bool decompress(const string& filename);
inline bool decompress(const uint8_t* data, unsigned size);
inline gzip();
inline ~gzip();
};
bool gzip::decompress(const string &filename) {
bool gzip::decompress(const string& filename) {
if(auto memory = file::read(filename)) {
return decompress(memory.data(), memory.size());
}
return false;
}
bool gzip::decompress(const uint8_t *data, unsigned size) {
bool gzip::decompress(const uint8_t* data, unsigned size) {
if(size < 18) return false;
if(data[0] != 0x1f) return false;
if(data[1] != 0x8b) return false;
@ -73,7 +73,7 @@ bool gzip::decompress(const uint8_t *data, unsigned size) {
return inflate(this->data, this->size, data + p, size - p - 8);
}
gzip::gzip() : data(nullptr) {
gzip::gzip() {
}
gzip::~gzip() {

View File

@ -19,11 +19,11 @@ namespace nall {
struct http {
string hostname;
addrinfo *serverinfo;
addrinfo* serverinfo;
int serversocket;
string header;
inline void download(const string &path, uint8_t *&data, unsigned &size) {
inline void download(const string& path, uint8_t*& data, unsigned& size) {
data = nullptr;
size = 0;
@ -59,11 +59,11 @@ struct http {
return true;
}
inline bool send(const string &data) {
inline bool send(const string& data) {
return send((const uint8_t*)(const char*)data, data.length());
}
inline bool send(const uint8_t *data, unsigned size) {
inline bool send(const uint8_t* data, unsigned size) {
while(size) {
int length = ::send(serversocket, (const char*)data, size, 0);
if(length == -1) return false;
@ -97,7 +97,7 @@ struct http {
return output;
}
inline void downloadContent(uint8_t *&data, unsigned &size) {
inline void downloadContent(uint8_t*& data, unsigned& size) {
unsigned capacity = 0;
if(header.iposition("\r\nTransfer-Encoding: chunked\r\n")) {

View File

@ -11,67 +11,72 @@
namespace nall {
struct image {
uint8_t *data;
unsigned width;
unsigned height;
unsigned pitch;
uint8_t* data = nullptr;
unsigned width = 0;
unsigned height = 0;
unsigned pitch = 0;
bool endian; //0 = little, 1 = big
unsigned depth;
unsigned stride;
bool endian = 0;
unsigned depth = 32;
unsigned stride = 4;
struct Channel {
uint64_t mask;
unsigned depth;
unsigned shift;
inline bool operator==(const Channel &source) {
inline bool operator==(const Channel& source) {
return mask == source.mask && depth == source.depth && shift == source.shift;
}
inline bool operator!=(const Channel &source) {
inline bool operator!=(const Channel& source) {
return !operator==(source);
}
} alpha, red, green, blue;
};
Channel alpha = {255u << 24, 8u, 24};
Channel red = {255u << 16, 8u, 16};
Channel green = {255u << 8, 8u, 8};
Channel blue = {255u << 0, 8u, 0};
typedef double (*interpolation)(double, double, double, double, double);
static inline unsigned bitDepth(uint64_t color);
static inline unsigned bitShift(uint64_t color);
static inline uint64_t normalize(uint64_t color, unsigned sourceDepth, unsigned targetDepth);
inline bool operator==(const image &source);
inline bool operator!=(const image &source);
inline bool operator==(const image& source);
inline bool operator!=(const image& source);
inline image& operator=(const image &source);
inline image& operator=(image &&source);
inline image(const image &source);
inline image(image &&source);
inline image& operator=(const image& source);
inline image& operator=(image&& source);
inline image(const image& source);
inline image(image&& source);
inline image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
inline image(const string &filename);
inline image(const uint8_t *data, unsigned size);
inline image(const string& filename);
inline image(const uint8_t* data, unsigned size);
inline image();
inline ~image();
inline uint64_t read(const uint8_t *data) const;
inline void write(uint8_t *data, uint64_t value) const;
inline uint64_t read(const uint8_t* data) const;
inline void write(uint8_t* data, uint64_t value) const;
inline void free();
inline bool empty() const;
inline void allocate(unsigned width, unsigned height);
inline void clear(uint64_t color);
inline bool load(const string &filename);
//inline bool loadBMP(const uint8_t *data, unsigned size);
inline bool loadPNG(const uint8_t *data, unsigned size);
inline bool load(const string& filename);
//inline bool loadBMP(const uint8_t* data, unsigned size);
inline bool loadPNG(const uint8_t* data, unsigned size);
inline void scale(unsigned width, unsigned height, interpolation op);
inline void transform(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
inline void alphaBlend(uint64_t alphaColor);
protected:
inline uint64_t interpolate(double mu, const uint64_t *s, interpolation op);
inline uint64_t interpolate(double mu, const uint64_t* s, interpolation op);
inline void scaleX(unsigned width, interpolation op);
inline void scaleY(unsigned height, interpolation op);
inline bool loadBMP(const string &filename);
inline bool loadPNG(const string &filename);
inline bool loadBMP(const string& filename);
inline bool loadPNG(const string& filename);
};
//static
@ -100,7 +105,7 @@ uint64_t image::normalize(uint64_t color, unsigned sourceDepth, unsigned targetD
//public
bool image::operator==(const image &source) {
bool image::operator==(const image& source) {
if(width != source.width) return false;
if(height != source.height) return false;
if(pitch != source.pitch) return false;
@ -116,11 +121,11 @@ bool image::operator==(const image &source) {
return memcmp(data, source.data, width * height * stride) == 0;
}
bool image::operator!=(const image &source) {
bool image::operator!=(const image& source) {
return !operator==(source);
}
image& image::operator=(const image &source) {
image& image::operator=(const image& source) {
free();
width = source.width;
@ -140,7 +145,7 @@ image& image::operator=(const image &source) {
return *this;
}
image& image::operator=(image &&source) {
image& image::operator=(image&& source) {
free();
width = source.width;
@ -160,79 +165,41 @@ image& image::operator=(image &&source) {
return *this;
}
image::image(const image &source) : data(nullptr) {
image::image(const image& source) {
operator=(source);
}
image::image(image &&source) : data(nullptr) {
image::image(image&& source) {
operator=(std::forward<image>(source));
}
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) : data(nullptr) {
width = 0, height = 0, pitch = 0;
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) {
this->endian = endian;
this->depth = depth;
this->stride = (depth / 8) + ((depth & 7) > 0);
alpha.mask = alphaMask, red.mask = redMask, green.mask = greenMask, blue.mask = blueMask;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
alpha = {alphaMask, bitDepth(alphaMask), bitShift(alphaMask)};
red = {redMask, bitDepth(redMask), bitShift(redMask)};
green = {greenMask, bitDepth(greenMask), bitShift(greenMask)};
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask)};
}
image::image(const string &filename) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image(const string& filename) {
load(filename);
}
image::image(const uint8_t *data, unsigned size) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image(const uint8_t* data, unsigned size) {
loadPNG(data, size);
}
image::image() : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image() {
}
image::~image() {
free();
}
uint64_t image::read(const uint8_t *data) const {
uint64_t image::read(const uint8_t* data) const {
uint64_t result = 0;
if(endian == 0) {
for(signed n = stride - 1; n >= 0; n--) result = (result << 8) | data[n];
@ -242,7 +209,7 @@ uint64_t image::read(const uint8_t *data) const {
return result;
}
void image::write(uint8_t *data, uint64_t value) const {
void image::write(uint8_t* data, uint64_t value) const {
if(endian == 0) {
for(signed n = 0; n < stride; n++) { data[n] = value; value >>= 8; }
} else {
@ -278,7 +245,7 @@ void image::clear(uint64_t color) {
}
}
bool image::load(const string &filename) {
bool image::load(const string& filename) {
if(loadBMP(filename) == true) return true;
if(loadPNG(filename) == true) return true;
return false;
@ -295,8 +262,8 @@ void image::transform(bool outputEndian, unsigned outputDepth, uint64_t outputAl
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
uint8_t *dp = output.data + output.pitch * y;
uint8_t *sp = data + pitch * y;
uint8_t* dp = output.data + output.pitch * y;
uint8_t* sp = data + pitch * y;
for(unsigned x = 0; x < width; x++) {
uint64_t color = read(sp);
sp += stride;
@ -326,7 +293,7 @@ void image::alphaBlend(uint64_t alphaColor) {
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
uint8_t *dp = data + pitch * y;
uint8_t* dp = data + pitch * y;
for(unsigned x = 0; x < width; x++) {
uint64_t color = read(dp);
@ -349,7 +316,7 @@ void image::alphaBlend(uint64_t alphaColor) {
//protected
uint64_t image::interpolate(double mu, const uint64_t *s, double (*op)(double, double, double, double, double)) {
uint64_t image::interpolate(double mu, const uint64_t* s, double (*op)(double, double, double, double, double)) {
uint64_t aa = (s[0] & alpha.mask) >> alpha.shift, ar = (s[0] & red.mask) >> red.shift,
ag = (s[0] & green.mask) >> green.shift, ab = (s[0] & blue.mask) >> blue.shift;
uint64_t ba = (s[1] & alpha.mask) >> alpha.shift, br = (s[1] & red.mask) >> red.shift,
@ -373,18 +340,18 @@ uint64_t image::interpolate(double mu, const uint64_t *s, double (*op)(double, d
}
void image::scaleX(unsigned outputWidth, interpolation op) {
uint8_t *outputData = new uint8_t[outputWidth * height * stride];
uint8_t* outputData = new uint8_t[outputWidth * height * stride];
unsigned outputPitch = outputWidth * stride;
double step = (double)width / (double)outputWidth;
const uint8_t *terminal = data + pitch * height;
const uint8_t* terminal = data + pitch * height;
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
uint8_t *dp = outputData + outputPitch * y;
uint8_t *sp = data + pitch * y;
uint8_t* dp = outputData + outputPitch * y;
uint8_t* sp = data + pitch * y;
double fraction = 0.0;
uint64_t s[4] = { sp < terminal ? read(sp) : 0 }; //B,C (0,1) = center of kernel { 0, 0, 1, 2 }
uint64_t s[4] = {sp < terminal ? read(sp) : 0}; //B,C (0,1) = center of kernel { 0, 0, 1, 2 }
s[1] = s[0];
s[2] = sp + stride < terminal ? read(sp += stride) : s[1];
s[3] = sp + stride < terminal ? read(sp += stride) : s[2];
@ -410,17 +377,17 @@ void image::scaleX(unsigned outputWidth, interpolation op) {
}
void image::scaleY(unsigned outputHeight, interpolation op) {
uint8_t *outputData = new uint8_t[width * outputHeight * stride];
uint8_t* outputData = new uint8_t[width * outputHeight * stride];
double step = (double)height / (double)outputHeight;
const uint8_t *terminal = data + pitch * height;
const uint8_t* terminal = data + pitch * height;
#pragma omp parallel for
for(unsigned x = 0; x < width; x++) {
uint8_t *dp = outputData + stride * x;
uint8_t *sp = data + stride * x;
uint8_t* dp = outputData + stride * x;
uint8_t* sp = data + stride * x;
double fraction = 0.0;
uint64_t s[4] = { sp < terminal ? read(sp) : 0 };
uint64_t s[4] = {sp < terminal ? read(sp) : 0};
s[1] = s[0];
s[2] = sp + pitch < terminal ? read(sp += pitch) : s[1];
s[3] = sp + pitch < terminal ? read(sp += pitch) : s[2];
@ -444,14 +411,14 @@ void image::scaleY(unsigned outputHeight, interpolation op) {
height = outputHeight;
}
bool image::loadBMP(const string &filename) {
uint32_t *outputData;
bool image::loadBMP(const string& filename) {
uint32_t* outputData;
unsigned outputWidth, outputHeight;
if(bmp::read(filename, outputData, outputWidth, outputHeight) == false) return false;
allocate(outputWidth, outputHeight);
const uint32_t *sp = outputData;
uint8_t *dp = data;
const uint32_t* sp = outputData;
uint8_t* dp = data;
for(unsigned y = 0; y < outputHeight; y++) {
for(unsigned x = 0; x < outputWidth; x++) {
@ -469,13 +436,13 @@ bool image::loadBMP(const string &filename) {
return true;
}
bool image::loadPNG(const uint8_t *pngData, unsigned pngSize) {
bool image::loadPNG(const uint8_t* pngData, unsigned pngSize) {
png source;
if(source.decode(pngData, pngSize) == false) return false;
allocate(source.info.width, source.info.height);
const uint8_t *sp = source.data;
uint8_t *dp = data;
const uint8_t* sp = source.data;
uint8_t* dp = data;
auto decode = [&]() -> uint64_t {
uint64_t p, r, g, b, a;
@ -528,7 +495,7 @@ bool image::loadPNG(const uint8_t *pngData, unsigned pngSize) {
return true;
}
bool image::loadPNG(const string &filename) {
bool image::loadPNG(const string& filename) {
filemap map;
if(map.open(filename, filemap::mode::read) == false) return false;
return loadPNG(map.data(), map.size());

View File

@ -7,14 +7,14 @@ namespace nall {
namespace puff {
inline int puff(
unsigned char *dest, unsigned long *destlen,
unsigned char *source, unsigned long *sourcelen
unsigned char* dest, unsigned long* destlen,
unsigned char* source, unsigned long* sourcelen
);
}
inline bool inflate(
uint8_t *target, unsigned targetLength,
const uint8_t *source, unsigned sourceLength
uint8_t* target, unsigned targetLength,
const uint8_t* source, unsigned sourceLength
) {
unsigned long tl = targetLength, sl = sourceLength;
int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl);
@ -23,15 +23,6 @@ inline bool inflate(
namespace puff {
//zlib/contrib/puff.c
//version 2.1*
//author: Mark Adler
//license: zlib
//ported by: byuu
//* I have corrected a bug in fixed(), where it was accessing uninitialized
// memory: calling construct() with lencode prior to initializing lencode.count
enum {
MAXBITS = 15,
MAXLCODES = 286,
@ -41,11 +32,11 @@ enum {
};
struct state {
unsigned char *out;
unsigned char* out;
unsigned long outlen;
unsigned long outcnt;
unsigned char *in;
unsigned char* in;
unsigned long inlen;
unsigned long incnt;
int bitbuf;
@ -55,11 +46,11 @@ struct state {
};
struct huffman {
short *count;
short *symbol;
short* count;
short* symbol;
};
inline int bits(state *s, int need) {
inline int bits(state* s, int need) {
long val;
val = s->bitbuf;
@ -75,7 +66,7 @@ inline int bits(state *s, int need) {
return (int)(val & ((1L << need) - 1));
}
inline int stored(state *s) {
inline int stored(state* s) {
unsigned len;
s->bitbuf = 0;
@ -100,9 +91,9 @@ inline int stored(state *s) {
return 0;
}
inline int decode(state *s, huffman *h) {
inline int decode(state* s, huffman* h) {
int len, code, first, count, index, bitbuf, left;
short *next;
short* next;
bitbuf = s->bitbuf;
left = s->bitcnt;
@ -135,7 +126,7 @@ inline int decode(state *s, huffman *h) {
return -10;
}
inline int construct(huffman *h, short *length, int n) {
inline int construct(huffman* h, short* length, int n) {
int symbol, len, left;
short offs[MAXBITS + 1];
@ -160,7 +151,7 @@ inline int construct(huffman *h, short *length, int n) {
return left;
}
inline int codes(state *s, huffman *lencode, huffman *distcode) {
inline int codes(state* s, huffman* lencode, huffman* distcode) {
int symbol, len;
unsigned dist;
static const short lens[29] = {
@ -222,7 +213,7 @@ inline int codes(state *s, huffman *lencode, huffman *distcode) {
return 0;
}
inline int fixed(state *s) {
inline int fixed(state* s) {
static int virgin = 1;
static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
@ -252,7 +243,7 @@ inline int fixed(state *s) {
return codes(s, &lencode, &distcode);
}
inline int dynamic(state *s) {
inline int dynamic(state* s) {
int nlen, ndist, ncode, index, err;
short lengths[MAXCODES];
short lencnt[MAXBITS + 1], lensym[MAXLCODES];
@ -313,8 +304,8 @@ inline int dynamic(state *s) {
}
inline int puff(
unsigned char *dest, unsigned long *destlen,
unsigned char *source, unsigned long *sourcelen
unsigned char* dest, unsigned long* destlen,
unsigned char* source, unsigned long* sourcelen
) {
state s;
int last, type, err;

View File

@ -88,7 +88,7 @@ struct Keyboard {
return false;
}
static uint16_t decode(const char *name) {
static uint16_t decode(const char* name) {
string s(name);
if(!strbegin(name, "KB")) return 0;
s.ltrim("KB");
@ -110,7 +110,7 @@ struct Keyboard {
break;
}
}
return { "KB", ID, "::", KeyboardScancodeName[index] };
return {"KB", ID, "::", KeyboardScancodeName[index]};
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
@ -185,7 +185,7 @@ struct Mouse {
return false;
}
static uint16_t decode(const char *name) {
static uint16_t decode(const char* name) {
string s(name);
if(!strbegin(name, "MS")) return 0;
s.ltrim("MS");
@ -207,7 +207,7 @@ struct Mouse {
break;
}
}
return { "MS", ID, "::", MouseScancodeName[index] };
return {"MS", ID, "::", MouseScancodeName[index]};
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
@ -309,7 +309,7 @@ struct Joypad {
return false;
}
static uint16_t decode(const char *name) {
static uint16_t decode(const char* name) {
string s(name);
if(!strbegin(name, "JP")) return 0;
s.ltrim("JP");
@ -330,7 +330,7 @@ struct Joypad {
index = code - (Base + Size * i);
}
}
return { "JP", ID, "::", JoypadScancodeName[index] };
return {"JP", ID, "::", JoypadScancodeName[index]};
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
@ -356,7 +356,7 @@ inline Joypad& joypad(unsigned id) {
struct Scancode {
enum { None = 0, Limit = Joypad::Base + Joypad::Size * Joypad::Count };
static uint16_t decode(const char *name) {
static uint16_t decode(const char* name) {
uint16_t code;
code = Keyboard::decode(name);
if(code) return code;

View File

@ -1,6 +1,8 @@
#ifndef NALL_INTRINSICS_HPP
#define NALL_INTRINSICS_HPP
namespace nall {
struct Intrinsics {
enum class Compiler : unsigned { Clang, GCC, VisualC, Unknown };
enum class Platform : unsigned { X, OSX, Windows, Unknown };
@ -63,4 +65,6 @@ struct Intrinsics {
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; }
#endif
}
#endif

View File

@ -20,21 +20,20 @@ namespace nall {
#if defined(PLATFORM_WINDOWS)
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
lstring argl(std::forward<Args>(args)...);
for(auto &arg : argl) if(arg.position(" ")) arg = {"\"", arg, "\""};
for(auto& arg : argl) if(arg.position(" ")) arg = {"\"", arg, "\""};
string arguments = argl.concatenate(" ");
ShellExecuteW(NULL, NULL, utf16_t(name), utf16_t(arguments), NULL, SW_SHOWNORMAL);
}
#elif defined(PLATFORM_X)
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
pid_t pid = fork();
if(pid == 0) {
const char *argv[1 + sizeof...(args) + 1], **argp = argv;
const char* argv[1 + sizeof...(args) + 1];
const char** argp = argv;
lstring argl(std::forward<Args>(args)...);
*argp++ = (const char*)name;
for(auto &arg : argl) *argp++ = (const char*)arg;
@ -49,8 +48,7 @@ inline void invoke(const string &name, Args&&... args) {
#else
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
}
#endif

View File

@ -9,17 +9,17 @@ namespace nall {
struct ips {
inline bool apply();
inline void source(const uint8_t *data, unsigned size);
inline void modify(const uint8_t *data, unsigned size);
inline void source(const uint8_t* data, unsigned size);
inline void modify(const uint8_t* data, unsigned size);
inline ips();
inline ~ips();
uint8_t *data;
unsigned size;
const uint8_t *sourceData;
unsigned sourceSize;
const uint8_t *modifyData;
unsigned modifySize;
uint8_t* data = nullptr;
unsigned size = 0;
const uint8_t* sourceData = nullptr;
unsigned sourceSize = 0;
const uint8_t* modifyData = nullptr;
unsigned modifySize = 0;
};
bool ips::apply() {
@ -78,15 +78,15 @@ bool ips::apply() {
return false;
}
void ips::source(const uint8_t *data, unsigned size) {
void ips::source(const uint8_t* data, unsigned size) {
sourceData = data, sourceSize = size;
}
void ips::modify(const uint8_t *data, unsigned size) {
void ips::modify(const uint8_t* data, unsigned size) {
modifyData = data, modifySize = size;
}
ips::ips() : data(nullptr), sourceData(nullptr), modifyData(nullptr) {
ips::ips() {
}
ips::~ips() {

View File

@ -1,115 +1,57 @@
#ifndef NALL_MAP_HPP
#define NALL_MAP_HPP
#include <nall/vector.hpp>
#include <nall/set.hpp>
namespace nall {
template<typename LHS, typename RHS>
struct map {
struct pair {
LHS name;
RHS data;
template<typename T, typename U> struct map {
struct node_t {
T key;
U value;
bool operator< (const node_t& source) const { return key < source.key; }
bool operator==(const node_t& source) const { return key == source.key; }
node_t() = default;
node_t(const T& key) : key(key) {}
node_t(const T& key, const U& value) : key(key), value(value) {}
};
inline void reset() {
list.reset();
optional<U> find(const T& key) const {
if(auto node = root.find({key})) return {true, node().value};
return false;
}
inline unsigned size() const {
return list.size();
}
void insert(const T& key, const U& value) { root.insert({key, value}); }
void remove(const T& key) { root.remove({key}); }
unsigned size() const { return root.size(); }
void reset() { root.reset(); }
//O(log n) find
inline optional<unsigned> find(const LHS &name) const {
signed first = 0, last = size() - 1;
while(first <= last) {
signed middle = (first + last) / 2;
if(name < list[middle].name) last = middle - 1; //search lower half
else if(list[middle].name < name) first = middle + 1; //search upper half
else return { true, (unsigned)middle }; //match found
}
return { false, 0u };
}
//O(n) insert + O(log n) find
inline RHS& insert(const LHS &name, const RHS &data) {
if(auto position = find(name)) {
list[position()].data = data;
return list[position()].data;
}
signed offset = size();
for(unsigned n = 0; n < size(); n++) {
if(name < list[n].name) { offset = n; break; }
}
list.insert(offset, { name, data });
return list[offset].data;
}
//O(log n) find
inline void modify(const LHS &name, const RHS &data) {
if(auto position = find(name)) list[position()].data = data;
}
//O(n) remove + O(log n) find
inline void remove(const LHS &name) {
if(auto position = find(name)) list.remove(position());
}
//O(log n) find
inline RHS& operator[](const LHS &name) {
if(auto position = find(name)) return list[position()].data;
throw;
}
inline const RHS& operator[](const LHS &name) const {
if(auto position = find(name)) return list[position()].data;
throw;
}
inline RHS& operator()(const LHS &name) {
if(auto position = find(name)) return list[position()].data;
return insert(name, RHS());
}
inline const RHS& operator()(const LHS &name, const RHS &data) const {
if(auto position = find(name)) return list[position()].data;
return data;
}
inline pair* begin() { return list.begin(); }
inline pair* end() { return list.end(); }
inline const pair* begin() const { return list.begin(); }
inline const pair* end() const { return list.end(); }
typename set<node_t>::iterator begin() { return root.begin(); }
typename set<node_t>::iterator end() { return root.end(); }
const typename set<node_t>::iterator begin() const { return root.begin(); }
const typename set<node_t>::iterator end() const { return root.end(); }
protected:
vector<pair> list;
set<node_t> root;
};
template<typename LHS, typename RHS>
struct bidirectional_map {
const map<LHS, RHS> &lhs;
const map<RHS, LHS> &rhs;
template<typename T, typename U> struct bimap {
optional<U> find(const T& key) const { return tmap.find(key); }
optional<T> find(const U& key) const { return umap.find(key); }
void insert(const T& key, const U& value) { tmap.insert(key, value); umap.insert(value, key); }
void remove(const T& key) { if(auto p = tmap.find(key)) { umap.remove(p().value); tmap.remove(key); } }
void remove(const U& key) { if(auto p = umap.find(key)) { tmap.remove(p().value); umap.remove(key); } }
unsigned size() const { return tmap.size(); }
void reset() { tmap.reset(); umap.reset(); }
inline void reset() {
llist.reset();
rlist.reset();
}
inline unsigned size() const {
return llist.size();
}
inline void insert(const LHS &ldata, const RHS &rdata) {
llist.insert(ldata, rdata);
rlist.insert(rdata, ldata);
}
inline bidirectional_map() : lhs(llist), rhs(rlist) {}
typename set<typename map<T, U>::node_t>::iterator begin() { return tmap.begin(); }
typename set<typename map<T, U>::node_t>::iterator end() { return tmap.end(); }
const typename set<typename map<T, U>::node_t>::iterator begin() const { return tmap.begin(); }
const typename set<typename map<T, U>::node_t>::iterator end() const { return tmap.end(); }
protected:
map<LHS, RHS> llist;
map<RHS, LHS> rlist;
map<T, U> tmap;
map<U, T> umap;
};
}

View File

@ -5,8 +5,7 @@ namespace nall {
namespace Matrix {
template<typename T>
inline void Multiply(T *output, const T *xdata, unsigned xrows, unsigned xcols, const T *ydata, unsigned yrows, unsigned ycols) {
template<typename T> inline void Multiply(T* output, const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) {
if(xcols != yrows) return;
for(unsigned y = 0; y < xrows; y++) {
@ -20,8 +19,7 @@ inline void Multiply(T *output, const T *xdata, unsigned xrows, unsigned xcols,
}
}
template<typename T>
inline vector<T> Multiply(const T *xdata, unsigned xrows, unsigned xcols, const T *ydata, unsigned yrows, unsigned ycols) {
template<typename T> inline vector<T> Multiply(const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) {
vector<T> output;
output.resize(xrows * ycols);
Multiply(output.data(), xdata, xrows, xcols, ydata, yrows, ycols);

View File

@ -5,25 +5,25 @@ namespace mosaic {
struct bitstream {
filemap fp;
uint8_t *data;
unsigned size;
bool readonly;
bool endian;
uint8_t* data = nullptr;
unsigned size = 0;
bool readonly = false;
bool endian = 1;
inline bool read(uint64_t addr) const {
bool read(uint64_t addr) const {
if(data == nullptr || (addr >> 3) >= size) return 0;
unsigned mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7));
return data[addr >> 3] & mask;
}
inline void write(uint64_t addr, bool value) {
void write(uint64_t addr, bool value) {
if(data == nullptr || readonly == true || (addr >> 3) >= size) return;
unsigned mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7));
if(value == 0) data[addr >> 3] &= ~mask;
if(value == 1) data[addr >> 3] |= mask;
}
inline bool open(const string &filename) {
bool open(const string& filename) {
readonly = false;
if(fp.open(filename, filemap::mode::readwrite) == false) {
readonly = true;
@ -36,15 +36,15 @@ struct bitstream {
return true;
}
inline void close() {
void close() {
fp.close();
data = nullptr;
}
inline bitstream() : data(nullptr), endian(1) {
bitstream() {
}
inline ~bitstream() {
~bitstream() {
close();
}
};

View File

@ -36,9 +36,9 @@ struct context {
unsigned paddingColor;
vector<unsigned> palette;
inline unsigned objectWidth() const { return blockWidth * tileWidth * mosaicWidth + paddingWidth; }
inline unsigned objectHeight() const { return blockHeight * tileHeight * mosaicHeight + paddingHeight; }
inline unsigned objectSize() const {
unsigned objectWidth() const { return blockWidth * tileWidth * mosaicWidth + paddingWidth; }
unsigned objectHeight() const { return blockHeight * tileHeight * mosaicHeight + paddingHeight; }
unsigned objectSize() const {
unsigned size = blockStride * tileWidth * tileHeight * mosaicWidth * mosaicHeight
+ blockOffset * tileHeight * mosaicWidth * mosaicHeight
+ tileStride * mosaicWidth * mosaicHeight
@ -46,23 +46,23 @@ struct context {
return max(1u, size);
}
inline unsigned eval(const string &expression) {
unsigned eval(const string& expression) {
intmax_t result;
if(fixedpoint::eval(expression, result) == false) return 0u;
return result;
}
inline void eval(vector<unsigned> &buffer, const string &expression_) {
void eval(vector<unsigned>& buffer, const string& expression_) {
string expression = expression_;
bool function = false;
for(auto &c : expression) {
for(auto& c : expression) {
if(c == '(') function = true;
if(c == ')') function = false;
if(c == ',' && function == true) c = ';';
}
lstring list = expression.split(",");
for(auto &item : list) {
for(auto& item : list) {
item.trim();
if(item.wildcard("f(?*) ?*")) {
item.ltrim<1>("f(");
@ -95,7 +95,7 @@ struct context {
item = part(1, "");
}
item.trim();
for(auto &c : item) {
for(auto& c : item) {
if(c >= 'A' && c <= 'Z') buffer.append(offset + c - 'A' + 0);
if(c >= 'a' && c <= 'z') buffer.append(offset + c - 'a' + 26);
if(c >= '0' && c <= '9') buffer.append(offset + c - '0' + 52);
@ -112,11 +112,11 @@ struct context {
}
}
inline void parse(const string &data) {
void parse(const string& data) {
reset();
lstring lines = data.split("\n");
for(auto &line : lines) {
for(auto& line : lines) {
lstring part = line.split<1>(":");
if(part.size() != 2) continue;
part[0].trim();
@ -158,14 +158,14 @@ struct context {
sanitize();
}
inline bool load(const string &filename) {
bool load(const string& filename) {
string filedata;
if(filedata.readfile(filename) == false) return false;
parse(filedata);
return true;
}
inline void sanitize() {
void sanitize() {
if(depth < 1) depth = 1;
if(depth > 24) depth = 24;
@ -179,7 +179,7 @@ struct context {
if(mosaicHeight < 1) mosaicHeight = 1;
}
inline void reset() {
void reset() {
offset = 0;
width = 0;
height = 0;
@ -213,7 +213,7 @@ struct context {
palette.reset();
}
inline context() {
context() {
reset();
}
};

View File

@ -7,14 +7,14 @@ struct parser {
image canvas;
//export from bitstream to canvas
inline void load(bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
void load(bitstream& stream, uint64_t offset, context& ctx, unsigned width, unsigned height) {
canvas.allocate(width, height);
canvas.clear(ctx.paddingColor);
parse(1, stream, offset, ctx, width, height);
}
//import from canvas to bitstream
inline bool save(bitstream &stream, uint64_t offset, context &ctx) {
bool save(bitstream& stream, uint64_t offset, context& ctx) {
if(stream.readonly) return false;
parse(0, stream, offset, ctx, canvas.width, canvas.height);
return true;
@ -24,21 +24,21 @@ struct parser {
}
private:
inline uint32_t read(unsigned x, unsigned y) const {
uint32_t read(unsigned x, unsigned y) const {
unsigned addr = y * canvas.width + x;
if(addr >= canvas.width * canvas.height) return 0u;
uint32_t *buffer = (uint32_t*)canvas.data;
return buffer[addr];
}
inline void write(unsigned x, unsigned y, uint32_t data) {
void write(unsigned x, unsigned y, uint32_t data) {
unsigned addr = y * canvas.width + x;
if(addr >= canvas.width * canvas.height) return;
uint32_t *buffer = (uint32_t*)canvas.data;
buffer[addr] = data;
}
inline void parse(bool load, bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
void parse(bool load, bitstream& stream, uint64_t offset, context& ctx, unsigned width, unsigned height) {
stream.endian = ctx.endian;
unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth);
unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight);

View File

@ -35,6 +35,7 @@
#include <nall/property.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>
#include <nall/set.hpp>
#include <nall/sha256.hpp>
#include <nall/sort.hpp>
#include <nall/stdint.hpp>

View File

@ -10,16 +10,16 @@
namespace nall {
struct png {
//colorType:
//0 = L
//2 = R,G,B
//3 = P
//4 = L,A
//6 = R,G,B,A
struct Info {
unsigned width;
unsigned height;
unsigned bitDepth;
//colorType:
//0 = L (luma)
//2 = R,G,B
//3 = P (palette)
//4 = L,A
//6 = R,G,B,A
unsigned colorType;
unsigned compressionMethod;
unsigned filterType;
@ -31,13 +31,13 @@ struct png {
uint8_t palette[256][3];
} info;
uint8_t *data;
unsigned size;
uint8_t* data = nullptr;
unsigned size = 0;
inline bool decode(const string &filename);
inline bool decode(const uint8_t *sourceData, unsigned sourceSize);
inline unsigned readbits(const uint8_t *&data);
unsigned bitpos;
inline bool decode(const string& filename);
inline bool decode(const uint8_t* sourceData, unsigned sourceSize);
inline unsigned readbits(const uint8_t*& data);
unsigned bitpos = 0;
inline png();
inline ~png();
@ -52,24 +52,24 @@ protected:
inline unsigned interlace(unsigned pass, unsigned index);
inline unsigned inflateSize();
inline bool deinterlace(const uint8_t *&inputData, unsigned pass);
inline bool filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height);
inline unsigned read(const uint8_t *data, unsigned length);
inline bool deinterlace(const uint8_t*& inputData, unsigned pass);
inline bool filter(uint8_t* outputData, const uint8_t* inputData, unsigned width, unsigned height);
inline unsigned read(const uint8_t* data, unsigned length);
};
bool png::decode(const string &filename) {
bool png::decode(const string& filename) {
if(auto memory = file::read(filename)) {
return decode(memory.data(), memory.size());
}
return false;
}
bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
bool png::decode(const uint8_t* sourceData, unsigned sourceSize) {
if(sourceSize < 8) return false;
if(read(sourceData + 0, 4) != 0x89504e47) return false;
if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false;
uint8_t *compressedData = nullptr;
uint8_t* compressedData = nullptr;
unsigned compressedSize = 0;
unsigned offset = 8;
@ -102,8 +102,9 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
default: return false;
}
if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6)
if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6) {
if(info.bitDepth != 8 && info.bitDepth != 16) return false;
}
if(info.colorType == 3 && info.bitDepth == 16) return false;
info.bytesPerPixel = (info.bytesPerPixel + 7) / 8;
@ -200,7 +201,7 @@ unsigned png::inflateSize() {
return size;
}
bool png::deinterlace(const uint8_t *&inputData, unsigned pass) {
bool png::deinterlace(const uint8_t*& inputData, unsigned pass) {
unsigned xd = interlace(pass, 0), yd = interlace(pass, 1);
unsigned xo = interlace(pass, 2), yo = interlace(pass, 3);
unsigned width = (info.width + (xd - xo - 1)) / xd;
@ -208,12 +209,12 @@ bool png::deinterlace(const uint8_t *&inputData, unsigned pass) {
if(width == 0 || height == 0) return true;
unsigned outputSize = width * height * info.bytesPerPixel;
uint8_t *outputData = new uint8_t[outputSize];
uint8_t* outputData = new uint8_t[outputSize];
bool result = filter(outputData, inputData, width, height);
const uint8_t *rd = outputData;
const uint8_t* rd = outputData;
for(unsigned y = yo; y < info.height; y += yd) {
uint8_t *wr = data + y * info.pitch;
uint8_t* wr = data + y * info.pitch;
for(unsigned x = xo; x < info.width; x += xd) {
for(unsigned b = 0; b < info.bytesPerPixel; b++) {
wr[x * info.bytesPerPixel + b] = *rd++;
@ -226,9 +227,9 @@ bool png::deinterlace(const uint8_t *&inputData, unsigned pass) {
return result;
}
bool png::filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height) {
uint8_t *wr = outputData;
const uint8_t *rd = inputData;
bool png::filter(uint8_t* outputData, const uint8_t* inputData, unsigned width, unsigned height) {
uint8_t* wr = outputData;
const uint8_t* rd = inputData;
int bpp = info.bytesPerPixel, pitch = width * bpp;
for(int y = 0; y < height; y++) {
uint8_t filter = *rd++;
@ -289,13 +290,13 @@ bool png::filter(uint8_t *outputData, const uint8_t *inputData, unsigned width,
return true;
}
unsigned png::read(const uint8_t *data, unsigned length) {
unsigned png::read(const uint8_t* data, unsigned length) {
unsigned result = 0;
while(length--) result = (result << 8) | (*data++);
return result;
}
unsigned png::readbits(const uint8_t *&data) {
unsigned png::readbits(const uint8_t*& data) {
unsigned result = 0;
switch(info.bitDepth) {
case 1:
@ -324,8 +325,7 @@ unsigned png::readbits(const uint8_t *&data) {
return result;
}
png::png() : data(nullptr) {
bitpos = 0;
png::png() {
}
png::~png() {

View File

@ -7,103 +7,104 @@
#include <nall/utility.hpp>
namespace nall {
template<typename type_t> void priority_queue_nocallback(type_t) {}
//priority queue implementation using binary min-heap array;
//does not require normalize() function.
//O(1) find (tick)
//O(log n) append (enqueue)
//O(log n) remove (dequeue)
template<typename type_t> class priority_queue {
public:
inline void tick(unsigned ticks) {
basecounter += ticks;
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
template<typename type_t> void priority_queue_nocallback(type_t) {}
//priority queue implementation using binary min-heap array;
//does not require normalize() function.
//O(1) find (tick)
//O(log n) append (enqueue)
//O(log n) remove (dequeue)
template<typename type_t> struct priority_queue {
inline void tick(unsigned ticks) {
basecounter += ticks;
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
}
//counter is relative to current time (eg enqueue(64, ...) fires in 64 ticks);
//counter cannot exceed std::numeric_limits<unsigned>::max() >> 1.
void enqueue(unsigned counter, type_t event) {
unsigned child = heapsize++;
counter += basecounter;
while(child) {
unsigned parent = (child - 1) >> 1;
if(gte(counter, heap[parent].counter)) break;
heap[child].counter = heap[parent].counter;
heap[child].event = heap[parent].event;
child = parent;
}
//counter is relative to current time (eg enqueue(64, ...) fires in 64 ticks);
//counter cannot exceed std::numeric_limits<unsigned>::max() >> 1.
void enqueue(unsigned counter, type_t event) {
unsigned child = heapsize++;
counter += basecounter;
heap[child].counter = counter;
heap[child].event = event;
}
while(child) {
unsigned parent = (child - 1) >> 1;
if(gte(counter, heap[parent].counter)) break;
type_t dequeue() {
type_t event(heap[0].event);
unsigned parent = 0;
unsigned counter = heap[--heapsize].counter;
heap[child].counter = heap[parent].counter;
heap[child].event = heap[parent].event;
child = parent;
}
while(true) {
unsigned child = (parent << 1) + 1;
if(child >= heapsize) break;
if(child + 1 < heapsize && gte(heap[child].counter, heap[child + 1].counter)) child++;
if(gte(heap[child].counter, counter)) break;
heap[child].counter = counter;
heap[child].event = event;
heap[parent].counter = heap[child].counter;
heap[parent].event = heap[child].event;
parent = child;
}
type_t dequeue() {
type_t event(heap[0].event);
unsigned parent = 0;
unsigned counter = heap[--heapsize].counter;
heap[parent].counter = counter;
heap[parent].event = heap[heapsize].event;
return event;
}
while(true) {
unsigned child = (parent << 1) + 1;
if(child >= heapsize) break;
if(child + 1 < heapsize && gte(heap[child].counter, heap[child + 1].counter)) child++;
if(gte(heap[child].counter, counter)) break;
void reset() {
basecounter = 0;
heapsize = 0;
}
heap[parent].counter = heap[child].counter;
heap[parent].event = heap[child].event;
parent = child;
}
heap[parent].counter = counter;
heap[parent].event = heap[heapsize].event;
return event;
void serialize(serializer& s) {
s.integer(basecounter);
s.integer(heapsize);
for(unsigned n = 0; n < heapcapacity; n++) {
s.integer(heap[n].counter);
s.integer(heap[n].event);
}
}
void reset() {
basecounter = 0;
heapsize = 0;
}
priority_queue(unsigned size, function<void (type_t)> callback = &priority_queue_nocallback<type_t>)
: callback(callback) {
heap = new heap_t[size];
heapcapacity = size;
reset();
}
void serialize(serializer &s) {
s.integer(basecounter);
s.integer(heapsize);
for(unsigned n = 0; n < heapcapacity; n++) {
s.integer(heap[n].counter);
s.integer(heap[n].event);
}
}
~priority_queue() {
delete[] heap;
}
priority_queue(unsigned size, function<void (type_t)> callback_ = &priority_queue_nocallback<type_t>)
: callback(callback_) {
heap = new heap_t[size];
heapcapacity = size;
reset();
}
priority_queue& operator=(const priority_queue&) = delete;
priority_queue(const priority_queue&) = delete;
~priority_queue() {
delete[] heap;
}
private:
function<void (type_t)> callback;
unsigned basecounter;
unsigned heapsize;
unsigned heapcapacity;
struct heap_t {
unsigned counter;
type_t event;
} *heap;
priority_queue& operator=(const priority_queue&) = delete;
priority_queue(const priority_queue&) = delete;
//return true if x is greater than or equal to y
inline bool gte(unsigned x, unsigned y) {
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
}
};
private:
function<void (type_t)> callback;
unsigned basecounter;
unsigned heapsize;
unsigned heapcapacity;
struct heap_t {
unsigned counter;
type_t event;
} *heap;
//return true if x is greater than or equal to y
inline bool gte(unsigned x, unsigned y) {
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
}
};
}
#endif

View File

@ -1,83 +1,44 @@
#ifndef NALL_PROPERTY_HPP
#define NALL_PROPERTY_HPP
//nall::property implements ownership semantics into container classes
//example: property<owner>::readonly<type> implies that only owner has full
//access to type; and all other code has readonly access.
//
//property can be used either of two ways:
//struct foo {
// property<foo>::readonly<bool> x;
// property<foo>::readwrite<int> y;
//};
//-or-
//struct foo : property<foo> {
// readonly<bool> x;
// readwrite<int> y;
//};
//return types are const T& (byref) instead of T (byval) to avoid major speed
//penalties for objects with expensive copy constructors
//operator-> provides access to underlying object type:
//readonly<Object> foo;
//foo->bar();
//... will call Object::bar();
//operator='s reference is constant so as to avoid leaking a reference handle
//that could bypass access restrictions
//both constant and non-constant operators are provided, though it may be
//necessary to cast first, for instance:
//struct foo : property<foo> { readonly<int> bar; } object;
//int main() { int value = const_cast<const foo&>(object); }
//writeonly is useful for objects that have non-const reads, but const writes.
//however, to avoid leaking handles, the interface is very restricted. the only
//way to write is via operator=, which requires conversion via eg copy
//constructor. example:
//struct foo {
// foo(bool value) { ... }
//};
//writeonly<foo> bar;
//bar = true;
namespace nall {
template<typename C> struct property {
template<typename T> struct readonly {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
private:
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
friend C;
};
template<typename T> struct writeonly {
void operator=(const T& value_) { value = value_; }
private:
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
T value;
friend C;
};
template<typename T> struct readwrite {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
};
template<typename C> struct property {
template<typename T> struct readonly {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
private:
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
friend C;
};
template<typename T> struct writeonly {
void operator=(const T& value_) { value = value_; }
private:
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
T value;
friend C;
};
template<typename T> struct readwrite {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
};
};
}
#endif

View File

@ -14,19 +14,21 @@
//Class::Reference may be a function, object or variable
namespace nall {
template<typename T, typename T::type... P> struct public_cast;
template<typename T> struct public_cast<T> {
static typename T::type value;
};
template<typename T, typename T::type... P> struct public_cast;
template<typename T> typename T::type public_cast<T>::value;
template<typename T> struct public_cast<T> {
static typename T::type value;
};
template<typename T, typename T::type P> struct public_cast<T, P> {
static typename T::type value;
};
template<typename T> typename T::type public_cast<T>::value;
template<typename T, typename T::type P> struct public_cast<T, P> {
static typename T::type value;
};
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
}
#endif

View File

@ -1,28 +1,32 @@
#ifndef NALL_RANDOM_HPP
#define NALL_RANDOM_HPP
//pseudo-random number generator
//very low-quality, but very fast (based on CRC32 polynomial)
namespace nall {
//pseudo-random number generator
inline unsigned prng() {
static unsigned n = 0;
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
inline unsigned prng() {
static unsigned n = 0;
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
}
struct random_lfsr {
inline void seed(unsigned seed__) {
seed_ = seed__;
}
struct random_lfsr {
inline void seed(unsigned seed__) {
seed_ = seed__;
}
inline unsigned operator()() {
return seed_ = (seed_ >> 1) ^ (((seed_ & 1) - 1) & 0xedb88320);
}
inline unsigned operator()() {
return seed_ = (seed_ >> 1) ^ (((seed_ & 1) - 1) & 0xedb88320);
}
random_lfsr() : seed_(0) {
}
random_lfsr() : seed_(0) {
}
private:
unsigned seed_;
};
private:
unsigned seed_;
};
}
#endif

View File

@ -1,110 +1,118 @@
#ifndef NALL_SERIAL_HPP
#define NALL_SERIAL_HPP
#include <nall/intrinsics.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#if !defined(PLATFORM_X) && !defined(PLATFORM_OSX)
#error "nall/serial: unsupported platform"
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <nall/stdint.hpp>
namespace nall {
struct serial {
bool readable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
struct serial {
bool readable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
}
//-1 on error, otherwise return bytes read
int read(uint8_t* data, unsigned length) {
if(port_open == false) return -1;
return ::read(port, (void*)data, length);
}
bool writable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, nullptr, &fdset, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
}
//-1 on error, otherwise return bytes written
int write(const uint8_t* data, unsigned length) {
if(port_open == false) return -1;
return ::write(port, (void*)data, length);
}
bool open(const string& portname, unsigned rate, bool flowcontrol) {
close();
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if(port == -1) return false;
if(ioctl(port, TIOCEXCL) == -1) { close(); return false; }
if(fcntl(port, F_SETFL, 0) == -1) { close(); return false; }
if(tcgetattr(port, &original_attr) == -1) { close(); return false; }
termios attr = original_attr;
cfmakeraw(&attr);
cfsetspeed(&attr, rate);
attr.c_lflag &=~ (ECHO | ECHONL | ISIG | ICANON | IEXTEN);
attr.c_iflag &=~ (BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
attr.c_iflag |= (IGNBRK | IGNPAR);
attr.c_oflag &=~ (OPOST);
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB | CLOCAL);
attr.c_cflag |= (CS8 | CREAD);
if(flowcontrol == false) {
attr.c_cflag &= ~CRTSCTS;
} else {
attr.c_cflag |= CRTSCTS;
}
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0;
//-1 on error, otherwise return bytes read
int read(uint8_t *data, unsigned length) {
if(port_open == false) return -1;
return ::read(port, (void*)data, length);
}
if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
return port_open = true;
}
bool writable() {
if(port_open == false) return false;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(port, &fdset);
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int result = select(FD_SETSIZE, nullptr, &fdset, nullptr, &timeout);
if(result < 1) return false;
return FD_ISSET(port, &fdset);
}
//-1 on error, otherwise return bytes written
int write(const uint8_t *data, unsigned length) {
if(port_open == false) return -1;
return ::write(port, (void*)data, length);
}
bool open(const char *portname, unsigned rate, bool flowcontrol) {
close();
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if(port == -1) return false;
if(ioctl(port, TIOCEXCL) == -1) { close(); return false; }
if(fcntl(port, F_SETFL, 0) == -1) { close(); return false; }
if(tcgetattr(port, &original_attr) == -1) { close(); return false; }
termios attr = original_attr;
cfmakeraw(&attr);
cfsetspeed(&attr, rate);
attr.c_lflag &=~ (ECHO | ECHONL | ISIG | ICANON | IEXTEN);
attr.c_iflag &=~ (BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
attr.c_iflag |= (IGNBRK | IGNPAR);
attr.c_oflag &=~ (OPOST);
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB | CLOCAL);
attr.c_cflag |= (CS8 | CREAD);
if(flowcontrol == false) {
attr.c_cflag &= ~CRTSCTS;
} else {
attr.c_cflag |= CRTSCTS;
void close() {
if(port != -1) {
tcdrain(port);
if(port_open == true) {
tcsetattr(port, TCSANOW, &original_attr);
port_open = false;
}
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0;
if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
return port_open = true;
}
void close() {
if(port != -1) {
tcdrain(port);
if(port_open == true) {
tcsetattr(port, TCSANOW, &original_attr);
port_open = false;
}
::close(port);
port = -1;
}
}
serial() {
::close(port);
port = -1;
port_open = false;
}
}
~serial() {
close();
}
serial() {
port = -1;
port_open = false;
}
~serial() {
close();
}
private:
int port;
bool port_open;
termios original_attr;
};
private:
int port;
bool port_open;
termios original_attr;
};
}
#endif

View File

@ -1,145 +1,141 @@
#ifndef NALL_SERIALIZER_HPP
#define NALL_SERIALIZER_HPP
//serializer: a class designed to save and restore the state of classes.
//
//benefits:
//- data() will be portable in size (it is not necessary to specify type sizes.)
//- data() will be portable in endianness (always stored internally as little-endian.)
//- one serialize function can both save and restore class states.
//
//caveats:
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
//- floating-point usage is not portable across platforms
#include <type_traits>
#include <utility>
#include <nall/stdint.hpp>
#include <nall/utility.hpp>
namespace nall {
//serializer: a class designed to save and restore the state of classes.
//
//benefits:
//- data() will be portable in size (it is not necessary to specify type sizes.)
//- data() will be portable in endianness (always stored internally as little-endian.)
//- one serialize function can both save and restore class states.
//
//caveats:
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
//- floating-point usage is not portable across platforms
class serializer {
public:
enum mode_t { Load, Save, Size };
struct serializer {
enum mode_t { Load, Save, Size };
mode_t mode() const {
return imode;
mode_t mode() const {
return imode;
}
const uint8_t* data() const {
return idata;
}
unsigned size() const {
return isize;
}
unsigned capacity() const {
return icapacity;
}
template<typename T> void floatingpoint(T& value) {
enum { size = sizeof(T) };
//this is rather dangerous, and not cross-platform safe;
//but there is no standardized way to export FP-values
uint8_t* p = (uint8_t*)&value;
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = p[n];
} else if(imode == Load) {
for(unsigned n = 0; n < size; n++) p[n] = idata[isize++];
} else {
isize += size;
}
}
const uint8_t* data() const {
return idata;
template<typename T> void integer(T& value) {
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = (uintmax_t)value >> (n << 3);
} else if(imode == Load) {
value = 0;
for(unsigned n = 0; n < size; n++) value |= (uintmax_t)idata[isize++] << (n << 3);
} else if(imode == Size) {
isize += size;
}
}
unsigned size() const {
return isize;
}
template<typename T> void array(T& array) {
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
unsigned capacity() const {
return icapacity;
}
template<typename T> void array(T array, unsigned size) {
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
template<typename T> void floatingpoint(T &value) {
enum { size = sizeof(T) };
//this is rather dangerous, and not cross-platform safe;
//but there is no standardized way to export FP-values
uint8_t *p = (uint8_t*)&value;
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = p[n];
} else if(imode == Load) {
for(unsigned n = 0; n < size; n++) p[n] = idata[isize++];
} else {
isize += size;
}
}
//copy
serializer& operator=(const serializer& s) {
if(idata) delete[] idata;
template<typename T> void integer(T &value) {
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = (uintmax_t)value >> (n << 3);
} else if(imode == Load) {
value = 0;
for(unsigned n = 0; n < size; n++) value |= (uintmax_t)idata[isize++] << (n << 3);
} else if(imode == Size) {
isize += size;
}
}
imode = s.imode;
idata = new uint8_t[s.icapacity];
isize = s.isize;
icapacity = s.icapacity;
template<typename T> void array(T &array) {
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
memcpy(idata, s.idata, s.icapacity);
return *this;
}
template<typename T> void array(T array, unsigned size) {
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
serializer(const serializer& s) {
operator=(s);
}
//copy
serializer& operator=(const serializer &s) {
if(idata) delete[] idata;
//move
serializer& operator=(serializer&& s) {
if(idata) delete[] idata;
imode = s.imode;
idata = new uint8_t[s.icapacity];
isize = s.isize;
icapacity = s.icapacity;
imode = s.imode;
idata = s.idata;
isize = s.isize;
icapacity = s.icapacity;
memcpy(idata, s.idata, s.icapacity);
return *this;
}
s.idata = nullptr;
return *this;
}
serializer(const serializer &s) : idata(nullptr) {
operator=(s);
}
serializer(serializer&& s) {
operator=(std::move(s));
}
//move
serializer& operator=(serializer &&s) {
if(idata) delete[] idata;
//construction
serializer() = default;
imode = s.imode;
idata = s.idata;
isize = s.isize;
icapacity = s.icapacity;
serializer(unsigned capacity) {
imode = Save;
idata = new uint8_t[capacity]();
isize = 0;
icapacity = capacity;
}
s.idata = nullptr;
return *this;
}
serializer(const uint8_t* data, unsigned capacity) {
imode = Load;
idata = new uint8_t[capacity];
isize = 0;
icapacity = capacity;
memcpy(idata, data, capacity);
}
serializer(serializer &&s) {
operator=(std::move(s));
}
//destruction
~serializer() {
if(idata) delete[] idata;
}
//construction
serializer() {
imode = Size;
idata = nullptr;
isize = 0;
icapacity = 0;
}
serializer(unsigned capacity) {
imode = Save;
idata = new uint8_t[capacity]();
isize = 0;
icapacity = capacity;
}
serializer(const uint8_t *data, unsigned capacity) {
imode = Load;
idata = new uint8_t[capacity];
isize = 0;
icapacity = capacity;
memcpy(idata, data, capacity);
}
~serializer() {
if(idata) delete[] idata;
}
private:
mode_t imode;
uint8_t *idata;
unsigned isize;
unsigned icapacity;
};
private:
mode_t imode = Size;
uint8_t* idata = nullptr;
unsigned isize = 0;
unsigned icapacity = 0;
};
};

258
higan/nall/set.hpp Normal file
View File

@ -0,0 +1,258 @@
#ifndef NALL_SET_HPP
#define NALL_SET_HPP
//set
//implementation: red-black tree
//search: O(log n) average; O(log n) worst
//insert: O(log n) average; O(log n) worst
//remove: O(log n) average; O(log n) worst
#include <nall/utility.hpp>
#include <nall/vector.hpp>
namespace nall {
template<typename T> struct set {
struct node_t {
T value;
bool red = 1;
node_t* link[2] = {nullptr, nullptr};
node_t() = default;
node_t(const T& value) : value(value) {}
};
node_t* root = nullptr;
unsigned nodes = 0;
set& operator=(const set& source) { copy(source); return *this; }
set& operator=(set&& source) { move(std::move(source)); return *this; }
set(const set& source) { operator=(source); }
set(set&& source) { operator=(std::move(source)); }
set(std::initializer_list<T> list) { for(auto& value : list) insert(value); }
set() = default;
~set() { reset(); }
unsigned size() const { return nodes; }
bool empty() const { return nodes == 0; }
void reset() {
reset(root);
nodes = 0;
}
optional<T&> find(const T& value) {
if(node_t* node = find(root, value)) return node->value;
return false;
}
optional<const T&> find(const T& value) const {
if(node_t* node = find(root, value)) return node->value;
return false;
}
bool insert(const T& value) {
unsigned count = size();
insert(root, value);
root->red = 0;
return size() > count;
}
template<typename... Args> bool insert(const T& value, Args&&... args) {
bool result = insert(value);
return insert(std::forward<Args>(args)...) | result;
}
bool remove(const T& value) {
unsigned count = size();
bool done = 0;
remove(root, &value, done);
if(root) root->red = 0;
return size() < count;
}
template<typename... Args> bool remove(const T& value, Args&&... args) {
bool result = remove(value);
return remove(std::forward<Args>(args)...) | result;
}
struct base_iterator {
bool operator!=(const base_iterator& source) const { return position != source.position; }
base_iterator& operator++() {
if(++position >= source.size()) { position = source.size(); return *this; }
if(stack.last()->link[1]) {
stack.append(stack.last()->link[1]);
while(stack.last()->link[0]) stack.append(stack.last()->link[0]);
} else {
node_t* child;
do child = stack.take();
while(child == stack.last()->link[1]);
}
return *this;
}
base_iterator(const set& source, unsigned position) : source(source), position(position) {
node_t* node = source.root;
while(node) {
stack.append(node);
node = node->link[0];
}
}
protected:
const set& source;
unsigned position;
vector<node_t*> stack;
};
struct iterator : base_iterator {
T& operator*() const { return base_iterator::stack.last()->value; }
iterator(const set& source, unsigned position) : base_iterator(source, position) {}
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, size()); }
struct const_iterator : base_iterator {
const T& operator*() const { return base_iterator::stack.last()->value; }
const_iterator(const set& source, unsigned position) : base_iterator(source, position) {}
};
const const_iterator begin() const { return const_iterator(*this, 0); }
const const_iterator end() const { return const_iterator(*this, size()); }
private:
void reset(node_t*& node) {
if(!node) return;
if(node->link[0]) reset(node->link[0]);
if(node->link[1]) reset(node->link[1]);
delete node;
node = nullptr;
}
void copy(const set& source) {
reset();
copy(root, source.root);
nodes = source.nodes;
}
void copy(node_t*& target, const node_t* source) {
if(!source) return;
target = new node_t(source->value);
target->red = source->red;
copy(target->link[0], source->link[0]);
copy(target->link[1], source->link[1]);
}
void move(set&& source) {
root = source.root;
nodes = source.nodes;
source.root = nullptr;
source.nodes = 0;
}
node_t* find(node_t* node, const T& value) const {
if(node == nullptr) return nullptr;
if(node->value == value) return node;
return find(node->link[node->value < value], value);
}
bool red(node_t* node) const { return node && node->red; }
bool black(node_t* node) const { return !red(node); }
void rotate(node_t*& a, bool dir) {
node_t*& b = a->link[!dir];
node_t*& c = b->link[dir];
a->red = 1, b->red = 0;
std::swap(a, b);
std::swap(b, c);
}
void rotateTwice(node_t*& node, bool dir) {
rotate(node->link[!dir], !dir);
rotate(node, dir);
}
void insert(node_t*& node, const T& value) {
if(!node) { nodes++; node = new node_t(value); return; }
if(node->value == value) { node->value = value; return; } //prevent duplicate entries
bool dir = node->value < value;
insert(node->link[dir], value);
if(black(node->link[dir])) return;
if(red(node->link[!dir])) {
node->red = 1;
node->link[0]->red = 0;
node->link[1]->red = 0;
} else if(red(node->link[dir]->link[dir])) {
rotate(node, !dir);
} else if(red(node->link[dir]->link[!dir])) {
rotateTwice(node, !dir);
}
}
void balance(node_t*& node, bool dir, bool& done) {
node_t* p = node;
node_t* s = node->link[!dir];
if(!s) return;
if(red(s)) {
rotate(node, dir);
s = p->link[!dir];
}
if(black(s->link[0]) && black(s->link[1])) {
if(red(p)) done = 1;
p->red = 0, s->red = 1;
} else {
bool save = p->red;
bool head = node == p;
if(red(s->link[!dir])) rotate(p, dir);
else rotateTwice(p, dir);
p->red = save;
p->link[0]->red = 0;
p->link[1]->red = 0;
if(head) node = p;
else node->link[dir] = p;
done = 1;
}
}
void remove(node_t*& node, const T* value, bool& done) {
if(!node) { done = 1; return; }
if(node->value == *value) {
if(!node->link[0] || !node->link[1]) {
node_t* save = node->link[!node->link[0]];
if(red(node)) done = 1;
else if(red(save)) save->red = 0, done = 1;
nodes--;
delete node;
node = save;
return;
} else {
node_t* heir = node->link[0];
while(heir->link[1]) heir = heir->link[1];
node->value = heir->value;
value = &heir->value;
}
}
bool dir = node->value < *value;
remove(node->link[dir], value, done);
if(!done) balance(node, dir, done);
}
};
}
#endif

View File

@ -6,140 +6,142 @@
#include <nall/stdint.hpp>
namespace nall {
#define PTR(t, a) ((t*)(a))
#define SWAP32(x) ((uint32_t)( \
(((uint32_t)(x) & 0x000000ff) << 24) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0xff000000) >> 24) \
))
#define PTR(t, a) ((t*)(a))
#define ST32(a, d) *PTR(uint32_t, a) = (d)
#define ST32BE(a, d) ST32(a, SWAP32(d))
#define SWAP32(x) ((uint32_t)( \
(((uint32_t)(x) & 0x000000ff) << 24) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0xff000000) >> 24) \
))
#define LD32(a) *PTR(uint32_t, a)
#define LD32BE(a) SWAP32(LD32(a))
#define ST32(a, d) *PTR(uint32_t, a) = (d)
#define ST32BE(a, d) ST32(a, SWAP32(d))
#define LSL32(x, n) ((uint32_t)(x) << (n))
#define LSR32(x, n) ((uint32_t)(x) >> (n))
#define ROR32(x, n) (LSR32(x, n) | LSL32(x, 32 - (n)))
#define LD32(a) *PTR(uint32_t, a)
#define LD32BE(a) SWAP32(LD32(a))
//first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
static const uint32_t T_H[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
};
#define LSL32(x, n) ((uint32_t)(x) << (n))
#define LSR32(x, n) ((uint32_t)(x) >> (n))
#define ROR32(x, n) (LSR32(x, n) | LSL32(x, 32 - (n)))
//first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
static const uint32_t T_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
};
//first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
static const uint32_t T_H[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
};
struct sha256_ctx {
uint8_t in[64];
unsigned inlen;
//first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
static const uint32_t T_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
};
uint32_t w[64];
uint32_t h[8];
uint64_t len;
};
struct sha256_ctx {
uint8_t in[64];
unsigned inlen;
inline void sha256_init(sha256_ctx *p) {
memset(p, 0, sizeof(sha256_ctx));
memcpy(p->h, T_H, sizeof(T_H));
uint32_t w[64];
uint32_t h[8];
uint64_t len;
};
inline void sha256_init(sha256_ctx* p) {
memset(p, 0, sizeof(sha256_ctx));
memcpy(p->h, T_H, sizeof(T_H));
}
static void sha256_block(sha256_ctx* p) {
unsigned i;
uint32_t s0, s1;
uint32_t a, b, c, d, e, f, g, h;
uint32_t t1, t2, maj, ch;
for(i = 0; i < 16; i++) p->w[i] = LD32BE(p->in + i * 4);
for(i = 16; i < 64; i++) {
s0 = ROR32(p->w[i - 15], 7) ^ ROR32(p->w[i - 15], 18) ^ LSR32(p->w[i - 15], 3);
s1 = ROR32(p->w[i - 2], 17) ^ ROR32(p->w[i - 2], 19) ^ LSR32(p->w[i - 2], 10);
p->w[i] = p->w[i - 16] + s0 + p->w[i - 7] + s1;
}
static void sha256_block(sha256_ctx *p) {
unsigned i;
uint32_t s0, s1;
uint32_t a, b, c, d, e, f, g, h;
uint32_t t1, t2, maj, ch;
a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
for(i = 0; i < 16; i++) p->w[i] = LD32BE(p->in + i * 4);
for(i = 0; i < 64; i++) {
s0 = ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22);
maj = (a & b) ^ (a & c) ^ (b & c);
t2 = s0 + maj;
s1 = ROR32(e, 6) ^ ROR32(e, 11) ^ ROR32(e, 25);
ch = (e & f) ^ (~e & g);
t1 = h + s1 + ch + T_K[i] + p->w[i];
for(i = 16; i < 64; i++) {
s0 = ROR32(p->w[i - 15], 7) ^ ROR32(p->w[i - 15], 18) ^ LSR32(p->w[i - 15], 3);
s1 = ROR32(p->w[i - 2], 17) ^ ROR32(p->w[i - 2], 19) ^ LSR32(p->w[i - 2], 10);
p->w[i] = p->w[i - 16] + s0 + p->w[i - 7] + s1;
}
a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
for(i = 0; i < 64; i++) {
s0 = ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22);
maj = (a & b) ^ (a & c) ^ (b & c);
t2 = s0 + maj;
s1 = ROR32(e, 6) ^ ROR32(e, 11) ^ ROR32(e, 25);
ch = (e & f) ^ (~e & g);
t1 = h + s1 + ch + T_K[i] + p->w[i];
h = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
p->h[0] += a; p->h[1] += b; p->h[2] += c; p->h[3] += d;
p->h[4] += e; p->h[5] += f; p->h[6] += g; p->h[7] += h;
//next block
p->inlen = 0;
h = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
inline void sha256_chunk(sha256_ctx *p, const uint8_t *s, unsigned len) {
unsigned l;
p->len += len;
p->h[0] += a; p->h[1] += b; p->h[2] += c; p->h[3] += d;
p->h[4] += e; p->h[5] += f; p->h[6] += g; p->h[7] += h;
while(len) {
l = 64 - p->inlen;
l = (len < l) ? len : l;
//next block
p->inlen = 0;
}
memcpy(p->in + p->inlen, s, l);
s += l;
p->inlen += l;
len -= l;
inline void sha256_chunk(sha256_ctx* p, const uint8_t* s, unsigned len) {
unsigned l;
p->len += len;
if(p->inlen == 64) sha256_block(p);
}
while(len) {
l = 64 - p->inlen;
l = (len < l) ? len : l;
memcpy(p->in + p->inlen, s, l);
s += l;
p->inlen += l;
len -= l;
if(p->inlen == 64) sha256_block(p);
}
}
inline void sha256_final(sha256_ctx *p) {
uint64_t len;
p->in[p->inlen++] = 0x80;
inline void sha256_final(sha256_ctx* p) {
uint64_t len;
p->in[p->inlen++] = 0x80;
if(p->inlen > 56) {
memset(p->in + p->inlen, 0, 64 - p->inlen);
sha256_block(p);
}
memset(p->in + p->inlen, 0, 56 - p->inlen);
len = p->len << 3;
ST32BE(p->in + 56, len >> 32);
ST32BE(p->in + 60, len);
if(p->inlen > 56) {
memset(p->in + p->inlen, 0, 64 - p->inlen);
sha256_block(p);
}
inline void sha256_hash(sha256_ctx *p, uint8_t *s) {
uint32_t *t = (uint32_t*)s;
for(unsigned i = 0; i < 8; i++) ST32BE(t++, p->h[i]);
}
memset(p->in + p->inlen, 0, 56 - p->inlen);
len = p->len << 3;
ST32BE(p->in + 56, len >> 32);
ST32BE(p->in + 60, len);
sha256_block(p);
}
inline void sha256_hash(sha256_ctx* p, uint8_t* s) {
uint32_t *t = (uint32_t*)s;
for(unsigned i = 0; i < 8; i++) ST32BE(t++, p->h[i]);
}
#undef PTR
#undef SWAP32
#undef ST32
#undef ST32BE
#undef LD32
#undef LD32BE
#undef LSL32
#undef LSR32
#undef ROR32
#undef PTR
#undef SWAP32
#undef ST32
#undef ST32BE
#undef LD32
#undef LD32BE
#undef LSL32
#undef LSR32
#undef ROR32
}
#endif

View File

@ -19,59 +19,59 @@
//#define NALL_SORT_SELECTION
namespace nall {
template<typename T, typename Comparator>
void sort(T list[], unsigned size, const Comparator &lessthan) {
if(size <= 1) return; //nothing to sort
//use insertion sort to quickly sort smaller blocks
if(size < 64) {
#if defined(NALL_SORT_INSERTION)
for(signed i = 1, j; i < size; i++) {
T copy = std::move(list[i]);
for(j = i - 1; j >= 0; j--) {
if(!lessthan(copy, list[j])) break;
list[j + 1] = std::move(list[j]);
}
list[j + 1] = std::move(copy);
template<typename T, typename Comparator> void sort(T list[], unsigned size, const Comparator& lessthan) {
if(size <= 1) return; //nothing to sort
//use insertion sort to quickly sort smaller blocks
if(size < 64) {
#if defined(NALL_SORT_INSERTION)
for(signed i = 1, j; i < size; i++) {
T copy = std::move(list[i]);
for(j = i - 1; j >= 0; j--) {
if(!lessthan(copy, list[j])) break;
list[j + 1] = std::move(list[j]);
}
#elif defined(NALL_SORT_SELECTION)
for(unsigned i = 0; i < size; i++) {
unsigned min = i;
for(unsigned j = i + 1; j < size; j++) {
if(lessthan(list[j], list[min])) min = j;
}
if(min != i) std::swap(list[i], list[min]);
}
#endif
return;
list[j + 1] = std::move(copy);
}
//split list in half and recursively sort both
unsigned middle = size / 2;
sort(list, middle, lessthan);
sort(list + middle, size - middle, lessthan);
//left and right are sorted here; perform merge sort
T *buffer = new T[size];
unsigned offset = 0, left = 0, right = middle;
while(left < middle && right < size) {
if(!lessthan(list[right], list[left])) {
buffer[offset++] = std::move(list[left++]);
} else {
buffer[offset++] = std::move(list[right++]);
#elif defined(NALL_SORT_SELECTION)
for(unsigned i = 0; i < size; i++) {
unsigned min = i;
for(unsigned j = i + 1; j < size; j++) {
if(lessthan(list[j], list[min])) min = j;
}
if(min != i) std::swap(list[i], list[min]);
}
while(left < middle) buffer[offset++] = std::move(list[left++]);
while(right < size) buffer[offset++] = std::move(list[right++]);
for(unsigned i = 0; i < size; i++) list[i] = std::move(buffer[i]);
delete[] buffer;
#endif
return;
}
template<typename T>
void sort(T list[], unsigned size) {
return sort(list, size, [](const T &l, const T &r) { return l < r; });
//split list in half and recursively sort both
unsigned middle = size / 2;
sort(list, middle, lessthan);
sort(list + middle, size - middle, lessthan);
//left and right are sorted here; perform merge sort
T* buffer = new T[size];
unsigned offset = 0, left = 0, right = middle;
while(left < middle && right < size) {
if(!lessthan(list[right], list[left])) {
buffer[offset++] = std::move(list[left++]);
} else {
buffer[offset++] = std::move(list[right++]);
}
}
while(left < middle) buffer[offset++] = std::move(list[left++]);
while(right < size) buffer[offset++] = std::move(list[right++]);
for(unsigned i = 0; i < size; i++) list[i] = std::move(buffer[i]);
delete[] buffer;
}
template<typename T> void sort(T list[], unsigned size) {
return sort(list, size, [](const T& l, const T& r) { return l < r; });
}
}
#endif

View File

@ -28,15 +28,17 @@
#endif
namespace nall {
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");
static_assert(sizeof(uint8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(uint16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(uint32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(uint64_t) == 8, "int64_t is not of the correct size");
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");
static_assert(sizeof(uint8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(uint16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(uint32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(uint64_t) == 8, "int64_t is not of the correct size");
}
#endif

View File

@ -5,18 +5,18 @@ namespace nall {
#define autostream(...) (*makestream(__VA_ARGS__))
inline std::unique_ptr<stream> makestream(const string &path) {
inline std::unique_ptr<stream> makestream(const string& path) {
if(path.ibeginswith("http://")) return std::unique_ptr<stream>(new httpstream(path, 80));
if(path.iendswith(".gz")) return std::unique_ptr<stream>(new gzipstream(filestream{path}));
if(path.iendswith(".zip")) return std::unique_ptr<stream>(new zipstream(filestream{path}));
return std::unique_ptr<stream>(new mmapstream(path));
}
inline std::unique_ptr<stream> makestream(uint8_t *data, unsigned size) {
inline std::unique_ptr<stream> makestream(uint8_t* data, unsigned size) {
return std::unique_ptr<stream>(new memorystream(data, size));
}
inline std::unique_ptr<stream> makestream(const uint8_t *data, unsigned size) {
inline std::unique_ptr<stream> makestream(const uint8_t* data, unsigned size) {
return std::unique_ptr<stream>(new memorystream(data, size));
}

View File

@ -21,13 +21,13 @@ struct filestream : stream {
uint8_t read() const { return pfile.read(); }
void write(uint8_t data) const { pfile.write(data); }
filestream(const string &filename) {
filestream(const string& filename) {
pfile.open(filename, file::mode::readwrite);
pwritable = pfile.open();
if(!pwritable) pfile.open(filename, file::mode::read);
}
filestream(const string &filename, file::mode mode) {
filestream(const string& filename, file::mode mode) {
pfile.open(filename, mode);
pwritable = mode == file::mode::write || mode == file::mode::readwrite;
}

View File

@ -9,7 +9,7 @@ struct gzipstream : memorystream {
using stream::read;
using stream::write;
gzipstream(const stream &stream) {
gzipstream(const stream& stream) {
unsigned size = stream.size();
uint8_t *data = new uint8_t[size];
stream.read(data, size);

View File

@ -24,7 +24,7 @@ struct httpstream : stream {
uint8_t read(unsigned offset) const { return pdata[offset]; }
void write(unsigned offset, uint8_t data) const { pdata[offset] = data; }
httpstream(const string &url, unsigned port) : pdata(nullptr), psize(0), poffset(0) {
httpstream(const string& url, unsigned port) : pdata(nullptr), psize(0), poffset(0) {
string uri = url;
uri.ltrim<1>("http://");
lstring part = uri.split<1>("/");
@ -40,7 +40,7 @@ struct httpstream : stream {
}
private:
mutable uint8_t *pdata;
mutable uint8_t* pdata;
mutable unsigned psize, poffset;
};

View File

@ -14,7 +14,7 @@ struct memorystream : stream {
bool writable() const { return pwritable; }
bool randomaccess() const { return true; }
uint8_t *data() const { return pdata; }
uint8_t* data() const { return pdata; }
unsigned size() const { return psize; }
unsigned offset() const { return poffset; }
void seek(unsigned offset) const { poffset = offset; }
@ -27,18 +27,18 @@ struct memorystream : stream {
memorystream() : pdata(nullptr), psize(0), poffset(0), pwritable(true) {}
memorystream(uint8_t *data, unsigned size) {
memorystream(uint8_t* data, unsigned size) {
pdata = data, psize = size, poffset = 0;
pwritable = true;
}
memorystream(const uint8_t *data, unsigned size) {
memorystream(const uint8_t* data, unsigned size) {
pdata = (uint8_t*)data, psize = size, poffset = 0;
pwritable = false;
}
protected:
mutable uint8_t *pdata;
mutable uint8_t* pdata;
mutable unsigned psize, poffset, pwritable;
};

View File

@ -24,7 +24,7 @@ struct mmapstream : stream {
uint8_t read(unsigned offset) const { return pdata[offset]; }
void write(unsigned offset, uint8_t data) const { pdata[offset] = data; }
mmapstream(const string &filename) {
mmapstream(const string& filename) {
pmmap.open(filename, filemap::mode::readwrite);
pwritable = pmmap.open();
if(!pwritable) pmmap.open(filename, filemap::mode::read);
@ -33,7 +33,7 @@ struct mmapstream : stream {
private:
mutable filemap pmmap;
mutable uint8_t *pdata;
mutable uint8_t* pdata;
mutable unsigned pwritable, poffset;
};

View File

@ -44,7 +44,7 @@ struct stream {
return data;
}
void read(uint8_t *data, unsigned length) const {
void read(uint8_t* data, unsigned length) const {
while(length--) *data++ = read();
}
@ -72,17 +72,17 @@ struct stream {
}
}
void write(const uint8_t *data, unsigned length) const {
void write(const uint8_t* data, unsigned length) const {
while(length--) write(*data++);
}
struct byte {
operator uint8_t() const { return s.read(offset); }
byte& operator=(uint8_t data) { s.write(offset, data); return *this; }
byte(const stream &s, unsigned offset) : s(s), offset(offset) {}
byte(const stream& s, unsigned offset) : s(s), offset(offset) {}
private:
const stream &s;
const stream& s;
const unsigned offset;
};

View File

@ -26,11 +26,11 @@ struct vectorstream : stream {
uint8_t read(unsigned offset) const { return memory[offset]; }
void write(unsigned offset, uint8_t data) const { memory[offset] = data; }
vectorstream(vector<uint8_t> &memory) : memory(memory), poffset(0), pwritable(true) {}
vectorstream(const vector<uint8_t> &memory) : memory((vector<uint8_t>&)memory), poffset(0), pwritable(false) {}
vectorstream(vector<uint8_t>& memory) : memory(memory), poffset(0), pwritable(true) {}
vectorstream(const vector<uint8_t>& memory) : memory((vector<uint8_t>&)memory), poffset(0), pwritable(false) {}
protected:
vector<uint8_t> &memory;
vector<uint8_t>& memory;
mutable unsigned poffset, pwritable;
};

View File

@ -9,16 +9,16 @@ struct zipstream : memorystream {
using stream::read;
using stream::write;
zipstream(const stream &stream, const string &filter = "*") {
zipstream(const stream& stream, const string& filter = "*") {
unsigned size = stream.size();
uint8_t *data = new uint8_t[size];
uint8_t* data = new uint8_t[size];
stream.read(data, size);
unzip archive;
if(archive.open(data, size) == false) return;
delete[] data;
for(auto &file : archive.file) {
for(auto& file : archive.file) {
if(file.name.wildcard(filter)) {
auto buffer = archive.extract(file);
psize = buffer.size();

View File

@ -11,19 +11,18 @@ namespace nall {
inline unsigned length() const;
inline bool operator==(const char*) const;
inline bool operator!=(const char*) const;
inline optional<unsigned> position(const char *key) const;
inline optional<unsigned> iposition(const char *key) const;
inline cstring& operator=(const char *data);
inline cstring(const char *data);
inline optional<unsigned> position(const char* key) const;
inline optional<unsigned> iposition(const char* key) const;
inline cstring& operator=(const char* data);
inline cstring(const char* data);
inline cstring();
protected:
const char *data;
const char* data;
};
struct string {
//deprecated: use string text = file::read(filename);
inline static string read(const string &filename);
inline static string read(const string& filename);
inline static string date();
inline static string time();
@ -68,18 +67,18 @@ namespace nall {
inline string& upper();
inline string& qlower();
inline string& qupper();
inline string& transform(const char *before, const char *after);
inline string& transform(const char* before, const char* after);
inline string& reverse();
template<unsigned limit = 0> inline string& ltrim(const char *key = " ");
template<unsigned limit = 0> inline string& rtrim(const char *key = " ");
template<unsigned limit = 0> inline string& trim(const char *key = " ", const char *rkey = nullptr);
template<unsigned limit = 0> inline string& ltrim(const char* key = " ");
template<unsigned limit = 0> inline string& rtrim(const char* key = " ");
template<unsigned limit = 0> inline string& trim(const char* key = " ", const char* rkey = nullptr);
inline string& strip();
inline optional<unsigned> position(const char *key) const;
inline optional<unsigned> iposition(const char *key) const;
inline optional<unsigned> qposition(const char *key) const;
inline optional<unsigned> iqposition(const char *key) const;
inline optional<unsigned> position(const char* key) const;
inline optional<unsigned> iposition(const char* key) const;
inline optional<unsigned> qposition(const char* key) const;
inline optional<unsigned> iqposition(const char* key) const;
inline explicit operator bool() const;
inline operator const char*() const;
@ -111,7 +110,7 @@ namespace nall {
inline string& append_(const char*);
protected:
char *data;
char* data;
unsigned size;
template<unsigned Limit, bool Insensitive, bool Quoted> inline string& ureplace(const char*, const char*);
@ -125,8 +124,9 @@ namespace nall {
struct lstring : vector<string> {
inline optional<unsigned> find(const char*) const;
inline string concatenate(const char*) const;
inline lstring& isort();
inline lstring& strip();
inline void append() {}
inline void isort();
template<typename... Args> inline void append(const string&, Args&&...);
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);
@ -153,81 +153,81 @@ namespace nall {
//compare.hpp
inline char chrlower(char c);
inline char chrupper(char c);
inline int istrcmp(const char *str1, const char *str2);
inline bool strbegin(const char *str, const char *key);
inline bool istrbegin(const char *str, const char *key);
inline bool strend(const char *str, const char *key);
inline bool istrend(const char *str, const char *key);
inline int istrcmp(const char* str1, const char* str2);
inline bool strbegin(const char* str, const char* key);
inline bool istrbegin(const char* str, const char* key);
inline bool strend(const char* str, const char* key);
inline bool istrend(const char* str, const char* key);
//convert.hpp
inline char* strlower(char *str);
inline char* strupper(char *str);
inline char* qstrlower(char *str);
inline char* qstrupper(char *str);
inline char* strtr(char *dest, const char *before, const char *after);
inline char* strlower(char* str);
inline char* strupper(char* str);
inline char* qstrlower(char* str);
inline char* qstrupper(char* str);
inline char* strtr(char* dest, const char* before, const char* after);
//format.hpp
template<signed precision = 0, char padchar = ' '> inline string format(const string &value);
template<signed precision = 0, char padchar = ' '> inline string format(const string& value);
template<signed precision = 0, char padchar = '0'> inline string hex(uintmax_t value);
template<signed precision = 0, char padchar = '0'> inline string octal(uintmax_t value);
template<signed precision = 0, char padchar = '0'> inline string binary(uintmax_t value);
//math.hpp
inline bool strint(const char *str, int &result);
inline bool strmath(const char *str, int &result);
inline bool strint(const char* str, int& result);
inline bool strmath(const char* str, int& result);
//platform.hpp
inline string activepath();
inline string realpath(const string &name);
inline string realpath(const string& name);
inline string userpath();
inline string configpath();
inline string sharedpath();
inline string temppath();
//strm.hpp
inline unsigned strmcpy(char *target, const char *source, unsigned length);
inline unsigned strmcat(char *target, const char *source, unsigned length);
inline bool strccpy(char *target, const char *source, unsigned length);
inline bool strccat(char *target, const char *source, unsigned length);
inline void strpcpy(char *&target, const char *source, unsigned &length);
inline unsigned strmcpy(char* target, const char* source, unsigned length);
inline unsigned strmcat(char* target, const char* source, unsigned length);
inline bool strccpy(char* target, const char* source, unsigned length);
inline bool strccat(char* target, const char* source, unsigned length);
inline void strpcpy(char*& target, const char* source, unsigned& length);
//strpos.hpp
inline optional<unsigned> strpos(const char *str, const char *key);
inline optional<unsigned> istrpos(const char *str, const char *key);
inline optional<unsigned> qstrpos(const char *str, const char *key);
inline optional<unsigned> iqstrpos(const char *str, const char *key);
template<bool Insensitive = false, bool Quoted = false> inline optional<unsigned> ustrpos(const char *str, const char *key);
inline optional<unsigned> strpos(const char* str, const char* key);
inline optional<unsigned> istrpos(const char* str, const char* key);
inline optional<unsigned> qstrpos(const char* str, const char* key);
inline optional<unsigned> iqstrpos(const char* str, const char* key);
template<bool Insensitive = false, bool Quoted = false> inline optional<unsigned> ustrpos(const char* str, const char* key);
//trim.hpp
template<unsigned limit = 0> inline char* ltrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* rtrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* trim(char *str, const char *key = " ", const char *rkey = nullptr);
inline char* strip(char *s);
template<unsigned limit = 0> inline char* ltrim(char* str, const char* key = " ");
template<unsigned limit = 0> inline char* rtrim(char* str, const char* key = " ");
template<unsigned limit = 0> inline char* trim(char* str, const char* key = " ", const char* rkey = nullptr);
inline char* strip(char* s);
//utility.hpp
template<bool Insensitive> alwaysinline bool chrequal(char x, char y);
template<bool Quoted, typename T> alwaysinline bool quoteskip(T *&p);
template<bool Quoted, typename T> alwaysinline bool quotecopy(char *&t, T *&p);
inline string substr(const char *src, unsigned start = 0, unsigned length = ~0u);
inline string sha256(const uint8_t *data, unsigned size);
template<bool Quoted, typename T> alwaysinline bool quoteskip(T*& p);
template<bool Quoted, typename T> alwaysinline bool quotecopy(char*& t, T*& p);
inline string substr(const char* src, unsigned start = 0, unsigned length = ~0u);
inline string sha256(const uint8_t* data, unsigned size);
inline char* integer(char *result, intmax_t value);
inline char* decimal(char *result, uintmax_t value);
inline char* integer(char* result, intmax_t value);
inline char* decimal(char* result, uintmax_t value);
//these functions are deprecated, use format() instead:
template<unsigned length = 0, char padding = ' '> inline string integer(intmax_t value);
template<unsigned length = 0, char padding = ' '> inline string linteger(intmax_t value);
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
inline unsigned fp(char *str, long double value);
inline unsigned fp(char* str, long double value);
inline string fp(long double value);
//variadic.hpp
template<typename... Args> inline void print(Args&&... args);
//wildcard.hpp
inline bool wildcard(const char *str, const char *pattern);
inline bool iwildcard(const char *str, const char *pattern);
inline bool wildcard(const char* str, const char* pattern);
inline bool iwildcard(const char* str, const char* pattern);
};
#endif

View File

@ -6,7 +6,7 @@
namespace nall {
struct BSV {
static inline string decode(const char *input) {
static inline string decode(const char* input) {
string output;
unsigned offset = 0;
while(*input) {
@ -30,7 +30,7 @@ struct BSV {
return output;
}
static inline string encode(const char *input) {
static inline string encode(const char* input) {
string output;
unsigned offset = 0;
while(*input) {

View File

@ -119,7 +119,7 @@ template<> struct stringify<long double> {
// arrays
template<> struct stringify<vector<uint8_t>> {
char *text;
char* text;
operator const char*() const { return text; }
stringify(vector<uint8_t> value) {
text = new char[value.size() + 1]();
@ -131,9 +131,9 @@ template<> struct stringify<vector<uint8_t>> {
};
template<> struct stringify<const vector<uint8_t>&> {
char *text;
char* text;
operator const char*() const { return text; }
stringify(const vector<uint8_t> &value) {
stringify(const vector<uint8_t>& value) {
text = new char[value.size() + 1]();
memcpy(text, value.data(), value.size());
}
@ -145,53 +145,53 @@ template<> struct stringify<const vector<uint8_t>&> {
// strings
template<> struct stringify<char*> {
const char *value;
const char* value;
operator const char*() const { return value; }
stringify(char *value) : value(value) {}
stringify(char* value) : value(value) {}
};
template<> struct stringify<const char*> {
const char *value;
const char* value;
operator const char*() const { return value; }
stringify(const char *value) : value(value) {}
stringify(const char* value) : value(value) {}
};
template<> struct stringify<string> {
const string &value;
const string& value;
operator const char*() const { return value; }
stringify(const string &value) : value(value) {}
stringify(const string& value) : value(value) {}
};
template<> struct stringify<const string&> {
const string &value;
const string& value;
operator const char*() const { return value; }
stringify(const string &value) : value(value) {}
stringify(const string& value) : value(value) {}
};
template<> struct stringify<cstring> {
const char *value;
const char* value;
operator const char*() const { return value; }
stringify(const cstring &value) : value(value) {}
stringify(const cstring& value) : value(value) {}
};
template<> struct stringify<const cstring&> {
const char *value;
const char* value;
operator const char*() const { return value; }
stringify(const cstring &value) : value(value) {}
stringify(const cstring& value) : value(value) {}
};
#if defined(QSTRING_H)
template<> struct stringify<QString> {
const QString &value;
const QString& value;
operator const char*() const { return value.toUtf8().constData(); }
stringify(const QString &value) : value(value) {}
stringify(const QString& value) : value(value) {}
};
template<> struct stringify<const QString&> {
const QString &value;
const QString& value;
operator const char*() const { return value.toUtf8().constData(); }
stringify(const QString &value) : value(value) {}
stringify(const QString& value) : value(value) {}
};
string::operator QString() const {

View File

@ -10,7 +10,7 @@ char chrupper(char c) {
return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
}
int istrcmp(const char *str1, const char *str2) {
int istrcmp(const char* str1, const char* str2) {
while(*str1) {
if(chrlower(*str1) != chrlower(*str2)) break;
str1++, str2++;
@ -18,14 +18,14 @@ int istrcmp(const char *str1, const char *str2) {
return (int)chrlower(*str1) - (int)chrlower(*str2);
}
bool strbegin(const char *str, const char *key) {
bool strbegin(const char* str, const char* key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;
return (!memcmp(str, key, ksl));
}
bool istrbegin(const char *str, const char *key) {
bool istrbegin(const char* str, const char* key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;
@ -41,14 +41,14 @@ bool istrbegin(const char *str, const char *key) {
return true;
}
bool strend(const char *str, const char *key) {
bool strend(const char* str, const char* key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;
return (!memcmp(str + ssl - ksl, key, ksl));
}
bool istrend(const char *str, const char *key) {
bool istrend(const char* str, const char* key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;

View File

@ -2,7 +2,7 @@
namespace nall {
char* strlower(char *str) {
char* strlower(char* str) {
if(!str) return nullptr;
int i = 0;
while(str[i]) {
@ -12,7 +12,7 @@ char* strlower(char *str) {
return str;
}
char* strupper(char *str) {
char* strupper(char* str) {
if(!str) return nullptr;
int i = 0;
while(str[i]) {
@ -22,7 +22,7 @@ char* strupper(char *str) {
return str;
}
char* qstrlower(char *s) {
char* qstrlower(char* s) {
if(!s) return nullptr;
bool quoted = false;
while(*s) {
@ -32,7 +32,7 @@ char* qstrlower(char *s) {
}
}
char* qstrupper(char *s) {
char* qstrupper(char* s) {
if(!s) return nullptr;
bool quoted = false;
while(*s) {
@ -42,7 +42,7 @@ char* qstrupper(char *s) {
}
}
char* strtr(char *dest, const char *before, const char *after) {
char* strtr(char* dest, const char* before, const char* after) {
if(!dest || !before || !after) return dest;
int sl = strlen(dest), bsl = strlen(before), asl = strlen(after);

View File

@ -6,7 +6,7 @@ static void istring(string &output) {
}
template<typename T, typename... Args>
static void istring(string &output, const T &value, Args&&... args) {
static void istring(string& output, const T& value, Args&&... args) {
output.append_(make_string(value));
istring(output, std::forward<Args>(args)...);
}
@ -46,14 +46,14 @@ template<typename... Args> string& string::append(Args&&... args) {
return *this;
}
string& string::assign_(const char *s) {
string& string::assign_(const char* s) {
unsigned length = strlen(s);
reserve(length);
strcpy(data, s);
return *this;
}
string& string::append_(const char *s) {
string& string::append_(const char* s) {
unsigned length = strlen(data) + strlen(s);
reserve(length);
strcat(data, s);
@ -77,20 +77,20 @@ char& string::operator[](int index) {
return data[index];
}
bool string::operator==(const char *str) const { return strcmp(data, str) == 0; }
bool string::operator!=(const char *str) const { return strcmp(data, str) != 0; }
bool string::operator< (const char *str) const { return strcmp(data, str) < 0; }
bool string::operator<=(const char *str) const { return strcmp(data, str) <= 0; }
bool string::operator> (const char *str) const { return strcmp(data, str) > 0; }
bool string::operator>=(const char *str) const { return strcmp(data, str) >= 0; }
bool string::operator==(const char* str) const { return strcmp(data, str) == 0; }
bool string::operator!=(const char* str) const { return strcmp(data, str) != 0; }
bool string::operator< (const char* str) const { return strcmp(data, str) < 0; }
bool string::operator<=(const char* str) const { return strcmp(data, str) <= 0; }
bool string::operator> (const char* str) const { return strcmp(data, str) > 0; }
bool string::operator>=(const char* str) const { return strcmp(data, str) >= 0; }
string& string::operator=(const string &value) {
string& string::operator=(const string& value) {
if(&value == this) return *this;
assign(value);
return *this;
}
string& string::operator=(string &&source) {
string& string::operator=(string&& source) {
if(&source == this) return *this;
if(data) free(data);
size = source.size;
@ -107,13 +107,13 @@ template<typename... Args> string::string(Args&&... args) {
istring(*this, std::forward<Args>(args)...);
}
string::string(const string &value) {
string::string(const string& value) {
if(&value == this) return;
size = strlen(value);
data = strdup(value);
}
string::string(string &&source) {
string::string(string&& source) {
if(&source == this) return;
size = source.size;
data = source.data;
@ -124,7 +124,7 @@ string::~string() {
if(data) free(data);
}
bool string::readfile(const string &filename) {
bool string::readfile(const string& filename) {
assign("");
#if !defined(_WIN32)
@ -147,14 +147,14 @@ bool string::readfile(const string &filename) {
return true;
}
optional<unsigned> lstring::find(const char *key) const {
optional<unsigned> lstring::find(const char* key) const {
for(unsigned i = 0; i < size(); i++) {
if(operator[](i) == key) return { true, i };
}
return { false, 0 };
}
string lstring::concatenate(const char *separator) const {
string lstring::concatenate(const char* separator) const {
string output;
for(unsigned i = 0; i < size(); i++) {
output.append(operator[](i), i < size() - 1 ? separator : "");
@ -162,18 +162,26 @@ string lstring::concatenate(const char *separator) const {
return output;
}
template<typename... Args> void lstring::append(const string &data, Args&&... args) {
lstring& lstring::isort() {
nall::sort(pool, objectsize, [](const string& x, const string& y) {
return istrcmp(x, y) < 0;
});
return *this;
}
lstring& lstring::strip() {
for(unsigned n = 0; n < size(); n++) {
operator[](n).strip();
}
return *this;
}
template<typename... Args> void lstring::append(const string& data, Args&&... args) {
vector::append(data);
append(std::forward<Args>(args)...);
}
void lstring::isort() {
nall::sort(pool, objectsize, [](const string &x, const string &y) {
return istrcmp(x, y) < 0;
});
}
bool lstring::operator==(const lstring &source) const {
bool lstring::operator==(const lstring& source) const {
if(this == &source) return true;
if(size() != source.size()) return false;
for(unsigned n = 0; n < size(); n++) {
@ -182,21 +190,21 @@ bool lstring::operator==(const lstring &source) const {
return true;
}
bool lstring::operator!=(const lstring &source) const {
bool lstring::operator!=(const lstring& source) const {
return !operator==(source);
}
lstring& lstring::operator=(const lstring &source) {
lstring& lstring::operator=(const lstring& source) {
vector::operator=(source);
return *this;
}
lstring& lstring::operator=(lstring &source) {
lstring& lstring::operator=(lstring& source) {
vector::operator=(source);
return *this;
}
lstring& lstring::operator=(lstring &&source) {
lstring& lstring::operator=(lstring&& source) {
vector::operator=(std::move(source));
return *this;
}
@ -205,15 +213,15 @@ template<typename... Args> lstring::lstring(Args&&... args) {
append(std::forward<Args>(args)...);
}
lstring::lstring(const lstring &source) {
lstring::lstring(const lstring& source) {
vector::operator=(source);
}
lstring::lstring(lstring &source) {
lstring::lstring(lstring& source) {
vector::operator=(source);
}
lstring::lstring(lstring &&source) {
lstring::lstring(lstring&& source) {
vector::operator=(std::move(source));
}

View File

@ -8,12 +8,12 @@ namespace nall {
cstring::operator const char*() const { return data; }
unsigned cstring::length() const { return strlen(data); }
bool cstring::operator==(const char *s) const { return !strcmp(data, s); }
bool cstring::operator!=(const char *s) const { return strcmp(data, s); }
optional<unsigned> cstring::position (const char *key) const { return strpos(data, key); }
optional<unsigned> cstring::iposition(const char *key) const { return istrpos(data, key); }
cstring& cstring::operator=(const char *data) { this->data = data; return *this; }
cstring::cstring(const char *data) : data(data) {}
bool cstring::operator==(const char* s) const { return !strcmp(data, s); }
bool cstring::operator!=(const char* s) const { return strcmp(data, s); }
optional<unsigned> cstring::position (const char* key) const { return strpos(data, key); }
optional<unsigned> cstring::iposition(const char* key) const { return istrpos(data, key); }
cstring& cstring::operator=(const char* data) { this->data = data; return *this; }
cstring::cstring(const char* data) : data(data) {}
cstring::cstring() : data("") {}
}

View File

@ -4,7 +4,7 @@ namespace nall {
string string::date() {
time_t timestamp = ::time(nullptr);
tm *info = localtime(&timestamp);
tm* info = localtime(&timestamp);
return {
decimal<4, '0'>(1900 + info->tm_year), "-",
decimal<2, '0'>(1 + info->tm_mon), "-",
@ -14,7 +14,7 @@ string string::date() {
string string::time() {
time_t timestamp = ::time(nullptr);
tm *info = localtime(&timestamp);
tm* info = localtime(&timestamp);
return {
decimal<2, '0'>(info->tm_hour), ":",
decimal<2, '0'>(info->tm_min), ":",

View File

@ -2,7 +2,7 @@
namespace nall {
template<signed precision, char padchar> string format(const string &value) {
template<signed precision, char padchar> string format(const string& value) {
if(precision == 0) return value;
bool padright = precision >= 0;

View File

@ -14,21 +14,21 @@ protected:
}
//determine indentation level, without incrementing pointer
unsigned readDepth(const char *p) {
unsigned readDepth(const char* p) {
unsigned depth = 0;
while(p[depth] == '\t' || p[depth] == ' ') depth++;
return depth;
}
//determine indentation level
unsigned parseDepth(const char *&p) {
unsigned parseDepth(const char*& p) {
unsigned depth = readDepth(p);
p += depth;
return depth;
}
//read name
void parseName(const char *&p) {
void parseName(const char*& p) {
unsigned length = 0;
while(valid(p[length])) length++;
if(length == 0) throw "Invalid node name";
@ -36,7 +36,7 @@ protected:
p += length;
}
void parseData(const char *&p) {
void parseData(const char*& p) {
if(*p == '=' && *(p + 1) == '\"') {
unsigned length = 2;
while(p[length] && p[length] != '\n' && p[length] != '\"') length++;
@ -58,7 +58,7 @@ protected:
}
//read all attributes for a node
void parseAttributes(const char *&p) {
void parseAttributes(const char*& p) {
while(*p && *p != '\n') {
if(*p != ' ') throw "Invalid node name";
while(*p == ' ') p++; //skip excess spaces
@ -77,8 +77,8 @@ protected:
}
//read a node and all of its child nodes
void parseNode(const lstring &text, unsigned &y) {
const char *p = text[y++];
void parseNode(const lstring& text, unsigned& y) {
const char* p = text[y++];
level = parseDepth(p);
parseName(p);
parseData(p);
@ -102,8 +102,8 @@ protected:
}
//read top-level nodes
void parse(const string &document) {
lstring text = document.split("\n");
void parse(const string& document) {
lstring text = string{document}.replace("\r", "").split("\n");
//remove empty lines and comment lines
for(unsigned y = 0; y < text.size();) {
@ -134,12 +134,12 @@ protected:
struct Document : Node {
string error;
bool load(const string &document) {
bool load(const string& document) {
name = "", data = "";
try {
parse(document);
} catch(const char *error) {
} catch(const char* error) {
this->error = error;
children.reset();
return false;
@ -147,7 +147,7 @@ struct Document : Node {
return true;
}
Document(const string &document = "") {
Document(const string& document = "") {
load(document);
}
};

View File

@ -3,7 +3,7 @@
namespace nall {
namespace Markup {
inline Node Document(const string &markup) {
inline Node Document(const string& markup) {
if(markup.beginswith("<")) return XML::Document(markup);
return BML::Document(markup);
}

View File

@ -32,11 +32,11 @@ struct Node {
children.reset();
}
bool evaluate(const string &query) const {
bool evaluate(const string& query) const {
if(query.empty()) return true;
lstring rules = string{query}.replace(" ", "").split(",");
for(auto &rule : rules) {
for(auto& rule : rules) {
enum class Comparator : unsigned { ID, EQ, NE, LT, LE, GT, GE };
auto comparator = Comparator::ID;
if(rule.wildcard("*!=*")) comparator = Comparator::NE;
@ -83,7 +83,7 @@ struct Node {
return true;
}
vector<Node> find(const string &query) const {
vector<Node> find(const string& query) const {
vector<Node> result;
lstring path = query.split("/");
@ -105,7 +105,7 @@ struct Node {
}
unsigned position = 0;
for(auto &node : children) {
for(auto& node : children) {
if(node.name.wildcard(name) == false) continue;
if(node.evaluate(rule) == false) continue;
@ -116,22 +116,23 @@ struct Node {
if(path.size() == 0) result.append(node);
else {
auto list = node.find(path.concatenate("/"));
for(auto &item : list) result.append(item);
for(auto& item : list) result.append(item);
}
}
return result;
}
Node operator[](const string &query) const {
Node operator[](const string& query) const {
auto result = find(query);
return result(0);
}
Node* begin() { return children.begin(); }
Node* end() { return children.end(); }
const Node* begin() const { return children.begin(); }
const Node* end() const { return children.end(); }
vector<Node>::iterator begin() { return children.begin(); }
vector<Node>::iterator end() { return children.end(); }
const vector<Node>::const_iterator begin() const { return children.begin(); }
const vector<Node>::const_iterator end() const { return children.end(); }
Node() : attribute(false), level(0) {}

View File

@ -35,7 +35,7 @@ protected:
}
//copy part of string from source document into target string; decode markup while copying
inline void copy(string &target, const char *source, unsigned length) {
inline void copy(string& target, const char* source, unsigned length) {
target.reserve(length + 1);
#if defined(NALL_XML_LITERAL)
@ -44,7 +44,7 @@ protected:
return;
#endif
char *output = target();
char* output = target();
while(length) {
if(*source == '&') {
if(!memcmp(source, "&lt;", 4)) { *output++ = '<'; source += 4; length -= 4; continue; }
@ -77,7 +77,7 @@ protected:
*output = 0;
}
inline bool parseExpression(const char *&p) {
inline bool parseExpression(const char*& p) {
if(*(p + 1) != '!') return false;
//comment
@ -112,11 +112,11 @@ protected:
}
//returns true if tag closes itself (<tag/>); false if not (<tag>)
inline bool parseHead(const char *&p) {
inline bool parseHead(const char*& p) {
//parse name
const char *nameStart = ++p; //skip '<'
const char* nameStart = ++p; //skip '<'
while(isName(*p)) p++;
const char *nameEnd = p;
const char* nameEnd = p;
copy(name, nameStart, nameEnd - nameStart);
if(name.empty()) throw "missing element name";
@ -130,9 +130,9 @@ protected:
Node attribute;
attribute.attribute = true;
const char *nameStart = p;
const char* nameStart = p;
while(isName(*p)) p++;
const char *nameEnd = p;
const char* nameEnd = p;
copy(attribute.name, nameStart, nameEnd - nameStart);
if(attribute.name.empty()) throw "missing attribute name";
@ -140,10 +140,10 @@ protected:
if(*p++ != '=') throw "missing attribute value";
char terminal = *p++;
if(terminal != '\'' && terminal != '\"') throw "attribute value not quoted";
const char *dataStart = p;
const char* dataStart = p;
while(*p && *p != terminal) p++;
if(!*p) throw "missing attribute data terminal";
const char *dataEnd = p++; //skip closing terminal
const char* dataEnd = p++; //skip closing terminal
copy(attribute.data, dataStart, dataEnd - dataStart);
children.append(attribute);
@ -157,27 +157,28 @@ protected:
}
//parse element and all of its child elements
inline void parseElement(const char *&p) {
inline void parseElement(const char*& p) {
Node node;
if(node.parseHead(p) == false) node.parse(p);
children.append(node);
}
//return true if </tag> matches this node's name
inline bool parseClosureElement(const char *&p) {
inline bool parseClosureElement(const char*& p) {
if(p[0] != '<' || p[1] != '/') return false;
p += 2;
const char *nameStart = p;
const char* nameStart = p;
while(*p && *p != '>') p++;
if(*p != '>') throw "unclosed closure element";
const char *nameEnd = p++;
const char* nameEnd = p++;
if(memcmp(name, nameStart, nameEnd - nameStart)) throw "closure element name mismatch";
return true;
}
//parse contents of an element
inline void parse(const char *&p) {
const char *dataStart = p, *dataEnd = p;
inline void parse(const char*& p) {
const char* dataStart = p;
const char* dataEnd = p;
while(*p) {
while(*p && *p != '<') p++;
@ -195,12 +196,12 @@ protected:
struct Document : Node {
string error;
inline bool load(const char *document) {
inline bool load(const char* document) {
if(document == nullptr) return false;
reset();
try {
parse(document);
} catch(const char *error) {
} catch(const char* error) {
reset();
this->error = error;
return false;
@ -209,7 +210,7 @@ struct Document : Node {
}
inline Document() {}
inline Document(const char *document) { load(document); }
inline Document(const char* document) { load(document); }
};
}

View File

@ -2,9 +2,9 @@
namespace fixedpoint {
static nall::function<intmax_t (const char *&)> eval_fallback;
static nall::function<intmax_t (const char*&)> eval_fallback;
static intmax_t eval_integer(const char *& s) {
static intmax_t eval_integer(const char*& s) {
if(!*s) throw "unrecognized integer";
intmax_t value = 0, x = *s, y = *(s + 1);
@ -58,7 +58,7 @@ static intmax_t eval_integer(const char *& s) {
throw "unrecognized integer";
}
static intmax_t eval(const char *&s, int depth = 0) {
static intmax_t eval(const char*& s, int depth = 0) {
while(*s == ' ' || *s == '\t') s++; //trim whitespace
if(!*s) throw "unrecognized token";
intmax_t value = 0, x = *s, y = *(s + 1);
@ -142,7 +142,7 @@ static intmax_t eval(const char *&s, int depth = 0) {
return value;
}
static bool eval(const char *s, intmax_t &result) {
static bool eval(const char* s, intmax_t &result) {
try {
result = eval(s);
return true;
@ -152,11 +152,11 @@ static bool eval(const char *s, intmax_t &result) {
}
}
static intmax_t parse(const char *s) {
static intmax_t parse(const char* s) {
try {
intmax_t result = eval(s);
return result;
} catch(const char *) {
} catch(const char*) {
return 0;
}
}

View File

@ -2,9 +2,9 @@
namespace floatingpoint {
static nall::function<double (const char *&)> eval_fallback;
static nall::function<double (const char*&)> eval_fallback;
static double eval_integer(const char *&s) {
static double eval_integer(const char*& s) {
if(!*s) throw "unrecognized integer";
intmax_t value = 0, radix = 0, x = *s, y = *(s + 1);
@ -64,7 +64,7 @@ static double eval_integer(const char *&s) {
throw "unrecognized integer";
}
static double eval(const char *&s, int depth = 0) {
static double eval(const char*& s, int depth = 0) {
while(*s == ' ' || *s == '\t') s++; //trim whitespace
if(!*s) throw "unrecognized token";
double value = 0, x = *s, y = *(s + 1);
@ -133,21 +133,21 @@ static double eval(const char *&s, int depth = 0) {
return value;
}
static bool eval(const char *s, double &result) {
static bool eval(const char* s, double& result) {
try {
result = eval(s);
return true;
} catch(const char*e) {
} catch(const char*) {
result = 0;
return false;
}
}
static double parse(const char *s) {
static double parse(const char* s) {
try {
double result = eval(s);
return result;
} catch(const char *) {
} catch(const char*) {
return 0;
}
}

View File

@ -19,7 +19,7 @@ string activepath() {
return result;
}
string realpath(const string &name) {
string realpath(const string& name) {
string result;
#if defined(PLATFORM_WINDOWS)
wchar_t path[PATH_MAX] = L"";

View File

@ -3,11 +3,11 @@
namespace nall {
template<unsigned Limit, bool Insensitive, bool Quoted>
string& string::ureplace(const char *key, const char *token) {
string& string::ureplace(const char* key, const char* token) {
if(!key || !*key) return *this;
enum : unsigned { limit = Limit ? Limit : ~0u };
const char *p = data;
const char* p = data;
unsigned counter = 0, keyLength = 0;
while(*p) {
@ -20,13 +20,14 @@ string& string::ureplace(const char *key, const char *token) {
if(counter == 0) return *this;
if(Limit) counter = min(counter, Limit);
char *t = data, *base;
char* t = data;
char* base;
unsigned tokenLength = strlen(token);
if(tokenLength > keyLength) {
t = base = strdup(data);
reserve((unsigned)(p - data) + ((tokenLength - keyLength) * counter));
}
char *o = data;
char* o = data;
while(*t && counter) {
if(quotecopy<Quoted>(o, t)) continue;
@ -41,10 +42,10 @@ string& string::ureplace(const char *key, const char *token) {
return *this;
}
template<unsigned Limit> string &string::replace(const char *key, const char *token) { return ureplace<Limit, false, false>(key, token); }
template<unsigned Limit> string &string::ireplace(const char *key, const char *token) { return ureplace<Limit, true, false>(key, token); }
template<unsigned Limit> string &string::qreplace(const char *key, const char *token) { return ureplace<Limit, false, true>(key, token); }
template<unsigned Limit> string &string::iqreplace(const char *key, const char *token) { return ureplace<Limit, true, true>(key, token); }
template<unsigned Limit> string& string::replace(const char* key, const char* token) { return ureplace<Limit, false, false>(key, token); }
template<unsigned Limit> string& string::ireplace(const char* key, const char* token) { return ureplace<Limit, true, false>(key, token); }
template<unsigned Limit> string& string::qreplace(const char* key, const char* token) { return ureplace<Limit, false, true>(key, token); }
template<unsigned Limit> string& string::iqreplace(const char* key, const char* token) { return ureplace<Limit, true, true>(key, token); }
};

View File

@ -2,11 +2,11 @@
namespace nall {
template<unsigned Limit, bool Insensitive, bool Quoted> lstring& lstring::usplit(const char *key, const char *base) {
template<unsigned Limit, bool Insensitive, bool Quoted> lstring& lstring::usplit(const char* key, const char* base) {
reset();
if(!key || !*key) return *this;
const char *p = base;
const char* p = base;
while(*p) {
if(Limit) if(size() >= Limit) break;
@ -26,10 +26,10 @@ template<unsigned Limit, bool Insensitive, bool Quoted> lstring& lstring::usplit
return *this;
}
template<unsigned Limit> lstring& lstring::split(const char *key, const char *src) { return usplit<Limit, false, false>(key, src); }
template<unsigned Limit> lstring& lstring::isplit(const char *key, const char *src) { return usplit<Limit, true, false>(key, src); }
template<unsigned Limit> lstring& lstring::qsplit(const char *key, const char *src) { return usplit<Limit, false, true>(key, src); }
template<unsigned Limit> lstring& lstring::iqsplit(const char *key, const char *src) { return usplit<Limit, true, true>(key, src); }
template<unsigned Limit> lstring& lstring::split(const char* key, const char* src) { return usplit<Limit, false, false>(key, src); }
template<unsigned Limit> lstring& lstring::isplit(const char* key, const char* src) { return usplit<Limit, true, false>(key, src); }
template<unsigned Limit> lstring& lstring::qsplit(const char* key, const char* src) { return usplit<Limit, false, true>(key, src); }
template<unsigned Limit> lstring& lstring::iqsplit(const char* key, const char* src) { return usplit<Limit, true, true>(key, src); }
};

View File

@ -2,7 +2,7 @@
namespace nall {
string string::read(const string &filename) {
string string::read(const string& filename) {
string data;
data.readfile(filename);
return data;

View File

@ -2,13 +2,9 @@
namespace nall {
//
//strmcpy, strmcat created by byuu
//
//return = strlen(target)
unsigned strmcpy(char *target, const char *source, unsigned length) {
const char *origin = target;
unsigned strmcpy(char* target, const char* source, unsigned length) {
const char* origin = target;
if(length) {
while(*source && --length) *target++ = *source++;
*target = 0;
@ -17,25 +13,25 @@ unsigned strmcpy(char *target, const char *source, unsigned length) {
}
//return = strlen(target)
unsigned strmcat(char *target, const char *source, unsigned length) {
const char *origin = target;
unsigned strmcat(char* target, const char* source, unsigned length) {
const char* origin = target;
while(*target && length) target++, length--;
return (target - origin) + strmcpy(target, source, length);
}
//return = true when all of source was copied
bool strccpy(char *target, const char *source, unsigned length) {
bool strccpy(char* target, const char* source, unsigned length) {
return !source[strmcpy(target, source, length)];
}
//return = true when all of source was copied
bool strccat(char *target, const char *source, unsigned length) {
bool strccat(char* target, const char* source, unsigned length) {
while(*target && length) target++, length--;
return !source[strmcpy(target, source, length)];
}
//return = reserved for future use
void strpcpy(char *&target, const char *source, unsigned &length) {
void strpcpy(char*& target, const char* source, unsigned& length) {
unsigned offset = strmcpy(target, source, length);
target += offset, length -= offset;
}

View File

@ -7,26 +7,26 @@
namespace nall {
template<bool Insensitive, bool Quoted>
optional<unsigned> ustrpos(const char *str, const char *key) {
const char *base = str;
optional<unsigned> ustrpos(const char* str, const char* key) {
const char* base = str;
while(*str) {
if(quoteskip<Quoted>(str)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) return { true, (unsigned)(str - base) };
if(str[n] == 0) return { false, 0 };
if(key[n] == 0) return {true, (unsigned)(str - base)};
if(str[n] == 0) return false;
if(!chrequal<Insensitive>(str[n], key[n])) break;
}
str++;
}
return { false, 0 };
return false;
}
optional<unsigned> strpos(const char *str, const char *key) { return ustrpos<false, false>(str, key); }
optional<unsigned> istrpos(const char *str, const char *key) { return ustrpos<true, false>(str, key); }
optional<unsigned> qstrpos(const char *str, const char *key) { return ustrpos<false, true>(str, key); }
optional<unsigned> iqstrpos(const char *str, const char *key) { return ustrpos<true, true>(str, key); }
optional<unsigned> strpos(const char* str, const char* key) { return ustrpos<false, false>(str, key); }
optional<unsigned> istrpos(const char* str, const char* key) { return ustrpos<true, false>(str, key); }
optional<unsigned> qstrpos(const char* str, const char* key) { return ustrpos<false, true>(str, key); }
optional<unsigned> iqstrpos(const char* str, const char* key) { return ustrpos<true, true>(str, key); }
}

View File

@ -3,11 +3,12 @@
namespace nall {
//limit defaults to zero, which will underflow on first compare; equivalent to no limit
template<unsigned Limit> char* ltrim(char *str, const char *key) {
template<unsigned Limit> char* ltrim(char* str, const char* key) {
unsigned limit = Limit;
if(!key || !*key) return str;
while(strbegin(str, key)) {
char *dest = str, *src = str + strlen(key);
char* dest = str;
char* src = str + strlen(key);
while(true) {
*dest = *src++;
if(!*dest) break;
@ -18,7 +19,7 @@ template<unsigned Limit> char* ltrim(char *str, const char *key) {
return str;
}
template<unsigned Limit> char* rtrim(char *str, const char *key) {
template<unsigned Limit> char* rtrim(char* str, const char* key) {
unsigned limit = Limit;
if(!key || !*key) return str;
while(strend(str, key)) {
@ -28,13 +29,13 @@ template<unsigned Limit> char* rtrim(char *str, const char *key) {
return str;
}
template<unsigned limit> char* trim(char *str, const char *key, const char *rkey) {
template<unsigned limit> char* trim(char* str, const char* key, const char* rkey) {
if(rkey) return ltrim<limit>(rtrim<limit>(str, rkey), key);
return ltrim<limit>(rtrim<limit>(str, key), key);
}
//remove whitespace characters from both left and right sides of string
char* strip(char *s) {
char* strip(char* s) {
signed n = 0, p = 0;
while(s[n]) {
if(s[n] != ' ' && s[n] != '\t' && s[n] != '\r' && s[n] != '\n') break;

View File

@ -8,7 +8,7 @@ struct UTF8 {
unsigned codepoint; //decoded codepoint
};
inline UTF8 utf8_read(const char *s) {
inline UTF8 utf8_read(const char* s) {
UTF8 utf8;
if((*s & 0xfe) == 0xfc) utf8.size = 6;
@ -32,7 +32,7 @@ inline UTF8 utf8_read(const char *s) {
return utf8;
}
inline void utf8_write(char *s, const UTF8 &utf8) {
inline void utf8_write(char* s, const UTF8& utf8) {
for(signed n = utf8.size - 1, shift = 0; n >= 0; n--, shift += 8) {
s[n] = utf8.data >> shift;
}

View File

@ -9,7 +9,7 @@ bool chrequal(char x, char y) {
}
template<bool Quoted, typename T>
bool quoteskip(T *&p) {
bool quoteskip(T*& p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
@ -21,7 +21,7 @@ bool quoteskip(T *&p) {
}
template<bool Quoted, typename T>
bool quotecopy(char *&t, T *&p) {
bool quotecopy(char*& t, T*& p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
@ -34,7 +34,7 @@ bool quotecopy(char *&t, T *&p) {
return true;
}
string substr(const char *src, unsigned start, unsigned length) {
string substr(const char* src, unsigned start, unsigned length) {
string dest;
if(length == ~0u) {
//copy entire string
@ -48,7 +48,7 @@ string substr(const char *src, unsigned start, unsigned length) {
return dest;
}
string sha256(const uint8_t *data, unsigned size) {
string sha256(const uint8_t* data, unsigned size) {
sha256_ctx sha;
uint8_t hash[32];
sha256_init(&sha);
@ -62,7 +62,7 @@ string sha256(const uint8_t *data, unsigned size) {
/* cast.hpp arithmetic -> string */
char* integer(char *result, intmax_t value) {
char* integer(char* result, intmax_t value) {
bool negative = value < 0;
if(negative) value = -value;
@ -82,7 +82,7 @@ char* integer(char *result, intmax_t value) {
return result;
}
char* decimal(char *result, uintmax_t value) {
char* decimal(char* result, uintmax_t value) {
char buffer[64];
unsigned size = 0;
@ -204,7 +204,7 @@ template<unsigned length_, char padding> string ldecimal(uintmax_t value) {
//using sprintf is certainly not the most ideal method to convert
//a double to a string ... but attempting to parse a double by
//hand, digit-by-digit, results in subtle rounding errors.
unsigned fp(char *str, long double value) {
unsigned fp(char* str, long double value) {
char buffer[256];
#ifdef _WIN32
//Windows C-runtime does not support long double via sprintf()
@ -214,9 +214,9 @@ unsigned fp(char *str, long double value) {
#endif
//remove excess 0's in fraction (2.500000 -> 2.5)
for(char *p = buffer; *p; p++) {
for(char* p = buffer; *p; p++) {
if(*p == '.') {
char *p = buffer + strlen(buffer) - 1;
char* p = buffer + strlen(buffer) - 1;
while(*p == '0') {
if(*(p - 1) != '.') *p = 0; //... but not for eg 1.0 -> 1.
p--;

View File

@ -2,8 +2,9 @@
namespace nall {
bool wildcard(const char *s, const char *p) {
const char *cp = nullptr, *mp = nullptr;
bool wildcard(const char* s, const char* p) {
const char* cp = nullptr;
const char* mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && *s != *p) return false;
p++, s++;
@ -22,8 +23,9 @@ bool wildcard(const char *s, const char *p) {
return !*p;
}
bool iwildcard(const char *s, const char *p) {
const char *cp = nullptr, *mp = nullptr;
bool iwildcard(const char* s, const char* p) {
const char* cp = nullptr;
const char* mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && chrlower(*s) != chrlower(*p)) return false;
p++, s++;
@ -42,7 +44,7 @@ bool iwildcard(const char *s, const char *p) {
return !*p;
}
inline bool tokenize(const char *s, const char *p) {
inline bool tokenize(const char* s, const char* p) {
while(*s) {
if(*p == '*') {
while(*s) if(tokenize(s++, p + 1)) return true;
@ -54,10 +56,10 @@ inline bool tokenize(const char *s, const char *p) {
return !*p;
}
inline bool tokenize(lstring &list, const char *s, const char *p) {
inline bool tokenize(lstring &list, const char* s, const char* p) {
while(*s) {
if(*p == '*') {
const char *b = s;
const char* b = s;
while(*s) {
if(tokenize(list, s++, p + 1)) {
list.prepend(substr(b, 0, --s - b));

Some files were not shown because too many files have changed in this diff Show More