origami 1.2.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +112 -0
  4. data/bin/config/pdfcop.conf.yml +232 -233
  5. data/bin/gui/about.rb +27 -37
  6. data/bin/gui/config.rb +108 -117
  7. data/bin/gui/file.rb +416 -365
  8. data/bin/gui/gtkhex.rb +1138 -1153
  9. data/bin/gui/hexview.rb +55 -57
  10. data/bin/gui/imgview.rb +48 -51
  11. data/bin/gui/menu.rb +388 -386
  12. data/bin/gui/properties.rb +114 -130
  13. data/bin/gui/signing.rb +571 -617
  14. data/bin/gui/textview.rb +77 -95
  15. data/bin/gui/treeview.rb +382 -387
  16. data/bin/gui/walker.rb +227 -232
  17. data/bin/gui/xrefs.rb +56 -60
  18. data/bin/pdf2pdfa +53 -57
  19. data/bin/pdf2ruby +212 -228
  20. data/bin/pdfcop +338 -348
  21. data/bin/pdfdecompress +58 -65
  22. data/bin/pdfdecrypt +56 -60
  23. data/bin/pdfencrypt +75 -80
  24. data/bin/pdfexplode +185 -182
  25. data/bin/pdfextract +201 -218
  26. data/bin/pdfmetadata +83 -82
  27. data/bin/pdfsh +4 -5
  28. data/bin/pdfwalker +1 -2
  29. data/bin/shell/.irbrc +45 -82
  30. data/bin/shell/console.rb +105 -130
  31. data/bin/shell/hexdump.rb +40 -64
  32. data/examples/README.md +34 -0
  33. data/examples/attachments/attachment.rb +38 -0
  34. data/examples/attachments/nested_document.rb +51 -0
  35. data/examples/encryption/encryption.rb +28 -0
  36. data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
  37. data/examples/flash/flash.rb +37 -0
  38. data/{samples → examples}/flash/helloworld.swf +0 -0
  39. data/examples/forms/javascript.rb +54 -0
  40. data/examples/forms/xfa.rb +115 -0
  41. data/examples/javascript/hello_world.rb +22 -0
  42. data/examples/javascript/js_emulation.rb +54 -0
  43. data/examples/loop/goto.rb +32 -0
  44. data/examples/loop/named.rb +33 -0
  45. data/examples/signature/signature.rb +65 -0
  46. data/examples/uri/javascript.rb +56 -0
  47. data/examples/uri/open-uri.rb +21 -0
  48. data/examples/uri/submitform.rb +47 -0
  49. data/lib/origami.rb +29 -42
  50. data/lib/origami/3d.rb +350 -225
  51. data/lib/origami/acroform.rb +262 -288
  52. data/lib/origami/actions.rb +268 -288
  53. data/lib/origami/annotations.rb +697 -722
  54. data/lib/origami/array.rb +258 -184
  55. data/lib/origami/boolean.rb +74 -84
  56. data/lib/origami/catalog.rb +397 -434
  57. data/lib/origami/collections.rb +144 -0
  58. data/lib/origami/destinations.rb +233 -194
  59. data/lib/origami/dictionary.rb +253 -232
  60. data/lib/origami/encryption.rb +1274 -1243
  61. data/lib/origami/export.rb +232 -268
  62. data/lib/origami/extensions/fdf.rb +307 -220
  63. data/lib/origami/extensions/ppklite.rb +368 -435
  64. data/lib/origami/filespec.rb +197 -0
  65. data/lib/origami/filters.rb +301 -295
  66. data/lib/origami/filters/ascii.rb +177 -180
  67. data/lib/origami/filters/ccitt.rb +528 -535
  68. data/lib/origami/filters/crypt.rb +26 -35
  69. data/lib/origami/filters/dct.rb +46 -52
  70. data/lib/origami/filters/flate.rb +95 -94
  71. data/lib/origami/filters/jbig2.rb +49 -55
  72. data/lib/origami/filters/jpx.rb +38 -44
  73. data/lib/origami/filters/lzw.rb +189 -183
  74. data/lib/origami/filters/predictors.rb +221 -235
  75. data/lib/origami/filters/runlength.rb +103 -104
  76. data/lib/origami/font.rb +173 -186
  77. data/lib/origami/functions.rb +67 -81
  78. data/lib/origami/graphics.rb +25 -21
  79. data/lib/origami/graphics/colors.rb +178 -187
  80. data/lib/origami/graphics/instruction.rb +79 -85
  81. data/lib/origami/graphics/path.rb +142 -148
  82. data/lib/origami/graphics/patterns.rb +160 -167
  83. data/lib/origami/graphics/render.rb +43 -50
  84. data/lib/origami/graphics/state.rb +138 -153
  85. data/lib/origami/graphics/text.rb +188 -205
  86. data/lib/origami/graphics/xobject.rb +819 -815
  87. data/lib/origami/header.rb +63 -78
  88. data/lib/origami/javascript.rb +596 -597
  89. data/lib/origami/linearization.rb +285 -290
  90. data/lib/origami/metadata.rb +139 -148
  91. data/lib/origami/name.rb +112 -148
  92. data/lib/origami/null.rb +53 -62
  93. data/lib/origami/numeric.rb +162 -175
  94. data/lib/origami/obfuscation.rb +186 -174
  95. data/lib/origami/object.rb +593 -573
  96. data/lib/origami/outline.rb +42 -47
  97. data/lib/origami/outputintents.rb +73 -82
  98. data/lib/origami/page.rb +703 -592
  99. data/lib/origami/parser.rb +238 -290
  100. data/lib/origami/parsers/fdf.rb +41 -33
  101. data/lib/origami/parsers/pdf.rb +75 -95
  102. data/lib/origami/parsers/pdf/lazy.rb +137 -0
  103. data/lib/origami/parsers/pdf/linear.rb +64 -66
  104. data/lib/origami/parsers/ppklite.rb +34 -70
  105. data/lib/origami/pdf.rb +1030 -1005
  106. data/lib/origami/reference.rb +102 -102
  107. data/lib/origami/signature.rb +591 -609
  108. data/lib/origami/stream.rb +668 -551
  109. data/lib/origami/string.rb +397 -373
  110. data/lib/origami/template/patterns.rb +56 -0
  111. data/lib/origami/template/widgets.rb +151 -0
  112. data/lib/origami/trailer.rb +144 -158
  113. data/lib/origami/tree.rb +62 -0
  114. data/lib/origami/version.rb +23 -0
  115. data/lib/origami/webcapture.rb +88 -79
  116. data/lib/origami/xfa.rb +2863 -2882
  117. data/lib/origami/xreftable.rb +472 -384
  118. data/test/dataset/calc.pdf +85 -0
  119. data/test/dataset/crypto.pdf +82 -0
  120. data/test/dataset/empty.pdf +49 -0
  121. data/test/test_actions.rb +27 -0
  122. data/test/test_annotations.rb +90 -0
  123. data/test/test_pages.rb +31 -0
  124. data/test/test_pdf.rb +16 -0
  125. data/test/test_pdf_attachment.rb +34 -0
  126. data/test/test_pdf_create.rb +24 -0
  127. data/test/test_pdf_encrypt.rb +95 -0
  128. data/test/test_pdf_parse.rb +96 -0
  129. data/test/test_pdf_sign.rb +58 -0
  130. data/test/test_streams.rb +182 -0
  131. data/test/test_xrefs.rb +67 -0
  132. metadata +88 -58
  133. data/README +0 -67
  134. data/bin/pdf2graph +0 -121
  135. data/bin/pdfcocoon +0 -104
  136. data/lib/origami/file.rb +0 -233
  137. data/samples/README.txt +0 -45
  138. data/samples/actions/launch/calc.rb +0 -87
  139. data/samples/actions/launch/winparams.rb +0 -22
  140. data/samples/actions/loop/loopgoto.rb +0 -24
  141. data/samples/actions/loop/loopnamed.rb +0 -21
  142. data/samples/actions/named/named.rb +0 -31
  143. data/samples/actions/samba/smbrelay.rb +0 -26
  144. data/samples/actions/webbug/submitform.js +0 -26
  145. data/samples/actions/webbug/webbug-browser.rb +0 -68
  146. data/samples/actions/webbug/webbug-js.rb +0 -67
  147. data/samples/actions/webbug/webbug-reader.rb +0 -90
  148. data/samples/attachments/attach.rb +0 -40
  149. data/samples/attachments/attached.txt +0 -1
  150. data/samples/crypto/crypto.rb +0 -28
  151. data/samples/digsig/signed.rb +0 -46
  152. data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
  153. data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
  154. data/samples/exploits/exploit_customdictopen.rb +0 -55
  155. data/samples/exploits/getannots.rb +0 -69
  156. data/samples/flash/flash.rb +0 -31
  157. data/samples/javascript/attached.txt +0 -1
  158. data/samples/javascript/js.rb +0 -52
  159. data/templates/patterns.rb +0 -66
  160. data/templates/widgets.rb +0 -173
  161. data/templates/xdp.rb +0 -92
  162. data/test/ts_pdf.rb +0 -50
