mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-03 08:26:27 +02:00
Next steps - persistency of meta info
This commit is contained in:
@@ -289,13 +289,19 @@ GDS2ReaderBase::do_read (db::Layout &layout)
|
||||
db::cell_index_type cell_index = make_cell (layout, m_cellname);
|
||||
|
||||
bool ignore_cell = false;
|
||||
std::map <tl::string, std::vector <std::string> >::const_iterator ctx = m_context_info.find (m_cellname);
|
||||
auto ctx = m_context_info.find (m_cellname);
|
||||
if (ctx != m_context_info.end ()) {
|
||||
|
||||
CommonReaderLayerMapping layer_mapping (this, &layout);
|
||||
if (layout.recover_proxy_as (cell_index, ctx->second.begin (), ctx->second.end (), &layer_mapping)) {
|
||||
LayoutOrCellContextInfo ci = LayoutOrCellContextInfo::deserialize (ctx->second.begin (), ctx->second.end ());
|
||||
|
||||
if (layout.recover_proxy_as (cell_index, ci, &layer_mapping)) {
|
||||
// ignore everything in that cell since it is created by the import:
|
||||
ignore_cell = true;
|
||||
}
|
||||
|
||||
layout.fill_meta_info_from_context (cell_index, ci);
|
||||
|
||||
}
|
||||
|
||||
db::Cell *cell = 0;
|
||||
@@ -386,6 +392,13 @@ GDS2ReaderBase::do_read (db::Layout &layout)
|
||||
|
||||
}
|
||||
|
||||
// deserialize global context information
|
||||
auto ctx = m_context_info.find (std::string ());
|
||||
if (ctx != m_context_info.end ()) {
|
||||
LayoutOrCellContextInfo ci = LayoutOrCellContextInfo::deserialize (ctx->second.begin (), ctx->second.end ());
|
||||
layout.fill_meta_info_from_context (ci);
|
||||
}
|
||||
|
||||
// check, if the last record is a ENDLIB
|
||||
if (rec_id != sENDLIB) {
|
||||
error (tl::to_string (tr ("ENDLIB record expected")));
|
||||
@@ -396,12 +409,16 @@ void
|
||||
GDS2ReaderBase::read_context_info_cell ()
|
||||
{
|
||||
short rec_id = 0;
|
||||
std::string cn;
|
||||
|
||||
// read cell content
|
||||
while ((rec_id = get_record ()) != sENDSTR) {
|
||||
|
||||
progress_checkpoint ();
|
||||
|
||||
bool valid_hook = false;
|
||||
cn.clear ();
|
||||
|
||||
if (rec_id == sSREF) {
|
||||
|
||||
do {
|
||||
@@ -411,7 +428,7 @@ GDS2ReaderBase::read_context_info_cell ()
|
||||
error (tl::to_string (tr ("SNAME record expected")));
|
||||
}
|
||||
|
||||
std::string cn = get_string ();
|
||||
cn = get_string ();
|
||||
|
||||
rec_id = get_record ();
|
||||
while (rec_id == sSTRANS || rec_id == sANGLE || rec_id == sMAG) {
|
||||
@@ -421,6 +438,24 @@ GDS2ReaderBase::read_context_info_cell ()
|
||||
error (tl::to_string (tr ("XY record expected")));
|
||||
}
|
||||
|
||||
valid_hook = true;
|
||||
|
||||
} else if (rec_id == sBOUNDARY) {
|
||||
|
||||
rec_id = get_record ();
|
||||
while (rec_id == sLAYER || rec_id == sDATATYPE) {
|
||||
rec_id = get_record ();
|
||||
}
|
||||
if (rec_id != sXY) {
|
||||
error (tl::to_string (tr ("XY record expected")));
|
||||
}
|
||||
|
||||
valid_hook = true;
|
||||
|
||||
}
|
||||
|
||||
if (valid_hook) {
|
||||
|
||||
std::vector <std::string> &strings = m_context_info.insert (std::make_pair (cn, std::vector <std::string> ())).first->second;
|
||||
|
||||
size_t attr = 0;
|
||||
|
||||
@@ -72,6 +72,109 @@ inline int scale (double sf, int value)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GDS2WriterBase::write_context_cell (db::Layout &layout, const short *time_data, const std::vector<db::cell_index_type> &cells)
|
||||
{
|
||||
write_record_size (4 + 12 * 2);
|
||||
write_record (sBGNSTR);
|
||||
write_time (time_data);
|
||||
write_time (time_data);
|
||||
|
||||
write_string_record (sSTRNAME, "$$$CONTEXT_INFO$$$");
|
||||
|
||||
std::vector <std::string> context_prop_strings;
|
||||
|
||||
if (layout.has_context_info ()) {
|
||||
|
||||
// Use a dummy BOUNDARY element to attach the global context
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sBOUNDARY);
|
||||
|
||||
write_record_size (6);
|
||||
write_record (sLAYER);
|
||||
write_short (0);
|
||||
|
||||
write_record_size (6);
|
||||
write_record (sDATATYPE);
|
||||
write_short (0);
|
||||
|
||||
write_record_size (4 + 5 * 2 * 4);
|
||||
write_record (sXY);
|
||||
for (unsigned int i = 0; i < 10; ++i) {
|
||||
write_int (0);
|
||||
}
|
||||
|
||||
context_prop_strings.clear ();
|
||||
|
||||
if (layout.get_context_info (context_prop_strings)) {
|
||||
|
||||
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
||||
// will arrive)
|
||||
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
||||
|
||||
--s;
|
||||
|
||||
write_record_size (6);
|
||||
write_record (sPROPATTR);
|
||||
write_short (short (std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s))); // = user string
|
||||
|
||||
write_string_record (sPROPVALUE, *s);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sENDEL);
|
||||
|
||||
}
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||
|
||||
if (layout.has_context_info (*cell)) {
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sSREF);
|
||||
|
||||
write_string_record (sSNAME, m_cell_name_map.cell_name (*cell));
|
||||
|
||||
write_record_size (12);
|
||||
write_record (sXY);
|
||||
write_int (0);
|
||||
write_int (0);
|
||||
|
||||
context_prop_strings.clear ();
|
||||
|
||||
if (layout.get_context_info (*cell, context_prop_strings)) {
|
||||
|
||||
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
||||
// will arrive)
|
||||
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
||||
|
||||
--s;
|
||||
|
||||
write_record_size (6);
|
||||
write_record (sPROPATTR);
|
||||
write_short (short (std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s))); // = user string
|
||||
|
||||
write_string_record (sPROPVALUE, *s);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sENDEL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sENDSTR);
|
||||
}
|
||||
|
||||
void
|
||||
GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options)
|
||||
{
|
||||
@@ -178,73 +281,17 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
|
||||
|
||||
// write context info
|
||||
|
||||
bool any_proxy = false;
|
||||
bool has_context = false;
|
||||
|
||||
if (options.write_context_info ()) {
|
||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end () && !any_proxy; ++cell) {
|
||||
const db::Cell &cref = layout.cell (*cell);
|
||||
if (cref.is_proxy () && ! cref.is_top ()) {
|
||||
any_proxy = true;
|
||||
}
|
||||
has_context = layout.has_context_info ();
|
||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end () && !has_context; ++cell) {
|
||||
has_context = layout.has_context_info (*cell);
|
||||
}
|
||||
}
|
||||
|
||||
if (any_proxy) {
|
||||
|
||||
write_record_size (4 + 12 * 2);
|
||||
write_record (sBGNSTR);
|
||||
write_time (time_data);
|
||||
write_time (time_data);
|
||||
|
||||
write_string_record (sSTRNAME, "$$$CONTEXT_INFO$$$");
|
||||
|
||||
std::vector <std::string> context_prop_strings;
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||
|
||||
const db::Cell &cref = layout.cell (*cell);
|
||||
if (cref.is_proxy () && ! cref.is_top ()) {
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sSREF);
|
||||
|
||||
write_string_record (sSNAME, m_cell_name_map.cell_name (*cell));
|
||||
|
||||
write_record_size (12);
|
||||
write_record (sXY);
|
||||
write_int (0);
|
||||
write_int (0);
|
||||
|
||||
context_prop_strings.clear ();
|
||||
|
||||
if (layout.get_context_info (*cell, context_prop_strings)) {
|
||||
|
||||
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
||||
// will arrive)
|
||||
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
||||
|
||||
--s;
|
||||
|
||||
write_record_size (6);
|
||||
write_record (sPROPATTR);
|
||||
write_short (short (std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s))); // = user string
|
||||
|
||||
write_string_record (sPROPVALUE, *s);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sENDEL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
write_record_size (4);
|
||||
write_record (sENDSTR);
|
||||
|
||||
if (has_context) {
|
||||
write_context_cell (layout, time_data, cells);
|
||||
}
|
||||
|
||||
// body
|
||||
|
||||
@@ -168,6 +168,7 @@ private:
|
||||
db::WriterCellNameMap m_cell_name_map;
|
||||
|
||||
void write_properties (const db::Layout &layout, db::properties_id_type prop_id);
|
||||
void write_context_cell (db::Layout &layout, const short *time_data, const std::vector<cell_index_type> &cells);
|
||||
};
|
||||
|
||||
} // namespace db
|
||||
|
||||
Reference in New Issue
Block a user