cborb 0.1.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 (44) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +27 -0
  3. data/.editorconfig +7 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +2 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +35 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +63 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +7 -0
  12. data/bin/generate_fixtures +262 -0
  13. data/bin/setup +8 -0
  14. data/cborb.gemspec +27 -0
  15. data/lib/cborb.rb +52 -0
  16. data/lib/cborb/decoding/decoder.rb +19 -0
  17. data/lib/cborb/decoding/ib_jump_table.rb +47 -0
  18. data/lib/cborb/decoding/simple_buffer.rb +24 -0
  19. data/lib/cborb/decoding/state.rb +130 -0
  20. data/lib/cborb/decoding/tagged_value.rb +3 -0
  21. data/lib/cborb/decoding/types/array.rb +20 -0
  22. data/lib/cborb/decoding/types/break.rb +12 -0
  23. data/lib/cborb/decoding/types/byte_string.rb +12 -0
  24. data/lib/cborb/decoding/types/floating_point.rb +18 -0
  25. data/lib/cborb/decoding/types/half_precision_floating_point.rb +28 -0
  26. data/lib/cborb/decoding/types/indefinite_array.rb +23 -0
  27. data/lib/cborb/decoding/types/indefinite_byte_string.rb +25 -0
  28. data/lib/cborb/decoding/types/indefinite_map.rb +24 -0
  29. data/lib/cborb/decoding/types/indefinite_text_string.rb +25 -0
  30. data/lib/cborb/decoding/types/integer.rb +12 -0
  31. data/lib/cborb/decoding/types/integer_decodable.rb +24 -0
  32. data/lib/cborb/decoding/types/map.rb +24 -0
  33. data/lib/cborb/decoding/types/negative_integer.rb +12 -0
  34. data/lib/cborb/decoding/types/root.rb +7 -0
  35. data/lib/cborb/decoding/types/simple_value.rb +17 -0
  36. data/lib/cborb/decoding/types/tag.rb +17 -0
  37. data/lib/cborb/decoding/types/text_string.rb +13 -0
  38. data/lib/cborb/decoding/types/type.rb +24 -0
  39. data/lib/cborb/decoding/types/unassigned_simple_value.rb +13 -0
  40. data/lib/cborb/decoding/types/unknown.rb +8 -0
  41. data/lib/cborb/decoding/unassigned_simple_value.rb +3 -0
  42. data/lib/cborb/errors.rb +11 -0
  43. data/lib/cborb/version.rb +3 -0
  44. metadata +128 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a99e458cdc0e473306db192ae994eee3486b4a7368c4e61578e83b6050766786
