Added 'read_bytes' without options and 'write_bytes'. Added tests for write_bytes and for Ruby. Doc fixed.

This commit is contained in:
Matthias Koefferlein 2024-11-30 18:46:25 +01:00
parent 41383e4642
commit e35aa97191
4 changed files with 98 additions and 3 deletions

View File

@ -713,6 +713,20 @@ write_options2 (db::Layout *layout, const std::string &filename, bool /*gzip*/,
write_options1 (layout, filename, options);
}
static std::vector<char>
write_bytes (db::Layout *layout, const db::SaveLayoutOptions &options)
{
tl::OutputMemoryStream byte_stream;
{
db::Writer writer (options);
tl::OutputStream stream (byte_stream);
writer.write (*layout, stream);
}
return std::vector<char> (byte_stream.data (), byte_stream.data () + byte_stream.size ());
}
static void check_layer (const db::Layout *layout, unsigned int layer)
{
if (! layout->is_valid_layer (layer) && ! layout->is_special_layer (layer)) {
@ -2399,6 +2413,16 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"@brief Writes the layout to a stream file\n"
"@param filename The file to which to write the layout\n"
) +
gsi::method_ext ("write_bytes", &write_bytes, gsi::arg ("options"),
"@brief Writes the layout to a binary string\n"
"@param options The option set to use for writing. See \\SaveLayoutOptions for details. Options are used specifically to define the format to use.\n"
"\n"
"Instead of writing a file, this function generates a binary string. As there is no filename, the "
"format cannot be determined from the suffix. It needs to be specified in the options. A "
"function that reads bytes is \\read_bytes.\n"
"\n"
"This method has been introduced in version 0.29.9.\n"
) +
gsi::method_ext ("clip", &clip, gsi::arg ("cell"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell index of the cell to clip\n"

View File

@ -433,10 +433,19 @@ namespace gsi
return reader.read (*layout, options);
}
static db::LayerMap
load_bytes (db::Layout *layout, const std::vector<char> &bytes)
{
tl::InputMemoryStream byte_stream (bytes.data (), bytes.size ());
tl::InputStream stream (byte_stream);
db::Reader reader (stream);
return reader.read (*layout);
}
static db::LayerMap
load_bytes_with_options (db::Layout *layout, const std::vector<char> &bytes, const db::LoadLayoutOptions &options)
{
tl::InputMemoryStream byte_stream (bytes.data(), bytes.size());
tl::InputMemoryStream byte_stream (bytes.data (), bytes.size ());
tl::InputStream stream (byte_stream);
db::Reader reader (stream);
return reader.read (*layout, options);
@ -464,15 +473,26 @@ namespace gsi
"\n"
"This method has been added in version 0.18."
) +
gsi::method_ext ("read_bytes", &load_bytes, gsi::arg ("bytes"),
"@brief Load the layout from the given bytes array\n"
"The format of the file is determined automatically and automatic unzipping is provided. "
"A function that creates a byte string is \\write_bytes.\n"
"\n"
"@param bytes The data to load.\n"
"@return A layer map that contains the mapping used by the reader including the layers that have been created."
"\n"
"This method has been added in version 0.29.9."
) +
gsi::method_ext ("read_bytes", &load_bytes_with_options, gsi::arg ("bytes"), gsi::arg ("options"),
"@brief Load the layout from the given bytes array with options\n"
"The format of the file is determined automatically and automatic unzipping is provided. "
"In this version, some reader options can be specified. "
"In this version, some reader options can be specified. A function that creates a byte string is \\write_bytes.\n"
"\n"
"@param bytes The data to load.\n"
"@param options The options object specifying further options for the reader.\n"
"@return A layer map that contains the mapping used by the reader including the layers that have been created."
"\n"
"This method has been added in version 0.29."
"This method has been added in version 0.29.9."
),
""
);

View File

@ -1220,6 +1220,21 @@ class DBLayoutTest(unittest.TestCase):
l2 = ly2.layer(1, 0)
self.assertEqual(ly2.top_cell().bbox().to_s(), "(0,10;20,30)")
def test_write_bytes(self):
ly = pya.Layout()
top = ly.create_cell("TOP")
l1 = ly.layer(1, 0)
shape = top.shapes(l1).insert(pya.Box(0, 10, 20, 30))
options = pya.SaveLayoutOptions()
options.format = "GDS2"
byte_buffer = ly.write_bytes(options)
ly2 = pya.Layout()
ly2.read_bytes(byte_buffer)
l2 = ly2.layer(1, 0)
self.assertEqual(ly2.top_cell().bbox().to_s(), "(0,10;20,30)")
# run unit tests
if __name__ == '__main__':

View File

@ -1445,6 +1445,42 @@ class DBLayoutTests2_TestClass < TestBase
end
def test_read_bytes
file_gds = File::join($ut_testtmp, "bytes.gds")
ly = RBA::Layout::new
top = ly.create_cell("TOP")
l1 = ly.layer(1, 0)
shape = top.shapes(l1).insert(RBA::Box::new(0, 10, 20, 30))
ly.write(file_gds)
byte_buffer = File.open(file_gds, "rb") { |f| f.read }
ly2 = RBA::Layout::new
ly2.read_bytes(byte_buffer, RBA::LoadLayoutOptions::new)
l2 = ly2.layer(1, 0)
assert_equal(ly2.top_cell.bbox.to_s, "(0,10;20,30)")
end
def test_write_bytes
ly = RBA::Layout::new
top = ly.create_cell("TOP")
l1 = ly.layer(1, 0)
shape = top.shapes(l1).insert(RBA::Box::new(0, 10, 20, 30))
options = RBA::SaveLayoutOptions::new
options.format = "GDS2"
byte_buffer = ly.write_bytes(options)
ly2 = RBA::Layout::new
ly2.read_bytes(byte_buffer)
l2 = ly2.layer(1, 0)
assert_equal(ly2.top_cell.bbox.to_s, "(0,10;20,30)")
end
end
load("test_epilogue.rb")