Some slight reorg.

This commit is contained in:
John Wiegley 2007-05-06 10:29:05 +00:00
parent 0528a1e49a
commit b95aa8d4ca
4 changed files with 62 additions and 139 deletions

View file

@ -56,17 +56,15 @@ bool amount_t::keep_tag = false;
bool amount_t::full_strings = false;
#define BIGINT_BULK_ALLOC 0x0001
#define BIGINT_KEEP_PREC 0x0002
#define BIGINT_BULK_ALLOC 0x01
#define BIGINT_KEEP_PREC 0x02
class amount_t::bigint_t
{
public:
typedef uint8_t precision_t;
mpz_t val;
precision_t prec;
uint8_t flags;
flags_t flags;
uint_least16_t ref;
uint_fast32_t index;
@ -87,10 +85,6 @@ class amount_t::bigint_t
~bigint_t();
};
std::size_t sizeof_bigint_t() {
return sizeof(amount_t::bigint_t);
}
#define MPZ(x) ((x)->val)
#ifndef THREADSAFE
@ -98,11 +92,9 @@ static mpz_t temp; // these are the global temp variables
static mpz_t divisor;
#endif
static amount_t::bigint_t * true_value = NULL;
inline amount_t::bigint_t::~bigint_t() {
TRACE_DTOR(bigint_t);
assert(ref == 0 || this == true_value);
assert(ref == 0);
mpz_clear(val);
}
@ -115,8 +107,16 @@ void amount_t::initialize()
if (! default_pool)
default_pool = new commodity_pool_t;
true_value = new amount_t::bigint_t;
mpz_set_ui(true_value->val, 1);
// Add time commodity conversions, so that timelog's may be parsed
// in terms of seconds, but reported as minutes or hours.
if (commodity_t * commodity = default_pool->create("s")) {
commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN);
parse_conversion("1.0m", "60s");
parse_conversion("1.0h", "60m");
} else {
assert(false);
}
}
void amount_t::shutdown()
@ -129,11 +129,6 @@ void amount_t::shutdown()
checked_delete(default_pool);
default_pool = NULL;
}
true_value->ref--;
assert(true_value->ref == 0);
checked_delete(true_value);
true_value = NULL;
}
void amount_t::_init()
@ -221,7 +216,7 @@ void amount_t::_release()
namespace {
amount_t::bigint_t::precision_t convert_double(mpz_t dest, double val)
amount_t::precision_t convert_double(mpz_t dest, double val)
{
#ifndef HAVE_GDTOA
// This code is far too imprecise to be worthwhile.
@ -261,7 +256,7 @@ namespace {
mpz_set_str(dest, buf, 10);
free(buf);
return amount_t::bigint_t::precision_t(exp);
return amount_t::precision_t(exp);
#else
int decpt, sign;
char * buf = dtoa(val, 0, 0, &decpt, &sign, NULL);
@ -868,9 +863,7 @@ static void parse_commodity(std::istream& in, string& symbol)
symbol = buf;
}
bool parse_annotations(commodity_pool_t& parent,
std::istream& in,
annotation_t& details)
bool parse_annotations(std::istream& in, annotation_t& details)
{
do {
char buf[256];
@ -887,7 +880,7 @@ bool parse_annotations(commodity_pool_t& parent,
throw_(amount_error, "Commodity price lacks closing brace");
amount_t temp;
temp.parse(parent, buf, AMOUNT_PARSE_NO_MIGRATE);
temp.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
temp.in_place_reduce();
// Since this price will maintain its own precision, make sure
@ -943,7 +936,7 @@ bool parse_annotations(commodity_pool_t& parent,
return details;
}
void amount_t::parse(commodity_pool_t& parent, std::istream& in, uint8_t flags)
void amount_t::parse(std::istream& in, flags_t flags)
{
// The possible syntax for an amount is:
//
@ -977,7 +970,7 @@ void amount_t::parse(commodity_pool_t& parent, std::istream& in, uint8_t flags)
comm_flags |= COMMODITY_STYLE_SUFFIXED;
if (! in.eof() && ((n = in.peek()) != '\n'))
parse_annotations(parent, in, details);
parse_annotations(in, details);
}
} else {
parse_commodity(in, symbol);
@ -989,7 +982,7 @@ void amount_t::parse(commodity_pool_t& parent, std::istream& in, uint8_t flags)
parse_quantity(in, quant);
if (! quant.empty() && ! in.eof() && ((n = in.peek()) != '\n'))
parse_annotations(parent, in, details);
parse_annotations(in, details);
}
}
@ -1006,15 +999,15 @@ void amount_t::parse(commodity_pool_t& parent, std::istream& in, uint8_t flags)
if (symbol.empty()) {
commodity_ = NULL;
} else {
commodity_ = parent.find(symbol);
commodity_ = default_pool->find(symbol);
if (! commodity_) {
commodity_ = parent.create(symbol);
commodity_ = default_pool->create(symbol);
newly_created = true;
}
assert(commodity_);
if (details)
commodity_ = parent.find_or_create(*commodity_, details);
commodity_ = default_pool->find_or_create(*commodity_, details);
}
// Determine the precision of the amount, based on the usage of
@ -1085,14 +1078,13 @@ void amount_t::parse(commodity_pool_t& parent, std::istream& in, uint8_t flags)
in_place_reduce();
}
void amount_t::parse_conversion(commodity_pool_t& parent,
const string& larger_str,
void amount_t::parse_conversion(const string& larger_str,
const string& smaller_str)
{
amount_t larger, smaller;
larger.parse(parent, larger_str, AMOUNT_PARSE_NO_REDUCE);
smaller.parse(parent, smaller_str, AMOUNT_PARSE_NO_REDUCE);
larger.parse(larger_str, AMOUNT_PARSE_NO_REDUCE);
smaller.parse(smaller_str, AMOUNT_PARSE_NO_REDUCE);
larger *= smaller.number();
@ -1128,8 +1120,8 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
// Ensure the value is rounded to the commodity's precision before
// outputting it. NOTE: `rquotient' is used here as a temp variable!
commodity_t& comm(base.commodity());
bigint_t::precision_t precision = 0;
commodity_t& comm(base.commodity());
precision_t precision = 0;
if (quantity) {
if (! comm || full_precision || base.quantity->flags & BIGINT_KEEP_PREC) {
@ -1285,32 +1277,32 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
}
void amount_t::read(commodity_pool_t& parent, std::istream& in)
void amount_t::read(std::istream& in)
{
commodity_t::ident_t ident;
read_binary_long(in, ident);
if (ident == 0xffffffff)
commodity_ = NULL;
else if (ident == 0)
commodity_ = parent.null_commodity;
commodity_ = default_pool->null_commodity;
else {
commodity_ = parent.find(ident - 1);
commodity_ = default_pool->find(ident - 1);
assert(commodity_);
}
read_quantity(in);
}
void amount_t::read(commodity_pool_t& parent, char *& data)
void amount_t::read(char *& data)
{
commodity_t::ident_t ident;
read_binary_long(data, ident);
if (ident == 0xffffffff)
commodity_ = NULL;
else if (ident == 0)
commodity_ = parent.null_commodity;
commodity_ = default_pool->null_commodity;
else {
commodity_ = parent.find(ident - 1);
commodity_ = default_pool->find(ident - 1);
assert(commodity_);
}
@ -1355,10 +1347,10 @@ void amount_t::read_quantity(char *& data)
if (negative)
mpz_neg(MPZ(quantity), MPZ(quantity));
quantity->prec = *((bigint_t::precision_t *) data);
data += sizeof(bigint_t::precision_t);
quantity->flags = *((uint8_t *) data);
data += sizeof(uint8_t);
quantity->prec = *((precision_t *) data);
data += sizeof(precision_t);
quantity->flags = *((flags_t *) data);
data += sizeof(flags_t);
quantity->flags |= BIGINT_BULK_ALLOC;
} else {
uint_fast32_t index = *((uint_fast32_t *) data);
@ -1436,7 +1428,7 @@ void amount_t::write_quantity(std::ostream& out) const
out.write(&byte, sizeof(byte));
out.write((char *)&quantity->prec, sizeof(quantity->prec));
uint8_t flags = quantity->flags & ~BIGINT_BULK_ALLOC;
flags_t flags = quantity->flags & ~BIGINT_BULK_ALLOC;
assert(sizeof(flags) == sizeof(quantity->flags));
out.write((char *)&flags, sizeof(flags));
} else {

View file

@ -88,8 +88,6 @@ public:
static void shutdown();
public:
class bigint_t;
typedef uint_least16_t precision_t;
/**
@ -150,6 +148,8 @@ protected:
void _clear();
void _release();
class bigint_t;
bigint_t * quantity;
commodity_t * commodity_;
@ -201,7 +201,7 @@ public:
/**
* Destructor. Releases the reference count held for the underlying
* bigint_t object.
* bigint_t object pointed to be `quantity'.
*/
~amount_t() {
TRACE_DTOR(amount_t);
@ -506,16 +506,10 @@ public:
* defined which simply calls parse on the input stream. The
* `parse' method has two forms:
*
* parse(commodity_pool_t, istream, flags_t) parses an
* amount from the given input stream, registering commodity details
* according to the commodity pool which is passed in as the first
* parameter.
* parse(istream, flags_t) parses an amount from the given input
* stream.
*
* parse(istream, flags_t) is the same as the preceding function,
* only it uses `amount_t::default_pool' as the commodity pool.
*
* parse(commodity_pool_t, string, flags_t) parses an amount from
* the given string.
* parse(string, flags_t) parses an amount from the given string.
*
* parse(string, flags_t) also parses an amount from a string.
*
@ -551,30 +545,14 @@ public:
typedef uint_least8_t flags_t;
void parse(commodity_pool_t& parent, std::istream& in, flags_t flags = 0);
void parse(commodity_pool_t& parent, const string& str, flags_t flags = 0) {
std::istringstream stream(str);
parse(parent, stream, flags);
}
void parse(std::istream& in, flags_t flags = 0) {
assert(default_pool);
parse(*default_pool, in, flags);
}
void parse(std::istream& in, flags_t flags = 0);
void parse(const string& str, flags_t flags = 0) {
assert(default_pool);
parse(*default_pool, str, flags);
std::istringstream stream(str);
parse(stream, flags);
}
static void parse_conversion(commodity_pool_t& parent,
const string& larger_str,
const string& smaller_str);
static void parse_conversion(const string& larger_str,
const string& smaller_str) {
assert(default_pool);
parse_conversion(*default_pool, larger_str, smaller_str);
}
const string& smaller_str);
/**
* Printing methods. An amount may be output to a stream using the
@ -600,40 +578,23 @@ public:
* input stream or a character pointer, and it may be serialized to
* an output stream. The methods used are:
*
* read(commodity_pool_t, istream) reads an amount from the given
* input stream. It must have been put there using
* `write(ostream)'. Also, the given pool must be exactly what it
* was at the time the amount was `written'. Thus, the required
* read(istream) reads an amount from the given input stream. It
* must have been put there using `write(ostream)'. The required
* flow of logic is:
* amount.write(out)
* pool.write(out)
* pool.read(in)
* amount.read(pool, in)
* amount_t::default_pool->write(out)
* amount.write(out) // write out all amounts
* amount_t::default_pool->read(in)
* amount.read(in)
*
* read(istream) does the same as read, only it relies on
* `amount_t::default_pool' to specify the pool.
*
* read(commodity_pool_t, char *&) reads an amount from data which
* has been read from an input stream into a buffer. it advances
* the pointer passed in to the end of the deserialized amount.
*
* read(char *&) does the same as read, only it relies on
* `amount_t::default_pool' to specify the pool.
* read(char *&) reads an amount from data which has been read from
* an input stream into a buffer. It advances the pointer passed in
* to the end of the deserialized amount.
*
* write(ostream) writes an amount to an output stream in a compact
* binary format.
*/
void read(commodity_pool_t& parent, std::istream& in);
void read(commodity_pool_t& parent, char *& data);
void read(std::istream& in) {
assert(default_pool);
read(*default_pool, in);
}
void read(char *& data) {
assert(default_pool);
read(*default_pool, data);
}
void read(std::istream& in);
void read(char *& data);
void write(std::ostream& out) const;
@ -665,9 +626,7 @@ public:
bool valid() const;
private:
friend bool parse_annotations(commodity_pool_t& parent,
std::istream& in,
annotation_t& details);
friend bool parse_annotations(std::istream& in, annotation_t& details);
};
inline amount_t amount_t::exact(const string& value) {

View file

@ -267,14 +267,6 @@ commodity_pool_t::commodity_pool_t() : default_commodity(NULL)
null_commodity = create("");
null_commodity->add_flags(COMMODITY_STYLE_NOMARKET |
COMMODITY_STYLE_BUILTIN);
// Add time commodity conversions, so that timelog's may be parsed
// in terms of seconds, but reported as minutes or hours.
commodity_t * commodity = create("s");
commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN);
amount_t::parse_conversion(*this, "1.0m", "60s");
amount_t::parse_conversion(*this, "1.0h", "60m");
}
commodity_t * commodity_pool_t::create(const string& symbol)

View file

@ -393,26 +393,6 @@ public:
commodity_t * find_or_create(commodity_t& comm,
const annotation_t& details);
void parse_amount(amount_t& amount, std::istream& in,
amount_t::flags_t flags = 0) {
amount.parse(*this, in, flags);
}
void parse_amount(amount_t& amount, const string& str,
amount_t::flags_t flags = 0) {
amount.parse(*this, str, flags);
}
amount_t parse_amount(std::istream& in, amount_t::flags_t flags = 0) {
amount_t temp;
parse_amount(temp, in, flags);
return temp;
}
amount_t parse_amount(const string& str, amount_t::flags_t flags = 0) {
amount_t temp;
parse_amount(temp, str, flags);
return temp;
}
};
} // namespace ledger