@@ -1,25 +1,20 @@
1
1
  =begin
2
2
 
3
- = File
4
- metadata.rb
5
-
6
- = Info
7
- This file is part of Origami, PDF manipulation framework for Ruby
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- Origami is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU Lesser General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- Origami is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU Lesser General Public License for more details.
20
-
21
- You should have received a copy of the GNU Lesser General Public License
22
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ Origami is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Origami is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
18
 
24
19
  =end
25
20
 
@@ -27,155 +22,151 @@ require 'rexml/document'
27
22
 
28
23
  module Origami
29
24
 
30
- class PDF
25
+ class PDF
26
+ #
27
+ # Returns true if the document has a document information dictionary.
28
+ #
29
+ def document_info?
30
+ trailer_key? :Info
31
+ end
31
32
 
32
- #
33
- # Returns true if the document has a document information dictionary.
34
- #
35
- def has_document_info?
36
- has_attr? :Info
37
- end
33
+ #
34
+ # Returns the document information dictionary if present.
35
+ #
36
+ def document_info
37
+ trailer_key :Info
38
+ end
38
39
 
39
- #
40
- # Returns true if the document has a catalog metadata stream.
41
- #
42
- def has_metadata?
43
- self.Catalog.Metadata.is_a?(Stream)
44
- end
40
+ def title; get_document_info_field(:Title) end
41
+ def author; get_document_info_field(:Author) end
42
+ def subject; get_document_info_field(:Subject) end
43
+ def keywords; get_document_info_field(:Keywords) end
44
+ def creator; get_document_info_field(:Creator) end
45
+ def producer; get_document_info_field(:Producer) end
46
+ def creation_date; get_document_info_field(:CreationDate) end
47
+ def mod_date; get_document_info_field(:ModDate) end
48
+
49
+ #
50
+ # Returns true if the document has a catalog metadata stream.
51
+ #
52
+ def metadata?
53
+ self.Catalog.Metadata.is_a?(Stream)
54
+ end
45
55
 
