Binary RDB format. Missing: progress bar on reading/writing, it is somewhat slower than necessary because of the counting passes.

This commit is contained in:
Matthias Koefferlein 2024-08-17 22:53:59 +02:00
parent 0f833da652
commit f9a1f730c1
5 changed files with 202 additions and 114 deletions

View File

@ -387,7 +387,7 @@ BEGIN_PROTECTED
} else {
rdb->save (rdb->filename ());
rdb->save (rdb->filename (), rdb->binary ());
rdb->reset_modified ();
}
@ -459,7 +459,7 @@ BEGIN_PROTECTED
throw tl::Exception (tl::to_string (tr ("The current report database is not saved.\nSave it to some file with 'Save As', before saving it as waiver DB.")));
}
rdb->write (rdb->filename () + ".w");
rdb->write (rdb->filename () + ".w", rdb->binary ());
END_PROTECTED
}
@ -475,11 +475,13 @@ BEGIN_PROTECTED
if (rdb) {
// prepare and open the file dialog
lay::FileDialog save_dialog (this, tl::to_string (QObject::tr ("Save Marker Database File")), "KLayout RDB files (*.lyrdb)");
lay::FileDialog save_dialog (this, tl::to_string (QObject::tr ("Save Marker Database File")), tl::to_string (tr ("KLayout RDB files (*.lyrdb);;KLayout binary RDB files (*.rdb);;All files (*)")));
std::string fn (rdb->filename ());
if (save_dialog.get_save (fn)) {
rdb->save (fn);
bool binary = (tl::extension (fn) == "rdb");
rdb->save (fn, binary);
rdb->reset_modified ();
// update the RDB title strings

View File

@ -1677,10 +1677,12 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
"The reader recognizes the format automatically and will choose the appropriate decoder. 'gzip' compressed files are uncompressed "
"automatically.\n"
) +
gsi::method ("save", &rdb::Database::save, gsi::arg ("filename"),
gsi::method ("save", &rdb::Database::save, gsi::arg ("filename"), gsi::arg ("binary", false),
"@brief Saves the database to the given file\n"
"@param filename The file to which to save the database\n"
"The database is always saved in KLayout's XML-based format.\n"
"The database is saved in KLayout's XML-based format if 'binary' is false or a ProtocolBuffer-based binary format if 'binary' is true.\n"
"\n"
"The 'binary' argument has been added in version 0.29.7."
),
"@brief The report database object\n"
"A report database is organized around a set of items which are associated with cells and categories. "

View File

@ -1767,6 +1767,7 @@ Database::clear ()
m_generator = "";
m_filename = "";
m_binary = false;
m_description = "";
m_name = "";
m_topcell = "";
@ -1819,6 +1820,7 @@ Database::load (std::string fn)
tl::log << "Loading RDB from " << fn;
clear ();
set_binary (false);
tl::InputStream stream (fn);

View File

@ -2044,7 +2044,7 @@ public:
~Database ();
/**
* @brief Get the database description
* @brief Gets the database description
*/
const std::string &description () const
{
@ -2052,7 +2052,7 @@ public:
}
/**
* @brief Set the database description
* @brief Sets the database description
*/
void set_description (const std::string &description)
{
@ -2061,7 +2061,7 @@ public:
}
/**
* @brief Get the database original file
* @brief Gets the database original file
*
* The original file describes what original file the marker database
* was derived from.
@ -2072,7 +2072,7 @@ public:
}
/**
* @brief Set the database original file
* @brief Sets the database original file
*/
void set_original_file (const std::string &original_file)
{
@ -2081,7 +2081,7 @@ public:
}
/**
* @brief Get the database name
* @brief Gets the database name
*/
const std::string &name () const
{
@ -2089,7 +2089,7 @@ public:
}
/**
* @brief Set the database name
* @brief Sets the database name
*/
void set_name (const std::string &name)
{
@ -2097,7 +2097,7 @@ public:
}
/**
* @brief Get the file name
* @brief Gets the file name
*/
const std::string &filename () const
{
@ -2105,7 +2105,7 @@ public:
}
/**
* @brief Set the file name
* @brief Sets the file name
*/
void set_filename (const std::string &filename)
{
@ -2114,7 +2114,24 @@ public:
}
/**
* @brief Get the generator name
* @brief Gets a value indicating whether the database was saved to binary format
*/
bool binary () const
{
return m_binary;
}
/**
* @brief Sets a value indicating whether the database was saved to binary format
*/
void set_binary (bool bin)
{
set_modified ();
m_binary = bin;
}
/**
* @brief Gets the generator name
*/
const std::string &generator () const
{
@ -2122,7 +2139,7 @@ public:
}
/**
* @brief Set the generator name
* @brief Sets the generator name
*/
void set_generator (const std::string &generator)
{
@ -2131,7 +2148,7 @@ public:
}
/**
* @brief Set the top cell name
* @brief Sets the top cell name
*/
void set_top_cell_name (const std::string &topcell)
{
@ -2140,7 +2157,7 @@ public:
}
/**
* @brief Return the top cell name
* @brief Returns the top cell name
*/
const std::string &top_cell_name () const
{
@ -2148,7 +2165,7 @@ public:
}
/*
* @brief Get the reference to the tags collection (const version)
* @brief Gets the reference to the tags collection (const version)
*/
const Tags &tags () const
{
@ -2156,14 +2173,14 @@ public:
}
/**
* @brief Import tags
* @brief Imports tags
*
* This method is provided for persistency application only. It should not be used otherwise.
*/
void import_tags (const Tags &tags);
/**
* @brief Get the reference to the categories collection (const version)
* @brief Gets the reference to the categories collection (const version)
*/
const Categories &categories () const
{
@ -2171,7 +2188,7 @@ public:
}
/**
* @brief Get the reference to the categories collection (non-const version)
* @brief Gets the reference to the categories collection (non-const version)
*/
Categories &categories_non_const ()
{
@ -2179,7 +2196,7 @@ public:
}
/**
* @brief Import categories
* @brief Imports categories
*
* This method is provided for persistency application only. It should not be used otherwise.
* This will take over the ownership over the Categories object.
@ -2187,17 +2204,17 @@ public:
void import_categories (Categories *categories);
/**
* @brief Create a category and register it
* @brief Creates a category and register it
*/
Category *create_category (const std::string &name);
/**
* @brief Create a category as a subcategory and register it
* @brief Creates a category as a subcategory and register it
*/
Category *create_category (Category *parent, const std::string &name);
/**
* @brief Create a category as a subcategory in the container and register it
* @brief Creates a category as a subcategory in the container and register it
*
* Hint: this method does not set the parent properly and must not be used
* under normal circumstances. It is provided as a internal method and
@ -2206,7 +2223,7 @@ public:
Category *create_category (Categories *container, const std::string &name);
/**
* @brief Get the category pointer for a category name (const version)
* @brief Gets the category pointer for a category name (const version)
*
* This method returns 0 if the category name is invalid.
*/
@ -2216,7 +2233,7 @@ public:
}
/**
* @brief Get the category pointer for a category id (const version)
* @brief Gets the category pointer for a category id (const version)
*
* This method returns 0 if the category is invalid.
*/
@ -2226,21 +2243,21 @@ public:
}
/**
* @brief Get the category pointer for a category name (non-const version)
* @brief Gets the category pointer for a category name (non-const version)
*
* This method returns 0 if the category name is invalid.
*/
Category *category_by_name_non_const (const std::string &name);
/**
* @brief Get the category pointer for a category id (non-const version)
* @brief Gets the category pointer for a category id (non-const version)
*
* This method returns 0 if the category is invalid.
*/
Category *category_by_id_non_const (id_type id);
/**
* @brief Access to the cell collection (const)
* @brief Gets the cell collection (const)
*/
const Cells &cells () const
{
@ -2248,7 +2265,7 @@ public:
}
/**
* @brief Access to the cell collection
* @brief Gets the cell collection
*/
Cells &cells_non_const ()
{
@ -2256,14 +2273,14 @@ public:
}
/**
* @brief Import cells
* @brief Imports cells
*
* This method is provided for persistency application only. It should not be used otherwise.
*/
void import_cells (const Cells &cells);
/**
* @brief Create a cell and register it
* @brief Creates a cell and registers it
*
* If a cell with that name already exists, a variant is created
*/
@ -2273,7 +2290,7 @@ public:
}
/**
* @brief Create a cell variant and register it
* @brief Creates a cell variant and registers it
*
* A cell with name name/variant combination must not exist already.
* If the variant string is empty, this method behaves the same as the
@ -2285,14 +2302,14 @@ public:
Cell *create_cell (const std::string &name, const std::string &variant, const std::string &layout_name);
/**
* @brief Get all variants registered for a given cell name (not qname!)
* @brief Gets all variants registered for a given cell name (not qname!)
*
* @return a vector of id's corresponding to the given variants or an empty vector if the name is not valid or the cell has no variants
*/
const std::vector <id_type> &variants (const std::string &name);
/**
* @brief Get the cell pointer for a cell name or name:variant combination (const version)
* @brief Gets the cell pointer for a cell name or name:variant combination (const version)
*
* This method returns 0 if the cell name or name:variant combination is invalid.
*/
@ -2302,7 +2319,7 @@ public:
}
/**
* @brief Get the cell pointer for a cell id (const version)
* @brief Gets the cell pointer for a cell id (const version)
*
* This method returns 0 if the cell id is invalid.
*/
@ -2312,21 +2329,21 @@ public:
}
/**
* @brief Get the cell pointer for a cell name or name:variant combination (non-const version)
* @brief Gets the cell pointer for a cell name or name:variant combination (non-const version)
*
* This method returns 0 if the cell name or name:variant combination is invalid.
*/
Cell *cell_by_qname_non_const (const std::string &qname);
/**
* @brief Get the cell pointer for a cell id (non-const version)
* @brief Gets the cell pointer for a cell id (non-const version)
*
* This method returns 0 if the cell id is invalid.
*/
Cell *cell_by_id_non_const (id_type id);
/**
* @brief Report the number of items in total
* @brief Reports the number of items in total
*/
size_t num_items () const
{
@ -2334,7 +2351,7 @@ public:
}
/**
* @brief Report the number of items visited
* @brief Reports the number of items visited
*/
size_t num_items_visited () const
{
@ -2342,37 +2359,37 @@ public:
}
/**
* @brief Report the number of items for a given cell and category id
* @brief Reports the number of items for a given cell and category id
*/
size_t num_items (id_type cell_id, id_type category_id) const;
/**
* @brief Report the number of items visited
* @brief Reports the number of items visited
*/
size_t num_items_visited (id_type cell_id, id_type category_id) const;
/**
* @brief Create a new item for the given cell and category (both given by id)
* @brief Creates a new item for the given cell and category (both given by id)
*/
Item *create_item (id_type cell_id, id_type category_id);
/**
* @brief Set a tag's description
* @brief Sets a tag's description
*/
void set_tag_description (id_type tag_id, const std::string &description);
/**
* @brief Set an item to visited state or reset the state
* @brief Sets an item to visited state or reset the state
*/
void set_item_visited (const Item *item, bool visited);
/**
* @brief Add a tag to the given item
* @brief Adds a tag to the given item
*/
void add_item_tag (const Item *item, id_type tag);
/**
* @brief Remove a tag from the given item
* @brief Removes a tag from the given item
*/
void remove_item_tag (const Item *item, id_type tag);
@ -2383,23 +2400,23 @@ public:
#if defined(HAVE_QT)
/**
* @brief Set the image of an item
* @brief Sets the image of an item
*/
void set_item_image (const Item *item, const QImage &image);
#endif
/**
* @brief Set the image string of an item
* @brief Sets the image string of an item
*/
void set_item_image_str (const Item *item, const std::string &image_str);
/**
* @brief Set the multiplicity of an item
* @brief Sets the multiplicity of an item
*/
void set_item_multiplicity (const Item *item, size_t n);
/**
* @brief Get the items collection (const version)
* @brief Gets the items collection (const version)
*/
const Items &items () const
{
@ -2407,7 +2424,7 @@ public:
}
/**
* @brief Get the items collection (non-const version)
* @brief Gets the items collection (non-const version)
*/
Items &items_non_const ()
{
@ -2415,7 +2432,7 @@ public:
}
/**
* @brief Set the items collection
* @brief Sets the items collection
*
* This method is provided for persistency application only. It should not be used otherwise.
* This will take ownership over the items collection.
@ -2423,32 +2440,32 @@ public:
void set_items (Items *items);
/**
* @brief Get an iterator pair that delivers the const items (ItemRef) for a given cell
* @brief Gets an iterator pair that delivers the const items (ItemRef) for a given cell
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell (id_type cell_id) const;
/**
* @brief Get an iterator pair that delivers the non-const items (ItemRef) for a given cell
* @brief Gets an iterator pair that delivers the non-const items (ItemRef) for a given cell
*/
std::pair<item_ref_iterator, item_ref_iterator> items_by_cell (id_type cell_id);
/**
* @brief Get an iterator that delivers the const items (ItemRef) for a given category
* @brief Gets an iterator that delivers the const items (ItemRef) for a given category
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_category (id_type category_id) const;
/**
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given category
* @brief Gets an iterator that delivers the non-const items (ItemRef) for a given category
*/
std::pair<item_ref_iterator, item_ref_iterator> items_by_category (id_type category_id);
/**
* @brief Get an iterator that delivers the const items (ItemRef) for a given cell and category
* @brief Gets an iterator that delivers the const items (ItemRef) for a given cell and category
*/
std::pair<const_item_ref_iterator, const_item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id) const;
/**
* @brief Get an iterator that delivers the non-const items (ItemRef) for a given cell and category
* @brief Gets an iterator that delivers the non-const items (ItemRef) for a given cell and category
*/
std::pair<item_ref_iterator, item_ref_iterator> items_by_cell_and_category (id_type cell_id, id_type category_id);
@ -2461,7 +2478,7 @@ public:
}
/**
* @brief Reset the modified file
* @brief Resets the modified file
*/
void reset_modified ()
{
@ -2469,19 +2486,19 @@ public:
}
/**
* @brief Save the database to a file
* @brief Saves the database to a file
*/
void save (const std::string &filename);
void save (const std::string &filename, bool binary = false);
/**
* @brief Write the database to a file
* @brief Writes the database to a file
*
* This function is like "save", but does not update the file name attribute.
*/
void write (const std::string &filename);
void write (const std::string &filename, bool binary = false);
/**
* @brief Load the database from a file
* @brief Loads the database from a file
*
* Note: This clears the existing database.
* The argument intentionally is a copy, so we can call
@ -2510,6 +2527,7 @@ public:
private:
std::string m_generator;
std::string m_filename;
bool m_binary;
std::string m_description;
std::string m_original_file;
std::string m_name;

View File

@ -71,81 +71,96 @@ make_rdb_structure ()
{
static
tl::XMLElementList categories_format =
tl::make_element_with_parent_ref<rdb::Category, rdb::Categories::const_iterator, rdb::Categories> (&rdb::Categories::begin, &rdb::Categories::end, &rdb::Categories::import_category, "category",
tl::make_member<std::string, rdb::Category> (&rdb::Category::name, &rdb::Category::set_name, "name") +
tl::make_member<std::string, rdb::Category> (&rdb::Category::description, &rdb::Category::set_description, "description") +
tl::make_element_with_parent_ref<rdb::Categories, rdb::Category> (&rdb::Category::sub_categories, &rdb::Category::import_sub_categories, "categories",
tl::make_element_with_parent_ref<rdb::Category, rdb::Categories::const_iterator, rdb::Categories> (&rdb::Categories::begin, &rdb::Categories::end, &rdb::Categories::import_category, "category#1",
tl::make_member<std::string, rdb::Category> (&rdb::Category::name, &rdb::Category::set_name, "name#1") +
tl::make_member<std::string, rdb::Category> (&rdb::Category::description, &rdb::Category::set_description, "description#2") +
tl::make_element_with_parent_ref<rdb::Categories, rdb::Category> (&rdb::Category::sub_categories, &rdb::Category::import_sub_categories, "categories#3",
&categories_format
)
)
;
return tl::XMLStruct <rdb::Database>("report-database",
tl::make_member<std::string, rdb::Database> (&rdb::Database::description, &rdb::Database::set_description, "description") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::original_file, &rdb::Database::set_original_file, "original-file") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::generator, &rdb::Database::set_generator, "generator") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::top_cell_name, &rdb::Database::set_top_cell_name, "top-cell") +
tl::make_element<rdb::Tags, rdb::Database> (&rdb::Database::tags, &rdb::Database::import_tags, "tags",
tl::make_element<rdb::Tag, rdb::Tags::const_iterator, rdb::Tags> (&rdb::Tags::begin_tags, &rdb::Tags::end_tags, &rdb::Tags::import_tag, "tag",
tl::make_member<std::string, rdb::Tag> (&rdb::Tag::name, &rdb::Tag::set_name, "name") +
tl::make_member<std::string, rdb::Tag> (&rdb::Tag::description, &rdb::Tag::set_description, "description")
return tl::XMLStruct <rdb::Database>("report-database#0",
tl::make_member<std::string, rdb::Database> (&rdb::Database::description, &rdb::Database::set_description, "description#1") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::original_file, &rdb::Database::set_original_file, "original-file#2") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::generator, &rdb::Database::set_generator, "generator#3") +
tl::make_member<std::string, rdb::Database> (&rdb::Database::top_cell_name, &rdb::Database::set_top_cell_name, "top-cell#4") +
tl::make_element<rdb::Tags, rdb::Database> (&rdb::Database::tags, &rdb::Database::import_tags, "tags#5",
tl::make_element<rdb::Tag, rdb::Tags::const_iterator, rdb::Tags> (&rdb::Tags::begin_tags, &rdb::Tags::end_tags, &rdb::Tags::import_tag, "tag#1",
tl::make_member<std::string, rdb::Tag> (&rdb::Tag::name, &rdb::Tag::set_name, "name#1") +
tl::make_member<std::string, rdb::Tag> (&rdb::Tag::description, &rdb::Tag::set_description, "description#2")
)
) +
tl::make_element_with_parent_ref<rdb::Categories, rdb::Database> (&rdb::Database::categories, &rdb::Database::import_categories, "categories",
tl::make_element_with_parent_ref<rdb::Categories, rdb::Database> (&rdb::Database::categories, &rdb::Database::import_categories, "categories#6",
&categories_format
) +
tl::make_element_with_parent_ref<rdb::Cells, rdb::Database> (&rdb::Database::cells, &rdb::Database::import_cells, "cells",
tl::make_element_with_parent_ref<rdb::Cells, rdb::Database> (&rdb::Database::cells, &rdb::Database::import_cells, "cells#7",
// must be sorted cells (children after parents)!
tl::make_element_with_parent_ref<rdb::Cell, rdb::Cells::const_iterator, rdb::Cells> (&rdb::Cells::begin, &rdb::Cells::end, &rdb::Cells::import_cell, "cell",
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::name, &rdb::Cell::set_name, "name") +
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::variant, &rdb::Cell::set_variant, "variant") +
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::layout_name, &rdb::Cell::set_layout_name, "layout-name") +
tl::make_element_with_parent_ref<rdb::References, rdb::Cell> (&rdb::Cell::references, &rdb::Cell::import_references, "references",
tl::make_element_with_parent_ref<rdb::Reference, rdb::References::const_iterator, rdb::References> (&rdb::References::begin, &rdb::References::end, &rdb::References::insert, "ref",
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::parent_cell_qname, &rdb::Reference::set_parent_cell_qname, "parent") +
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::trans_str, &rdb::Reference::set_trans_str, "trans")
tl::make_element_with_parent_ref<rdb::Cell, rdb::Cells::const_iterator, rdb::Cells> (&rdb::Cells::begin, &rdb::Cells::end, &rdb::Cells::import_cell, "cell#1",
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::name, &rdb::Cell::set_name, "name#1") +
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::variant, &rdb::Cell::set_variant, "variant#2") +
tl::make_member<std::string, rdb::Cell> (&rdb::Cell::layout_name, &rdb::Cell::set_layout_name, "layout-name#3") +
tl::make_element_with_parent_ref<rdb::References, rdb::Cell> (&rdb::Cell::references, &rdb::Cell::import_references, "references#4",
tl::make_element_with_parent_ref<rdb::Reference, rdb::References::const_iterator, rdb::References> (&rdb::References::begin, &rdb::References::end, &rdb::References::insert, "ref#1",
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::parent_cell_qname, &rdb::Reference::set_parent_cell_qname, "parent#1") +
tl::make_member<std::string, rdb::Reference> (&rdb::Reference::trans_str, &rdb::Reference::set_trans_str, "trans#2")
)
)
)
) +
tl::make_element_with_parent_ref<rdb::Items, rdb::Database> (&rdb::Database::items, &rdb::Database::set_items, "items",
tl::make_element_with_parent_ref<rdb::Item, rdb::Items::const_iterator, rdb::Items> (&rdb::Items::begin, &rdb::Items::end, &rdb::Items::add_item, "item",
tl::make_member<std::string, rdb::Item> (&rdb::Item::tag_str, &rdb::Item::set_tag_str, "tags") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::category_name, &rdb::Item::set_category_name, "category") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::cell_qname, &rdb::Item::set_cell_qname, "cell") +
tl::make_member<bool, rdb::Item> (&rdb::Item::visited, &rdb::Item::set_visited, "visited") +
tl::make_member<size_t, rdb::Item> (&rdb::Item::multiplicity, &rdb::Item::set_multiplicity, "multiplicity") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::comment, &rdb::Item::set_comment, "comment") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter ())
)
tl::make_element_with_parent_ref<rdb::Items, rdb::Database> (&rdb::Database::items, &rdb::Database::set_items, "items#8",
tl::make_element_with_parent_ref<rdb::Item, rdb::Items::const_iterator, rdb::Items> (&rdb::Items::begin, &rdb::Items::end, &rdb::Items::add_item, "item#1",
tl::make_member<std::string, rdb::Item> (&rdb::Item::tag_str, &rdb::Item::set_tag_str, "tags#1") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::category_name, &rdb::Item::set_category_name, "category#2") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::cell_qname, &rdb::Item::set_cell_qname, "cell#3") +
tl::make_member<bool, rdb::Item> (&rdb::Item::visited, &rdb::Item::set_visited, "visited#4") +
tl::make_member<size_t, rdb::Item> (&rdb::Item::multiplicity, &rdb::Item::set_multiplicity, "multiplicity#5") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::comment, &rdb::Item::set_comment, "comment#6") +
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image#7") +
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values#8",
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value#1", ValueConverter ()) )
)
)
);
}
static tl::XMLStruct <rdb::Database> s_rdb_struct = make_rdb_structure ();
static tl::RegisteredClass<tl::XMLElementBase> rdb_struct_def (&s_rdb_struct, 0, "KLayout-RDB", false);
// -------------------------------------------------------------
// Implementation of rdb::Database::save and write
// TODO: move this somewhere else - with generalized functionality
void
rdb::Database::save (const std::string &fn)
rdb::Database::save (const std::string &fn, bool binary)
{
write (fn);
write (fn, binary);
set_filename (fn);
set_binary (binary);
}
void
rdb::Database::write (const std::string &fn)
rdb::Database::write (const std::string &fn, bool binary)
{
tl::OutputStream os (fn, tl::OutputStream::OM_Auto);
s_rdb_struct.write (os, *this);
if (tl::verbosity () >= 10) {
tl::log << "Saved RDB to " << fn;
if (binary) {
tl::ProtocolBufferWriter writer (os);
s_rdb_struct.write (writer, *this);
if (tl::verbosity () >= 10) {
tl::log << tl::to_string (tr ("Saved binary RDB to ")) << fn;
}
} else {
s_rdb_struct.write (os, *this);
if (tl::verbosity () >= 10) {
tl::log << tl::to_string (tr ("Saved RDB to ")) << fn;
}
}
}
@ -156,8 +171,8 @@ class StandardReader
: public ReaderBase
{
public:
StandardReader (tl::InputStream &stream)
: m_input_stream (stream)
StandardReader (tl::InputStream &stream, bool binary)
: m_input_stream (stream), m_binary (binary)
{
// .. nothing yet ..
}
@ -165,17 +180,30 @@ public:
virtual void read (Database &db)
{
tl::SelfTimer timer (tl::verbosity () >= 11, "Reading marker database file");
tl::XMLStreamSource in (m_input_stream, tl::to_string (tr ("Reading RDB")));
s_rdb_struct.parse (in, db);
if (m_binary) {
tl::ProtocolBufferReader reader (m_input_stream);
s_rdb_struct.parse (reader, db);
db.set_binary (true);
} else {
tl::XMLStreamSource in (m_input_stream, tl::to_string (tr ("Reading RDB")));
s_rdb_struct.parse (in, db);
db.set_binary (false);
}
}
virtual const char *format () const
{
return "KLayout-RDB";
return m_binary ? "KLayout-RDB-PB" : "KLayout-RDB";
}
private:
tl::InputStream &m_input_stream;
bool m_binary;
};
class StandardFormatDeclaration
@ -203,10 +231,46 @@ class StandardFormatDeclaration
virtual ReaderBase *create_reader (tl::InputStream &s) const
{
return new StandardReader (s);
return new StandardReader (s, false);
}
};
static tl::RegisteredClass<rdb::FormatDeclaration> format_decl (new StandardFormatDeclaration (), 0, "KLayout-RDB");
class BinaryFormatDeclaration
: public FormatDeclaration
{
virtual std::string format_name () const { return "KLayout-RDB-PB"; }
virtual std::string format_desc () const { return "KLayout binary report database format"; }
virtual std::string file_format () const { return "KLayout binary RDB files (*.rdb *.rdb.gz)"; }
virtual bool detect (tl::InputStream &stream) const
{
static const char header[] = {
// ProtocolBuffer wire format, LEN record with ID 0 and string "report-database".
0x02, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65
};
const char *h = stream.get (sizeof (header));
if (! h) {
return false;
}
for (size_t i = 0; i < sizeof (header); ++i) {
if (h[i] != header[i]) {
return false;
}
}
return true;
}
virtual ReaderBase *create_reader (tl::InputStream &s) const
{
return new StandardReader (s, true);
}
};
static tl::RegisteredClass<rdb::FormatDeclaration> pb_format_decl (new BinaryFormatDeclaration (), 1, "KLayout-RDB-PB");
}