first commit
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
mruby-pack (pack / unpack)
|
||||
=========
|
||||
|
||||
mruby-pack provides `Array#pack` and `String#unpack` for mruby.
|
||||
|
||||
|
||||
## Installation
|
||||
Add the line below into your `build_config.rb`:
|
||||
|
||||
```
|
||||
conf.gem :github => 'iij/mruby-pack'
|
||||
```
|
||||
|
||||
There is no dependency on other mrbgems.
|
||||
|
||||
|
||||
## Supported template string
|
||||
- A : arbitrary binary string (space padded, count is width)
|
||||
- a : arbitrary binary string (null padded, count is width)
|
||||
- C : 8-bit unsigned (unsigned char)
|
||||
- c : 8-bit signed (signed char)
|
||||
- D, d: 64-bit float, native format
|
||||
- E : 64-bit float, little endian byte order
|
||||
- e : 32-bit float, little endian byte order
|
||||
- F, f: 32-bit float, native format
|
||||
- G : 64-bit float, network (big-endian) byte order
|
||||
- g : 32-bit float, network (big-endian) byte order
|
||||
- H : hex string (high nibble first)
|
||||
- h : hex string (low nibble first)
|
||||
- I : unsigned integer, native endian (`unsigned int` in C)
|
||||
- i : signed integer, native endian (`int` in C)
|
||||
- L : 32-bit unsigned, native endian (`uint32_t`)
|
||||
- l : 32-bit signed, native endian (`int32_t`)
|
||||
- m : base64 encoded string (see RFC 2045, count is width)
|
||||
- N : 32-bit unsigned, network (big-endian) byte order
|
||||
- n : 16-bit unsigned, network (big-endian) byte order
|
||||
- Q : 64-bit unsigned, native endian (`uint64_t`)
|
||||
- q : 64-bit signed, native endian (`int64_t`)
|
||||
- S : 16-bit unsigned, native endian (`uint16_t`)
|
||||
- s : 16-bit signed, native endian (`int16_t`)
|
||||
- U : UTF-8 character
|
||||
- V : 32-bit unsigned, VAX (little-endian) byte order
|
||||
- v : 16-bit unsigned, VAX (little-endian) byte order
|
||||
- x : null byte
|
||||
- Z : same as "a", except that null is added with *
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2012 Internet Initiative Japan Inc.
|
||||
Copyright (c) 2017 mruby developers
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
MRuby::Gem::Specification.new('mruby-pack') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
|
||||
spec.summary = 'Array#pack and String#unpack method'
|
||||
|
||||
spec.cc.include_paths << "#{build.root}/src"
|
||||
end
|
||||
+1439
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,159 @@
|
||||
PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01
|
||||
|
||||
def assert_pack tmpl, packed, unpacked
|
||||
t = tmpl.inspect
|
||||
assert "assert_pack" do
|
||||
assert_equal packed, unpacked.pack(tmpl), "#{unpacked.inspect}.pack(#{t})"
|
||||
assert_equal unpacked, packed.unpack(tmpl), "#{packed.inspect}.unpack(#{t})"
|
||||
end
|
||||
end
|
||||
|
||||
# pack & unpack 'm' (base64)
|
||||
assert('[""].pack("m")') do
|
||||
assert_pack "m", "", [""]
|
||||
end
|
||||
|
||||
assert('["\0"].pack("m")') do
|
||||
assert_pack "m", "AA==\n", ["\0"]
|
||||
end
|
||||
|
||||
assert('["\0\0"].pack("m")') do
|
||||
assert_pack "m", "AAA=\n", ["\0\0"]
|
||||
end
|
||||
|
||||
assert('["\0\0\0"].pack("m")') do
|
||||
assert_pack "m", "AAAA\n", ["\0\0\0"]
|
||||
end
|
||||
|
||||
assert('["abc..xyzABC..XYZ"].pack("m")') do
|
||||
assert_pack "m", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
|
||||
end
|
||||
|
||||
assert('"YWJ...".unpack("m") should "abc..xyzABC..XYZ"') do
|
||||
ary = ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
|
||||
assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m")
|
||||
assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m")
|
||||
end
|
||||
|
||||
assert('["A", "B"].pack') do
|
||||
assert_equal "QQ==\n", ["A", "B"].pack("m50")
|
||||
assert_equal ["A"], "QQ==\n".unpack("m50")
|
||||
assert_equal "QQ==Qg==", ["A", "B"].pack("m0 m0")
|
||||
assert_equal ["A", "B"], "QQ==Qg==".unpack("m10 m10")
|
||||
end
|
||||
|
||||
assert('["abc..xyzABC..XYZ"].pack("m0")') do
|
||||
assert_pack "m0", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
|
||||
end
|
||||
|
||||
# pack & unpack 'H'
|
||||
assert('["3031"].pack("H*")') do
|
||||
assert_pack "H*", "01", ["3031"]
|
||||
end
|
||||
|
||||
assert('["10"].pack("H*")') do
|
||||
assert_pack "H*", "\020", ["10"]
|
||||
end
|
||||
|
||||
assert('[0,1,127,128,255].pack("C*")') do
|
||||
assert_pack "C*", "\x00\x01\x7F\x80\xFF", [0, 1, 127, 128, 255]
|
||||
end
|
||||
|
||||
# pack "a"
|
||||
assert('["abc"].pack("a")') do
|
||||
assert_equal "a", ["abc"].pack("a")
|
||||
assert_equal "abc", ["abc"].pack("a*")
|
||||
assert_equal "abc\0", ["abc"].pack("a4")
|
||||
end
|
||||
|
||||
# upack "a"
|
||||
assert('["abc"].pack("a")') do
|
||||
assert_equal ["abc\0"], "abc\0".unpack("a4")
|
||||
assert_equal ["abc "], "abc ".unpack("a4")
|
||||
end
|
||||
|
||||
# pack "A"
|
||||
assert('["abc"].pack("A")') do
|
||||
assert_equal "a", ["abc"].pack("A")
|
||||
assert_equal "abc", ["abc"].pack("A*")
|
||||
assert_equal "abc ", ["abc"].pack("A4")
|
||||
end
|
||||
|
||||
# upack "A"
|
||||
assert('["abc"].pack("A")') do
|
||||
assert_equal ["abc"], "abc\0".unpack("A4")
|
||||
assert_equal ["abc"], "abc ".unpack("A4")
|
||||
end
|
||||
|
||||
# regression tests
|
||||
assert('issue #1') do
|
||||
assert_equal "\000\001\000\002", [1, 2].pack("nn")
|
||||
end
|
||||
|
||||
assert 'pack float' do
|
||||
assert_pack 'e', "\x00\x00@@", [3.0]
|
||||
assert_pack 'g', "@@\x00\x00", [3.0]
|
||||
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
assert_pack 'f', "\x00\x00@@", [3.0]
|
||||
assert_pack 'F', "\x00\x00@@", [3.0]
|
||||
else
|
||||
assert_pack 'f', "@@\x00\x00", [3.0]
|
||||
assert_pack 'F', "@@\x00\x00", [3.0]
|
||||
end
|
||||
end
|
||||
|
||||
assert 'pack double' do
|
||||
assert_pack 'E', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
assert_pack 'G', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
assert_pack 'd', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
assert_pack 'D', "\x00\x00\x00\x00\x00\x00\b@", [3.0]
|
||||
else
|
||||
assert_pack 'd', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
assert_pack 'D', "@\b\x00\x00\x00\x00\x00\x00", [3.0]
|
||||
end
|
||||
end
|
||||
|
||||
assert 'pack/unpack "i"' do
|
||||
int_size = [0].pack('i').size
|
||||
raise "pack('i').size is too small (#{int_size})" if int_size < 2
|
||||
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
str = "\xC7\xCF" + "\xFF" * (int_size-2)
|
||||
else
|
||||
str = "\xFF" * (int_size-2) + "\xCF\xC7"
|
||||
end
|
||||
assert_pack 'i', str, [-12345]
|
||||
end
|
||||
|
||||
assert 'pack/unpack "I"' do
|
||||
uint_size = [0].pack('I').size
|
||||
raise "pack('I').size is too small (#{uint_size})" if uint_size < 2
|
||||
|
||||
if PACK_IS_LITTLE_ENDIAN
|
||||
str = "\x39\x30" + "\0" * (uint_size-2)
|
||||
else
|
||||
str = "\0" * (uint_size-2) + "\x30\x39"
|
||||
end
|
||||
assert_pack 'I', str, [12345]
|
||||
end
|
||||
|
||||
assert 'pack/unpack "U"' do
|
||||
assert_equal [], "".unpack("U")
|
||||
assert_equal [], "".unpack("U*")
|
||||
assert_equal [65, 66], "ABC".unpack("U2")
|
||||
assert_equal [12371, 12435, 12395, 12385, 12399, 19990, 30028], "こんにちは世界".unpack("U*")
|
||||
|
||||
assert_equal "", [].pack("U")
|
||||
assert_equal "", [].pack("U*")
|
||||
assert_equal "AB", [65, 66, 67].pack("U2")
|
||||
assert_equal "こんにちは世界", [12371, 12435, 12395, 12385, 12399, 19990, 30028].pack("U*")
|
||||
|
||||
assert_equal "\000", [0].pack("U")
|
||||
|
||||
assert_raise(RangeError) { [-0x40000000].pack("U") }
|
||||
assert_raise(RangeError) { [-1].pack("U") }
|
||||
assert_raise(RangeError) { [0x40000000].pack("U") }
|
||||
end
|
||||
Reference in New Issue
Block a user