46
- #
47
- # Returns the document information dictionary if present.
48
- #
49
- def get_document_info
50
- get_doc_attr :Info
51
- end
56
+ #
57
+ # Returns a Hash of the information found in the metadata stream
58
+ #
59
+ def metadata
60
+ metadata_stm = self.Catalog.Metadata
52
61
 
53
- def title; get_document_info_field(:Title) end
54
- def author; get_document_info_field(:Author) end
55
- def subject; get_document_info_field(:Subject) end
56
- def keywords; get_document_info_field(:Keywords) end
57
- def creator; get_document_info_field(:Creator) end
58
- def producer; get_document_info_field(:Producer) end
59
- def creation_date; get_document_info_field(:CreationDate) end
60
- def mod_date; get_document_info_field(:ModDate) end
62
+ if metadata_stm.is_a?(Stream)
63
+ doc = REXML::Document.new(metadata_stm.data)
64
+ info = {}
61
65
 
62
- #
63
- # Returns a Hash of the information found in the metadata stream
64
- #
65
- def get_metadata
66
- metadata_stm = self.Catalog.Metadata
66
+ doc.elements.each('*/*/rdf:Description') do |description|
67
67
 
68
- if metadata_stm.is_a?(Stream)
69
- doc = REXML::Document.new(metadata_stm.data)
68
+ description.attributes.each_attribute do |attr|
69
+ case attr.prefix
70
+ when 'pdf','xap'
71
+ info[attr.name] = attr.value
72
+ end
73
+ end
70
74
 
