mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Add 'mrbgems/mruby-pack/' from commit '383a9c79e191d524a9a2b4107cc5043ecbf6190b'
git-subtree-dir: mrbgems/mruby-pack git-subtree-mainline:842e6945f2git-subtree-split:383a9c79e1
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
gem_*
|
||||
gem-*
|
||||
mrb-*.a
|
||||
src/*.o
|
||||
/tmp
|
||||
@@ -0,0 +1,2 @@
|
||||
script:
|
||||
- "ruby run_test.rb all test"
|
||||
@@ -0,0 +1,70 @@
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
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
|
||||
@@ -0,0 +1,157 @@
|
||||
# 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"
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,165 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user