summaryrefslogtreecommitdiff
path: root/binary.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2006-02-25 10:55:49 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:41:26 -0400
commitf2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac (patch)
treecd0dd475208cb9af1e8f2c95530d7ca4b73ad766 /binary.cc
parent9545b22b41e06dcbee1a1368eddf709218458eb2 (diff)
downloadfork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.tar.gz
fork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.tar.bz2
fork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.zip
*** empty log message ***
Diffstat (limited to 'binary.cc')
-rw-r--r--binary.cc243
1 files changed, 175 insertions, 68 deletions
diff --git a/binary.cc b/binary.cc
index fd22c443..cd96512a 100644
--- a/binary.cc
+++ b/binary.cc
@@ -11,11 +11,19 @@
namespace ledger {
static unsigned long binary_magic_number = 0xFFEED765;
+#ifdef USE_EDITOR
+#ifdef DEBUG_ENABLED
+static unsigned long format_version = 0x00020583;
+#else
+static unsigned long format_version = 0x00020582;
+#endif
+#else
#ifdef DEBUG_ENABLED
static unsigned long format_version = 0x00020503;
#else
static unsigned long format_version = 0x00020502;
#endif
+#endif
static account_t ** accounts;
static account_t ** accounts_next;
@@ -46,12 +54,43 @@ inline void read_binary_number(std::istream& in, T& num) {
}
template <typename T>
+inline void read_binary_long(std::istream& in, T& num) {
+ unsigned char len;
+ in.read((char *)&len, sizeof(unsigned char));
+
+ num = 0;
+ unsigned char temp;
+ if (len > 3) {
+ in.read((char *)&temp, sizeof(unsigned char));
+ num |= ((unsigned long)temp) << 24;
+ }
+ if (len > 2) {
+ in.read((char *)&temp, sizeof(unsigned char));
+ num |= ((unsigned long)temp) << 16;
+ }
+ if (len > 1) {
+ in.read((char *)&temp, sizeof(unsigned char));
+ num |= ((unsigned long)temp) << 8;
+ }
+
+ in.read((char *)&temp, sizeof(unsigned char));
+ num |= ((unsigned long)temp);
+}
+
+template <typename T>
inline T read_binary_number(std::istream& in) {
T num;
read_binary_number(in, num);
return num;
}
+template <typename T>
+inline T read_binary_long(std::istream& in) {
+ T num;
+ read_binary_long(in, num);
+ return num;
+}
+
inline void read_binary_string(std::istream& in, std::string& str)
{
read_binary_guard(in, 0x3001);
@@ -93,12 +132,42 @@ inline void read_binary_number(char *& data, T& num) {
}
template <typename T>
+inline void read_binary_long(char *& data, T& num) {
+ unsigned char len = *((unsigned char *)data++);
+
+ num = 0;
+ unsigned char temp;
+ if (len > 3) {
+ temp = *((unsigned char *)data++);
+ num |= ((unsigned long)temp) << 24;
+ }
+ if (len > 2) {
+ temp = *((unsigned char *)data++);
+ num |= ((unsigned long)temp) << 16;
+ }
+ if (len > 1) {
+ temp = *((unsigned char *)data++);
+ num |= ((unsigned long)temp) << 8;
+ }
+
+ temp = *((unsigned char *)data++);
+ num |= ((unsigned long)temp);
+}
+
+template <typename T>
inline T read_binary_number(char *& data) {
T num;
read_binary_number(data, num);
return num;
}
+template <typename T>
+inline T read_binary_long(char *& data) {
+ T num;
+ read_binary_long(data, num);
+ return num;
+}
+
inline void read_binary_string(char *& data, std::string& str)
{
#if DEBUG_LEVEL >= ALPHA
@@ -169,7 +238,7 @@ inline void read_binary_string(char *& data, std::string * str)
inline void read_binary_amount(char *& data, amount_t& amt)
{
commodity_t::ident_t ident;
- read_binary_number(data, ident);
+ read_binary_long(data, ident);
if (ident == 0xffffffff)
amt.commodity_ = NULL;
else if (ident == 0)
@@ -182,9 +251,9 @@ inline void read_binary_amount(char *& data, amount_t& amt)
inline void read_binary_transaction(char *& data, transaction_t * xact)
{
- read_binary_number(data, xact->_date);
- read_binary_number(data, xact->_date_eff);
- xact->account = accounts[read_binary_number<account_t::ident_t>(data) - 1];
+ read_binary_long(data, xact->_date);
+ read_binary_long(data, xact->_date_eff);
+ xact->account = accounts[read_binary_long<account_t::ident_t>(data) - 1];
read_binary_amount(data, xact->amount);
if (*data++ == 1) {
@@ -198,10 +267,13 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
read_binary_number(data, xact->flags);
xact->flags |= TRANSACTION_BULK_ALLOC;
read_binary_string(data, &xact->note);
- read_binary_number(data, xact->beg_pos);
- read_binary_number(data, xact->beg_line);
- read_binary_number(data, xact->end_pos);
- read_binary_number(data, xact->end_line);
+
+#ifdef USE_EDITOR
+ xact->beg_pos = read_binary_long<unsigned long>(data);
+ read_binary_long(data, xact->beg_line);
+ xact->end_pos = read_binary_long<unsigned long>(data);
+ read_binary_long(data, xact->end_line);
+#endif
xact->data = NULL;
}
@@ -209,13 +281,15 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
inline void read_binary_entry_base(char *& data, entry_base_t * entry,
transaction_t *& xact_pool)
{
- read_binary_number(data, entry->src_idx);
- read_binary_number(data, entry->beg_pos);
- read_binary_number(data, entry->beg_line);
- read_binary_number(data, entry->end_pos);
- read_binary_number(data, entry->end_line);
+#ifdef USE_EDITOR
+ read_binary_long(data, entry->src_idx);
+ entry->beg_pos = read_binary_long<unsigned long>(data);
+ read_binary_long(data, entry->beg_line);
+ entry->end_pos = read_binary_long<unsigned long>(data);
+ read_binary_long(data, entry->end_line);
+#endif
- for (unsigned long i = 0, count = read_binary_number<unsigned long>(data);
+ for (unsigned long i = 0, count = read_binary_long<unsigned long>(data);
i < count;
i++) {
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
@@ -228,8 +302,8 @@ inline void read_binary_entry(char *& data, entry_t * entry,
transaction_t *& xact_pool)
{
read_binary_entry_base(data, entry, xact_pool);
- read_binary_number(data, entry->_date);
- read_binary_number(data, entry->_date_eff);
+ read_binary_long(data, entry->_date);
+ read_binary_long(data, entry->_date_eff);
read_binary_string(data, &entry->code);
read_binary_string(data, &entry->payee);
}
@@ -262,7 +336,7 @@ inline commodity_t * read_binary_commodity(char *& data)
read_binary_string(data, commodity->note);
read_binary_number(data, commodity->precision);
read_binary_number(data, commodity->flags);
- read_binary_number(data, commodity->ident);
+ read_binary_long(data, commodity->ident);
return commodity;
}
@@ -272,11 +346,11 @@ inline void read_binary_commodity_extra(char *& data,
{
commodity_t * commodity = commodities[ident];
- for (unsigned long i = 0, count = read_binary_number<unsigned long>(data);
+ for (unsigned long i = 0, count = read_binary_long<unsigned long>(data);
i < count;
i++) {
std::time_t when;
- read_binary_number(data, when);
+ read_binary_long(data, when);
amount_t amt;
read_binary_amount(data, amt);
@@ -288,7 +362,7 @@ inline void read_binary_commodity_extra(char *& data,
commodity->history->prices.insert(history_pair(when, amt));
}
if (commodity->history)
- read_binary_number(data, commodity->history->last_lookup);
+ read_binary_long(data, commodity->history->last_lookup);
unsigned char flag;
@@ -314,11 +388,11 @@ account_t * read_binary_account(char *& data, journal_t * journal,
account_t * acct = new account_t(NULL);
*accounts_next++ = acct;
- acct->ident = read_binary_number<account_t::ident_t>(data);
+ acct->ident = read_binary_long<account_t::ident_t>(data);
acct->journal = journal;
account_t::ident_t id;
- read_binary_number(data, id); // parent id
+ read_binary_long(data, id); // parent id
if (id == 0xffffffff)
acct->parent = NULL;
else
@@ -338,7 +412,7 @@ account_t * read_binary_account(char *& data, journal_t * journal,
}
for (account_t::ident_t i = 0,
- count = read_binary_number<account_t::ident_t>(data);
+ count = read_binary_long<account_t::ident_t>(data);
i < count;
i++) {
account_t * child = read_binary_account(data, journal);
@@ -370,7 +444,7 @@ unsigned int read_binary_journal(std::istream& in,
return 0;
std::time_t old_mtime;
- read_binary_number(in, old_mtime);
+ read_binary_long(in, old_mtime);
struct stat info;
stat(path.c_str(), &info);
if (std::difftime(info.st_mtime, old_mtime) > 0)
@@ -397,19 +471,19 @@ unsigned int read_binary_journal(std::istream& in,
// Read in the accounts
- account_t::ident_t a_count = read_binary_number<account_t::ident_t>(data);
+ account_t::ident_t a_count = read_binary_long<account_t::ident_t>(data);
accounts = accounts_next = new account_t *[a_count];
journal->master = read_binary_account(data, journal, master);
if (read_binary_number<bool>(data))
- journal->basket = accounts[read_binary_number<account_t::ident_t>(data) - 1];
+ journal->basket = accounts[read_binary_long<account_t::ident_t>(data) - 1];
// Allocate the memory needed for the entries and transactions in
// one large block, which is then chopped up and custom constructed
// as necessary.
- unsigned long count = read_binary_number<unsigned long>(data);
- unsigned long auto_count = read_binary_number<unsigned long>(data);
- unsigned long period_count = read_binary_number<unsigned long>(data);
+ unsigned long count = read_binary_long<unsigned long>(data);
+ unsigned long auto_count = read_binary_long<unsigned long>(data);
+ unsigned long period_count = read_binary_long<unsigned long>(data);
unsigned long xact_count = read_binary_number<unsigned long>(data);
unsigned long bigint_count = read_binary_number<unsigned long>(data);
@@ -428,7 +502,7 @@ unsigned int read_binary_journal(std::istream& in,
// Read in the commodities
- commodity_t::ident_t c_count = read_binary_number<commodity_t::ident_t>(data);
+ commodity_t::ident_t c_count = read_binary_long<commodity_t::ident_t>(data);
commodities = commodities_next = new commodity_t *[c_count];
for (commodity_t::ident_t i = 0; i < c_count; i++) {
commodity_t * commodity = read_binary_commodity(data);
@@ -446,7 +520,7 @@ unsigned int read_binary_journal(std::istream& in,
read_binary_commodity_extra(data, i);
commodity_t::ident_t ident;
- read_binary_number(data, ident);
+ read_binary_long(data, ident);
if (ident == 0xffffffff || ident == 0)
commodity_t::default_commodity = NULL;
else
@@ -490,7 +564,7 @@ unsigned int read_binary_journal(std::istream& in,
bool binary_parser_t::test(std::istream& in) const
{
if (read_binary_number<unsigned long>(in) == binary_magic_number &&
- read_binary_number<unsigned long>(in) == format_version)
+ read_binary_long<unsigned long>(in) == format_version)
return true;
in.clear();
@@ -522,6 +596,34 @@ inline void write_binary_number(std::ostream& out, T num) {
out.write((char *)&num, sizeof(num));
}
+template <typename T>
+inline void write_binary_long(std::ostream& out, T num) {
+ unsigned char len = 4;
+ if (((unsigned long)num) < 0x00000100UL)
+ len = 1;
+ else if (((unsigned long)num) < 0x00010000UL)
+ len = 2;
+ else if (((unsigned long)num) < 0x01000000UL)
+ len = 3;
+ out.write((char *)&len, sizeof(unsigned char));
+
+ if (len > 3) {
+ unsigned char temp = (((unsigned long)num) & 0xFF000000UL) >> 24;
+ out.write((char *)&temp, sizeof(unsigned char));
+ }
+ if (len > 2) {
+ unsigned char temp = (((unsigned long)num) & 0x00FF0000UL) >> 16;
+ out.write((char *)&temp, sizeof(unsigned char));
+ }
+ if (len > 1) {
+ unsigned char temp = (((unsigned long)num) & 0x0000FF00UL) >> 8;
+ out.write((char *)&temp, sizeof(unsigned char));
+ }
+
+ unsigned char temp = (((unsigned long)num) & 0x000000FFUL);
+ out.write((char *)&temp, sizeof(unsigned char));
+}
+
inline void write_binary_string(std::ostream& out, const std::string& str)
{
write_binary_guard(out, 0x3001);
@@ -544,18 +646,18 @@ inline void write_binary_string(std::ostream& out, const std::string& str)
void write_binary_amount(std::ostream& out, const amount_t& amt)
{
if (amt.commodity_)
- write_binary_number(out, amt.commodity().ident);
+ write_binary_long(out, amt.commodity().ident);
else
- write_binary_number<commodity_t::ident_t>(out, 0xffffffff);
+ write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
amt.write_quantity(out);
}
void write_binary_transaction(std::ostream& out, transaction_t * xact)
{
- write_binary_number(out, xact->_date);
- write_binary_number(out, xact->_date_eff);
- write_binary_number(out, xact->account->ident);
+ write_binary_long(out, xact->_date);
+ write_binary_long(out, xact->_date_eff);
+ write_binary_long(out, xact->account->ident);
write_binary_amount(out, xact->amount);
if (xact->cost) {
@@ -568,21 +670,26 @@ void write_binary_transaction(std::ostream& out, transaction_t * xact)
write_binary_number(out, xact->state);
write_binary_number(out, xact->flags);
write_binary_string(out, xact->note);
- write_binary_number<istream_pos_type>(out, xact->beg_pos);
- write_binary_number<unsigned long>(out, xact->beg_line);
- write_binary_number<istream_pos_type>(out, xact->end_pos);
- write_binary_number<unsigned long>(out, xact->end_line);
+
+#ifdef USE_EDITOR
+ write_binary_long(out, xact->beg_pos);
+ write_binary_long(out, xact->beg_line);
+ write_binary_long(out, xact->end_pos);
+ write_binary_long(out, xact->end_line);
+#endif
}
void write_binary_entry_base(std::ostream& out, entry_base_t * entry)
{
- write_binary_number<unsigned long>(out, entry->src_idx);
- write_binary_number<istream_pos_type>(out, entry->beg_pos);
- write_binary_number<unsigned long>(out, entry->beg_line);
- write_binary_number<istream_pos_type>(out, entry->end_pos);
- write_binary_number<unsigned long>(out, entry->end_line);
+#ifdef USE_EDITOR
+ write_binary_long(out, entry->src_idx);
+ write_binary_long(out, entry->beg_pos);
+ write_binary_long(out, entry->beg_line);
+ write_binary_long(out, entry->end_pos);
+ write_binary_long(out, entry->end_line);
+#endif
- write_binary_number<unsigned long>(out, entry->transactions.size());
+ write_binary_long(out, entry->transactions.size());
for (transactions_list::const_iterator i = entry->transactions.begin();
i != entry->transactions.end();
i++)
@@ -592,8 +699,8 @@ void write_binary_entry_base(std::ostream& out, entry_base_t * entry)
void write_binary_entry(std::ostream& out, entry_t * entry)
{
write_binary_entry_base(out, entry);
- write_binary_number(out, entry->_date);
- write_binary_number(out, entry->_date_eff);
+ write_binary_long(out, entry->_date);
+ write_binary_long(out, entry->_date_eff);
write_binary_string(out, entry->code);
write_binary_string(out, entry->payee);
}
@@ -619,22 +726,22 @@ void write_binary_commodity(std::ostream& out, commodity_t * commodity)
write_binary_number(out, commodity->precision);
write_binary_number(out, commodity->flags);
commodity->ident = ++commodity_index;
- write_binary_number(out, commodity->ident);
+ write_binary_long(out, commodity->ident);
}
void write_binary_commodity_extra(std::ostream& out, commodity_t * commodity)
{
if (! commodity->history) {
- write_binary_number<unsigned long>(out, 0);
+ write_binary_long<unsigned long>(out, 0);
} else {
- write_binary_number<unsigned long>(out, commodity->history->prices.size());
+ write_binary_long<unsigned long>(out, commodity->history->prices.size());
for (history_map::const_iterator i = commodity->history->prices.begin();
i != commodity->history->prices.end();
i++) {
- write_binary_number(out, (*i).first);
+ write_binary_long(out, (*i).first);
write_binary_amount(out, (*i).second);
}
- write_binary_number(out, commodity->history->last_lookup);
+ write_binary_long(out, commodity->history->last_lookup);
}
if (commodity->smaller) {
@@ -668,17 +775,17 @@ void write_binary_account(std::ostream& out, account_t * account)
{
account->ident = ++account_index;
- write_binary_number(out, account->ident);
+ write_binary_long(out, account->ident);
if (account->parent)
- write_binary_number(out, account->parent->ident);
+ write_binary_long(out, account->parent->ident);
else
- write_binary_number<account_t::ident_t>(out, 0xffffffff);
+ write_binary_long<account_t::ident_t>(out, 0xffffffff);
write_binary_string(out, account->name);
write_binary_string(out, account->note);
write_binary_number(out, account->depth);
- write_binary_number<account_t::ident_t>(out, account->accounts.size());
+ write_binary_long<account_t::ident_t>(out, account->accounts.size());
for (accounts_map::iterator i = account->accounts.begin();
i != account->accounts.end();
i++)
@@ -691,7 +798,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
commodity_index = 0;
write_binary_number(out, binary_magic_number);
- write_binary_number(out, format_version);
+ write_binary_long(out, format_version);
// Write out the files that participated in this journal, so that
// they can be checked for changes on reading.
@@ -706,7 +813,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
write_binary_string(out, *i);
struct stat info;
stat((*i).c_str(), &info);
- write_binary_number(out, std::time_t(info.st_mtime));
+ write_binary_long(out, std::time_t(info.st_mtime));
}
// Write out the price database that relates to this data file, so
@@ -719,21 +826,21 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
// Write out the accounts
- write_binary_number<account_t::ident_t>(out, count_accounts(journal->master));
+ write_binary_long<account_t::ident_t>(out, count_accounts(journal->master));
write_binary_account(out, journal->master);
if (journal->basket) {
write_binary_number<bool>(out, true);
- write_binary_number(out, journal->basket->ident);
+ write_binary_long(out, journal->basket->ident);
} else {
write_binary_number<bool>(out, false);
}
// Write out the number of entries, transactions, and amounts
- write_binary_number<unsigned long>(out, journal->entries.size());
- write_binary_number<unsigned long>(out, journal->auto_entries.size());
- write_binary_number<unsigned long>(out, journal->period_entries.size());
+ write_binary_long<unsigned long>(out, journal->entries.size());
+ write_binary_long<unsigned long>(out, journal->auto_entries.size());
+ write_binary_long<unsigned long>(out, journal->period_entries.size());
ostream_pos_type xacts_val = out.tellp();
@@ -744,7 +851,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
// Write out the commodities
- write_binary_number<commodity_t::ident_t>
+ write_binary_long<commodity_t::ident_t>
(out, commodity_t::commodities.size() - 1);
for (commodities_map::const_iterator i = commodity_t::commodities.begin();
@@ -762,9 +869,9 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
write_binary_commodity_extra(out, (*i).second);
if (commodity_t::default_commodity)
- write_binary_number(out, commodity_t::default_commodity->ident);
+ write_binary_long(out, commodity_t::default_commodity->ident);
else
- write_binary_number<commodity_t::ident_t>(out, 0xffffffff);
+ write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
// Write out the entries and transactions