leb128 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE.md +9 -0
- data/README.md +50 -0
- data/Rakefile +13 -0
- data/leb128.gemspec +16 -0
- data/lib/leb128.rb +63 -0
- data/test/test_leb128.rb +73 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20748dc4ff2f263fdf41f1a864716734727820d2
|
4
|
+
data.tar.gz: 1429a8e432ebbf3564c7f5b65ed88801ffca98e4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 96530e760a059bab741ad7f017693d3890e09e5262644c9bffc06d120a81921125f2b56c1b400c2de11aed63f47729cd0604e923a140ad411739e96b22730cae
|
7
|
+
data.tar.gz: ead3aa1418ce06b4f313c4d365c248cc381b890a8bd70e34e5e98cf40f392de5acc314b09359ebacb6c1bacb1f199d26f5dc953ca3d4f2daf4ffa7777914f3cd
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Clayton Bonigut
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# LEB128
|
2
|
+
|
3
|
+
This gem is a pair of utility functions for encoding and decoding LEB128-compressed integers.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'leb128'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install leb128
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Require the Gem:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'leb128'
|
27
|
+
```
|
28
|
+
|
29
|
+
### Encoding and Decoding
|
30
|
+
|
31
|
+
Encode integers into LEB128-compressed data by using the `encode` method. The first argument takes an integer, and the second takes a bool that tells whether to use a signed datatype or not. The following encodes the given integer and returns a new StringIO containing it:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
LEB128.encode(-0x143f, true)
|
35
|
+
#=> #<StringIO:0x00000003533e20>
|
36
|
+
```
|
37
|
+
|
38
|
+
Decode LEB128-compressed data into integers by using the `decode` method. The first argument takes a StringIO, the second takes a bool that tells whether to use a signed datatype or not, and the third takes an integer that sets the position of the StringIO (default is 0). The following decodes the given StringIO and returns a new integer containing it:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
sio = StringIO.new
|
42
|
+
sio.putc(0xc1)
|
43
|
+
sio.putc(0x57)
|
44
|
+
LEB128.decode(sio, false)
|
45
|
+
#=> 11201
|
46
|
+
```
|
47
|
+
|
48
|
+
## License
|
49
|
+
|
50
|
+
This gem is available as open source under the terms of the MIT License. See [LICENSE.md](https://github.com/cl8n/leb128/blob/master/LICENSE.md) and <https://opensource.org/licenses/MIT>.
|
data/Rakefile
ADDED
data/leb128.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "leb128"
|
3
|
+
spec.version = "0.1.0"
|
4
|
+
spec.authors = ["Clayton Bonigut"]
|
5
|
+
|
6
|
+
spec.summary = %q{A pair of utility functions for encoding and decoding LEB128-compressed integers.}
|
7
|
+
spec.homepage = "https://github.com/cl8n/leb128"
|
8
|
+
spec.license = "MIT"
|
9
|
+
|
10
|
+
spec.files = `git ls-files -z`.split("\x0")
|
11
|
+
|
12
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
13
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
14
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
15
|
+
spec.add_development_dependency "yard"
|
16
|
+
end
|
data/lib/leb128.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
# Includes a pair of functions to encode and decode the LEB128 integer compression type.
|
4
|
+
module LEB128
|
5
|
+
# Encode an integer into LEB128-compressed data.
|
6
|
+
#
|
7
|
+
# @param value [Integer]
|
8
|
+
# @param signed [Boolean]
|
9
|
+
# @return [StringIO]
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# LEB128.encode(-0x143f, true) #=> #<StringIO:0x00000003533e20>
|
13
|
+
|
14
|
+
def self.encode(value, signed)
|
15
|
+
if value < 0 && !signed
|
16
|
+
raise(ArgumentError, 'Cannot encode a negative integer to an unsigned LEB128')
|
17
|
+
end
|
18
|
+
io = StringIO.new
|
19
|
+
loop do
|
20
|
+
byte = value & 0x7F
|
21
|
+
value >>= 7
|
22
|
+
if signed
|
23
|
+
byte |= 0x80 unless (value == 0 && byte & 0x40 == 0) || (value == -1 && byte & 0x40 != 0)
|
24
|
+
elsif value != 0
|
25
|
+
byte |= 0x80
|
26
|
+
end
|
27
|
+
io.putc(byte)
|
28
|
+
break if (signed && byte & 0x80 == 0) || (!signed && value == 0)
|
29
|
+
end
|
30
|
+
io.pos = 0
|
31
|
+
io
|
32
|
+
end
|
33
|
+
|
34
|
+
# Decode LEB128-compressed data into an integer.
|
35
|
+
#
|
36
|
+
# @param io [StringIO]
|
37
|
+
# @param signed [Boolean]
|
38
|
+
# @param index [Integer]
|
39
|
+
# @return [Integer]
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# sio = StringIO.new
|
43
|
+
# sio.putc(0xc1)
|
44
|
+
# sio.putc(0x57)
|
45
|
+
# LEB128.decode(sio, false) #=> 11201
|
46
|
+
|
47
|
+
def self.decode(io, signed, index = 0)
|
48
|
+
io.pos = index
|
49
|
+
raise(EOFError) if io.eof?
|
50
|
+
value = 0
|
51
|
+
offset = 0
|
52
|
+
loop do
|
53
|
+
byte = io.read(1).unpack('C')[0]
|
54
|
+
value |= (byte & 0x7F) << offset
|
55
|
+
offset += 7
|
56
|
+
if byte & 0x80 == 0
|
57
|
+
value |= -(1 << offset) if signed && byte & 0x40 != 0
|
58
|
+
break
|
59
|
+
end
|
60
|
+
end
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
data/test/test_leb128.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'leb128'
|
3
|
+
|
4
|
+
class LEB128Test < Minitest::Test
|
5
|
+
def test_decode_signed_negative_leb128
|
6
|
+
buffer = StringIO.new
|
7
|
+
buffer.putc(0xc1)
|
8
|
+
buffer.putc(0x57)
|
9
|
+
actual = LEB128.decode(buffer, true)
|
10
|
+
expected = -0x143f
|
11
|
+
assert_equal(expected, actual)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_decode_signed_positive_leb128
|
15
|
+
buffer = StringIO.new
|
16
|
+
buffer.putc(0x8e)
|
17
|
+
buffer.putc(0x32)
|
18
|
+
actual = LEB128.decode(buffer, true)
|
19
|
+
expected = 0x190e
|
20
|
+
assert_equal(expected, actual)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_decode_unsigned_leb128
|
24
|
+
buffer = StringIO.new
|
25
|
+
buffer.putc(0xc1)
|
26
|
+
buffer.putc(0x57)
|
27
|
+
actual = LEB128.decode(buffer, false)
|
28
|
+
expected = 0x2bc1
|
29
|
+
assert_equal(expected, actual)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_decode_eoferror
|
33
|
+
assert_raises(EOFError) do
|
34
|
+
buffer = StringIO.new
|
35
|
+
buffer.putc(0x01)
|
36
|
+
LEB128.decode(buffer, false, 1)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_encode_signed_negative_int
|
41
|
+
buffer = StringIO.new
|
42
|
+
buffer.putc(0xc1)
|
43
|
+
buffer.putc(0x57)
|
44
|
+
actual = LEB128.encode(-0x143f, true).string
|
45
|
+
expected = buffer.string
|
46
|
+
assert_equal(expected, actual)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_encode_signed_positive_int
|
50
|
+
buffer = StringIO.new
|
51
|
+
buffer.putc(0x8e)
|
52
|
+
buffer.putc(0x32)
|
53
|
+
actual = LEB128.encode(0x190e, true).string
|
54
|
+
expected = buffer.string
|
55
|
+
assert_equal(expected, actual)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_encode_unsigned_negative_int_argumenterror
|
59
|
+
exception = assert_raises(ArgumentError) do
|
60
|
+
LEB128.encode(-0x01, false)
|
61
|
+
end
|
62
|
+
assert_equal('Cannot encode a negative integer to an unsigned LEB128', exception.message)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_encode_unsigned_positive_int
|
66
|
+
buffer = StringIO.new
|
67
|
+
buffer.putc(0xc1)
|
68
|
+
buffer.putc(0x57)
|
69
|
+
actual = LEB128.encode(0x2bc1, false).string
|
70
|
+
expected = buffer.string
|
71
|
+
assert_equal(expected, actual)
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: leb128
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Clayton Bonigut
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- ".gitignore"
|
76
|
+
- ".travis.yml"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.md
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- leb128.gemspec
|
82
|
+
- lib/leb128.rb
|
83
|
+
- test/test_leb128.rb
|
84
|
+
homepage: https://github.com/cl8n/leb128
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.5.1
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: A pair of utility functions for encoding and decoding LEB128-compressed integers.
|
108
|
+
test_files: []
|
109
|
+
has_rdoc:
|