71
- info = {}
75
+ description.elements.each('*') do |element|
76
+ value = (element.elements['.//rdf:li'] || element).text
77
+ info[element.name] = value.to_s
78
+ end
79
+ end
72
80
 
73
- doc.elements.each('*/*/rdf:Description') do |description|
74
-
75
- description.attributes.each_attribute do |attr|
76
- case attr.prefix
77
- when 'pdf','xap'
78
- info[attr.name] = attr.value
81
+ info
79
82
  end
80
- end
81
-
82
- description.elements.each('*') do |element|
83
- value = (element.elements['.//rdf:li'] || element).text
84
- info[element.name] = value.to_s
85
- end
86
-
87
83
  end
88
84
 
89
- info
90
- end
91
- end
85
+ #
86
+ # Modifies or creates a metadata stream.
87
+ #
88
+ def create_metadata(info = {})
89
+ skeleton = <<-XMP
90
+ <?packet begin="#{"\xef\xbb\xbf"}" id="W5M0MpCehiHzreSzNTczkc9d"?>
91
+ <x:xmpmeta xmlns:x="adobe:ns:meta/">
92
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
93
+ <rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
94
+ </rdf:Description>
95
+ </rdf:RDF>
96
+ </x:xmpmeta>
97
+ <?xpacket end="w"?>
98
+ XMP
99
+
100
+ xml =
101
+ if self.Catalog.Metadata.is_a?(Stream)
102
+ self.Catalog.Metadata.data
103
+ else
104
+ skeleton
105
+ end
106
+
107
+ doc = REXML::Document.new(xml)
108
+ desc = doc.elements['*/*/rdf:Description']
109
+
110
+ info.each do |name, value|
111
+ elt = REXML::Element.new "pdf:#{name}"
112
+ elt.text = value
113
+
114
+ desc.elements << elt
115
+ end
92
116
 
93
- #
94
- # Modifies or creates a metadata stream.
95
- #
96
- def create_metadata(info = {})
97
- skeleton = <<-XMP
98
- <?packet begin="#{"\xef\xbb\xbf"}" id="W5M0MpCehiHzreSzNTczkc9d"?>
99
- <x:xmpmeta xmlns:x="adobe:ns:meta/">
100
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
101
- <rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
102
- </rdf:Description>
103
- </rdf:RDF>
104
- </x:xmpmeta>
105
- <?xpacket end="w"?>
106
- XMP
107
-
108
- xml =
109
- if self.Catalog.Metadata.is_a?(Stream)
110
- self.Catalog.Metadata.data
111
- else
112
- skeleton
113
- end
117
+ xml = ""; doc.write(xml, 4)
114
118
 
