diff options
author | John Wiegley <johnw@newartisans.com> | 2004-08-29 23:32:29 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2004-08-29 23:32:29 -0400 |
commit | 63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc (patch) | |
tree | 6af161c7d0a7ca78a26f8b1f1f57426acddf9be9 /amount.cc | |
parent | 2d62f7b633bdaa39c650bb67425514cf1e66a4dd (diff) | |
download | fork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.tar.gz fork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.tar.bz2 fork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.zip |
the amount/balance/value logic is now a library, completely separate from ledger
Diffstat (limited to 'amount.cc')
-rw-r--r-- | amount.cc | 203 |
1 files changed, 121 insertions, 82 deletions
@@ -1,10 +1,8 @@ #include "amount.h" -#include "binary.h" -#include "error.h" #include "util.h" #include <sstream> -#include <cstring> +#include <deque> #include "gmp.h" @@ -21,23 +19,17 @@ class amount_t::bigint_t { unsigned int index; bigint_t() : prec(0), flags(0), ref(1), index(0) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t"); mpz_init(val); } bigint_t(mpz_t _val) : prec(0), flags(0), ref(1), index(0) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t"); mpz_init_set(val, _val); } bigint_t(const bigint_t& other) : prec(other.prec), flags(0), ref(1), index(0) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t"); mpz_init_set(val, other.val); } ~bigint_t() { - DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t::bigint_t"); -#if DEBUG_LEVEL >= BETA assert(ref == 0); -#endif mpz_clear(val); } }; @@ -56,7 +48,12 @@ commodity_t::updater_t * commodity_t::updater = NULL; commodities_map commodity_t::commodities; commodity_t * commodity_t::null_commodity; -void initialize_amounts() +static struct _init_amounts { + _init_amounts(); + ~_init_amounts(); +} _init_obj; + +_init_amounts::_init_amounts() { mpz_init(temp); mpz_init(divisor); @@ -67,6 +64,26 @@ void initialize_amounts() commodity_t::null_commodity = commodity_t::find_commodity("", true); } +_init_amounts::~_init_amounts() +{ + mpz_clear(divisor); + mpz_clear(temp); + + if (commodity_t::updater) { + delete commodity_t::updater; + commodity_t::updater = NULL; + } + + for (commodities_map::iterator i = commodity_t::commodities.begin(); + i != commodity_t::commodities.end(); + i++) + delete (*i).second; + + commodity_t::commodities.clear(); + + true_value.ref--; +} + void clean_commodity_history(char * item_pool, char * item_pool_end) { for (commodities_map::iterator i = commodity_t::commodities.begin(); @@ -94,26 +111,6 @@ void clean_commodity_history(char * item_pool, char * item_pool_end) } } -void shutdown_amounts() -{ - mpz_clear(divisor); - mpz_clear(temp); - - if (commodity_t::updater) { - delete commodity_t::updater; - commodity_t::updater = NULL; - } - - for (commodities_map::iterator i = commodity_t::commodities.begin(); - i != commodity_t::commodities.end(); - i++) - delete (*i).second; - - commodity_t::commodities.clear(); - - true_value.ref--; -} - static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) { // Round `value', with an encoding precision of `value_prec', to a @@ -162,21 +159,17 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) amount_t::amount_t(const bool value) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t"); - if (value) { - quantity = &true_value; + quantity = &true_value; quantity->ref++; } else { - quantity = NULL; + quantity = NULL; } commodity_ = NULL; } amount_t::amount_t(const int value) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t"); - if (value != 0) { quantity = new bigint_t; mpz_set_si(MPZ(quantity), value); @@ -188,8 +181,6 @@ amount_t::amount_t(const int value) amount_t::amount_t(const unsigned int value) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t"); - if (value != 0) { quantity = new bigint_t; mpz_set_ui(MPZ(quantity), value); @@ -201,8 +192,6 @@ amount_t::amount_t(const unsigned int value) amount_t::amount_t(const double value) { - DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t"); - if (value != 0.0) { quantity = new bigint_t; mpz_set_d(MPZ(quantity), value); @@ -668,7 +657,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt) std::free(p); } else { - strings_list strs; + std::deque<std::string> strs; char buf[4]; for (int powers = 0; true; powers += 3) { @@ -687,7 +676,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt) bool printed = false; - for (strings_list::reverse_iterator i = strs.rbegin(); + for (std::deque<std::string>::reverse_iterator i = strs.rbegin(); i != strs.rend(); i++) { if (printed) { @@ -858,8 +847,81 @@ void amount_t::parse(const std::string& str) } +char * bigints; +char * bigints_next; +unsigned int bigints_index; +unsigned int bigints_count; + +void amount_t::read_quantity(char *& data) +{ + char byte = *data++;; + + if (byte == 0) { + quantity = NULL; + } + else if (byte == 1) { + quantity = new((bigint_t *)bigints_next) bigint_t; + bigints_next += sizeof(bigint_t); + quantity->flags |= BIGINT_BULK_ALLOC; + + unsigned short len = *((unsigned short *) data); + data += sizeof(unsigned short); + mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short), + 0, 0, data); + data += len; + + char negative = *data++; + if (negative) + mpz_neg(MPZ(quantity), MPZ(quantity)); + + quantity->prec = *((unsigned short *) data); + data += sizeof(unsigned short); + } else { + unsigned int index = *((unsigned int *) data); + data += sizeof(unsigned int); + + quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t)); + quantity->ref++; + } +} + static char buf[4096]; +void amount_t::read_quantity(std::istream& in) +{ + static std::deque<bigint_t *> _bigints; + + char byte; + in.read(&byte, sizeof(byte)); + + if (byte == 0) { + quantity = NULL; + } + else if (byte == 1) { + quantity = new bigint_t; + _bigints.push_back(quantity); + + unsigned short len; + in.read((char *)&len, sizeof(len)); + assert(len < 4096); + in.read(buf, len); + mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short), + 0, 0, buf); + + char negative; + in.read(&negative, sizeof(negative)); + if (negative) + mpz_neg(MPZ(quantity), MPZ(quantity)); + + in.read((char *)&quantity->prec, sizeof(quantity->prec)); + } else { + unsigned int index; + in.read((char *)&index, sizeof(index)); + quantity = _bigints[index - 1]; + quantity->ref++; + } +} + void amount_t::write_quantity(std::ostream& out) const { char byte; @@ -883,6 +945,7 @@ void amount_t::write_quantity(std::ostream& out) const out.write((char *)&len, sizeof(len)); if (len) { + assert(len < 4096); out.write(buf, len); byte = mpz_sgn(MPZ(quantity)) < 0 ? 1 : 0; @@ -901,38 +964,6 @@ void amount_t::write_quantity(std::ostream& out) const } } -void amount_t::read_quantity(char *& data) -{ - char byte = *data++;; - - if (byte == 0) { - quantity = NULL; - } - else if (byte == 1) { - quantity = new(bigints_next++) bigint_t; - quantity->flags |= BIGINT_BULK_ALLOC; - - unsigned short len = *((unsigned short *) data); - data += sizeof(unsigned short); - mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short), - 0, 0, data); - data += len; - - char negative = *data++; - if (negative) - mpz_neg(MPZ(quantity), MPZ(quantity)); - - quantity->prec = *((unsigned short *) data); - data += sizeof(unsigned short); - } else { - unsigned int index = *((unsigned int *) data); - data += sizeof(unsigned int); - - quantity = bigints + (index - 1); - quantity->ref++; - } -} - bool amount_t::valid() const { if (quantity) { @@ -1039,30 +1070,38 @@ void export_amount() .def("commodity", &amount_t::commodity, return_value_policy<reference_existing_object>()) .def("set_commodity", &amount_t::set_commodity) + .def("clear_commodity", &amount_t::clear_commodity) .def(self += self) + .def(self += int()) .def(self + self) + .def(self + int()) .def(self -= self) + .def(self -= int()) .def(self - self) + .def(self - int()) .def(self *= self) + .def(self *= int()) .def(self * self) + .def(self * int()) .def(self /= self) + .def(self /= int()) .def(self / self) - - .def(self < int()) - .def(self <= int()) - .def(self > int()) - .def(self >= int()) - .def(self == int()) - .def(self != int()) + .def(self / int()) + .def(- self) .def(self < self) + .def(self < int()) .def(self <= self) + .def(self <= int()) .def(self > self) + .def(self > int()) .def(self >= self) + .def(self >= int()) .def(self == self) + .def(self == int()) .def(self != self) - .def(- self) + .def(self != int()) .def(! self) .def(abs(self)) |