diff options
author | Nicolas Noble <pixel@nobis-crew.org> | 2013-08-12 13:25:22 -0700 |
---|---|---|
committer | Nicolas Noble <pixel@nobis-crew.org> | 2013-08-12 13:25:22 -0700 |
commit | f5e970f17e9bb3fc30cda214cf8522e4216de30f (patch) | |
tree | 6286fea5e5fd968114c6fae3c3f51ec983af21dd | |
parent | a91c3d3a6cb5e71c6376b1efe7d037f02b36f035 (diff) |
Fixing a few more things, added BigInt to ints conversions, and added the 64 bits read / write versions for LuaHandle.
-rw-r--r-- | includes/BigInt.h | 7 | ||||
-rw-r--r-- | src/BigInt.cc | 49 | ||||
-rw-r--r-- | src/LuaHandle.cc | 67 | ||||
-rw-r--r-- | src/Main.cc | 7 |
4 files changed, 124 insertions, 6 deletions
diff --git a/includes/BigInt.h b/includes/BigInt.h index a94396c..ae5b0f7 100644 --- a/includes/BigInt.h +++ b/includes/BigInt.h @@ -12,6 +12,8 @@ class BigInt { BigInt(const BigInt &) throw (GeneralException); BigInt(BigInt &&); ~BigInt(); + template<class T> + BigInt(const T & v) : BigInt() { set(v); } BigInt & operator=(const BigInt &) throw (GeneralException); @@ -23,6 +25,11 @@ class BigInt { void set(const String &, int radix = 10) throw (GeneralException); void set2expt(int i) throw (GeneralException); + uint64_t to_uint64() const throw (GeneralException); + int64_t to_int64() const throw (GeneralException); + uint32_t to_uint32() const throw (GeneralException); + int32_t to_int32() const throw (GeneralException); + BigInt operator+(unsigned int) const throw (GeneralException); BigInt operator+(const BigInt &) const throw (GeneralException); BigInt operator-(unsigned int) const throw (GeneralException); diff --git a/src/BigInt.cc b/src/BigInt.cc index 3735ad7..7ff1422 100644 --- a/src/BigInt.cc +++ b/src/BigInt.cc @@ -8,12 +8,15 @@ namespace { class InitMP : public Balau::AtStart { public: - InitMP() : AtStart(0) { } + InitMP() : AtStart(20) { } void doStart() { ltc_mp = ltm_desc; + IAssert(MP_DIGIT_BIT >= 32, "The code needs at least 32 bits digits."); + IAssert(MP_DIGIT_BIT <= 64, "The code needs at most 64 bits digits."); + IAssert(!m_initialized, "doStart should only be called once."); m_initialized = true; + static Balau::BigInt s2p32; - IAssert(!m_2p32, "doStart should only be called once."); s2p32.set2expt(32); m_2p32 = &s2p32; } @@ -132,6 +135,48 @@ void Balau::BigInt::set2expt(int i) throw (GeneralException) { throw GeneralException("Error while calling mp_2expt"); } +uint64_t Balau::BigInt::to_uint64() const throw (GeneralException) { + if (mp_get_digit_count(m_bi) > 2) + throw GeneralException("BigInt too big to fit in a uint64"); + if (MP_DIGIT_BIT == 64) + return mp_get_digit(m_bi, 0); + uint64_t low = mp_get_digit(m_bi, 0); + uint64_t high = mp_get_digit(m_bi, 1); + uint64_t highest = 1 << (64 - MP_DIGIT_BIT); + if (high >= highest) + throw GeneralException("BigInt too big to fit in a uint64"); + return low | (high << MP_DIGIT_BIT); +} + +int64_t Balau::BigInt::to_int64() const throw (GeneralException) { + uint64_t v = to_uint64(); + if (v & 0x8000000000000000ULL) + throw GeneralException("BigInt too big to fit in a int64"); + if (comp(0) == LT) + return -v; + else + return v; +} + +uint32_t Balau::BigInt::to_uint32() const throw (GeneralException) { + if (mp_get_digit_count(m_bi) > 1) + throw GeneralException("BigInt too big to fit in a uint32"); + uint64_t v = mp_get_digit(m_bi, 0); + if (v >= 0x100000000ULL) + throw GeneralException("BigInt too big to fit in a uint32"); + return v; +} + +int32_t Balau::BigInt::to_int32() const throw (GeneralException) { + uint32_t v = to_uint32(); + if (v & 0x80000000) + throw GeneralException("BigInt too big to fit in a int32"); + if (comp(0) == LT) + return -v; + else + return v; +} + Balau::BigInt Balau::BigInt::operator+(unsigned int i) const throw (GeneralException) { BigInt r; if (mp_add_d(m_bi, i, r.m_bi) != CRYPT_OK) diff --git a/src/LuaHandle.cc b/src/LuaHandle.cc index c7ff88a..de9e7e2 100644 --- a/src/LuaHandle.cc +++ b/src/LuaHandle.cc @@ -1,4 +1,5 @@ #include "LuaHandle.h" +#include "LuaBigInt.h" #include "Handle.h" typedef Balau::IO<Balau::Handle> IOHandle; @@ -11,15 +12,19 @@ enum IOHandle_methods_t { IOHANDLE_READU8, IOHANDLE_READU16, IOHANDLE_READU32, + IOHANDLE_READU64, IOHANDLE_READI8, IOHANDLE_READI16, IOHANDLE_READI32, + IOHANDLE_READI64, IOHANDLE_WRITEU8, IOHANDLE_WRITEU16, IOHANDLE_WRITEU32, + IOHANDLE_WRITEU64, IOHANDLE_WRITEI8, IOHANDLE_WRITEI16, IOHANDLE_WRITEI32, + IOHANDLE_WRITEI64, }; struct Balau::lua_functypes_t IOHandle_methods[] = { @@ -27,15 +32,19 @@ struct Balau::lua_functypes_t IOHandle_methods[] = { { IOHANDLE_READU8, "readU8", 0, 0, { } }, { IOHANDLE_READU16, "readU16", 0, 0, { } }, { IOHANDLE_READU32, "readU32", 0, 0, { } }, + { IOHANDLE_READU64, "readU64", 0, 0, { } }, { IOHANDLE_READI8, "readI8", 0, 0, { } }, { IOHANDLE_READI16, "readI16", 0, 0, { } }, { IOHANDLE_READI32, "readI32", 0, 0, { } }, + { IOHANDLE_READI64, "readI64", 0, 0, { } }, { IOHANDLE_WRITEU8, "writeU8", 1, 1, { Balau::BLUA_NUMBER } }, { IOHANDLE_WRITEU16, "writeU16", 1, 1, { Balau::BLUA_NUMBER } }, { IOHANDLE_WRITEU32, "writeU32", 1, 1, { Balau::BLUA_NUMBER } }, + { IOHANDLE_WRITEU64, "writeU64", 1, 1, { Balau::BLUA_NUMBER | Balau::BLUA_OBJECT | Balau::BLUA_STRING } }, { IOHANDLE_WRITEI8, "writeI8", 1, 1, { Balau::BLUA_NUMBER } }, { IOHANDLE_WRITEI16, "writeI16", 1, 1, { Balau::BLUA_NUMBER } }, { IOHANDLE_WRITEI32, "writeI32", 1, 1, { Balau::BLUA_NUMBER } }, + { IOHANDLE_WRITEI64, "writeI64", 1, 1, { Balau::BLUA_NUMBER | Balau::BLUA_OBJECT | Balau::BLUA_STRING } }, { -1, 0, 0, 0, 0 }, }; @@ -69,6 +78,17 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c return L.yield(Balau::Future<int>([L, c]() mutable { L.push((lua_Number) c.get()); return 1; })); } break; + case IOHANDLE_READU64: + { + Balau::Future<uint64_t> c = h->readU64(); + return L.yield(Balau::Future<int>([L, c]() mutable { + uint64_t v = c.get(); + Balau::LuaBigIntFactory f(new Balau::BigInt(v)); + f.pushDestruct(L); + return 1; + })); + } + break; case IOHANDLE_READI8: { Balau::Future<int8_t> c = h->readI8(); @@ -87,6 +107,17 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c return L.yield(Balau::Future<int>([L, c]() mutable { L.push((lua_Number) c.get()); return 1; })); } break; + case IOHANDLE_READI64: + { + Balau::Future<int64_t> c = h->readI64(); + return L.yield(Balau::Future<int>([L, c]() mutable { + int64_t v = c.get(); + Balau::LuaBigIntFactory f(new Balau::BigInt(v)); + f.pushDestruct(L); + return 1; + })); + } + break; case IOHANDLE_WRITEU8: { Balau::Future<void> c = h->writeU8(L.tonumber()); @@ -105,6 +136,22 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; })); } break; + case IOHANDLE_WRITEU64: + { + uint64_t v; + if (L.istable()) { + Balau::BigInt * b = L.recast<Balau::BigInt>(); + v = b->to_uint64(); + } else if (L.type() == LUA_TSTRING) { + Balau::BigInt b(L.tostring()); + v = b.to_uint64(); + } else { + v = L.tonumber(); + } + Balau::Future<void> c = h->writeU64(v); + return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; })); + } + break; case IOHANDLE_WRITEI8: { Balau::Future<void> c = h->writeI8(L.tonumber()); @@ -123,6 +170,22 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; })); } break; + case IOHANDLE_WRITEI64: + { + int64_t v; + if (L.istable()) { + Balau::BigInt * b = L.recast<Balau::BigInt>(); + v = b->to_int64(); + } else if (L.type() == LUA_TSTRING) { + Balau::BigInt b(L.tostring()); + v = b.to_int64(); + } else { + v = L.tonumber(); + } + Balau::Future<void> c = h->writeI64(v); + return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; })); + } + break; } return r; @@ -141,15 +204,19 @@ void Balau::LuaHandleFactory::pushObjectAndMembers(Lua & L) { PUSH_METHOD(IOHandle, IOHANDLE_READU8); PUSH_METHOD(IOHandle, IOHANDLE_READU16); PUSH_METHOD(IOHandle, IOHANDLE_READU32); + PUSH_METHOD(IOHandle, IOHANDLE_READU64); PUSH_METHOD(IOHandle, IOHANDLE_READI8); PUSH_METHOD(IOHandle, IOHANDLE_READI16); PUSH_METHOD(IOHandle, IOHANDLE_READI32); + PUSH_METHOD(IOHandle, IOHANDLE_READI64); PUSH_METHOD(IOHandle, IOHANDLE_WRITEU8); PUSH_METHOD(IOHandle, IOHANDLE_WRITEU16); PUSH_METHOD(IOHandle, IOHANDLE_WRITEU32); + PUSH_METHOD(IOHandle, IOHANDLE_WRITEU64); PUSH_METHOD(IOHandle, IOHANDLE_WRITEI8); PUSH_METHOD(IOHandle, IOHANDLE_WRITEI16); PUSH_METHOD(IOHandle, IOHANDLE_WRITEI32); + PUSH_METHOD(IOHandle, IOHANDLE_WRITEI64); } diff --git a/src/Main.cc b/src/Main.cc index e872411..a01ad24 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -146,14 +146,13 @@ int Balau::Main::bootstrap(int argc, char ** argv) { int r = 0; m_status = STARTING; - for (AtStart * ptr = AtStart::s_head; ptr; ptr = ptr->m_next) - ptr->doStart(); - try { + for (AtStart * ptr = AtStart::s_head; ptr; ptr = ptr->m_next) + ptr->doStart(); + m_status = RUNNING; TaskMan::registerTask(new BootstrapTask(argc, argv, NULL)); r = TaskMan::getDefaultTaskMan()->mainLoop(); - m_status = STOPPING; } catch (Exit & e) { m_status = STOPPING; |