Commit a5412d48 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Add 'mrbgems/mruby-pack/' from commit '383a9c79'

git-subtree-dir: mrbgems/mruby-pack
git-subtree-mainline: 842e6945
git-subtree-split: 383a9c79
parents 842e6945 383a9c79
gem_*
gem-*
mrb-*.a
src/*.o
/tmp
script:
- "ruby run_test.rb all test"
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.
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.
MRuby::Gem::Specification.new('mruby-pack') do |spec|
spec.license = 'MIT'
spec.authors = 'Internet Initiative Japan Inc.'
spec.cc.include_paths << "#{build.root}/src"
end
# encoding: ascii
# a = Array, s = String, t = Template
def packtest(a, s, t)
begin
r = a.pack(t)
return if r == s
puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}"
rescue => r
unless r.is_a? s
puts "#{a.inspect}.pack(#{t.inspect}) -> #{r.inspect} should be #{s.inspect}"
end
end
end
def unpacktest(a, s, t)
r = s.unpack(t)
return if r == a
puts "#{s.inspect}.unpack(#{t.inspect}) -> #{r.inspect} should be #{a.inspect}"
end
def pptest(a, s, t)
packtest(a, s, t)
unpacktest(a, s, t)
end
pptest [1], "\x01", "C"
packtest [1.1], "\x01", "C"
packtest [-1], "\xff", "C"
packtest [1,2], "\x01\x02", "C2"
#packtest [1], "X", ArgumentError
unpacktest [48, nil], "0", "CC"
unpacktest [160, -96], "\xa0\xa0", "Cc"
unpacktest [49, 50, 51], "123", "C*"
pptest [12849], "12", "S"
unpacktest [nil], "0", "S"
unpacktest [12849, nil], "123", "SS"
unpacktest [12849], "123", "S*"
pptest [10000], "\x27\x10", "s>"
pptest [-10000], "\xd8\xf0", "s>"
pptest [50000], "\xc3\x50", "S>"
pptest [10000], "\x10\x27", "s<"
pptest [-10000], "\xf0\xd8", "s<"
pptest [50000], "\x50\xc3", "S<"
pptest [1000000000], "\x3b\x9a\xca\x00", "l>"
pptest [-1000000000], "\xc4\x65\x36\x00", "l>"
pptest [1], "\x01\x00\x00\x00", "L<"
pptest [258], "\x02\x01\x00\x00", "L<"
pptest [66051], "\x03\x02\x01\x00", "L<"
pptest [16909060], "\x04\x03\x02\x01", "L<"
pptest [16909060], "\x01\x02\x03\x04", "L>"
packtest [-1], "\xff\xff\xff\xff", "L<"
pptest [1000000000], "\x00\x00\x00\x00\x3b\x9a\xca\x00", "q>"
pptest [-1000000000], "\xff\xff\xff\xff\xc4\x65\x36\x00", "q>"
if (2**33).is_a? Fixnum
pptest [81985529216486895], "\x01\x23\x45\x67\x89\xab\xcd\xef", "q>"
pptest [-1167088121787636991], "\x01\x23\x45\x67\x89\xab\xcd\xef", "q<"
end
pptest [16909060], "\x01\x02\x03\x04", "N"
pptest [258], "\x01\x02", "n"
pptest [32769], "\x80\x01", "n"
pptest [16909060], "\x04\x03\x02\x01", "V"
pptest [258], "\x02\x01", "v"
packtest [""], "", "m"
packtest ["a"], "YQ==\n", "m"
packtest ["ab"], "YWI=\n", "m"
packtest ["abc"], "YWJj\n", "m"
packtest ["abcd"], "YWJjZA==\n", "m"
unpacktest [""], "", "m"
unpacktest ["a"], "YQ==\n", "m"
unpacktest ["ab"], "YWI=\n", "m"
unpacktest ["abc"], "YWJj\n", "m"
unpacktest ["abcd"], "YWJjZA==\n", "m"
packtest [""], "\0", "H"
packtest ["3"], "0", "H"
packtest ["34"], "", "H0"
packtest ["34"], "0", "H"
packtest ["34"], "4", "H2"
packtest ["34"], "4\0", "H3"
packtest ["3456"], "4P", "H3"
packtest ["34563"], "4V0", "H*"
packtest ["5a"], "Z", "H*"
packtest ["5A"], "Z", "H*"
unpacktest [""], "", "H"
unpacktest [""], "0", "H0"
unpacktest ["3"], "0", "H"
unpacktest ["30"], "0", "H2"
unpacktest ["30"], "0", "H3"
unpacktest ["303"], "01", "H3"
unpacktest ["303132"], "012", "H*"
unpacktest ["3031", 50], "012", "H4C"
unpacktest ["5a"], "Z", "H*"
packtest [""], "\0", "h"
packtest ["3"], "\03", "h"
packtest ["34"], "", "h0"
packtest ["34"], "\03", "h"
packtest ["34"], "C", "h2"
packtest ["34"], "C\0", "h3"
packtest ["3456"], "C\05", "h3"
packtest ["34563"], "Ce\03", "h*"
packtest [""], " ", "A"
unpacktest [""], "", "A"
pptest ["1"], "1", "A"
pptest ["1"], "1 ", "A2"
unpacktest ["1"], "1", "A2"
unpacktest ["1"], "1 ", "A2"
unpacktest ["1"], "1\0", "A2"
packtest ["12"], "1", "A"
unpacktest ["1"], "12", "A"
pptest ["123"], "123", "A*"
packtest ["1","2"], "2", "A0A"
unpacktest ["","2"], "2", "A0A"
packtest [""], "\0", "a"
unpacktest [""], "", "a"
pptest ["1"], "1", "a"
pptest ["1 "], "1 ", "a2"
pptest ["1\0"], "1\0", "a2"
packtest ["1"], "1\0", "a2"
pptest ["123"], "123", "a*"
packtest [""], "\0", "Z"
unpacktest [""], "", "Z"
pptest ["1"], "1", "Z"
pptest ["1"], "1\0", "Z2"
pptest ["1 "], "1 ", "Z2"
pptest ["123"], "123\0", "Z*"
pptest ["1","2"], "12", "ZZ"
pptest ["1","2"], "1\0002", "Z*Z"
unpacktest ["1","3"], "1\00023", "Z3Z"
packtest [1, 2], "\x01\x02", "CyC"
packtest [65], "A", 'U'
packtest [59411], "\xEE\xA0\x93", 'U'
pptest [1], "\x00\x01", "xC"
unpacktest [2], "\xcc\x02", "xC"
#!/usr/bin/env ruby
#
# mrbgems test runner
#
gemname = File.basename(File.dirname(File.expand_path __FILE__))
if __FILE__ == $0
repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
build_args = ARGV
build_args = ['all', 'test'] if build_args.nil? or build_args.empty?
Dir.mkdir 'tmp' unless File.exist?('tmp')
unless File.exist?(dir)
system "git clone #{repository} #{dir}"
end
exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
end
MRuby::Build.new do |conf|
toolchain :gcc
conf.gembox 'default'
conf.gem File.expand_path(File.dirname(__FILE__))
end
This diff is collapsed.
# pack & unpack 'm' (base64)
assert('[""].pack("m")') do
ary = ""
str = ""
[ary].pack("m") == str and
str.unpack("m") == [ary]
end
assert('["\0"].pack("m")') do
ary = "\0"
str = "AA==\n"
[ary].pack("m") == str and
str.unpack("m") == [ary]
end
assert('["\0\0"].pack("m")') do
ary = "\0\0"
str = "AAA=\n"
[ary].pack("m") == str and
str.unpack("m") == [ary]
end
assert('["\0\0\0"].pack("m")') do
ary = "\0\0\0"
str = "AAAA\n"
[ary].pack("m") == str and
str.unpack("m") == [ary]
end
assert('["abc..xyzABC..XYZ"].pack("m")') do
["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"].pack("m") == "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n"
end
assert('"YWJ...".unpack("m") should "abc..xyzABC..XYZ"') do
str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m") == [str] and
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m") == [str]
end
# pack & unpack 'H'
assert('["3031"].pack("H*")') do
ary = "3031"
str = "01"
[ary].pack("H*") == str and
str.unpack("H*") == [ary]
end
assert('["10"].pack("H*")') do
ary = "10"
str = "\020"
[ary].pack("H*") == str and
str.unpack("H*") == [ary]
end
assert('[0,1,127,128,255].pack("C*")') do
ary = [ 0, 1, 127, 128, 255 ]
str = "\x00\x01\x7F\x80\xFF"
ary.pack("C*") == str and str.unpack("C*") == ary
end
# pack "a"
assert('["abc"].pack("a")') do
["abc"].pack("a") == "a" and
["abc"].pack("a*") == "abc" and
["abc"].pack("a4") == "abc\0"
end
# upack "a"
assert('["abc"].pack("a")') do
"abc\0".unpack("a4") == ["abc\0"] and
"abc ".unpack("a4") == ["abc "]
end
# pack "A"
assert('["abc"].pack("A")') do
["abc"].pack("A") == "a" and
["abc"].pack("A*") == "abc" and
["abc"].pack("A4") == "abc "
end
# upack "A"
assert('["abc"].pack("A")') do
"abc\0".unpack("A4") == ["abc"] and
"abc ".unpack("A4") == ["abc"]
end
# regression tests
assert('issue #1') do
[1, 2].pack("nn") == "\000\001\000\002"
end
def assert_pack tmpl, packed, unpacked
assert_equal packed, unpacked.pack(tmpl)
assert_equal unpacked, packed.unpack(tmpl)
end
PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01
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) + "\xC7\xCF"
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) + "\x39\x30"
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment