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

View File

@ -23,7 +23,6 @@ struct Interface {
string type; string type;
bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges) bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges)
}; };
vector<Media> media; vector<Media> media;
struct Device { struct Device {
@ -58,21 +57,22 @@ struct Interface {
virtual unsigned dipSettings(const Markup::Node&) { return 0; } virtual unsigned dipSettings(const Markup::Node&) { return 0; }
virtual string path(unsigned) { return ""; } virtual string path(unsigned) { return ""; }
virtual string server() { return ""; } virtual string server() { return ""; }
virtual void notify(const string &text) { print(text, "\n"); } virtual void notify(const string& text) { print(text, "\n"); }
} *bind; };
Bind* bind = nullptr;
//callback bindings (provided by user interface) //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& name, const string& type) { return bind->loadRequest(id, name, type); }
void loadRequest(unsigned id, const string &path) { return bind->loadRequest(id, path); } 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 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); } 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); } 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); } 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 path(unsigned group) { return bind->path(group); }
string server() { return bind->server(); } 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 //information
virtual string title() = 0; virtual string title() = 0;
@ -85,8 +85,8 @@ struct Interface {
virtual unsigned group(unsigned id) = 0; virtual unsigned group(unsigned id) = 0;
virtual void load(unsigned id) {} virtual void load(unsigned id) {}
virtual void save() {} virtual void save() {}
virtual void load(unsigned id, const stream &memory) {} virtual void load(unsigned id, const stream& memory) {}
virtual void save(unsigned id, const stream &memory) {} virtual void save(unsigned id, const stream& memory) {}
virtual void unload() {} virtual void unload() {}
//system interface //system interface
@ -112,8 +112,6 @@ struct Interface {
//debugger functions //debugger functions
virtual bool tracerEnable(bool) { return false; } virtual bool tracerEnable(bool) { return false; }
virtual void exportMemory() {} 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.irq_apu_line);
s.integer(status.rdy_line); s.integer(status.rdy_line);
s.integer(status.rdy_addr.valid); bool rdy_addr_valid = status.rdy_addr;
s.integer(status.rdy_addr.value); 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_pending);
s.integer(status.oam_dma_page); s.integer(status.oam_dma_page);

View File

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

View File

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

View File