115
- doc = REXML::Document.new(xml)
116
- desc = doc.elements['*/*/rdf:Description']
117
-
118
- info.each do |name, value|
119
- elt = REXML::Element.new "pdf:#{name}"
120
- elt.text = value
119
+ if self.Catalog.Metadata.is_a?(Stream)
120
+ self.Catalog.Metadata.data = xml
121
+ else
122
+ self.Catalog.Metadata = Stream.new(xml)
123
+ end
121
124
 
122
- desc.elements << elt
123
- end
125
+ self.Catalog.Metadata
126
+ end
124
127
 
125
- xml = ""; doc.write(xml, 3)
128
+ private
126
129
 
127
- if self.Catalog.Metadata.is_a?(Stream)
128
- self.Catalog.Metadata.data = xml
129
- else
130
- self.Catalog.Metadata = Stream.new(xml)
131
- end
130
+ def get_document_info_field(field) #:nodoc:
131
+ if self.document_info?
132
+ doc_info = self.document_info
132
133
 
133
- self.Catalog.Metadata
134
+ if doc_info.key?(field)
135
+ case obj = doc_info[field].solve
136
+ when String then obj.value
137
+ when Stream then obj.data
138
+ end
139
+ end
140
+ end
141
+ end
134
142
  end
135
143
 
136
- private
144
+ #
145
+ # Class representing an information Dictionary, containing title, author, date of creation and the like.
146
+ #
147
+ class Metadata < Dictionary
148
+ include StandardObject
149
+
150
+ field :Title, :Type => String, :Version => "1.1"
151
+ field :Author, :Type => String
152
+ field :Subject, :Type => String, :Version => "1.1"
153
+ field :Keywords, :Type => String, :Version => "1.1"
154
+ field :Creator, :Type => String
155
+ field :Producer, :Type => String
156
+ field :CreationDate, :Type => String
157
+ field :ModDate, :Type => String, :Version => "1.1"
158
+ field :Trapped, :Type => Name, :Default => :Unknown, :Version => "1.3"
159
+ end
137
160
 
138
- def get_document_info_field(field) #:nodoc:
139
- if has_document_info?
140
- doc_info = get_document_info
161
+ #
162
+ # Class representing a metadata Stream.
163
+ # This stream can contain the same information as the Metadata dictionary, but is storing in XML data.
164
+ #
165
+ class MetadataStream < Stream
166
+ include StandardObject
141
167
 
142
- if doc_info.has_key?(field)
143
- case obj = get_document_info[field].solve
144
- when String then obj.value
145
- when Stream then obj.data
146
- end
147
- end
148
- end
168
+ field :Type, :Type => Name, :Default => :Metadata, :Required => true
169
+ field :Subtype, :Type => Name, :Default =>:XML, :Required => true
149
170
  end
150
171
 
151
- end
152
-
153
- #
154
- # Class representing an information Dictionary, containing title, author, date of creation and the like.
155
- #
156
- class Metadata < Dictionary
157
- include StandardObject
158
-
159
- field :Title, :Type => String, :Version => "1.1"
160
- field :Author, :Type => String
161
- field :Subject, :Type => String, :Version => "1.1"
162
- field :Keywords, :Type => String, :Version => "1.1"
163
- field :Creator, :Type => String
164
- field :Producer, :Type => String
165
- field :CreationDate, :Type => ByteString
166
- field :ModDate, :Type => ByteString, :Version => "1.1"
167
- field :Trapped, :Type => Name, :Default => :Unknown, :Version => "1.3"
168
- end
169
-
170
- #
171
- # Class representing a metadata Stream.
172
- # This stream can contain the same information as the Metadata dictionary, but is storing in XML data.
173
- #
174
- class MetadataStream < Stream
175
- include StandardObject
176
-
177
- field :Type, :Type => Name, :Default => :Metadata, :Required => true
178
- field :Subtype, :Type => Name, :Default =>:XML, :Required => true
179
- end
180
-
181
172
  end
@@ -1,170 +1,134 @@
1
1
  =begin
2
2
 
