summaryrefslogtreecommitdiff
path: root/src/data/document.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-21 20:42:05 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:39:06 -0400
commit7380da43ab403dacb41d2010093d11942bb7cec1 (patch)
tree1b9db99b018695254584fe9f8b9ca34a4aa073cb /src/data/document.cc
parentf12d41f233d460bd6d2eb8efb90bf6e36e994a30 (diff)
downloadfork-ledger-7380da43ab403dacb41d2010093d11942bb7cec1.tar.gz
fork-ledger-7380da43ab403dacb41d2010093d11942bb7cec1.tar.bz2
fork-ledger-7380da43ab403dacb41d2010093d11942bb7cec1.zip
Many changes.
Diffstat (limited to 'src/data/document.cc')
-rw-r--r--src/data/document.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/data/document.cc b/src/data/document.cc
new file mode 100644
index 00000000..120440b0
--- /dev/null
+++ b/src/data/document.cc
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of New Artisans LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "document.h"
+
+namespace ledger {
+namespace xml {
+
+namespace {
+ const std::size_t ledger_builtins_size = 39;
+ const char * ledger_builtins[] = {
+ "account",
+ "account-path",
+ "amount",
+ "amount",
+ "amount-expr",
+ "arg",
+ "auto-entry",
+ "balance",
+ "checkin",
+ "cleared",
+ "code",
+ "commodity",
+ "commodity-conversion",
+ "commodity-nomarket",
+ "commodity-template",
+ "cost",
+ "current-year",
+ "date",
+ "default-account",
+ "directive",
+ "effective",
+ "entries",
+ "entry",
+ "from",
+ "journal",
+ "ledger",
+ "name",
+ "note",
+ "payee",
+ "pending",
+ "period",
+ "period-entry",
+ "price",
+ "price-history",
+ "rule",
+ "symbol",
+ "template",
+ "time",
+ "to",
+ "transaction",
+ "virtual",
+ "year"
+ };
+}
+
+node_t::nameid_t document_t::register_name(const string& name)
+{
+ optional<nameid_t> index = lookup_name_id(name);
+ if (index)
+ return *index;
+
+ if (! names)
+ names = names_t();
+
+ nameid_t real_index = names->size() + 1000;
+ names->push_back(name_pair(name, real_index));
+ DEBUG("xml.lookup", this << " Inserted name: " << name);
+
+ return real_index;
+}
+
+optional<node_t::nameid_t> document_t::lookup_name_id(const string& name) const
+{
+ if (optional<node_t::nameid_t> id = lookup_builtin_id(name))
+ return id;
+
+ if (! names)
+ return none;
+
+ DEBUG("xml.lookup", this << " Finding name: " << name);
+
+ typedef names_t::nth_index<1>::type names_by_name;
+
+ const names_by_name& name_index = names->get<1>();
+ names_by_name::const_iterator i = name_index.find(name);
+ if (i != name_index.end())
+ return (*i).second;
+
+ return none;
+}
+
+optional<node_t::nameid_t> document_t::lookup_builtin_id(const string& name)
+{
+ int first = 0;
+ int last = (int)ledger_builtins_size;
+
+ while (first <= last) {
+ int mid = (first + last) / 2; // compute mid point.
+
+ int result;
+ if ((result = (int)name[0] - (int)ledger_builtins[mid][0]) == 0)
+ result = std::strcmp(name.c_str(), ledger_builtins[mid]);
+
+ if (result > 0)
+ first = mid + 1; // repeat search in top half.
+ else if (result < 0)
+ last = mid - 1; // repeat search in bottom half.
+ else
+ return nameid_t(mid + 10);
+ }
+
+ return none;
+}
+
+optional<const char *> document_t::lookup_name(nameid_t id) const
+{
+ if (id < 1000) {
+ switch (id) {
+ case CURRENT:
+ return ".";
+ case PARENT:
+ return "..";
+ case ROOT:
+ return "";
+ case ALL:
+ return "*";
+
+ default:
+ assert(id >= 10);
+ return ledger_builtins[id - 10];
+ }
+ }
+ else if (names) {
+ assert(id >= 1000);
+ std::size_t index = id - 1000;
+ typedef names_t::nth_index<0>::type names_by_random_access;
+ const names_by_random_access& random_access = names->get<0>();
+ if (index < random_access.size())
+ return random_access[index].first.c_str();
+ }
+ return none;
+}
+
+void document_t::print(std::ostream& out) const
+{
+ out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ parent_node_t::print(out);
+}
+
+} // namespace xml
+} // namespace ledger