fixed problem with writing binary amounts

This commit is contained in:
John Wiegley 2004-08-13 17:29:46 -04:00
parent 6944e5950a
commit 0c8dff61ed
3 changed files with 69 additions and 85 deletions

View file

@ -754,6 +754,10 @@ void amount_t::write_quantity(std::ostream& out) const
assert(len); assert(len);
out.write((char *)&len, sizeof(len)); out.write((char *)&len, sizeof(len));
out.write(buf, len); out.write(buf, len);
#ifndef WRITE_AMOUNTS_TEXTUALLY
char negative = mpz_sgn(MPZ(quantity)) < 0 ? 1 : 0;
out.write(&negative, sizeof(negative));
#endif
} else { } else {
len = 0; len = 0;
out.write((char *)&len, sizeof(len)); out.write((char *)&len, sizeof(len));
@ -771,7 +775,11 @@ void amount_t::read_quantity(std::istream& in)
buf[len] = '\0'; buf[len] = '\0';
mpz_set_str(MPZ(quantity), buf, 10); mpz_set_str(MPZ(quantity), buf, 10);
#else #else
char negative;
in.read(&negative, sizeof(negative));
mpz_import(MPZ(quantity), len / sizeof(int), 1, sizeof(int), 0, 0, buf); mpz_import(MPZ(quantity), len / sizeof(int), 1, sizeof(int), 0, 0, buf);
if (negative)
mpz_neg(MPZ(quantity), MPZ(quantity));
#endif #endif
} else { } else {
if (quantity) if (quantity)

View file

@ -20,8 +20,12 @@ void sort_transactions::flush()
void calc_transactions::operator()(transaction_t * xact) void calc_transactions::operator()(transaction_t * xact)
{ {
if (last_xact) if (last_xact) {
xact->total += last_xact->total; xact->total += last_xact->total;
xact->index = last_xact->index + 1;
} else {
xact->index = 0;
}
if (inverted) { if (inverted) {
xact->amount.negate(); xact->amount.negate();
@ -29,7 +33,6 @@ void calc_transactions::operator()(transaction_t * xact)
} }
xact->total += *xact; xact->total += *xact;
xact->index = last_xact ? last_xact->index + 1 : 0;
(*handler)(xact); (*handler)(xact);

139
walk.h
View file

@ -13,8 +13,20 @@ namespace ledger {
template <typename T> template <typename T>
struct item_handler { struct item_handler {
item_handler * handler;
public:
item_handler() : handler(NULL) {}
item_handler(item_handler * _handler) : handler(_handler) {}
virtual ~item_handler() {} virtual ~item_handler() {}
virtual item_handler * copy() { return NULL; } virtual void close() {
flush();
if (handler) {
handler->flush();
delete handler;
handler = NULL;
}
}
virtual void flush() {} virtual void flush() {}
virtual void operator()(T * item) = 0; virtual void operator()(T * item) = 0;
}; };
@ -109,24 +121,17 @@ class add_to_account_value : public item_handler<transaction_t>
class sort_transactions : public item_handler<transaction_t> class sort_transactions : public item_handler<transaction_t>
{ {
transactions_deque transactions; transactions_deque transactions;
const value_expr_t * sort_order; const value_expr_t * sort_order;
item_handler<transaction_t> * handler;
public: public:
sort_transactions(item_handler<transaction_t> * _handler, sort_transactions(item_handler<transaction_t> * handler,
const value_expr_t * _sort_order) const value_expr_t * _sort_order)
: sort_order(_sort_order), handler(_handler) {} : item_handler<transaction_t>(handler),
sort_order(_sort_order) {}
virtual ~sort_transactions() { virtual ~sort_transactions() { close(); }
flush();
handler->flush();
delete handler;
}
virtual void flush(); virtual void flush();
virtual void operator()(transaction_t * xact) { virtual void operator()(transaction_t * xact) {
transactions.push_back(xact); transactions.push_back(xact);
} }
@ -136,17 +141,12 @@ class filter_transactions : public item_handler<transaction_t>
{ {
item_predicate<transaction_t> pred; item_predicate<transaction_t> pred;
item_handler<transaction_t> * handler;
public: public:
filter_transactions(item_handler<transaction_t> * _handler, filter_transactions(item_handler<transaction_t> * handler,
const std::string& predicate) const std::string& predicate)
: pred(predicate), handler(_handler) {} : item_handler<transaction_t>(handler), pred(predicate) {}
virtual ~filter_transactions() { virtual ~filter_transactions() { close(); }
handler->flush();
delete handler;
}
virtual void operator()(transaction_t * xact) { virtual void operator()(transaction_t * xact) {
if (pred(xact)) if (pred(xact))
@ -159,45 +159,36 @@ class calc_transactions : public item_handler<transaction_t>
transaction_t * last_xact; transaction_t * last_xact;
const bool inverted; const bool inverted;
item_handler<transaction_t> * handler;
public: public:
calc_transactions(item_handler<transaction_t> * _handler, calc_transactions(item_handler<transaction_t> * handler,
const bool _inverted = false) const bool _inverted = false)
: last_xact(NULL), inverted(_inverted), handler(_handler) {} : item_handler<transaction_t>(handler),
last_xact(NULL), inverted(_inverted) {}
virtual ~calc_transactions() { virtual ~calc_transactions() { close(); }
handler->flush();
delete handler;
}
virtual void operator()(transaction_t * xact); virtual void operator()(transaction_t * xact);
}; };
class collapse_transactions : public item_handler<transaction_t> class collapse_transactions : public item_handler<transaction_t>
{ {
balance_pair_t subtotal; balance_pair_t subtotal;
unsigned int count; unsigned int count;
entry_t * last_entry; entry_t * last_entry;
transaction_t * last_xact; transaction_t * last_xact;
item_handler<transaction_t> * handler;
account_t * totals_account; account_t * totals_account;
transactions_deque xact_temps; transactions_deque xact_temps;
public: public:
collapse_transactions(item_handler<transaction_t> * _handler) collapse_transactions(item_handler<transaction_t> * handler)
: count(0), last_entry(NULL), last_xact(NULL), : item_handler<transaction_t>(handler), count(0),
handler(_handler) { last_entry(NULL), last_xact(NULL) {
totals_account = new account_t(NULL, "<Total>"); totals_account = new account_t(NULL, "<Total>");
} }
virtual ~collapse_transactions() { virtual ~collapse_transactions() {
flush(); close();
handler->flush();
delete handler;
delete totals_account; delete totals_account;
for (transactions_deque::iterator i = xact_temps.begin(); for (transactions_deque::iterator i = xact_temps.begin();
@ -233,24 +224,19 @@ class changed_value_transactions : public item_handler<transaction_t>
// This filter requires that calc_transactions be used at some point // This filter requires that calc_transactions be used at some point
// later in the chain. // later in the chain.
bool changed_values_only; bool changed_values_only;
transaction_t * last_xact; transaction_t * last_xact;
item_handler<transaction_t> * handler;
entries_deque entry_temps; entries_deque entry_temps;
transactions_deque xact_temps; transactions_deque xact_temps;
public: public:
changed_value_transactions(item_handler<transaction_t> * _handler, changed_value_transactions(item_handler<transaction_t> * handler,
bool _changed_values_only) bool _changed_values_only)
: changed_values_only(_changed_values_only), last_xact(NULL), : item_handler<transaction_t>(handler),
handler(_handler) {} changed_values_only(_changed_values_only), last_xact(NULL) {}
virtual ~changed_value_transactions() { virtual ~changed_value_transactions() {
flush(); close();
handler->flush();
delete handler;
for (entries_deque::iterator i = entry_temps.begin(); for (entries_deque::iterator i = entry_temps.begin();
i != entry_temps.end(); i != entry_temps.end();
@ -276,23 +262,18 @@ class subtotal_transactions : public item_handler<transaction_t>
typedef std::pair<account_t *, balance_pair_t> balances_pair; typedef std::pair<account_t *, balance_pair_t> balances_pair;
protected: protected:
std::time_t start; std::time_t start;
std::time_t finish; std::time_t finish;
balances_map balances; balances_map balances;
item_handler<transaction_t> * handler;
entries_deque entry_temps; entries_deque entry_temps;
transactions_deque xact_temps; transactions_deque xact_temps;
public: public:
subtotal_transactions(item_handler<transaction_t> * _handler) subtotal_transactions(item_handler<transaction_t> * handler)
: handler(_handler) {} : item_handler<transaction_t>(handler) {}
virtual ~subtotal_transactions() { virtual ~subtotal_transactions() {
flush(); close();
handler->flush();
delete handler;
for (entries_deque::iterator i = entry_temps.begin(); for (entries_deque::iterator i = entry_temps.begin();
i != entry_temps.end(); i != entry_temps.end();
@ -316,11 +297,11 @@ class interval_transactions : public subtotal_transactions
transaction_t * last_xact; transaction_t * last_xact;
public: public:
interval_transactions(item_handler<transaction_t> * _handler, interval_transactions(item_handler<transaction_t> * handler,
const interval_t& _interval, const interval_t& _interval,
const std::time_t _begin = 0) const std::time_t _begin = 0)
: subtotal_transactions(_handler), : subtotal_transactions(handler), begin(_begin),
begin(_begin), interval(_interval), last_xact(NULL) {} interval(_interval), last_xact(NULL) {}
virtual ~interval_transactions() { virtual ~interval_transactions() {
start = begin; start = begin;
@ -338,10 +319,6 @@ class dow_transactions : public subtotal_transactions
dow_transactions(item_handler<transaction_t> * handler) dow_transactions(item_handler<transaction_t> * handler)
: subtotal_transactions(handler) {} : subtotal_transactions(handler) {}
virtual ~dow_transactions() {
flush();
}
virtual void flush(); virtual void flush();
virtual void operator()(transaction_t * xact) { virtual void operator()(transaction_t * xact) {
@ -354,17 +331,13 @@ class related_transactions : public item_handler<transaction_t>
{ {
bool also_matching; bool also_matching;
item_handler<transaction_t> * handler;
public: public:
related_transactions(item_handler<transaction_t> * _handler, related_transactions(item_handler<transaction_t> * handler,
bool _also_matching = false) const bool _also_matching = false)
: also_matching(_also_matching), handler(_handler) {} : item_handler<transaction_t>(handler),
also_matching(_also_matching) {}
virtual ~related_transactions() { virtual ~related_transactions() { close(); }
handler->flush();
delete handler;
}
virtual void operator()(transaction_t * xact) { virtual void operator()(transaction_t * xact) {
for (transactions_list::iterator i = xact->entry->transactions.begin(); for (transactions_list::iterator i = xact->entry->transactions.begin();