3
- = File
4
- name.rb
5
-
6
- = Info
7
- This file is part of Origami, PDF manipulation framework for Ruby
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- Origami is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU Lesser General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- Origami is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU Lesser General Public License for more details.
20
-
21
- You should have received a copy of the GNU Lesser General Public License
22
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
23
5
 
24
- =end
6
+ Origami is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
25
10
 
26
- if RUBY_VERSION < '1.9'
27
- class EmptySymbol
28
- def ==(sym)
29
- sym.is_a?(EmptySymbol)
30
- end
11
+ Origami is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
31
15
 
32
- def id2name
33
- ""
34
- end
35
- alias to_s id2name
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
36
18
 
37
- def to_sym
38
- self
39
- end
19
+ =end
40
20
 
41
- def to_o
42
- Name.new("")
43
- end
21
+ module Origami
44
22
 
45
- def inspect
46
- ":"
47
- end
48
- end
49
- end
23
+ REGULARCHARS = "([^ \\t\\r\\n\\0\\[\\]<>()%\\/]|#[a-fA-F0-9][a-fA-F0-9])*" #:nodoc:
50
24
 
51
- module Origami
25
+ class InvalidNameObjectError < InvalidObjectError #:nodoc:
26
+ end
52
27
 
53
- REGULARCHARS = "([^ \\t\\r\\n\\0\\[\\]<>()%\\/]|#[a-fA-F0-9][a-fA-F0-9])*" #:nodoc:
54
-
55
- class InvalidNameObjectError < InvalidObjectError #:nodoc:
56
- end
57
-
58
- #
59
- # Class representing a Name Object.
60
- # Name objects are strings which identify some PDF file inner structures.
61
- #
62
- class Name #< DelegateClass(Symbol)
63
-
64
- include Origami::Object
65
-
66
- TOKENS = %w{ / } #:nodoc:
67
-
68
- @@regexp = Regexp.new(WHITESPACES + TOKENS.first + "(" + REGULARCHARS + ")" + WHITESPACES) #:nodoc
69
-
70
28
  #
71
- # Creates a new Name.
72
- # _name_:: A symbol representing the new Name value.
29
+ # Class representing a Name Object.
30
+ # Name objects are strings which identify some PDF file inner structures.
73
31
  #
74
- def initialize(name = "")
75
- unless name.is_a?(Symbol) or name.is_a?(::String)
76
- raise TypeError, "Expected type Symbol or String, received #{name.class}."
77
- end
78
-
79
- @value = name.to_s
80
-
81
- super()
82
- end
32
+ class Name #< DelegateClass(Symbol)
33
+ include Origami::Object
83
34
 
84
- if RUBY_VERSION < '1.9'
85
- def value
86
- ( @value.empty? ) ? EmptySymbol.new : @value.to_sym
87
- end
88
- else
89
- def value
90
- @value.to_sym
91
- end
92
- end
35
+ TOKENS = %w{ / } #:nodoc:
93
36
 
94
- def ==(object) #:nodoc:
95
- self.eql?(object) or @value.to_sym == object
96
- end
97
-
98
- def eql?(object) #:nodoc:
99
- object.is_a?(Name) and self.to_s == object.to_s
100
- end
101
-
102
- def hash #:nodoc:
103
- @value.hash
104
- end
105
-
106
- def to_s #:nodoc:
107
- super(TOKENS.first + Name.expand(@value))
108
- end
109
-
110
- def self.parse(stream, parser = nil) #:nodoc:
111
-
112
- offset = stream.pos
113
-
114
- name =
115
- if stream.scan(@@regexp).nil?
116
- raise InvalidNameObjectError, "Bad name format"
117
- else
118
- value = stream[2]
119
-
120
- Name.new(value.include?('#') ? contract(value) : value)
37
+ @@regexp = Regexp.new(WHITESPACES + TOKENS.first + "(?<name>#{REGULARCHARS})" + WHITESPACES) #:nodoc
38
+
39
+ #
40
+ # Creates a new Name.
41
+ # _name_:: A symbol representing the new Name value.
42
+ #
43
+ def initialize(name = "")
44
+ unless name.is_a?(Symbol) or name.is_a?(::String)
45
+ raise TypeError, "Expected type Symbol or String, received #{name.class}."
46
+ end
47
+
48
+ @value = name.to_s
49
+
50
+ super()
121
51
  end