@ -2,7 +2,7 @@
namespace GameBoy { namespace GameBoy {
Interface *interface = nullptr; Interface* interface = nullptr;
void Interface::lcdScanline() { void Interface::lcdScanline() {
if(hook) hook->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) { if(id == ID::GameBoyBootROM) {
stream.read(system.bootROM.dmg, min( 256u, stream.size())); 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) { if(id == ID::RAM) {
stream.write(cartridge.ramdata, cartridge.ramsize); stream.write(cartridge.ramdata, cartridge.ramsize);
} }
@ -114,15 +114,15 @@ serializer Interface::serialize() {
return system.serialize(); return system.serialize();
} }
bool Interface::unserialize(serializer &s) { bool Interface::unserialize(serializer& s) {
return system.unserialize(s); return system.unserialize(s);
} }
void Interface::cheatSet(const lstring &list) { void Interface::cheatSet(const lstring& list) {
cheat.reset(); cheat.reset();
for(auto &code : list) { for(auto& code : list) {
lstring codelist = code.split("+"); lstring codelist = code.split("+");
for(auto &part : codelist) { for(auto& part : codelist) {
unsigned addr, data, comp; unsigned addr, data, comp;
if(Cheat::decode(part, addr, data, comp)) cheat.append({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 { struct Hook {
virtual void lcdScanline() {} virtual void lcdScanline() {}
virtual void joypWrite(bool p15, bool p14) {} virtual void joypWrite(bool p15, bool p14) {}
} *hook; };
Hook* hook = nullptr;
void lcdScanline(); void lcdScanline();
void joypWrite(bool p15, bool p14); void joypWrite(bool p15, bool p14);
@ -44,8 +45,8 @@ struct Interface : Emulator::Interface {
unsigned group(unsigned id); unsigned group(unsigned id);
void load(unsigned id); void load(unsigned id);
void save(); void save();
void load(unsigned id, const stream &stream); void load(unsigned id, const stream& stream);
void save(unsigned id, const stream &stream); void save(unsigned id, const stream& stream);
void unload(); void unload();
void power(); void power();
@ -65,7 +66,7 @@ private:
vector<Device> device; vector<Device> device;
}; };
extern Interface *interface; extern Interface* interface;
#ifndef GB_HPP #ifndef GB_HPP
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -5,34 +5,28 @@
namespace nall { namespace nall {
//note: this header is intended to form the base for user-defined literals; constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
//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) {
return ( return (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') : *s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
sum 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 ( return (
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') : *s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
sum 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 ( return (
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') : *s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') :
sum 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 ( 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) :
*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 ( return (
*s == '0' && *(s + 1) == 'B' ? binary_(s + 2) : *s == '0' && *(s + 1) == 'B' ? binary_(s + 2) :
*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 ( return (
octal_(s) octal_(s)
); );
} }
constexpr inline intmax_t integer(const char *s) { constexpr inline intmax_t integer(const char* s) {
return ( return (
*s == '+' ? +decimal_(s + 1) : *s == '+' ? +decimal_(s + 1) :
*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 ( return (
decimal_(s) decimal_(s)
); );
} }
constexpr inline uintmax_t hex(const char *s) { constexpr inline uintmax_t hex(const char* s) {
return ( return (
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) : *s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
*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 ( return (
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) : *s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
*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); return atof(s);
} }

View File

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

View File

@ -6,7 +6,7 @@
namespace nall { namespace nall {
struct beatArchive : beatBase { 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(fp.open(beatname, file::mode::write) == false) return false;
if(pathname.endswith("/") == false) pathname.append("/"); if(pathname.endswith("/") == false) pathname.append("/");
@ -44,7 +44,7 @@ struct beatArchive : beatBase {
return true; 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(fp.open(beatname, file::mode::read) == false) return false;
if(pathname.endswith("/") == false) pathname.append("/"); if(pathname.endswith("/") == false) pathname.append("/");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,63 +4,65 @@
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
namespace nall { 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) { const uint32_t crc32_table[256] = {
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff]; 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) { inline uint32_t crc32_adjust(uint32_t crc32, uint8_t input) {
uint32_t crc32 = ~0; return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
for(unsigned i = 0; i < length; i++) { }
crc32 = crc32_adjust(crc32, data[i]);
} inline uint32_t crc32_calculate(const uint8_t* data, unsigned length) {
return ~crc32; uint32_t crc32 = ~0;
for(unsigned i = 0; i < length; i++) {
crc32 = crc32_adjust(crc32, data[i]);
} }
return ~crc32;
}
} }
#endif #endif

View File

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

View File

@ -16,102 +16,104 @@
#endif #endif
namespace nall { 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) {} struct library {
~library() { close(); } 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() = default;
library(const library&) = delete; ~library() { close(); }
private: library& operator=(const library&) = delete;
uintptr_t handle; library(const library&) = delete;
};
#if defined(PLATFORM_X) private:
inline bool library::open(const char *name, const char *path) { uintptr_t handle = 0;
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
}; };
#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 #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -83,7 +83,7 @@ static void sigint(int) {
usart_sigint = true; 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 setpriority(PRIO_PROCESS, 0, -20); //requires superuser privileges; otherwise priority = +0
signal(SIGINT, sigint); signal(SIGINT, sigint);

View File

@ -9,346 +9,348 @@
#include <nall/stream/memory.hpp> #include <nall/stream/memory.hpp>
namespace nall { 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) #if !defined(_WIN32)
return fopen(utf8_filename, mode); return rename(sourcename, targetname) == 0;
#else #else
return _wfopen(utf16_t(utf8_filename), utf16_t(mode)); return _wrename(utf16_t(sourcename), utf16_t(targetname)) == 0;
#endif #endif
} }
struct file { static bool remove(const string& filename) {
enum class mode : unsigned { read, write, modify, append, readwrite = modify, writeread = append }; return unlink(filename) == 0;
enum class index : unsigned { absolute, relative }; }
enum class time : unsigned { create, modify, access };
static bool copy(const string &sourcename, const string &targetname) { static bool truncate(const string& filename, unsigned size) {
file rd, wr; #if !defined(_WIN32)
if(rd.open(sourcename, mode::read) == false) return false; return truncate(filename, size) == 0;
if(wr.open(targetname, mode::write) == false) return false; #else
for(unsigned n = 0; n < rd.size(); n++) wr.write(rd.read()); bool result = false;
return true; FILE* fp = fopen(filename, "rb+");
} if(fp) {
result = _chsize(fileno(fp), size) == 0;
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();
fclose(fp); 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() { 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
file(const string &filename, mode mode_) { req_offset = file_size;
open(filename, mode_); } else { //pad file to requested location
} file_offset = file_size;
while(file_size < req_offset) write(0x00);
~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);
} }
} }
void buffer_flush() { file_offset = req_offset;
if(!fp) return; //file not open }
if(file_mode == mode::read) return; //buffer cannot be written to
if(buffer_offset < 0) return; //buffer unused unsigned offset() const {
if(buffer_dirty == false) return; //buffer unmodified since read 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); fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask); unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fwrite(buffer, 1, length, fp); if(length) unsigned unused = fread(buffer, 1, length, fp);
buffer_offset = -1; //invalidate buffer
buffer_dirty = false;
} }
}; }
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 #endif

View File

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

View File

@ -2,59 +2,63 @@
#define NALL_FUNCTION_HPP #define NALL_FUNCTION_HPP
namespace nall { namespace nall {
template<typename T> class function;
template<typename R, typename... P> class function<R (P...)> { template<typename T> class function;
struct container {
virtual R operator()(P... p) const = 0;
virtual container* copy() const = 0;
virtual ~container() {}
} *callback;
struct global : container { template<typename R, typename... P> class function<R (P...)> {
R (*function)(P...); struct container {
R operator()(P... p) const { return function(std::forward<P>(p)...); } virtual R operator()(P... p) const = 0;
container* copy() const { return new global(function); } virtual container* copy() const = 0;
global(R (*function)(P...)) : function(function) {} virtual ~container() {}
};
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; }
}; };
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 #endif

View File

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

View File

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

View File

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

View File

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

View File

@ -7,14 +7,14 @@ namespace nall {
namespace puff { namespace puff {
inline int puff( inline int puff(
unsigned char *dest, unsigned long *destlen, unsigned char* dest, unsigned long* destlen,
unsigned char *source, unsigned long *sourcelen unsigned char* source, unsigned long* sourcelen
); );
} }
inline bool inflate( inline bool inflate(
uint8_t *target, unsigned targetLength, uint8_t* target, unsigned targetLength,
const uint8_t *source, unsigned sourceLength const uint8_t* source, unsigned sourceLength
) { ) {
unsigned long tl = targetLength, sl = sourceLength; unsigned long tl = targetLength, sl = sourceLength;
int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl); int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl);
@ -23,15 +23,6 @@ inline bool inflate(
namespace puff { 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 { enum {
MAXBITS = 15, MAXBITS = 15,
MAXLCODES = 286, MAXLCODES = 286,
@ -41,11 +32,11 @@ enum {
}; };
struct state { struct state {
unsigned char *out; unsigned char* out;
unsigned long outlen; unsigned long outlen;
unsigned long outcnt; unsigned long outcnt;
unsigned char *in; unsigned char* in;
unsigned long inlen; unsigned long inlen;
unsigned long incnt; unsigned long incnt;
int bitbuf; int bitbuf;
@ -55,11 +46,11 @@ struct state {
}; };
struct huffman { struct huffman {
short *count; short* count;
short *symbol; short* symbol;
}; };
inline int bits(state *s, int need) { inline int bits(state* s, int need) {
long val; long val;
val = s->bitbuf; val = s->bitbuf;
@ -75,7 +66,7 @@ inline int bits(state *s, int need) {
return (int)(val & ((1L << need) - 1)); return (int)(val & ((1L << need) - 1));
} }
inline int stored(state *s) { inline int stored(state* s) {
unsigned len; unsigned len;
s->bitbuf = 0; s->bitbuf = 0;
@ -100,9 +91,9 @@ inline int stored(state *s) {
return 0; return 0;
} }
inline int decode(state *s, huffman *h) { inline int decode(state* s, huffman* h) {
int len, code, first, count, index, bitbuf, left; int len, code, first, count, index, bitbuf, left;
short *next; short* next;
bitbuf = s->bitbuf; bitbuf = s->bitbuf;
left = s->bitcnt; left = s->bitcnt;
@ -135,7 +126,7 @@ inline int decode(state *s, huffman *h) {
return -10; return -10;
} }
inline int construct(huffman *h, short *length, int n) { inline int construct(huffman* h, short* length, int n) {
int symbol, len, left; int symbol, len, left;
short offs[MAXBITS + 1]; short offs[MAXBITS + 1];
@ -160,7 +151,7 @@ inline int construct(huffman *h, short *length, int n) {
return left; return left;
} }
inline int codes(state *s, huffman *lencode, huffman *distcode) { inline int codes(state* s, huffman* lencode, huffman* distcode) {
int symbol, len; int symbol, len;
unsigned dist; unsigned dist;
static const short lens[29] = { static const short lens[29] = {
@ -222,7 +213,7 @@ inline int codes(state *s, huffman *lencode, huffman *distcode) {
return 0; return 0;
} }
inline int fixed(state *s) { inline int fixed(state* s) {
static int virgin = 1; static int virgin = 1;
static short lencnt[MAXBITS + 1], lensym[FIXLCODES]; static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
static short distcnt[MAXBITS + 1], distsym[MAXDCODES]; static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
@ -252,7 +243,7 @@ inline int fixed(state *s) {
return codes(s, &lencode, &distcode); return codes(s, &lencode, &distcode);
} }
inline int dynamic(state *s) { inline int dynamic(state* s) {
int nlen, ndist, ncode, index, err; int nlen, ndist, ncode, index, err;
short lengths[MAXCODES]; short lengths[MAXCODES];
short lencnt[MAXBITS + 1], lensym[MAXLCODES]; short lencnt[MAXBITS + 1], lensym[MAXLCODES];
@ -313,8 +304,8 @@ inline int dynamic(state *s) {
} }
inline int puff( inline int puff(
unsigned char *dest, unsigned long *destlen, unsigned char* dest, unsigned long* destlen,
unsigned char *source, unsigned long *sourcelen unsigned char* source, unsigned long* sourcelen
) { ) {
state s; state s;
int last, type, err; int last, type, err;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,115 +1,57 @@
#ifndef NALL_MAP_HPP #ifndef NALL_MAP_HPP
#define NALL_MAP_HPP #define NALL_MAP_HPP
#include <nall/vector.hpp> #include <nall/set.hpp>
namespace nall { namespace nall {
template<typename LHS, typename RHS> template<typename T, typename U> struct map {
struct map { struct node_t {
struct pair { T key;
LHS name; U value;
RHS data; 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() { optional<U> find(const T& key) const {
list.reset(); if(auto node = root.find({key})) return {true, node().value};
return false;
} }
inline unsigned size() const { void insert(const T& key, const U& value) { root.insert({key, value}); }
return list.size(); void remove(const T& key) { root.remove({key}); }
} unsigned size() const { return root.size(); }
void reset() { root.reset(); }
//O(log n) find typename set<node_t>::iterator begin() { return root.begin(); }
inline optional<unsigned> find(const LHS &name) const { typename set<node_t>::iterator end() { return root.end(); }
signed first = 0, last = size() - 1; const typename set<node_t>::iterator begin() const { return root.begin(); }
while(first <= last) { const typename set<node_t>::iterator end() const { return root.end(); }
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(); }
protected: protected:
vector<pair> list; set<node_t> root;
}; };
template<typename LHS, typename RHS> template<typename T, typename U> struct bimap {
struct bidirectional_map { optional<U> find(const T& key) const { return tmap.find(key); }
const map<LHS, RHS> &lhs; optional<T> find(const U& key) const { return umap.find(key); }
const map<RHS, LHS> &rhs; 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() { typename set<typename map<T, U>::node_t>::iterator begin() { return tmap.begin(); }
llist.reset(); typename set<typename map<T, U>::node_t>::iterator end() { return tmap.end(); }
rlist.reset(); 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(); }
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) {}
protected: protected:
map<LHS, RHS> llist; map<T, U> tmap;
map<RHS, LHS> rlist; map<U, T> umap;
}; };
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,83 +1,44 @@
#ifndef NALL_PROPERTY_HPP #ifndef NALL_PROPERTY_HPP
#define 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 { 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 { template<typename C> struct property {
void operator=(const T& value_) { value = value_; } template<typename T> struct readonly {
private: const T* operator->() const { return &value; }
const T* operator->() const { return &value; } const T& operator()() const { return value; }
const T& operator()() const { return value; } operator const T&() const { return value; }
operator const T&() const { return value; } private:
T* operator->() { return &value; } T* operator->() { return &value; }
operator T&() { return value; } operator T&() { return value; }
T value; const T& operator=(const T& value_) { return value = value_; }
friend C; 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 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 #endif

View File

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

View File

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

View File

@ -1,110 +1,118 @@
#ifndef NALL_SERIAL_HPP #ifndef NALL_SERIAL_HPP
#define 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 <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#include <nall/stdint.hpp>
namespace nall { namespace nall {
struct serial {
bool readable() { struct serial {
if(port_open == false) return false; bool readable() {
fd_set fdset; if(port_open == false) return false;
FD_ZERO(&fdset); fd_set fdset;
FD_SET(port, &fdset); FD_ZERO(&fdset);
timeval timeout; FD_SET(port, &fdset);
timeout.tv_sec = 0; timeval timeout;
timeout.tv_usec = 0; timeout.tv_sec = 0;
int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout); timeout.tv_usec = 0;
if(result < 1) return false; int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout);
return FD_ISSET(port, &fdset); 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 if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
int read(uint8_t *data, unsigned length) { return port_open = true;
if(port_open == false) return -1; }
return ::read(port, (void*)data, length);
}
bool writable() { void close() {
if(port_open == false) return false; if(port != -1) {
fd_set fdset; tcdrain(port);
FD_ZERO(&fdset); if(port_open == true) {
FD_SET(port, &fdset); tcsetattr(port, TCSANOW, &original_attr);
timeval timeout; port_open = false;
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;
} }
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0; ::close(port);
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() {
port = -1; port = -1;
port_open = false;
} }
}
~serial() { serial() {
close(); 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 #endif

View File

@ -1,145 +1,141 @@
#ifndef NALL_SERIALIZER_HPP #ifndef NALL_SERIALIZER_HPP
#define 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 <type_traits>
#include <utility> #include <utility>
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/utility.hpp> #include <nall/utility.hpp>
namespace nall { 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 { struct serializer {
public: enum mode_t { Load, Save, Size };
enum mode_t { Load, Save, Size };
mode_t mode() const { mode_t mode() const {
return imode; 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 { template<typename T> void integer(T& value) {
return idata; 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 { template<typename T> void array(T& array) {
return isize; enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
} for(unsigned n = 0; n < size; n++) integer(array[n]);
}
unsigned capacity() const { template<typename T> void array(T array, unsigned size) {
return icapacity; for(unsigned n = 0; n < size; n++) integer(array[n]);
} }
template<typename T> void floatingpoint(T &value) { //copy
enum { size = sizeof(T) }; serializer& operator=(const serializer& s) {
//this is rather dangerous, and not cross-platform safe; if(idata) delete[] idata;
//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;
}
}
template<typename T> void integer(T &value) { imode = s.imode;
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) }; idata = new uint8_t[s.icapacity];
if(imode == Save) { isize = s.isize;
for(unsigned n = 0; n < size; n++) idata[isize++] = (uintmax_t)value >> (n << 3); icapacity = s.icapacity;
} 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;
}
}
template<typename T> void array(T &array) { memcpy(idata, s.idata, s.icapacity);
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) }; return *this;
for(unsigned n = 0; n < size; n++) integer(array[n]); }
}
template<typename T> void array(T array, unsigned size) { serializer(const serializer& s) {
for(unsigned n = 0; n < size; n++) integer(array[n]); operator=(s);
} }
//copy //move
serializer& operator=(const serializer &s) { serializer& operator=(serializer&& s) {
if(idata) delete[] idata; if(idata) delete[] idata;
imode = s.imode; imode = s.imode;
idata = new uint8_t[s.icapacity]; idata = s.idata;
isize = s.isize; isize = s.isize;
icapacity = s.icapacity; icapacity = s.icapacity;
memcpy(idata, s.idata, s.icapacity); s.idata = nullptr;
return *this; return *this;
} }
serializer(const serializer &s) : idata(nullptr) { serializer(serializer&& s) {
operator=(s); operator=(std::move(s));
} }
//move //construction
serializer& operator=(serializer &&s) { serializer() = default;
if(idata) delete[] idata;
imode = s.imode; serializer(unsigned capacity) {
idata = s.idata; imode = Save;
isize = s.isize; idata = new uint8_t[capacity]();
icapacity = s.icapacity; isize = 0;
icapacity = capacity;
}
s.idata = nullptr; serializer(const uint8_t* data, unsigned capacity) {
return *this; imode = Load;
} idata = new uint8_t[capacity];
isize = 0;
icapacity = capacity;
memcpy(idata, data, capacity);
}
serializer(serializer &&s) { //destruction
operator=(std::move(s)); ~serializer() {
} if(idata) delete[] idata;
}
//construction private:
serializer() { mode_t imode = Size;
imode = Size; uint8_t* idata = nullptr;
idata = nullptr; unsigned isize = 0;
isize = 0; unsigned icapacity = 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;
};
}; };

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> #include <nall/stdint.hpp>
namespace nall { namespace nall {
#define PTR(t, a) ((t*)(a))
#define SWAP32(x) ((uint32_t)( \ #define PTR(t, a) ((t*)(a))
(((uint32_t)(x) & 0x000000ff) << 24) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0xff000000) >> 24) \
))
#define ST32(a, d) *PTR(uint32_t, a) = (d) #define SWAP32(x) ((uint32_t)( \
#define ST32BE(a, d) ST32(a, SWAP32(d)) (((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 ST32(a, d) *PTR(uint32_t, a) = (d)
#define LD32BE(a) SWAP32(LD32(a)) #define ST32BE(a, d) ST32(a, SWAP32(d))
#define LSL32(x, n) ((uint32_t)(x) << (n)) #define LD32(a) *PTR(uint32_t, a)
#define LSR32(x, n) ((uint32_t)(x) >> (n)) #define LD32BE(a) SWAP32(LD32(a))
#define ROR32(x, n) (LSR32(x, n) | LSL32(x, 32 - (n)))
//first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 #define LSL32(x, n) ((uint32_t)(x) << (n))
static const uint32_t T_H[8] = { #define LSR32(x, n) ((uint32_t)(x) >> (n))
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, #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 //first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
static const uint32_t T_K[64] = { static const uint32_t T_H[8] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
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,
};
struct sha256_ctx { //first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
uint8_t in[64]; static const uint32_t T_K[64] = {
unsigned inlen; 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]; struct sha256_ctx {
uint32_t h[8]; uint8_t in[64];
uint64_t len; unsigned inlen;
};
inline void sha256_init(sha256_ctx *p) { uint32_t w[64];
memset(p, 0, sizeof(sha256_ctx)); uint32_t h[8];
memcpy(p->h, T_H, sizeof(T_H)); 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) { a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
unsigned i; e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
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 = 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++) { h = g; g = f; f = e; e = d + t1;
s0 = ROR32(p->w[i - 15], 7) ^ ROR32(p->w[i - 15], 18) ^ LSR32(p->w[i - 15], 3); d = c; c = b; b = a; a = t1 + t2;
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;
} }
inline void sha256_chunk(sha256_ctx *p, const uint8_t *s, unsigned len) { p->h[0] += a; p->h[1] += b; p->h[2] += c; p->h[3] += d;
unsigned l; p->h[4] += e; p->h[5] += f; p->h[6] += g; p->h[7] += h;
p->len += len;
while(len) { //next block
l = 64 - p->inlen; p->inlen = 0;
l = (len < l) ? len : l; }
memcpy(p->in + p->inlen, s, l); inline void sha256_chunk(sha256_ctx* p, const uint8_t* s, unsigned len) {
s += l; unsigned l;
p->inlen += l; p->len += len;
len -= l;
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) { inline void sha256_final(sha256_ctx* p) {
uint64_t len; uint64_t len;
p->in[p->inlen++] = 0x80; p->in[p->inlen++] = 0x80;
if(p->inlen > 56) { if(p->inlen > 56) {
memset(p->in + p->inlen, 0, 64 - p->inlen); 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);
sha256_block(p); sha256_block(p);
} }
inline void sha256_hash(sha256_ctx *p, uint8_t *s) { memset(p->in + p->inlen, 0, 56 - p->inlen);
uint32_t *t = (uint32_t*)s;
for(unsigned i = 0; i < 8; i++) ST32BE(t++, p->h[i]); 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 #endif

View File

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

View File

@ -28,15 +28,17 @@
#endif #endif
namespace nall { 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(int8_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(int16_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(int32_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(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 #endif

View File

@ -5,18 +5,18 @@ namespace nall {
#define autostream(...) (*makestream(__VA_ARGS__)) #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.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(".gz")) return std::unique_ptr<stream>(new gzipstream(filestream{path}));
if(path.iendswith(".zip")) return std::unique_ptr<stream>(new zipstream(filestream{path})); if(path.iendswith(".zip")) return std::unique_ptr<stream>(new zipstream(filestream{path}));
return std::unique_ptr<stream>(new mmapstream(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)); 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)); 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(); } uint8_t read() const { return pfile.read(); }
void write(uint8_t data) const { pfile.write(data); } void write(uint8_t data) const { pfile.write(data); }
filestream(const string &filename) { filestream(const string& filename) {
pfile.open(filename, file::mode::readwrite); pfile.open(filename, file::mode::readwrite);
pwritable = pfile.open(); pwritable = pfile.open();
if(!pwritable) pfile.open(filename, file::mode::read); 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); pfile.open(filename, mode);
pwritable = mode == file::mode::write || mode == file::mode::readwrite; pwritable = mode == file::mode::write || mode == file::mode::readwrite;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
namespace nall { namespace nall {
char* strlower(char *str) { char* strlower(char* str) {
if(!str) return nullptr; if(!str) return nullptr;
int i = 0; int i = 0;
while(str[i]) { while(str[i]) {
@ -12,7 +12,7 @@ char* strlower(char *str) {
return str; return str;
} }
char* strupper(char *str) { char* strupper(char* str) {
if(!str) return nullptr; if(!str) return nullptr;
int i = 0; int i = 0;
while(str[i]) { while(str[i]) {
@ -22,7 +22,7 @@ char* strupper(char *str) {
return str; return str;
} }
char* qstrlower(char *s) { char* qstrlower(char* s) {
if(!s) return nullptr; if(!s) return nullptr;
bool quoted = false; bool quoted = false;
while(*s) { while(*s) {
@ -32,7 +32,7 @@ char* qstrlower(char *s) {
} }
} }
char* qstrupper(char *s) { char* qstrupper(char* s) {
if(!s) return nullptr; if(!s) return nullptr;
bool quoted = false; bool quoted = false;
while(*s) { 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; if(!dest || !before || !after) return dest;
int sl = strlen(dest), bsl = strlen(before), asl = strlen(after); 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> 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)); output.append_(make_string(value));
istring(output, std::forward<Args>(args)...); istring(output, std::forward<Args>(args)...);
} }
@ -46,14 +46,14 @@ template<typename... Args> string& string::append(Args&&... args) {
return *this; return *this;
} }
string& string::assign_(const char *s) { string& string::assign_(const char* s) {
unsigned length = strlen(s); unsigned length = strlen(s);
reserve(length); reserve(length);
strcpy(data, s); strcpy(data, s);
return *this; return *this;
} }
string& string::append_(const char *s) { string& string::append_(const char* s) {
unsigned length = strlen(data) + strlen(s); unsigned length = strlen(data) + strlen(s);
reserve(length); reserve(length);
strcat(data, s); strcat(data, s);
@ -77,20 +77,20 @@ char& string::operator[](int index) {
return data[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; if(&value == this) return *this;
assign(value); assign(value);
return *this; return *this;
} }
string& string::operator=(string &&source) { string& string::operator=(string&& source) {
if(&source == this) return *this; if(&source == this) return *this;
if(data) free(data); if(data) free(data);
size = source.size; size = source.size;
@ -107,13 +107,13 @@ template<typename... Args> string::string(Args&&... args) {
istring(*this, std::forward<Args>(args)...); istring(*this, std::forward<Args>(args)...);
} }
string::string(const string &value) { string::string(const string& value) {
if(&value == this) return; if(&value == this) return;
size = strlen(value); size = strlen(value);
data = strdup(value); data = strdup(value);
} }
string::string(string &&source) { string::string(string&& source) {
if(&source == this) return; if(&source == this) return;
size = source.size; size = source.size;
data = source.data; data = source.data;
@ -124,7 +124,7 @@ string::~string() {
if(data) free(data); if(data) free(data);
} }
bool string::readfile(const string &filename) { bool string::readfile(const string& filename) {
assign(""); assign("");
#if !defined(_WIN32) #if !defined(_WIN32)
@ -147,14 +147,14 @@ bool string::readfile(const string &filename) {
return true; 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++) { for(unsigned i = 0; i < size(); i++) {
if(operator[](i) == key) return { true, i }; if(operator[](i) == key) return { true, i };
} }
return { false, 0 }; return { false, 0 };
} }
string lstring::concatenate(const char *separator) const { string lstring::concatenate(const char* separator) const {
string output; string output;
for(unsigned i = 0; i < size(); i++) { for(unsigned i = 0; i < size(); i++) {
output.append(operator[](i), i < size() - 1 ? separator : ""); output.append(operator[](i), i < size() - 1 ? separator : "");
@ -162,18 +162,26 @@ string lstring::concatenate(const char *separator) const {
return output; 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); vector::append(data);
append(std::forward<Args>(args)...); append(std::forward<Args>(args)...);
} }
void lstring::isort() { bool lstring::operator==(const lstring& source) const {
nall::sort(pool, objectsize, [](const string &x, const string &y) {
return istrcmp(x, y) < 0;
});
}
bool lstring::operator==(const lstring &source) const {
if(this == &source) return true; if(this == &source) return true;
if(size() != source.size()) return false; if(size() != source.size()) return false;
for(unsigned n = 0; n < size(); n++) { for(unsigned n = 0; n < size(); n++) {
@ -182,21 +190,21 @@ bool lstring::operator==(const lstring &source) const {
return true; return true;
} }
bool lstring::operator!=(const lstring &source) const { bool lstring::operator!=(const lstring& source) const {
return !operator==(source); return !operator==(source);
} }
lstring& lstring::operator=(const lstring &source) { lstring& lstring::operator=(const lstring& source) {
vector::operator=(source); vector::operator=(source);
return *this; return *this;
} }
lstring& lstring::operator=(lstring &source) { lstring& lstring::operator=(lstring& source) {
vector::operator=(source); vector::operator=(source);
return *this; return *this;
} }
lstring& lstring::operator=(lstring &&source) { lstring& lstring::operator=(lstring&& source) {
vector::operator=(std::move(source)); vector::operator=(std::move(source));
return *this; return *this;
} }
@ -205,15 +213,15 @@ template<typename... Args> lstring::lstring(Args&&... args) {
append(std::forward<Args>(args)...); append(std::forward<Args>(args)...);
} }
lstring::lstring(const lstring &source) { lstring::lstring(const lstring& source) {
vector::operator=(source); vector::operator=(source);
} }
lstring::lstring(lstring &source) { lstring::lstring(lstring& source) {
vector::operator=(source); vector::operator=(source);
} }
lstring::lstring(lstring &&source) { lstring::lstring(lstring&& source) {
vector::operator=(std::move(source)); vector::operator=(std::move(source));
} }

View File

@ -8,12 +8,12 @@ namespace nall {
cstring::operator const char*() const { return data; } cstring::operator const char*() const { return data; }
unsigned cstring::length() const { return strlen(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); }
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::position (const char* key) const { return strpos(data, key); }
optional<unsigned> cstring::iposition(const char *key) const { return istrpos(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::operator=(const char* data) { this->data = data; return *this; }
cstring::cstring(const char *data) : data(data) {} cstring::cstring(const char* data) : data(data) {}
cstring::cstring() : data("") {} cstring::cstring() : data("") {}
} }

View File

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

View File

@ -2,7 +2,7 @@
namespace nall { 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; if(precision == 0) return value;
bool padright = precision >= 0; bool padright = precision >= 0;

View File

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

View File

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

View File

@ -32,11 +32,11 @@ struct Node {
children.reset(); children.reset();
} }
bool evaluate(const string &query) const { bool evaluate(const string& query) const {
if(query.empty()) return true; if(query.empty()) return true;
lstring rules = string{query}.replace(" ", "").split(","); 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 }; enum class Comparator : unsigned { ID, EQ, NE, LT, LE, GT, GE };
auto comparator = Comparator::ID; auto comparator = Comparator::ID;
if(rule.wildcard("*!=*")) comparator = Comparator::NE; if(rule.wildcard("*!=*")) comparator = Comparator::NE;
@ -83,7 +83,7 @@ struct Node {
return true; return true;
} }
vector<Node> find(const string &query) const { vector<Node> find(const string& query) const {
vector<Node> result; vector<Node> result;
lstring path = query.split("/"); lstring path = query.split("/");
@ -105,7 +105,7 @@ struct Node {
} }
unsigned position = 0; unsigned position = 0;
for(auto &node : children) { for(auto& node : children) {
if(node.name.wildcard(name) == false) continue; if(node.name.wildcard(name) == false) continue;
if(node.evaluate(rule) == false) continue; if(node.evaluate(rule) == false) continue;
@ -116,22 +116,23 @@ struct Node {
if(path.size() == 0) result.append(node); if(path.size() == 0) result.append(node);
else { else {
auto list = node.find(path.concatenate("/")); auto list = node.find(path.concatenate("/"));
for(auto &item : list) result.append(item); for(auto& item : list) result.append(item);
} }
} }
return result; return result;
} }
Node operator[](const string &query) const { Node operator[](const string& query) const {
auto result = find(query); auto result = find(query);
return result(0); return result(0);
} }
Node* begin() { return children.begin(); } vector<Node>::iterator begin() { return children.begin(); }
Node* end() { return children.end(); } vector<Node>::iterator end() { return children.end(); }
const Node* begin() const { return children.begin(); }
const Node* end() const { 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) {} 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 //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); target.reserve(length + 1);
#if defined(NALL_XML_LITERAL) #if defined(NALL_XML_LITERAL)
@ -44,7 +44,7 @@ protected:
return; return;
#endif #endif
char *output = target(); char* output = target();
while(length) { while(length) {
if(*source == '&') { if(*source == '&') {
if(!memcmp(source, "&lt;", 4)) { *output++ = '<'; source += 4; length -= 4; continue; } if(!memcmp(source, "&lt;", 4)) { *output++ = '<'; source += 4; length -= 4; continue; }
@ -77,7 +77,7 @@ protected:
*output = 0; *output = 0;
} }
inline bool parseExpression(const char *&p) { inline bool parseExpression(const char*& p) {
if(*(p + 1) != '!') return false; if(*(p + 1) != '!') return false;
//comment //comment
@ -112,11 +112,11 @@ protected:
} }
//returns true if tag closes itself (<tag/>); false if not (<tag>) //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 //parse name
const char *nameStart = ++p; //skip '<' const char* nameStart = ++p; //skip '<'
while(isName(*p)) p++; while(isName(*p)) p++;
const char *nameEnd = p; const char* nameEnd = p;
copy(name, nameStart, nameEnd - nameStart); copy(name, nameStart, nameEnd - nameStart);
if(name.empty()) throw "missing element name"; if(name.empty()) throw "missing element name";
@ -130,9 +130,9 @@ protected:
Node attribute; Node attribute;
attribute.attribute = true; attribute.attribute = true;
const char *nameStart = p; const char* nameStart = p;
while(isName(*p)) p++; while(isName(*p)) p++;
const char *nameEnd = p; const char* nameEnd = p;
copy(attribute.name, nameStart, nameEnd - nameStart); copy(attribute.name, nameStart, nameEnd - nameStart);
if(attribute.name.empty()) throw "missing attribute name"; if(attribute.name.empty()) throw "missing attribute name";
@ -140,10 +140,10 @@ protected:
if(*p++ != '=') throw "missing attribute value"; if(*p++ != '=') throw "missing attribute value";
char terminal = *p++; char terminal = *p++;
if(terminal != '\'' && terminal != '\"') throw "attribute value not quoted"; if(terminal != '\'' && terminal != '\"') throw "attribute value not quoted";
const char *dataStart = p; const char* dataStart = p;
while(*p && *p != terminal) p++; while(*p && *p != terminal) p++;
if(!*p) throw "missing attribute data terminal"; 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); copy(attribute.data, dataStart, dataEnd - dataStart);
children.append(attribute); children.append(attribute);
@ -157,27 +157,28 @@ protected:
} }
//parse element and all of its child elements //parse element and all of its child elements
inline void parseElement(const char *&p) { inline void parseElement(const char*& p) {
Node node; Node node;
if(node.parseHead(p) == false) node.parse(p); if(node.parseHead(p) == false) node.parse(p);
children.append(node); children.append(node);
} }
//return true if </tag> matches this node's name //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; if(p[0] != '<' || p[1] != '/') return false;
p += 2; p += 2;
const char *nameStart = p; const char* nameStart = p;
while(*p && *p != '>') p++; while(*p && *p != '>') p++;
if(*p != '>') throw "unclosed closure element"; 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"; if(memcmp(name, nameStart, nameEnd - nameStart)) throw "closure element name mismatch";
return true; return true;
} }
//parse contents of an element //parse contents of an element
inline void parse(const char *&p) { inline void parse(const char*& p) {
const char *dataStart = p, *dataEnd = p; const char* dataStart = p;
const char* dataEnd = p;
while(*p) { while(*p) {
while(*p && *p != '<') p++; while(*p && *p != '<') p++;
@ -195,12 +196,12 @@ protected:
struct Document : Node { struct Document : Node {
string error; string error;
inline bool load(const char *document) { inline bool load(const char* document) {
if(document == nullptr) return false; if(document == nullptr) return false;
reset(); reset();
try { try {
parse(document); parse(document);
} catch(const char *error) { } catch(const char* error) {
reset(); reset();
this->error = error; this->error = error;
return false; return false;
@ -209,7 +210,7 @@ struct Document : Node {
} }
inline Document() {} inline Document() {}
inline Document(const char *document) { load(document); } inline Document(const char* document) { load(document); }
}; };
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,11 +3,12 @@
namespace nall { namespace nall {
//limit defaults to zero, which will underflow on first compare; equivalent to no limit //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; unsigned limit = Limit;
if(!key || !*key) return str; if(!key || !*key) return str;
while(strbegin(str, key)) { while(strbegin(str, key)) {
char *dest = str, *src = str + strlen(key); char* dest = str;
char* src = str + strlen(key);
while(true) { while(true) {
*dest = *src++; *dest = *src++;
if(!*dest) break; if(!*dest) break;
@ -18,7 +19,7 @@ template<unsigned Limit> char* ltrim(char *str, const char *key) {
return str; 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; unsigned limit = Limit;
if(!key || !*key) return str; if(!key || !*key) return str;
while(strend(str, key)) { while(strend(str, key)) {
@ -28,13 +29,13 @@ template<unsigned Limit> char* rtrim(char *str, const char *key) {
return str; 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); if(rkey) return ltrim<limit>(rtrim<limit>(str, rkey), key);
return ltrim<limit>(rtrim<limit>(str, key), key); return ltrim<limit>(rtrim<limit>(str, key), key);
} }
//remove whitespace characters from both left and right sides of string //remove whitespace characters from both left and right sides of string
char* strip(char *s) { char* strip(char* s) {
signed n = 0, p = 0; signed n = 0, p = 0;
while(s[n]) { while(s[n]) {
if(s[n] != ' ' && s[n] != '\t' && s[n] != '\r' && s[n] != '\n') break; 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 unsigned codepoint; //decoded codepoint
}; };
inline UTF8 utf8_read(const char *s) { inline UTF8 utf8_read(const char* s) {
UTF8 utf8; UTF8 utf8;
if((*s & 0xfe) == 0xfc) utf8.size = 6; if((*s & 0xfe) == 0xfc) utf8.size = 6;
@ -32,7 +32,7 @@ inline UTF8 utf8_read(const char *s) {
return utf8; 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) { for(signed n = utf8.size - 1, shift = 0; n >= 0; n--, shift += 8) {
s[n] = utf8.data >> shift; s[n] = utf8.data >> shift;
} }

View File

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

View File

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

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