packsnap 0.0.1
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.
- data/.gitignore +17 -0
- data/ChangeLog +29 -0
- data/README.rdoc +26 -0
- data/Rakefile +150 -0
- data/doclib/msgpack.rb +54 -0
- data/doclib/packsnap/buffer.rb +177 -0
- data/doclib/packsnap/error.rb +14 -0
- data/doclib/packsnap/packer.rb +131 -0
- data/doclib/packsnap/unpacker.rb +130 -0
- data/ext/packsnap/buffer.cc +684 -0
- data/ext/packsnap/buffer.hh +439 -0
- data/ext/packsnap/buffer_class.cc +490 -0
- data/ext/packsnap/buffer_class.hh +32 -0
- data/ext/packsnap/compat.h +128 -0
- data/ext/packsnap/extconf.rb +94 -0
- data/ext/packsnap/packer.cc +137 -0
- data/ext/packsnap/packer.h +334 -0
- data/ext/packsnap/packer_class.cc +288 -0
- data/ext/packsnap/packer_class.hh +32 -0
- data/ext/packsnap/packsnap.h +4 -0
- data/ext/packsnap/rbinit.cc +52 -0
- data/ext/packsnap/rmem.cc +110 -0
- data/ext/packsnap/rmem.h +100 -0
- data/ext/packsnap/sysdep.h +112 -0
- data/ext/packsnap/sysdep_endian.h +50 -0
- data/ext/packsnap/sysdep_types.h +46 -0
- data/ext/packsnap/unpacker.cc +654 -0
- data/ext/packsnap/unpacker.hh +108 -0
- data/ext/packsnap/unpacker_class.cc +392 -0
- data/ext/packsnap/unpacker_class.hh +32 -0
- data/lib/packsnap.rb +12 -0
- data/lib/packsnap/version.rb +3 -0
- data/packsnap.gemspec +23 -0
- data/spec/buffer_io_spec.rb +228 -0
- data/spec/buffer_spec.rb +572 -0
- data/spec/cases.json +1 -0
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +39 -0
- data/spec/format_spec.rb +225 -0
- data/spec/packer_spec.rb +127 -0
- data/spec/random_compat.rb +24 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/unpacker_spec.rb +128 -0
- metadata +183 -0
data/.gitignore
ADDED
data/ChangeLog
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
2012-05-05 version 0.4.7:
|
3
|
+
|
4
|
+
* Fixed serialization of double values on ARM OABI architectures
|
5
|
+
* Fixed byteorder problem on big-endian platforms
|
6
|
+
* Don't use MRI internals in the Ruby extension for Rubinius
|
7
|
+
* Detect whether st.h is present and don't use RUBY_VM as the condition for
|
8
|
+
Rubinius
|
9
|
+
|
10
|
+
2011-08-08 version 0.4.6:
|
11
|
+
|
12
|
+
* Fixed compile error problem on Mac OS X Lion
|
13
|
+
|
14
|
+
2011-05-09 version 0.4.5:
|
15
|
+
|
16
|
+
* Improves compatibility with JRuby
|
17
|
+
|
18
|
+
2010-11-28 version 0.4.4:
|
19
|
+
|
20
|
+
* Adds Unpacker#feed_each method
|
21
|
+
* Improves compatibility with Rubinius
|
22
|
+
* Improves compatibility with ruby-1.8.5
|
23
|
+
* Encodings of String instances to UTF-8 on Ruby 1.9
|
24
|
+
|
25
|
+
2010-06-29 version 0.4.3:
|
26
|
+
|
27
|
+
* Adds MessagePack::VERSION constant
|
28
|
+
* Fixes SEGV problem caused by GC bug at MessagePack_Unpacker_mark
|
29
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
= MessagePack
|
3
|
+
|
4
|
+
MessagePack is an efficient binary serialization format.
|
5
|
+
It lets you exchange data among multiple languages like JSON but it's faster and smaller.
|
6
|
+
For example, small integers (like flags or error code) are encoded into a single byte,
|
7
|
+
and typical short strings only require an extra byte in addition to the strings themselves.
|
8
|
+
|
9
|
+
If you ever wished to use JSON for convenience (storing an image with metadata) but could
|
10
|
+
not for technical reasons (encoding, size, speed...), MessagePack is a perfect replacement.
|
11
|
+
|
12
|
+
require 'msgpack'
|
13
|
+
msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
|
14
|
+
MessagePack.unpack(msg) #=> [1,2,3]
|
15
|
+
|
16
|
+
Use RubyGems to install:
|
17
|
+
|
18
|
+
gem install msgpack
|
19
|
+
|
20
|
+
|
21
|
+
== Copyright
|
22
|
+
|
23
|
+
Author:: FURUHASHI Sadayuki <frsyuki@gmail.com>
|
24
|
+
Copyright:: Copyright (c) 2008-2012 FURUHASHI Sadayuki
|
25
|
+
License:: Apache License, Version 2.0
|
26
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
|
2
|
+
require 'bundler'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'yard'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
10
|
+
t.rspec_opts = ["-c", "-f progress"]
|
11
|
+
t.rspec_opts << "-Ilib"
|
12
|
+
t.pattern = 'spec/**/*_spec.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
task :spec => :compile
|
17
|
+
|
18
|
+
desc 'Run RSpec code examples and measure coverage'
|
19
|
+
task :coverage do |t|
|
20
|
+
ENV['SIMPLE_COV'] = '1'
|
21
|
+
Rake::Task["spec"].invoke
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Generate YARD document'
|
25
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
26
|
+
t.files = ['lib/packsnap/version.rb','doclib/**/*.rb']
|
27
|
+
t.options = []
|
28
|
+
t.options << '--debug' << '--verbose' if $trace
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_gemspec(platform, extra_globs, remove_globs)
|
32
|
+
spec = eval(File.read('packsnap.gemspec'))
|
33
|
+
|
34
|
+
extra_globs.each {|glob| spec.files += Dir[glob] }
|
35
|
+
remove_globs.each {|glob| spec.files -= Dir[glob] }
|
36
|
+
|
37
|
+
if platform && !platform.empty?
|
38
|
+
spec.platform = platform
|
39
|
+
end
|
40
|
+
|
41
|
+
spec
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_gem(platform, extra_globs, remove_globs)
|
45
|
+
spec = create_gemspec(platform, extra_globs, remove_globs)
|
46
|
+
name = Gem::Builder.new(spec).build
|
47
|
+
|
48
|
+
FileUtils.mkdir_p('pkg/')
|
49
|
+
FileUtils.mv(name, 'pkg/')
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_command(cmd, env = {})
|
53
|
+
puts env.map {|k,v| "#{k}=\"#{v}\"" }.join(' ')
|
54
|
+
puts cmd
|
55
|
+
if env.empty?
|
56
|
+
system(cmd) # for jruby
|
57
|
+
else
|
58
|
+
system(env, cmd)
|
59
|
+
end
|
60
|
+
|
61
|
+
if $?.to_i != 0
|
62
|
+
raise "command failed (#{$?.to_i}): #{cmd}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
task :default => :gem
|
67
|
+
|
68
|
+
desc "Create gem package"
|
69
|
+
task "gem" do
|
70
|
+
#if RUBY_PLATFORM =~ /java/
|
71
|
+
# Rake::Task["gem:java"].invoke
|
72
|
+
#else
|
73
|
+
create_gem(nil, ["lib/packsnap/**/*.{so,bundle}"], ["ext/**/*"])
|
74
|
+
#end
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "Create precompiled gem package"
|
78
|
+
task "gem:build" do
|
79
|
+
config = YAML.load_file("packsnap.build.yml")
|
80
|
+
|
81
|
+
platform = config['platform']
|
82
|
+
archs = []
|
83
|
+
|
84
|
+
begin
|
85
|
+
FileUtils.rm_rf Dir["lib/packsnap/*-*"]
|
86
|
+
|
87
|
+
config['versions'].each {|ver|
|
88
|
+
ruby = ver.delete('ruby')
|
89
|
+
env = ver.delete('env') || {}
|
90
|
+
arch = `'#{ruby}' -rrbconfig -e "puts RUBY_PLATFORM"`.strip
|
91
|
+
ruby_version = `'#{ruby}' -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.strip
|
92
|
+
vpath = "#{arch}/#{ruby_version}"
|
93
|
+
|
94
|
+
run_command "cd ext/packsnap && '#{ruby}' extconf.rb && make clean && make", env
|
95
|
+
|
96
|
+
path = Dir['ext/packsnap/packsnap.{so,bundle}'].first
|
97
|
+
FileUtils.mkdir_p("lib/packsnap/#{vpath}")
|
98
|
+
FileUtils.cp(path, "lib/packsnap/#{vpath}/")
|
99
|
+
|
100
|
+
archs << arch
|
101
|
+
}
|
102
|
+
|
103
|
+
create_gem(platform, ["lib/packsnap/**/*.{so,bundle}"], ["ext/**/*"])
|
104
|
+
|
105
|
+
ensure
|
106
|
+
FileUtils.rm_rf Dir["lib/packsnap/*-*"]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#task "gem:java" do
|
111
|
+
# Rake::Task["compile:java"].invoke
|
112
|
+
#
|
113
|
+
# begin
|
114
|
+
# FileUtils.mkdir_p 'lib/packsnap/java'
|
115
|
+
# FileUtils.cp Dir["ext/java/*.jar"], "lib/"
|
116
|
+
# FileUtils.cp "ext/java/packsnap.jar", "lib/packsnap"
|
117
|
+
#
|
118
|
+
# create_gem('java', [], ["ext/packsnap/**/*"])
|
119
|
+
# ensure
|
120
|
+
# FileUtils.rm_rf "ext/java/build"
|
121
|
+
# FileUtils.rm_rf "lib/packsnap/java"
|
122
|
+
# FileUtils.rm_rf Dir["lib/*.jar"]
|
123
|
+
# end
|
124
|
+
#end
|
125
|
+
|
126
|
+
task "compile" do
|
127
|
+
#if RUBY_PLATFORM =~ /java/
|
128
|
+
# Rake::Task["compile:java"].invoke
|
129
|
+
#else
|
130
|
+
ruby = 'ruby' # TODO use self
|
131
|
+
run_command "cd ext/packsnap && '#{ruby}' extconf.rb && make clean && make"
|
132
|
+
#end
|
133
|
+
end
|
134
|
+
|
135
|
+
#task "compile:java" do
|
136
|
+
# Dir.chdir('ext/java')
|
137
|
+
# begin
|
138
|
+
# jruby_home = RbConfig::CONFIG['prefix']
|
139
|
+
# classpath = ["#{jruby_home}/lib/jruby.jar"] + Dir['*.jar']
|
140
|
+
# files = Dir['packsnap/**/*.java']
|
141
|
+
#
|
142
|
+
# FileUtils.rm_rf "ext/java/build"
|
143
|
+
# FileUtils.mkdir_p 'build'
|
144
|
+
# run_command "javac -cp '#{classpath.join(':')}' -d build #{files.join(' ')}"
|
145
|
+
# run_command "jar cvf packsnap.jar -C build/ ."
|
146
|
+
# ensure
|
147
|
+
# Dir.chdir('../..')
|
148
|
+
# end
|
149
|
+
#end
|
150
|
+
|
data/doclib/msgpack.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Packsnap
|
2
|
+
#
|
3
|
+
# Serializes an object into an IO or String.
|
4
|
+
#
|
5
|
+
# @overload dump(obj)
|
6
|
+
# @return [String] serialized data
|
7
|
+
#
|
8
|
+
# @overload dump(obj, io)
|
9
|
+
# @return [IO]
|
10
|
+
#
|
11
|
+
def self.dump(arg)
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Serializes an object into an IO or String. Alias of dump.
|
16
|
+
#
|
17
|
+
# @overload dump(obj)
|
18
|
+
# @return [String] serialized data
|
19
|
+
#
|
20
|
+
# @overload dump(obj, io)
|
21
|
+
# @return [IO]
|
22
|
+
#
|
23
|
+
def self.pack(arg)
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Deserializes an object from an IO or String.
|
28
|
+
#
|
29
|
+
# @overload load(string)
|
30
|
+
# @param string [String] data to deserialize
|
31
|
+
#
|
32
|
+
# @overload load(io)
|
33
|
+
# @param io [IO]
|
34
|
+
#
|
35
|
+
# @return [Object] deserialized object
|
36
|
+
#
|
37
|
+
def self.load(arg)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Deserializes an object from an IO or String. Alias of load.
|
42
|
+
#
|
43
|
+
# @overload unpack(string)
|
44
|
+
# @param string [String] data to deserialize
|
45
|
+
#
|
46
|
+
# @overload unpack(io)
|
47
|
+
# @param io [IO]
|
48
|
+
#
|
49
|
+
# @return [Object] deserialized object
|
50
|
+
#
|
51
|
+
def self.unpack(arg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module Packsnap
|
2
|
+
|
3
|
+
class Buffer
|
4
|
+
#
|
5
|
+
# Creates a Packsnap::Buffer instance.
|
6
|
+
#
|
7
|
+
# @overload initialize(options={})
|
8
|
+
# @param options [Hash]
|
9
|
+
#
|
10
|
+
# @overload initialize(io, options={})
|
11
|
+
# @param io [IO]
|
12
|
+
# @param options [Hash]
|
13
|
+
# This buffer writes written data into the IO when it is filled.
|
14
|
+
# This buffer reads data from the IO when it is empty.
|
15
|
+
#
|
16
|
+
# _io_ must respond to readpartial(length, [,string]) or read(string) method and
|
17
|
+
# write(string) or append(string) method.
|
18
|
+
#
|
19
|
+
# Supported options:
|
20
|
+
#
|
21
|
+
# * *:io_buffer_size* buffer size to read data from the internal IO. (default: 32768)
|
22
|
+
# * *:read_reference_threshold* the threshold size to enable zero-copy deserialize optimization. Read strings longer than this threshold will refer the original string instead of copying it. (default: 256) (supported in MRI only)
|
23
|
+
# * *:write_reference_threshold* the threshold size to enable zero-copy serialize optimization. The buffer refers written strings longer than this threshold instead of copying it. (default: 524288) (supported in MRI only)
|
24
|
+
#
|
25
|
+
def initialize(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Makes the buffer empty
|
30
|
+
#
|
31
|
+
# @return nil
|
32
|
+
#
|
33
|
+
def clear
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Returns byte size of the buffer.
|
38
|
+
#
|
39
|
+
# @return nil
|
40
|
+
#
|
41
|
+
def size
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Returns _true_ if the buffer is empty.
|
46
|
+
# This method is slightly faster than _size_.
|
47
|
+
#
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
def empty?
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Appends the given data to the buffer.
|
55
|
+
#
|
56
|
+
# @param data [String]
|
57
|
+
# @return [Integer] byte size written
|
58
|
+
#
|
59
|
+
def write(data)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Appends the given data to the buffer.
|
64
|
+
#
|
65
|
+
# @param data [String]
|
66
|
+
# @return [Buffer] self
|
67
|
+
#
|
68
|
+
def <<(data)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Consumes _n_ bytes from the head of the buffer and returns consumed data.
|
73
|
+
# If the size of the buffer is less than _n_, it reads all of data in the buffer.
|
74
|
+
#
|
75
|
+
# If _n_ is 0, it does nothing and returns an empty string.
|
76
|
+
# If the optional _buffer_ argument is given, the content of the string will be replaced with the consumed data.
|
77
|
+
#
|
78
|
+
# @overload read
|
79
|
+
#
|
80
|
+
# @overload read(n)
|
81
|
+
# @param n [Integer] bytes to read
|
82
|
+
#
|
83
|
+
# @overload read(n, buffer)
|
84
|
+
# @param n [Integer] bytes to read
|
85
|
+
# @param buffer [String] buffer to read into
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
#
|
89
|
+
def read(n)
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Consumes _n_ bytes from the head of the buffer and returns consumed data.
|
94
|
+
# If the size of the buffer is less than _n_, it does nothing and raises EOFError.
|
95
|
+
#
|
96
|
+
# If _n_ is 0, it does nothing and returns an empty string.
|
97
|
+
# If the optional _buffer_ argument is given, the content of the string will be replaced with the consumed data.
|
98
|
+
#
|
99
|
+
# @overload read_all
|
100
|
+
#
|
101
|
+
# @overload read_all(n)
|
102
|
+
# @param n [Integer] bytes to read
|
103
|
+
#
|
104
|
+
# @overload read_all(n, buffer)
|
105
|
+
# @param n [Integer] bytes to read
|
106
|
+
# @param buffer [String] buffer to read into
|
107
|
+
#
|
108
|
+
# @return [String]
|
109
|
+
#
|
110
|
+
def read_all(n, buffer=nil)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Consumes _n_ bytes from the head of the buffer.
|
115
|
+
# If the size of the buffer is less than _n_, it skips all of data in the buffer and returns integer less than _n_.
|
116
|
+
#
|
117
|
+
# If _n_ is 0, it does nothing and returns _0_.
|
118
|
+
#
|
119
|
+
# @param n [Integer] byte size to skip
|
120
|
+
# @return [Integer] byte size actually skipped
|
121
|
+
#
|
122
|
+
def skip(n)
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Consumes _n_ bytes from the head of the buffer.
|
127
|
+
# If the size of the buffer is less than _n_, it does nothing and raises EOFError.
|
128
|
+
# If _n_ is 0, it does nothing.
|
129
|
+
#
|
130
|
+
# @param n [Integer] byte size to skip
|
131
|
+
# @return [Buffer] self
|
132
|
+
#
|
133
|
+
def skip_all(n)
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Returns all data in the buffer as a string.
|
138
|
+
# Destructive update to the returned string does NOT effect the buffer.
|
139
|
+
#
|
140
|
+
# @return [String]
|
141
|
+
#
|
142
|
+
def to_str
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
# Returns content of the buffer as an array of strings.
|
147
|
+
#
|
148
|
+
# This method is sometimes faster than to_s because the internal
|
149
|
+
# structure of the buffer is a queue of buffer chunks.
|
150
|
+
#
|
151
|
+
# @return [Array] array of strings
|
152
|
+
#
|
153
|
+
def to_a
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Flushes data in the internal buffer to the internal IO.
|
158
|
+
# If internal IO is not set, it doesn nothing.
|
159
|
+
#
|
160
|
+
# @return [Buffer] self
|
161
|
+
#
|
162
|
+
def flush
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Writes all of data in the internal buffer into the given IO.
|
167
|
+
# This method consumes and removes data from the internal buffer.
|
168
|
+
# _io_ must respond to write(data) method.
|
169
|
+
#
|
170
|
+
# @param io [IO]
|
171
|
+
# @return [Integer] byte size of written data
|
172
|
+
#
|
173
|
+
def write_to(io)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|