122
52
 
123
- name.file_offset = offset
53
+ def value
54
+ @value.to_sym
55
+ end
124
56
 
125
- name
126
- end
127
-
128
- def self.contract(name) #:nodoc:
129
-
130
- i = 0
131
- name = name.dup
132
-
133
- while i < name.length
134
-
135
- if name[i,1] == "#"
136
- digits = name[i+1, 2]
137
-
138
- unless /^[A-Za-z0-9]{2}$/ === digits
139
- raise InvalidNameObjectError, "Irregular use of # token"
140
- end
141
-
142
- char = digits.hex.chr
143
-
144
- if char == "\0"
145
- raise InvalidNameObjectError, "Null byte forbidden inside name definition"
146
- end
147
-
148
- name[i, 3] = char
57
+ def <=>(name)
58
+ return unless name.is_a?(Name)
59
+
60
+ self.value <=> name.value
149
61
  end
150
-
151
- i = i + 1
152
- end
153
62
 
154
- name
155
- end
156
-
157
- def self.expand(name) #:nodoc:
158
-
159
- forbiddenchars = /[ #\t\r\n\0\[\]<>()%\/]/
160
-
161
- name.gsub(forbiddenchars) do |c|
162
- "#" + c[0].ord.to_s(16).rjust(2,"0")
163
- end
164
- end
165
-
166
- def self.native_type ; Name end
63
+ def ==(object) #:nodoc:
64
+ self.eql?(object) or @value.to_sym == object
65
+ end
167
66
 
168
- end
67
+ def eql?(object) #:nodoc:
68
+ object.is_a?(Name) and self.value.eql?(object.value)
69
+ end
70
+
71
+ def hash #:nodoc:
72
+ @value.hash
73
+ end
74
+
75
+ def to_s #:nodoc:
76
+ super(TOKENS.first + Name.expand(@value))
77
+ end
78
+
79
+ def self.parse(stream, parser = nil) #:nodoc:
80
+ offset = stream.pos
81
+
82
+ name =
83
+ if stream.scan(@@regexp).nil?
84
+ raise InvalidNameObjectError, "Bad name format"
85
+ else
86
+ value = stream['name']
87
+
88
+ Name.new(value.include?('#') ? contract(value) : value)
89
+ end
90
+
91
+ name.file_offset = offset
92
+
93
+ name
94
+ end
95
+
96
+ def self.contract(name) #:nodoc:
97
+ i = 0
98
+ name = name.dup
99
+
100
+ while i < name.length
101
+ if name[i] == "#"
102
+ digits = name[i+1, 2]
103
+
104
+ unless /^[A-Za-z0-9]{2}$/ === digits
105
+ raise InvalidNameObjectError, "Irregular use of # token"
106
+ end
107
+
108
+ char = digits.hex.chr
109
+
110
+ if char == "\0"
111
+ raise InvalidNameObjectError, "Null byte forbidden inside name definition"
112
+ end
113
+
114
+ name[i, 3] = char
115
+ end
116
+
117
+ i = i + 1
118
+ end
119
+
120
+ name
121
+ end
122
+
123
+ def self.expand(name) #:nodoc:
124
+ forbiddenchars = /[ #\t\r\n\0\[\]<>()%\/]/
125
+
126
+ name.gsub(forbiddenchars) do |c|
127
+ "#" + c.ord.to_s(16).rjust(2,"0")
128
+ end
129
+ end
130
+
131
+ def self.native_type ; Name end
132
+ end
169
133
 
170
134
  end