4
+ data.tar.gz: 2524de034a4263811f61cb1bd9cfbbdd46c690da7e631d30e5b22f2ebd2f994c
5
+ SHA512:
6
+ metadata.gz: 28aa0c323e37738493b08fd8d662293de6264d6c553e44e07d62091f0a1084755b4d8f86d2343414694fc78ae83fa37821c480bee8646952bc218fed1f6d8b24
7
+ data.tar.gz: bcd65e60a0eb7d3673455d51b513832849801fbc7ffe55a4009d9fe954dc46b8f6ad9a27560d671544449400e9cfe57e8ffab8a9dd47bc93f62e379a65743d35
@@ -0,0 +1,27 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: circleci/ruby:2.4.1-node-browsers
6
+
7
+ working_directory: ~/cborb
8
+
9
+ steps:
10
+ - checkout
11
+
12
+ - restore_cache:
13
+ keys:
14
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
15
+
16
+ - run:
17
+ name: setup
18
+ command: bin/setup
19
+
20
+ - save_cache:
21
+ paths:
22
+ - ./vendor/bundle
23
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
24
+
25
+ - run:
26
+ name: run specs
27
+ command: bundle exec rspec
data/.editorconfig ADDED
@@ -0,0 +1,7 @@
1
+ [*]
2
+ end_of_line = lf
3
+ insert_final_newline = true
4
+ indent_size = 2
5
+
6
+ [*.rb]
7
+ trim_trailing_whitespace = true
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ /spec/fixtures/*.cbor
13
+ /vendor
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in cborb.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cborb (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (10.5.0)
11
+ rspec (3.7.0)
12
+ rspec-core (~> 3.7.0)
13
+ rspec-expectations (~> 3.7.0)
14
+ rspec-mocks (~> 3.7.0)
15
+ rspec-core (3.7.1)
16
+ rspec-support (~> 3.7.0)
17
+ rspec-expectations (3.7.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.7.0)
20
+ rspec-mocks (3.7.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.7.0)
23
+ rspec-support (3.7.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.16)
30
+ cborb!
31
+ rake (~> 10.0)
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 1.16.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 murakmii
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Cborb
2
+
3
+ [![CircleCI](https://circleci.com/gh/murakmii/cborb/tree/master.svg?style=svg)](https://circleci.com/gh/murakmii/cborb/tree/master)
4
+
5
+ Cborb is a pure ruby decoder for CBOR([RFC 7049](https://tools.ietf.org/html/rfc7049))
6
+
7
+ ```rb
8
+ require "cborb"
9
+
10
+ decoder = Cborb::Decoding::Decoder.new
11
+
12
+ decoder.decode("\x83\x01")
13
+ decoder.finished? # => false
14
+
15
+ decoder.decode("\x02\x03")
16
+ decoder.finished? # => true
17
+
18
+ decoder.result # => [1, 2, 3]
19
+
20
+ # Shorthand
21
+ Cborb.decode("\x83\x01\x02\x03") # => [1, 2, 3]
22
+ ```
23
+
24
+ ## Handling indefinite-length data
25
+
26
+ Cborb can handle indefinite-length data(array, map, byte string, unicode string).
27
+
28
+ ```rb
29
+ Cborb.decode("\x9F\x01\x82\x02\x03\x9F\x04\x05\xFF\xFF") # => [1, [2, 3], [4, 5]]
30
+ ```
31
+
32
+ ## Handling tags
33
+
34
+ If Cborb encounters a tag, generates instance of `Cborb::Decoding::TaggedValue`.
35
+ That contains tag number and original value.
36
+
37
+ ```rb
38
+ Cborb.decode "\xC0" + "\x71" + "1970-01-01T00:00Z"
39
+ # => #<struct Cborb::Decoding::TaggedValue tag=0, value="1970-01-01T00:00Z">
40
+ ```
41
+
42
+ ## Handling simple values
43
+
44
+ Cborb can handle simple values(true, false, nil, undefined).
45
+
46
+ ```rb
47
+ Cborb.decode "\xF5" # => true
48
+ ```
49
+
50
+ "Undefined" doesn't exist in Ruby.
51
+ So, Cborb converts "undefined" to `nil`.
52
+
53
+ ```rb
54
+ Cborb.decode "\xF7" # => nil
55
+ ```
56
+
57
+ If Cborb encounters unassigned simple value, generates instance of `Cborb::Decoding::UnassignedSimpleValue`.
58
+ That contains simple value number.
59
+
60
+ ```rb
61
+ Cborb.decode "\xEF"
62
+ # => #<struct Cborb::Decoding::UnassignedSimpleValue number=15>
63
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cborb"
5
+
6
+ require "irb"
7
+ IRB.start(__FILE__)
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ def generate(name)
4
+ path = File.join(File.dirname(__FILE__), "../spec/fixtures/#{name}.cbor")
5
+ File.open(path, "wb") do |f|
6
+ yield f
7
+ end
8
+ end
9
+
10
+ def generate_definite_string(text, size_byte)
11
+ text = text.dup.force_encoding(Encoding::ASCII_8BIT)
12
+ ib =
13
+ case size_byte
14
+ when 0
15
+ (0b01100000 | text.bytesize).chr
16
+ when 1
17
+ "\x78" + [text.bytesize].pack("C")
18
+ when 2
19
+ "\x79" + [text.bytesize].pack("S>")
20
+ when 4
21
+ "\x7A" + [text.bytesize].pack("I>")
22
+ when 8
23
+ "\x7B" + [text.bytesize].pack("Q>")
24
+ else
25
+ raise "invalid string size byte: #{size_byte}"
26
+ end
27
+
28
+ ib + text
29
+ end
30
+
31
+ # NOTE:
32
+ # 0x83 = The initial byte of array that has 3 items
33
+
34
+ # only unknown initial byte
35
+ generate "001" do |out|
36
+ out << "\x1C"
37
+ end
38
+
39
+ # includes unknown initial byte
40
+ generate "002" do |out|
41
+ out << "\x83\x01\x1C\x03"
42
+ end
43
+
44
+ # includes unnecessary data
45
+ generate "003" do |out|
46
+ out << "\x83\x01\x02\x03\x04"
47
+ end
48
+
49
+ # lack data
50
+ generate "004" do |out|
51
+ out << "\x83\x01\x02"
52
+ end
53
+
54
+ # correct array
55
+ generate "005" do |out|
56
+ out << "\x83\x01\x02\x03"
57
+ end
58
+
59
+ # 100000 times nested array
60
+ generate "006" do |out|
61
+ out << ("\x81" * 100000)
62
+ out << "\x18\x7B" # 123(Integer)
63
+ end
64
+
65
+ # includes all data
66
+ generate "007" do |out|
67
+ out << "\x9F" # start indefinite array
68
+
69
+ # start map that contains 6 items
70
+ out << "\xA6"
71
+
72
+ out << generate_definite_string("description", 0)
73
+ out << generate_definite_string("The map that contains positive integers", 1)
74
+
75
+ out << generate_definite_string("zero byte integer", 0)
76
+ out << "\x17" # 23
77
+
78
+ out << generate_definite_string("single byte integer", 1)
79
+ out << "\x18\x0F" # 15
80
+
81
+ out << generate_definite_string("2 byte integer", 2)
82
+ out << "\x19\x00\xFF" # 255
83
+
84
+ out << generate_definite_string("4 byte integer", 4)
85
+ out << "\x1A\x00\x00\xFF\xFF" # 65535
86
+
87
+ out << generate_definite_string("8 byte integer", 8)
88
+ out << "\x1B\x00\x00\x00\x00\xFF\xFF\xFF\xFF" # 4294967295
89
+
90
+ # start map that contains 6 items
91
+ out << "\xB8\x06"
92
+
93
+ out << generate_definite_string("description", 0)
94
+ out << generate_definite_string("The map that contains negative integers", 1)
95
+
96
+ out << generate_definite_string("zero byte integer", 0)
97
+ out << "\x37" # -24
98
+
99
+ out << generate_definite_string("single byte integer", 1)
100
+ out << "\x38\x0F" # -16
101
+
102
+ out << generate_definite_string("2 byte integer", 2)
103
+ out << "\x39\x00\xFF" # -256
104
+
105
+ out << generate_definite_string("4 byte integer", 4)
106
+ out << "\x3A\x00\x00\xFF\xFF" # -65536
107
+
108
+ out << generate_definite_string("8 byte integer", 8)
109
+ out << "\x3B\x00\x00\x00\x00\xFF\xFF\xFF\xFF" # -4294967296
110
+
111
+ # start map that contains 7 items
112
+ out << "\xB9\x00\x07"
113
+
114
+ out << generate_definite_string("description", 0)
115
+ out << generate_definite_string("The map that contains byte strings", 1)
116
+
117
+ out << generate_definite_string("byte string(represented by 0 byte integer)", 1)
118
+ out << "\x43\x41\x42\x43"
119
+
120
+ out << generate_definite_string("byte string(represented by 1 byte integer)", 1)
121
+ out << "\x58\x03\x41\x42\x43"
122
+
123
+ out << generate_definite_string("byte string(represented by 2 byte integer)", 1)
124
+ out << "\x59\x00\x03\x41\x42\x43"
125
+
126
+ out << generate_definite_string("byte string(represented by 4 byte integer)", 1)
127
+ out << "\x5A\x00\x00\x00\x03\x41\x42\x43"
128
+
129
+
130
+ out << generate_definite_string("byte string(represented by 8 byte integer)", 1)
131
+ out << "\x5B\x00\x00\x00\x00\x00\x00\x00\x03\x41\x42\x43"
132
+
133
+ out << generate_definite_string("indefinite byte string", 1)
134
+ out << "\x5F"
135
+ out << "\x41\x41"
136
+ out << "\x41\x42"
137
+ out << "\x41\x43"
138
+ out << "\xFF"
139
+
140
+ # start map that contains 7 items
141
+ out << "\xBA\x00\x00\x00\x07"
142
+
143
+ ustr = "おはよう".force_encoding("ASCII-8BIT") # 12 bytes
144
+
145
+ out << generate_definite_string("description", 0)
146
+ out << generate_definite_string("The map that contains unicode strings", 1)
147
+
148
+ out << generate_definite_string("unicode string(represented by 0 byte integer)", 1)
149
+ out << "\x6C" + ustr
150
+
151
+ out << generate_definite_string("unicode string(represented by 1 byte integer)", 1)
152
+ out << "\x78\x0C" + ustr
153
+
154
+ out << generate_definite_string("unicode string(represented by 2 byte integer)", 1)
155
+ out << "\x79\x00\x0C" + ustr
156
+
157
+ out << generate_definite_string("unicode string(represented by 4 byte integer)", 1)
158
+ out << "\x7A\x00\x00\x00\x0C" + ustr
159
+
160
+ out << generate_definite_string("unicode string(represented by 8 byte integer)", 1)
161
+ out << "\x7B\x00\x00\x00\x00\x00\x00\x00\x0C" + ustr
162
+
163
+ out << generate_definite_string("indefinite unicode string", 1)
164
+ out << "\x7F"
165
+ out << "\x66" + "おは".force_encoding("ASCII-8BIT")
166
+ out << "\x66" + "よう".force_encoding("ASCII-8BIT")
167
+ out << "\x6F" + "ございます".force_encoding("ASCII-8BIT")
168
+ out << "\xFF"
169
+
170
+ # start map that contains 7 items
171
+ out << "\xBB\x00\x00\x00\x00\x00\x00\x00\x07"
172
+
173
+ out << generate_definite_string("description", 0)
174
+ out << generate_definite_string("The map that contains arrays", 1)
175
+
176
+ out << generate_definite_string("array(represented by 0 byte integer)", 1)
177
+ out << "\x83\x01\x02\x03" # [1, 2, 3]
178
+
179
+ out << generate_definite_string("array(represented by 1 byte integer)", 1)
180
+ out << "\x98\x03\x01\x02\x03"
181
+
182
+ out << generate_definite_string("array(represented by 2 byte integer)", 1)
183
+ out << "\x99\x00\x03\x01\x02\x03"
184
+
185
+ out << generate_definite_string("array(represented by 4 byte integer)", 1)
186
+ out << "\x9A\x00\x00\x00\x03\x01\x02\x03"
187
+
188
+ out << generate_definite_string("array(represented by 8 byte integer)", 1)
189
+ out << "\x9B\x00\x00\x00\x00\x00\x00\x00\x03\x01\x02\x03" # [1, 2, 3]
190
+
191
+ out << generate_definite_string("indefinite array", 1)
192
+ out << "\x9F"
193
+ out << "\x01\x02\x03"
194
+ out << "\x65" + "hello"
195
+ out << "\xFF"
196
+
197
+ # tag
198
+ out << "\xC0"
199
+ out << "\x71"
200
+ out << "1970-01-01T00:00Z"
201
+
202
+ out << "\xD8\x0F" # tag: 15
203
+ out << "\x18\x7B" # 123
204
+
205
+ out << "\xD9\x00\xFF" # tag: 255
206
+ out << "\x18\x7B"
207
+
208
+ out << "\xDA\x00\x00\xFF\xFF" # tag: 65535
209
+ out << "\x18\x7B"
210
+
211
+ out << "\xDB\x00\x00\x00\x00\xFF\xFF\xFF\xFF" # tag: 4294967295
212
+ out << "\x18\x7B"
213
+
214
+ # simple values
215
+ out << "\xF4\xF5\xF6\xF7"
216
+
217
+ # start map that contains 4 items
218
+ out << "\xA4"
219
+
220
+ out << generate_definite_string("description", 0)
221
+ out << generate_definite_string("The map that contains floating point values", 1)
222
+
223
+ out << generate_definite_string("half precision float", 1)
224
+ out << "\xF9\x35\x55"
225
+
226
+ out << generate_definite_string("single precision float", 1)
227
+ out << "\xFA"
228
+ out << [1.23].pack("g")
229
+
230
+ out << generate_definite_string("double precision float", 1)
231
+ out << "\xFB"
232
+ out << [1.23].pack("G")
233
+
234
+ # unassigned simple values
235
+ out << "\xEF"
236
+ out << "\xF8\xFF"
237
+
238
+ # start indefinite-length map
239
+ out << "\xBF"
240
+ out << "\x63" + "abc"
241
+ out << "\x18\x7B"
242
+ out << "\x63" + "def"
243
+ out << "\x19\x01\xC8"
244
+ out << "\xFF"
245
+
246
+ out << "\xFF" # enf of indefinite array
247
+ end
248
+
249
+ # indefinite-length byte string that contains invalid chunk
250
+ generate "008" do |out|
251
+ out << "\x5F\x01"
252
+ end
253
+
254
+ # indefinite-length unicode string that contains invalid chunk
255
+ generate "009" do |out|
256
+ out << "\x7F\x01"
257
+ end
258
+
259
+ # nil only
260
+ generate "010" do |out|
261
+ out << "\xF6"
262
+ end