ruby-gdsii 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README.txt +113 -0
  3. data/bin/rgds-debug +43 -0
  4. data/bin/rgds-dump +38 -0
  5. data/bin/rgds-join +98 -0
  6. data/bin/rgds-layers +53 -0
  7. data/bin/rgds-sremove +135 -0
  8. data/bin/rgds-ssplit +113 -0
  9. data/bin/rgds-stats +134 -0
  10. data/bin/rgds-structs +41 -0
  11. data/bin/rgds-tree +166 -0
  12. data/bin/rgds2rb +99 -0
  13. data/lib/gdsii.rb +137 -0
  14. data/lib/gdsii/aref.rb +243 -0
  15. data/lib/gdsii/bnf.rb +309 -0
  16. data/lib/gdsii/boundary.rb +53 -0
  17. data/lib/gdsii/box.rb +65 -0
  18. data/lib/gdsii/byte_order.rb +36 -0
  19. data/lib/gdsii/element.rb +172 -0
  20. data/lib/gdsii/group.rb +98 -0
  21. data/lib/gdsii/library.rb +518 -0
  22. data/lib/gdsii/mixins.rb +378 -0
  23. data/lib/gdsii/node.rb +65 -0
  24. data/lib/gdsii/path.rb +169 -0
  25. data/lib/gdsii/property.rb +108 -0
  26. data/lib/gdsii/record.rb +606 -0
  27. data/lib/gdsii/record/consts.rb +384 -0
  28. data/lib/gdsii/record/datatypes/ascii.rb +145 -0
  29. data/lib/gdsii/record/datatypes/bitarray.rb +101 -0
  30. data/lib/gdsii/record/datatypes/data.rb +111 -0
  31. data/lib/gdsii/record/datatypes/int2.rb +67 -0
  32. data/lib/gdsii/record/datatypes/int4.rb +65 -0
  33. data/lib/gdsii/record/datatypes/nodata.rb +60 -0
  34. data/lib/gdsii/record/datatypes/real4.rb +51 -0
  35. data/lib/gdsii/record/datatypes/real8.rb +120 -0
  36. data/lib/gdsii/sref.rb +61 -0
  37. data/lib/gdsii/strans.rb +133 -0
  38. data/lib/gdsii/structure.rb +352 -0
  39. data/lib/gdsii/text.rb +203 -0
  40. data/pkg/ruby-gdsii.gem +23 -0
  41. data/samples/hello.gds +0 -0
  42. data/samples/hello.out.rb +84 -0
  43. data/samples/hello.rb +94 -0
  44. data/test/baseline/dcp1.gds +0 -0
  45. data/test/baseline/h_write.gds +0 -0
  46. data/test/h_pthru.rb +22 -0
  47. data/test/h_write.rb +117 -0
  48. data/test/hs_pthru.rb +31 -0
  49. data/test/l_pthru.rb +23 -0
  50. data/test/test_gds_group.rb +379 -0
  51. data/test/test_gds_record.rb +99 -0
  52. metadata +118 -0
@@ -0,0 +1,101 @@
1
+ require 'gdsii/record/datatypes/data.rb'
2
+
3
+ module Gdsii
4
+
5
+ module RecData
6
+
7
+ #
8
+ # Class for BITARRAY data type
9
+ #
10
+ class BitArray < Data
11
+
12
+ # Value is an array of 16-bit integers which represent the bit array.
13
+ # To get a String of the bit array represented as an array of strings
14
+ # madeup of 16 1's and 0's consider using the #to_s_a or #to_s methods.
15
+ attr_reader :value
16
+
17
+ # Construct an Gdsii::RecData::BitArray data object. The value is an
18
+ # array of 16-bit integers representing the bit array. Examples:
19
+ #
20
+ # record = Gdsii::RecData::BitArray.new([1234])
21
+ # record.value.inspect #=> [1234]
22
+ #
23
+ # Or alternatively to initialize with an array of strings madeup of 16
24
+ # 1's and 0's, use Gdsii::RecData::BitArray.s_a_to_i_a:
25
+ #
26
+ # arr = Gdsii::RecData::BitArray.s_a_to_i_a(["0000010011010010"])
27
+ # record = Gdsii::RecData::BitArray.new(arr)
28
+ # record.value.inspect #=> [1234]
29
+ #
30
+ def initialize(value)
31
+ super(GDT_BITARRAY, value)
32
+ end
33
+
34
+ # Set the value for this object; verify that the value items are of
35
+ # type Fixnum (or at least can be coerced using "to_i").
36
+ def value=(value)
37
+ @value = Data.coerce_value(value, Integer, :to_i)
38
+ end
39
+
40
+ # Returns the size of the record *data* in bytes. Each array element
41
+ # consumes 2 bytes.
42
+ def byte_size()
43
+ @value.length * 2
44
+ end
45
+
46
+ # Reads a BITARRAY record from the given file and for the length of bytes
47
+ # given and returns a new Gdsii::RecData::BitArray object.
48
+ def BitArray.read(file, byte_count)
49
+ raw = file.read(byte_count)
50
+ data = raw.unpack("n")
51
+ BitArray.new(data)
52
+ end
53
+
54
+ # Writes the integer values representing the bit array in this
55
+ # Gdsii::RecData::BitArray object to the given file as a GDSII BITARRAY
56
+ # record.
57
+ def write(file)
58
+ file.write @value.pack("n")
59
+ end
60
+
61
+ #
62
+ # Returns an array containing string representations for each of the
63
+ # 16-bit integers in the value. Example:
64
+ #
65
+ # record = Gdsii::RecData::BitArray.new([1234, 9876])
66
+ # record.to_s_a.inspect #=> ["0000010011010010", "0010011010010100"]
67
+ #
68
+ def to_s_a()
69
+ @value.map {|string| [string].pack("n").unpack("B16")[0]}
70
+ end
71
+
72
+ #
73
+ # Returns a string containing string representations for each of the
74
+ # 16-bit integers in the value joined by spaces. Example:
75
+ #
76
+ # record = Gdsii::RecData::BitArray.new([1234, 9876])
77
+ # record.to_s.inspect #=> "0000010011010010 0010011010010100"
78
+ #
79
+ def to_s()
80
+ to_s_a.join(' ')
81
+ end
82
+
83
+ #
84
+ # Converts an array of strings at 16 characters in length using 1's and
85
+ # 0's to an array of respective integer values.
86
+ #
87
+ # arr = Gdsii::RecData::BitArray.s_a_to_i_a(["0000010011010010"])
88
+ # arr.inspect #=> [1234]
89
+ #
90
+ # Also see #new for an example used in object construction.
91
+ #
92
+ def BitArray.s_a_to_i_a(value)
93
+ string_arr = Data.coerce_value(value, String, :to_s)
94
+ string_arr.map {|string| [string].pack("B16").unpack("n")[0]}
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,111 @@
1
+
2
+ module Gdsii
3
+
4
+ module RecData
5
+
6
+ #
7
+ # Generic class to represent various record data types. This class is
8
+ # intended to be inherited and not called directly.
9
+ #
10
+ class Data
11
+
12
+ # Data type integer represented by one of the Gdsii::GDT_ constants.
13
+ attr_reader :type
14
+
15
+ # Pointer to the parent record object
16
+ attr_reader :record
17
+
18
+ #
19
+ # Create a generic record data object. Intended to be called internally
20
+ # by Gdsii::RecType classes - not intended to be called directly.
21
+ #
22
+ def initialize(type, value, record=nil)
23
+ if Data.valid_type?(type)
24
+ @type = type
25
+ else
26
+ raise TypeError,
27
+ "Invalid data type specified: #{type}"
28
+ end
29
+ @record = record
30
+ self.value = value
31
+ end
32
+
33
+ # Quick access to the data value array. Equivalent to self.value[index].
34
+ def [](index); @value[index]; end
35
+
36
+ # Check that the given data type (as an integer) is valid as defined by
37
+ # the Gdsii::DATATYPE_INFO array.
38
+ def Data.valid_type?(type)
39
+ (0...DATATYPE_INFO.length).member?(type)
40
+ end
41
+
42
+ ########################################################################
43
+ # DATA TYPE SHORTCUTS
44
+ ########################################################################
45
+
46
+ # Returns true if this record is an ASCII data type, false if not
47
+ def is_ascii?(); @type == GDT_ASCII; end
48
+
49
+ # Returns true if this record is an INT2 data type, false if not
50
+ def is_int2?(); @type == GDT_INT2; end
51
+
52
+ # Returns true if this record is an INT4 data type, false if not
53
+ def is_int4?(); @type == GDT_INT4; end
54
+
55
+ # Returns true if this record is a REAL8 data type, false if not
56
+ def is_real8?(); @type == GDT_REAL8; end
57
+
58
+ # Returns true if this record is a BITARRAY data type, false if not
59
+ def is_bitarray?(); @type == GDT_BITARRAY; end
60
+
61
+ # Returns true if this record is a NO_DATA data type, false if not
62
+ def is_no_data?(); @type == GDT_NO_DATA; end
63
+
64
+ # Returns true if this record is a REAL4 data type, false if not
65
+ def is_real4?(); @type == GDT_REAL4; end
66
+
67
+
68
+ ########################################################################
69
+ # PROTECTED METHODS (private to this class)
70
+ ########################################################################
71
+
72
+ protected
73
+
74
+ # Check the class for the given datum (single data element, NOT an array)
75
+ # and raises an exception if the datum does not match the given class.
76
+ def Data.ensure_class(datum, klass)
77
+ unless datum.kind_of?(klass)
78
+ raise TypeError,
79
+ "#{self.class.to_s} value must be descended from #{klass}; given: '#{datum.class}'"
80
+ end
81
+ end
82
+
83
+ # Ensures that the given value is descended from the Array class. If
84
+ # not, then an InvalidValue exception is raised.
85
+ def Data.ensure_array(value)
86
+ unless value.kind_of?(Array)
87
+ raise TypeError,
88
+ "All data must be descended from Array class; given: #{value.class}"
89
+ end
90
+ end
91
+
92
+ # Generic method for setting a value. The classes that inherit from
93
+ # this class use this to coerce and validate their value.
94
+ def Data.coerce_value(value, klass, coerce_method)
95
+ Data.ensure_array value
96
+ value.each_with_index do |datum, i|
97
+ # Make sure that it matches the class; if not, try to coerce
98
+ unless datum.kind_of?(klass)
99
+ if datum.respond_to?(coerce_method) then
100
+ the_method = datum.method(coerce_method)
101
+ value[i] = the_method.call
102
+ end
103
+ Data.ensure_class(value[i], klass)
104
+ end
105
+ end
106
+ value
107
+ end
108
+
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,67 @@
1
+ require 'gdsii/record/datatypes/data.rb'
2
+ require 'gdsii/byte_order.rb'
3
+
4
+ module Gdsii
5
+
6
+ module RecData
7
+
8
+ #
9
+ # Store a GDSII INT2 data type
10
+ #
11
+ class Int2 < Data
12
+
13
+ # Value is an array of integers.
14
+ attr_reader :value
15
+
16
+ # Construct an Gdsii::RecData::Int2 data object. The value is an array
17
+ # of integers (Fixnum).
18
+ def initialize(value)
19
+ super(GDT_INT2, value)
20
+ end
21
+
22
+ # Set the value for this object; verify that the value items are of
23
+ # type Fixnum (or at least can be coerced using "to_i").
24
+ def value=(value)
25
+ @value = Data.coerce_value(value, Fixnum, :to_i)
26
+ end
27
+
28
+ # Returns the size of the record *data* in bytes. Each array element
29
+ # consumes 2 bytes (hence INT2).
30
+ def byte_size()
31
+ @value.length * 2
32
+ end
33
+
34
+ # Reads an INT2 record from the given file and for the length of bytes
35
+ # given and returns a new Gdsii::RecData::Int2 object.
36
+ def Int2.read(file, byte_count)
37
+ data = []
38
+ while (byte_count > 0)
39
+ raw = file.read(2)
40
+ raw.reverse! if (ByteOrder::little_endian?)
41
+ data.push raw.unpack('s')[0]
42
+ byte_count -= 2
43
+ end
44
+ Int2.new(data)
45
+ end
46
+
47
+ # Writes the integer values in this Gdsii::RecData::Int2 object to the
48
+ # given file as a GDSII INT2 record.
49
+ def write(file)
50
+ value.each do |item|
51
+ # always write int2 as network order (as per GDSII spec)
52
+ file.write [item].pack('n')
53
+ end
54
+ end
55
+
56
+ # Converts the array of integer values to a string (values are joined by
57
+ # spaces).
58
+ def to_s()
59
+ value.map {|v| v.to_s}.join(' ')
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
@@ -0,0 +1,65 @@
1
+ require 'gdsii/record/datatypes/data.rb'
2
+ require 'gdsii/byte_order.rb'
3
+
4
+ module Gdsii
5
+
6
+ module RecData
7
+
8
+ #
9
+ # Class for INT4 data type
10
+ #
11
+ class Int4 < Data
12
+
13
+ # Value is an array of integers.
14
+ attr_reader :value
15
+
16
+ # Construct an Gdsii::RecData::Int4 data object. The value is an array
17
+ # of integers (Fixnum).
18
+ def initialize(value)
19
+ super(GDT_INT4, value)
20
+ end
21
+
22
+ # Set the value for this object; verify that the value items are of
23
+ # type Fixnum (or at least can be coerced using "to_i").
24
+ def value=(value)
25
+ @value = Data.coerce_value(value, Fixnum, :to_i)
26
+ end
27
+
28
+ # Returns the size of the record *data* in bytes. Each array element
29
+ # consumes 4 bytes (hence INT4).
30
+ def byte_size()
31
+ @value.length * 4
32
+ end
33
+
34
+ # Reads an INT4 record from the given file and for the length of bytes
35
+ # given and returns a new Gdsii::RecData::Int4 object.
36
+ def Int4.read(file, byte_count)
37
+ data = []
38
+ while (byte_count > 0)
39
+ raw = file.read(4)
40
+ raw.reverse! if (ByteOrder::little_endian?)
41
+ data.push raw.unpack('i')[0]
42
+ byte_count -= 4
43
+ end
44
+ Int4.new(data)
45
+ end
46
+
47
+ # Writes the integer values in this Gdsii::RecData::Int2 object to the
48
+ # given file as a GDSII INT4 record.
49
+ def write(file)
50
+ value.each do |item|
51
+ # always write int4 in network order (as per GDSII spec)
52
+ file.write [item].pack('N')
53
+ end
54
+ end
55
+
56
+ # Converts the array of integer values to a string (values are joined by
57
+ # spaces).
58
+ def to_s()
59
+ value.map {|v| v.to_s}.join(' ')
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,60 @@
1
+ require 'gdsii/record/datatypes/data.rb'
2
+
3
+ module Gdsii
4
+
5
+ module RecData
6
+
7
+ #
8
+ # Store a GDSII NODATA data type. This data type has no value.
9
+ #
10
+ class NoData < Data
11
+
12
+ # Value will always be an empty array for a Gdsii::RecData::NoData object
13
+ attr_reader :value
14
+
15
+ # Construct an NoData data object. No value is given because there
16
+ # isn't a value for Gdsii::RecData::NoData.
17
+ def initialize()
18
+ super(GDT_NO_DATA, [])
19
+ end
20
+
21
+ # Throws an exception unless an empty arra is passed because there is
22
+ # no data associated with a Gdsii::RecData::NoData object.
23
+ def value=(value=[])
24
+ Data.ensure_array value
25
+ unless value.empty?
26
+ raise ArgumentError,
27
+ "GDT_NO_DATA must have an empty array; given length: #{value.length}"
28
+ end
29
+ @value = value
30
+ end
31
+
32
+ # Returns the size of the record *data* in bytes. Since a
33
+ # Gdsii::RecData::NoData object has no data, 0 is always returned.
34
+ def byte_size(); 0; end
35
+
36
+ # Reads a NO_DATA record from the given file object and returns a
37
+ # new Gdsii::RecData::NoData object.
38
+ def NoData.read(file, byte_count=0)
39
+ # validate byte count
40
+ if byte_count > 0 then
41
+ raise ArgumentError,
42
+ "GDT_NO_DATA expects 0 bytes of record length; requested: #{byte_count}"
43
+ end
44
+ NoData.new()
45
+ end
46
+
47
+ # Performs no operation since there is no data in a Gdsii::RecType::NoData
48
+ # object to write to a file. However this method is necessary so that
49
+ # it can respond to methods common to other Gdsii::RecType::Data
50
+ # descended classes.
51
+ def write(file); end
52
+
53
+ # Returns an empty string (which represents no data).
54
+ def to_s(); ''; end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,51 @@
1
+ require 'gdsii/record/datatypes/data.rb'
2
+
3
+ module Gdsii
4
+
5
+ module RecData
6
+
7
+ #
8
+ # Class for REAL4 data type (UNSUPPORTED - will raise an exception)
9
+ #
10
+ class Real4 < Data
11
+
12
+ # Value is an array of floating point numbers
13
+ attr_reader :value
14
+
15
+ # Will raise an exception immediately as REAL4 is not supported in the
16
+ # GDSII specification.
17
+ def initialize(value)
18
+ raise "GDT_REAL4 is unsupported"
19
+ end
20
+
21
+ # Raises an TypeError exception as REAL4 is not supported
22
+ def value=(value)
23
+ raise "GDT_REAL4 is unsupported"
24
+ end
25
+
26
+ # Returns the size of the record *data* in bytes. Each array element
27
+ # consumes 4 bytes (hence REAL4).
28
+ def byte_size()
29
+ @value.length * 4
30
+ end
31
+
32
+ # just create the Gdsii::RecData::Real4 object and raise the exception
33
+ def Real4.read(file, byte_count)
34
+ Real4.new([0])
35
+ end
36
+
37
+ # Raises an exception since REAL4 is unsupported
38
+ def write(file)
39
+ raise "GDT_REAL4 is unsupported"
40
+ end
41
+
42
+ # Converts the array of floating point values to a string (values are
43
+ # joined by spaces).
44
+ def to_s()
45
+ value.map {|v| v.to_s}.join(' ')
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end