cbor-0.5.9.8/0000755000004100000410000000000014567454543012671 5ustar www-datawww-datacbor-0.5.9.8/cbor.gemspec0000644000004100000410000000177714567454543015177 0ustar www-datawww-data$:.push File.expand_path("../lib", __FILE__) require 'cbor/version' Gem::Specification.new do |s| s.name = "cbor" s.version = CBOR::VERSION s.summary = "CBOR, Concise Binary Object Representation." s.description = %q{CBOR is a library for the CBOR binary object representation format, based on Sadayuki Furuhashi's MessagePack library.} s.author = "Carsten Bormann, standing on the tall shoulders of Sadayuki Furuhashi" s.email = "cabo@tzi.org" s.license = "Apache-2.0" s.homepage = "http://cbor.io/" # s.has_rdoc = false s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec}/*`.split("\n") s.require_paths = ["lib"] s.extensions = ["ext/cbor/extconf.rb"] s.add_development_dependency 'bundler' s.add_development_dependency 'rake', ['~> 0.9.2'] s.add_development_dependency 'rake-compiler', ['~> 0.8.3'] s.add_development_dependency 'rspec', ['~> 2.11'] s.add_development_dependency 'json', ['~> 1.7'] s.add_development_dependency 'yard', ['~> 0.9.11'] end cbor-0.5.9.8/.gitignore0000644000004100000410000000032414567454543014660 0ustar www-datawww-data*.o *.so *.gem *.class .bundle Gemfile.lock pkg test/debug.log *~ /rdoc tmp .classpath .project .settings /nbproject/private/ ext/java/build ext/java/msgpack.jar spec/bench* lib/cbor/cbor.bundle TAGS .yardoc doc cbor-0.5.9.8/README.rdoc0000644000004100000410000001467014567454543014507 0ustar www-datawww-data= CBOR for Ruby This is a Ruby implementation of the CBOR[http://cbor.io] encoding, based on the (polished) high-performance msgpack-ruby code. Documentation will follow, but generally, if you replace MessagePack and msgpack with CBOR and cbor in the text cited from MessagePack below, you will be on the right track. For a starter: require 'cbor' s = [1, 2, 33.5, 4].to_cbor #=> "\x84\x01\x02\xF9P0\x04" CBOR.decode(s) #=> [1, 2, 33.5, 4] Use RubyGems to install: gem install cbor CBOR is an object representation format defined by the IETF[http://ietf.org]. The specification[http://tools.ietf.org/html/rfc7049] is an IETF Standards-Track specification and has been published as RFC 7049. This is all based on wonderful work by frsyuki, and I have no idea how to acknowledge him appropriately. This gem is not intended to fork or supersede MessagePack[http://msgpack.org], which has a vibrant ecosystem. It is just making use of the high-quality code that is available in this community. If MessagePack works for you, go for it. If you need CBOR, you need this. Todos: * This code has not yet been fully optimized, so it is still a few percent slower than msgpack-ruby. * Properly document things, in particular the classes CBOR::Simple and CBOR::Tagged. If you check out the source, you can +rake+ +doc+ to get some documentation in the directory +doc+ (see +index.html+ there). * Cover more rubies. * \[✔✔✔✔] tested on MRI (1.9.3, 2.0.0, 2.1.10, 2.2.10, 2.3.7, 2.4.4 and 2.5.1). * (\[✔] There now also is some basic MRI 1.8.7 compatibility, however 1.8.7 does not support differentiation between byte and text strings.) * \[✔] tested on Rubinius 2.4.1. * \[_] Publish the pure-ruby version and make it work the same way on JRuby. * Find and implement good ways to offer CBOR's indefinite length ("streaming") capability at the Ruby API level. (Decoding is fully supported, just no streaming or indefinite length encoding.) * Rename some of the internals from msgpack to cbor. Right now, much of the code still uses the name msgpack in its identifiers, to facilitate merging upstream fixes. (The msgpack and cbor gems coexist nicely in one MRI instance due to the magic in +renamer.h+.) Same Apache 2.0 License applies to the changes as to the original. For the changes: Author:: Carsten Bormann Copyright:: Copyright (c) 2013, 2014 Carsten Bormann License:: Apache License, Version 2.0 {}[https://travis-ci.org/cabo/cbor-ruby] {Gem Version}[http://badge.fury.io/rb/cbor] For the original, see below. = MessagePack MessagePack[http://msgpack.org] is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. For example, small integers (like flags or error code) are encoded into a single byte, and typical short strings only require an extra byte in addition to the strings themselves. If you ever wished to use JSON for convenience (storing an image with metadata) but could not for technical reasons (binary data, size, speed...), MessagePack is a perfect replacement. require 'msgpack' msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03" MessagePack.unpack(msg) #=> [1,2,3] Use RubyGems to install: gem install msgpack or build msgpack-ruby and install: bundle rake gem install --local pkg/msgpack = Use cases * Store objects efficiently serialized by msgpack on memcached or Redis * In fact Redis supports msgpack in EVAL-scripts[http://redis.io/commands/eval] * Upload data in efficient format from mobile devices such as smartphones * MessagePack works on iPhone/iPad and Android. See also Objective-C[https://github.com/msgpack/msgpack-objectivec] and Java[https://github.com/msgpack/msgpack-java] implementations * Design a portable protocol to communicate with embedded devices * Check also Fluentd[http://fluentd.org/] which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON) * Exchange objects between software components written in different languages * You'll need a flexible but efficient format so that components exchange objects while keeping compatibility = Portability MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU architectures. And it works with MRI (CRuby) and Rubinius. Patches to improve portability is highly welcomed. = Serializing objects Use *MessagePack.pack* or *to_msgpack*: require 'msgpack' msg = MessagePack.pack(obj) # or msg = obj.to_msgpack == Streaming serialization Packer provides advanced API to serialize objects in streaming style: # serialize a 2-element array [e1, e2] pk = MessagePack::Packer.new(io) pk.write_array_header(2).write(e1).write(e2).flush See {API reference}[http://ruby.msgpack.org/MessagePack/Packer.html] for details. = Deserializing objects Use *MessagePack.unpack*: require 'msgpack' obj = MessagePack.unpack(msg) == Streaming deserialization Unpacker provides advanced API to deserialize objects in streaming style: # deserialize objects from an IO u = MessagePack::Unpacker.new(io) u.each do |obj| # ... end or event-driven style which works well with EventMachine: # event-driven deserialization def on_read(data) @u ||= MessagePack::Unpacker.new @u.feed_each(data) {|obj| # ... } end See {API reference}[http://ruby.msgpack.org/MessagePack/Unpacker.html] for details. = Buffer API MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API. This {MessagePack::Buffer}[http://ruby.msgpack.org/MessagePack/Buffer.html] is backed with a fixed-length shared memory pool which is very fast for small data (<= 4KB), and has zero-copy capability which significantly affects performance to handle large binary data. = How to build and run tests Before building msgpack, you need to install bundler and dependencies. gem install bundler bundle install Then, you can run the tasks as follows: * Build bundle exec rake build * Run tests bundle exec rake spec * Generating docs bundle exec rake doc = Copyright Author:: Sadayuki Furuhashi Copyright:: Copyright (c) 2008-2013 Sadayuki Furuhashi License:: Apache License, Version 2.0 cbor-0.5.9.8/lib/0000755000004100000410000000000014567454543013437 5ustar www-datawww-datacbor-0.5.9.8/lib/cbor.rb0000644000004100000410000000017114567454543014710 0ustar www-datawww-datarequire "cbor/version" begin require "cbor/#{RUBY_VERSION[/\d+.\d+/]}/cbor" rescue LoadError require "cbor/cbor" end cbor-0.5.9.8/lib/cbor/0000755000004100000410000000000014567454543014364 5ustar www-datawww-datacbor-0.5.9.8/lib/cbor/version.rb0000644000004100000410000000004514567454543016375 0ustar www-datawww-datamodule CBOR VERSION = "0.5.9.8" end cbor-0.5.9.8/spec/0000755000004100000410000000000014567454543013623 5ustar www-datawww-datacbor-0.5.9.8/spec/cases.cbor_stream0000644000004100000410000000014314567454543017141 0ustar www-datawww-data 8889:<aaaaaa```aaaaaaaaaaacbor-0.5.9.8/spec/spec_helper.rb0000644000004100000410000000230414567454543016440 0ustar www-datawww-datarequire 'rubygems' # for 1.8 RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = [:should, :expect] end config.mock_with :rspec do |c| c.syntax = [:should, :expect] end end class String if ''.respond_to? :encode def encode_as_utf8 encode(Encoding::UTF_8) end def force_as_utf8 force_encoding(Encoding::UTF_8) end unless String.instance_methods.include?(:b) def b dup.force_encoding(Encoding::BINARY) end end else def encode_as_utf8 self # MRI 1.8 end def force_as_utf8 self # MRI 1.8 end def b self end end unless ''.respond_to? :clear def clear replace('') end end def hexbytes(sep = '') bytes.map{|x| "%02x" % x}.join(sep) end end if ENV['SIMPLE_COV'] require 'simplecov' SimpleCov.start do add_filter 'spec/' add_filter 'pkg/' add_filter 'vendor/' end end if ENV['GC_STRESS'] puts "enable GC.stress" GC.stress = true end require 'cbor' MessagePack = CBOR # XXX Packer = MessagePack::Packer Unpacker = MessagePack::Unpacker Buffer = MessagePack::Buffer cbor-0.5.9.8/spec/cases_spec.rb0000644000004100000410000000134314567454543016261 0ustar www-datawww-datarequire 'spec_helper' require 'json' describe MessagePack do here = File.dirname(__FILE__) CASES = File.read("#{here}/cases.cbor_stream") CASES_JSON = File.read("#{here}/cases.json") CASES_INDEFINITE = File.read("#{here}/cases.cbor_stream") # TODO it 'compare with json' do ms = [] MessagePack::Unpacker.new.feed_each(CASES) {|m| ms << m } js = JSON.load(CASES_JSON) ms.zip(js) {|m,j| m.should == j } end it 'compare with compat' do ms = [] MessagePack::Unpacker.new.feed_each(CASES) {|m| ms << m } cs = [] MessagePack::Unpacker.new.feed_each(CASES_INDEFINITE) {|c| cs << c } ms.zip(cs) {|m,c| m.should == c } end end cbor-0.5.9.8/spec/cases_compact.msg0000644000004100000410000000016414567454543017140 0ustar www-datawww-dataЀрҀˀ?˿aaaaaaaaaacbor-0.5.9.8/spec/cases.cbor0000644000004100000410000000014514567454543015570 0ustar www-datawww-data3 8889:<aaaaaa```aaaaaaaaaaacbor-0.5.9.8/spec/unpacker_spec.rb0000644000004100000410000001245514567454543017001 0ustar www-datawww-data# encoding: ascii-8bit require 'spec_helper' describe Unpacker do let :unpacker do Unpacker.new end let :packer do Packer.new end # TODO initialize it 'read_array_header succeeds' do unpacker.feed("\x81") unpacker.read_array_header.should == 1 end it 'read_array_header fails' do unpacker.feed("\xa1") lambda { unpacker.read_array_header }.should raise_error(MessagePack::TypeError) end it 'read_array_header converts an array to value sequence' do packer.write_array_header(2) packer.write("e") packer.write(1) unpacker = Unpacker.new unpacker.feed(packer.to_s) unpacker.read_array_header.should == 2 unpacker.read.should == "e" unpacker.read.should == 1 end it 'read_map_header succeeds' do unpacker.feed("\xa1") unpacker.read_map_header.should == 1 end it 'read_map_header converts an map to key-value sequence' do packer.write_map_header(1) packer.write("k") packer.write("v") unpacker = Unpacker.new unpacker.feed(packer.to_s) unpacker.read_map_header.should == 1 unpacker.read.should == "k" unpacker.read.should == "v" end it 'read_map_header fails' do unpacker.feed("\x81") lambda { unpacker.read_map_header }.should raise_error(MessagePack::TypeError) end it 'skip_nil succeeds' do unpacker.feed("\xf6") unpacker.skip_nil.should == true end it 'skip_nil fails' do unpacker.feed("\x80") unpacker.skip_nil.should == false end it 'skip skips objects' do packer.write(1) packer.write(2) packer.write(3) packer.write(4) packer.write(5) unpacker = Unpacker.new(packer.buffer) unpacker.read.should == 1 unpacker.skip unpacker.read.should == 3 unpacker.skip unpacker.read.should == 5 end it 'read raises EOFError' do lambda { unpacker.read }.should raise_error(EOFError) end it 'skip raises EOFError' do lambda { unpacker.skip }.should raise_error(EOFError) end it 'skip_nil raises EOFError' do lambda { unpacker.skip_nil }.should raise_error(EOFError) end let :sample_object do [1024, {["a","b"]=>["c","d"]}, ["e","f"], "d", 70000, 4.12, 1.5, 1.5, 1.5] end it 'sample object OK' do obj2 = MessagePack.unpack(sample_object.to_cbor) obj2.should == sample_object end it 'feed and each continue internal state' do raw = sample_object.to_cbor.to_s * 4 objects = [] raw.split(//).each do |b| unpacker.feed(b) unpacker.each {|c| objects << c } end objects.should == [sample_object] * 4 end it 'feed_each continues internal state' do raw = sample_object.to_cbor.to_s * 4 objects = [] raw.split(//).each do |b| unpacker.feed_each(b) {|c| objects << c } end objects.should == [sample_object] * 4 end it 'reset clears internal buffer' do # 1-element array unpacker.feed("\x91") unpacker.reset unpacker.feed("\x01") unpacker.each.map {|x| x }.should == [1] end it 'reset clears internal state' do # 1-element array unpacker.feed("\x91") unpacker.each.map {|x| x }.should == [] unpacker.reset unpacker.feed("\x01") unpacker.each.map {|x| x }.should == [1] end it 'buffer' do o1 = unpacker.buffer.object_id unpacker.buffer << 'frsyuki' unpacker.buffer.to_s.should == 'frsyuki' unpacker.buffer.object_id.should == o1 end it 'frozen short strings' do raw = sample_object.to_cbor.to_s.force_as_utf8 lambda { unpacker.feed_each(raw.freeze) { } }.should_not raise_error end it 'frozen long strings' do raw = (sample_object.to_cbor.to_s * 10240).force_as_utf8 lambda { unpacker.feed_each(raw.freeze) { } }.should_not raise_error end it 'read raises level stack too deep error' do 512.times { packer.write_array_header(1) } packer.write(nil) unpacker = Unpacker.new(packer.buffer) lambda { unpacker.read }.should raise_error(MessagePack::StackError) end it 'skip raises level stack too deep error' do 512.times { packer.write_array_header(1) } packer.write(nil) unpacker = Unpacker.new(packer.buffer) lambda { unpacker.skip }.should raise_error(MessagePack::StackError) end it 'read raises invalid byte error' do unpacker.feed("\xdf") lambda { unpacker.read }.should raise_error(MessagePack::MalformedFormatError) end it 'skip raises invalid byte error' do unpacker.feed("\xdf") lambda { unpacker.skip }.should raise_error(MessagePack::MalformedFormatError) end it "gc mark" do raw = sample_object.to_cbor.to_s * 4 n = 0 raw.split(//).each do |b| GC.start unpacker.feed_each(b) {|o| GC.start o.should == sample_object n += 1 } GC.start end n.should == 4 end it "buffer" do orig = "a"*32*1024*4 raw = orig.to_cbor.to_s n = 655 times = raw.size / n times += 1 unless raw.size % n == 0 off = 0 parsed = false times.times do parsed.should == false seg = raw[off, n] off += seg.length unpacker.feed_each(seg) {|obj| parsed.should == false obj.should == orig parsed = true } end parsed.should == true end end cbor-0.5.9.8/spec/buffer_spec.rb0000644000004100000410000002631014567454543016435 0ustar www-datawww-datarequire 'spec_helper' require 'random_compat' describe Buffer do STATIC_EXAMPLES = {} STATIC_EXAMPLES[:empty01] = '' STATIC_EXAMPLES[:empty02] = '' STATIC_EXAMPLES[:copy01] = 'short' STATIC_EXAMPLES[:copy02] = 'short'*2 STATIC_EXAMPLES[:ref01] = 'short'*128 STATIC_EXAMPLES[:ref02] = 'short'*128*2 STATIC_EXAMPLES[:ref03] = 'a'*((1024*1024+2)*2) STATIC_EXAMPLES[:refcopy01] = 'short'*128 STATIC_EXAMPLES[:expand01] = 'short'*1024 STATIC_EXAMPLES[:expand02] = 'short'*(127+1024) STATIC_EXAMPLES[:offset01] = 'ort'+'short' STATIC_EXAMPLES[:offset02] = 'ort'+'short'*127 STATIC_EXAMPLES[:offset03] = 'ort'+'short'*(126+1024) if ''.respond_to?(:force_encoding) STATIC_EXAMPLES.each_value {|v| v.force_encoding('ASCII-8BIT') } end STATIC_EXAMPLES.each_value {|v| v.freeze } r = Random.new random_seed = r.seed puts "buffer random seed: 0x#{random_seed.to_s(16)}" let :repetition do ENV['SLOW'] ? 2 : 10 end let :random_cases_examples do r = Random.new(random_seed) cases = {} examples = {} repetition.times do |i| b = Buffer.new s = r.bytes(0) r.rand(3).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b << x end r.rand(2).times do n = r.rand(1024*1400) b.read(n) s.slice!(0, n) end key = :"random#{"%02d"%i}" cases[key] = b examples[key] = s end [cases, examples] end let :static_cases do map = {} map[:empty01] = empty01 map[:empty02] = empty02 map[:copy01] = copy01 map[:copy02] = copy02 map[:ref01] = ref01 map[:ref02] = ref02 map[:ref03] = ref03 map[:refcopy01] = refcopy01 map[:expand01] = expand01 map[:expand02] = expand02 map[:offset01] = offset01 map[:offset02] = offset02 map[:offset03] = offset03 map end let :static_examples do STATIC_EXAMPLES end let :random_cases do random_cases_examples[0] end let :random_examples do random_cases_examples[1] end let :cases do static_cases.merge(random_cases) end let :examples do static_examples.merge(random_examples) end let :case_keys do examples.keys end let :empty01 do Buffer.new end let :empty02 do b = Buffer.new b << 'a' b.read_all(1) b end let :copy01 do # one copy chunk b = Buffer.new b << 'short' b end let :copy02 do # one copy chunk b = Buffer.new b << 'short' b << 'short' b end let :expand02 do # one copy chunk / expanded b = Buffer.new 1024.times do b << 'short' end b end let :ref01 do # one reference chunk b = Buffer.new b << 'short'*128 b.to_s b end let :ref02 do # two reference chunks b = Buffer.new b << 'short'*128 b.to_s b << 'short'*128 b.to_a b end let :ref03 do # two reference chunks b = Buffer.new b << 'a'*(1024*1024+2) b << 'a'*(1024*1024+2) b end let :refcopy01 do # one reference chunk + one copy chunk b = Buffer.new b << 'short'*127 b.to_s b << 'short' b end let :expand01 do # one copy chunk / expanded b = Buffer.new 1024.times do b << 'short' end b end let :expand02 do # one reference chunk + one copy chunk / expanded b = Buffer.new b << 'short'*127 b.to_s 1024.times do b << 'short' end b end let :offset01 do # one copy chunk / offset b = Buffer.new b << 'short' b << 'short' b.skip(2) b end let :offset02 do # one reference chunk / offset b = Buffer.new b << 'short'*127 b.to_s b.skip(2) b << 'short' b end let :offset03 do # one reference chunk / offset + one copy chunk / expanded b = Buffer.new b << 'short'*127 b.to_s 1024.times do b << 'short' end b.skip(2) b end it 'empty?' do empty01.empty?.should == true empty02.empty?.should == true end it 'size' do case_keys.each {|k| cases[k].size.should == examples[k].size } end it 'short write increments size' do case_keys.each {|k| sz = examples[k].size 10.times do |i| cases[k].write 'short' sz += 'short'.size cases[k].size.should == sz end } end it 'read with limit decrements size' do case_keys.each {|k| sz = examples[k].size next if sz < 2 cases[k].read(1).should == examples[k][0,1] sz -= 1 cases[k].size.should == sz cases[k].read(1).should == examples[k][1,1] sz -= 1 cases[k].size.should == sz } end it 'read_all with limit decrements size' do case_keys.each {|k| sz = examples[k].size next if sz < 2 cases[k].read_all(1).should == examples[k][0,1] sz -= 1 cases[k].size.should == sz cases[k].read_all(1).should == examples[k][1,1] sz -= 1 cases[k].size.should == sz } end it 'skip decrements size' do case_keys.each {|k| sz = examples[k].size next if sz < 2 cases[k].skip(1).should == 1 sz -= 1 cases[k].size.should == sz cases[k].skip(1).should == 1 sz -= 1 cases[k].size.should == sz } end it 'skip_all decrements size' do case_keys.each {|k| sz = examples[k].size next if sz < 2 cases[k].skip_all(1) sz -= 1 cases[k].size.should == sz cases[k].skip_all(1) sz -= 1 cases[k].size.should == sz } end it 'read_all against insufficient buffer raises EOFError and consumes nothing' do case_keys.each {|k| sz = examples[k].size lambda { cases[k].read_all(sz+1) }.should raise_error(EOFError) cases[k].size.should == sz } end it 'skip_all against insufficient buffer raises EOFError and consumes nothing' do case_keys.each {|k| sz = examples[k].size lambda { cases[k].skip_all(sz+1) }.should raise_error(EOFError) cases[k].size.should == sz } end it 'read against insufficient buffer consumes all buffer or return nil' do case_keys.each {|k| sz = examples[k].size if sz == 0 cases[k].read(sz+1).should == nil else cases[k].read(sz+1).should == examples[k] end cases[k].size.should == 0 } end it 'skip against insufficient buffer consumes all buffer' do case_keys.each {|k| sz = examples[k].size cases[k].skip(sz+1).should == examples[k].size cases[k].size.should == 0 } end it 'read with no arguments consumes all buffer and returns string and do not return nil' do case_keys.each {|k| cases[k].read_all.should == examples[k] cases[k].size.should == 0 } end it 'read_all with no arguments consumes all buffer and returns string' do case_keys.each {|k| cases[k].read_all.should == examples[k] cases[k].size.should == 0 } end it 'to_s returns a string and consume nothing' do case_keys.each {|k| cases[k].to_s.should == examples[k] cases[k].size.should == examples[k].size } end it 'to_s and modify' do case_keys.each {|k| s = cases[k].to_s s << 'x' cases[k].to_s.should == examples[k] } end it 'big write and modify reference' do big2 = "a" * (1024*1024 + 2) case_keys.each {|k| big1 = "a" * (1024*1024 + 2) cases[k].write(big1) big1 << 'x' cases[k].read.should == examples[k] + big2 } end it 'big write -> short write' do biglen = 1024*1024 + 2 big1 = "a" * (1024*1024 + 2) case_keys.each {|k| sz = examples[k].size cases[k].write big1 cases[k].size.should == sz + big1.size cases[k].write("c") cases[k].size.should == sz + big1.size + 1 cases[k].read_all.should == examples[k] + big1 + "c" cases[k].size.should == 0 cases[k].empty?.should == true } end it 'big write 2'do big1 = "a" * (1024*1024 + 2) big2 = "b" * (1024*1024 + 2) case_keys.each {|k| sz = examples[k].size cases[k].write big1 cases[k].write big2 cases[k].size.should == sz + big1.size + big2.size cases[k].read_all(sz + big1.size).should == examples[k] + big1 cases[k].size.should == big2.size cases[k].read.should == big2 cases[k].size.should == 0 cases[k].empty?.should == true } end it 'read 0' do case_keys.each {|k| cases[k].read(0).should == '' cases[k].read.should == examples[k] } end it 'skip 0' do case_keys.each {|k| cases[k].skip(0).should == 0 cases[k].read.should == examples[k] } end it 'read_all 0' do case_keys.each {|k| cases[k].read_all(0).should == '' cases[k].read_all.should == examples[k] } end it 'skip_all 0' do case_keys.each {|k| cases[k].skip_all(0) cases[k].read_all.should == examples[k] } end it 'write_to' do case_keys.each {|k| sio = StringIO.new cases[k].write_to(sio).should == examples[k].size cases[k].size.should == 0 sio.string.should == examples[k] } end it 'random read/write' do r = Random.new(random_seed) s = r.bytes(0) b = Buffer.new 10.times { # write r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end # read r.rand(3).times do n = r.rand(1024*1400) ex = s.slice!(0, n) ex = nil if ex.empty? x = b.read(n) x.size == ex.size if x != nil x.should == ex b.size.should == s.size end } end it 'random read_all/write' do r = Random.new(random_seed) s = r.bytes(0) b = Buffer.new 10.times { # write r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end # read_all r.rand(3).times do n = r.rand(1024*1400) begin x = b.read_all(n) ex = s.slice!(0, n) x.size == n x.should == ex b.size.should == s.size rescue EOFError b.size.should == s.size b.read.should == s s.clear break end end } end it 'random skip write' do r = Random.new(random_seed) s = r.bytes(0) b = Buffer.new 10.times { # write r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end # skip r.rand(3).times do n = r.rand(1024*1400) ex = s.slice!(0, n) b.skip(n).should == ex.size b.size.should == s.size end } end it 'random skip_all write' do r = Random.new(random_seed) s = r.bytes(0) b = Buffer.new 10.times { # write r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end # skip_all r.rand(3).times do n = r.rand(1024*1400) begin b.skip_all(n) ex = s.slice!(0, n) b.size.should == s.size ensure EOFError b.size.should == s.size b.read.should == s s.clear break end end } end end cbor-0.5.9.8/spec/random_compat.rb0000644000004100000410000000051614567454543016775 0ustar www-datawww-data unless defined? Random class Random def initialize(seed=Time.now.to_i) Kernel.srand(seed) @seed = seed end attr_reader :seed def rand(arg) Kernel.rand(arg) end def bytes(n) array = [] n.times do array << rand(256) end array.pack('C*') end end end cbor-0.5.9.8/spec/format_spec.rb0000644000004100000410000003540614567454543016462 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' def bignum_to_bytes(bn) bn.to_s(16).chars.each_slice(2).map{|a| a.join.to_i(16).chr}.join end # => "\x98!sHq#\x98W\x91\x82sY\x87)Hu#E" # 0x982173487123985791827359872948752345 unless defined?(Float::INFINITY) class Float INFINITY = 1.0/0.0 NAN = 0.0/0.0 end end describe MessagePack do it "nil" do check 1, nil end it "true" do check 1, true end it "false" do check 1, false end it "zero" do check 1, 0 end it "positive fixnum" do check 1, 1 check 2, (1<<6) check 2, (1<<7)-1 end it "positive int 8" do check 1, -1 check 2, (1<<7) check 2, (1<<8)-1 end it "positive int 16" do check 3, (1<<8) check 3, (1<<16)-1 check 3, 1024 check 4, [1024] end it "positive int 32" do check 5, (1<<16) check 5, (1<<32)-1 end it "positive int 64" do check 9, (1<<32) check 9, (1<<64)-1 end it "negative fixnum" do check 1, -1 check 1, -24 check 2, -25 end it "negative int 8" do check 2, -((1<<5)+1) check 2, -(1<<7) end it "negative int 16" do check 2, -((1<<7)+1) check 2, -256 check 3, -(1<<15) end it "negative int 32" do check 3, -((1<<15)+1) check 3, -(1<<16) check 5, -(1<<31) check 5, -(1<<32) end it "negative int 64" do check 5, -((1<<31)+1) check 9, -(1<<63) check 9, -(1<<64) end it "half" do check 3, 1.0 check 3, -1.0 check 3, -2.0 check 3, 65504.0 check 3, -65504.0 check 3, Math.ldexp(1, -14) # ≈ 6.10352 × 10−5 (minimum positive normal) check 3, -Math.ldexp(1, -14) # ≈ 6.10352 × 10−5 (maximum negative normal) check 3, Math.ldexp(1, -14) - Math.ldexp(1, -24) # ≈ 6.09756 × 10−5 (maximum subnormal) check 3, Math.ldexp(1, -24) # ≈ 5.96046 × 10−8 (minimum positive subnormal) check 3, -Math.ldexp(1, -24) # ≈ -5.96046 × 10−8 (maximum negative subnormal) check 5, Math.ldexp(1, -14) - Math.ldexp(0.5, -24) # check loss of precision check 5, Math.ldexp(1.5, -24) # loss of precision (subnormal) check 3, Math.ldexp(1.5, -23) check 5, Math.ldexp(1.75, -23) check 3, Float::INFINITY check 3, -Float::INFINITY # check 3, Float::NAN # NAN is not equal to itself, to this never checks out... raw = Float::NAN.to_cbor.to_s raw.length.should == 3 MessagePack.unpack(raw).nan?.should == true end it "double" do check 9, 0.1 check 9, -0.1 end it "fixraw" do check_raw 1, 0 check_raw 1, 23 end it "raw 16" do check_raw 2, (1<<5) check_raw 3, (1<<16)-1 end it "raw 32" do check_raw 5, (1<<16) #check_raw 5, (1<<32)-1 # memory error end it "fixarray" do check_array 1, 0 check_array 1, (1<<4)-1 check_array 1, 23 end it "array 16" do check_array 1, (1<<4) #check_array 3, (1<<16)-1 end it "array 32" do #check_array 5, (1<<16) #check_array 5, (1<<32)-1 # memory error end it "nil" do match nil, "\xf6".b end it "false" do match false, "\xf4".b end it "true" do match true, "\xf5".b end it "0" do match 0, "\x00".b end it "127" do match 127, "\x18\x7f".b end it "128" do match 128, "\x18\x80".b end it "256" do match 256, "\x19\x01\x00".b end it "-1" do match -1, "\x20".b end it "-33" do match -33, "\x38\x20".b end it "-129" do match -129, "\x38\x80".b end it "-257" do match -257, "\x39\x01\x00".b end it "{1=>1}" do obj = {1=>1} match obj, "\xA1\x01\x01".b end it "1.0" do match 1.0, "\xF9\x3c\x00".b end it "NaN" do match Float::NAN, "\xF9\x7e\x00".b end it "[]" do match [], "\x80".b end it "[0, 1, ..., 14]" do obj = (0..14).to_a match obj, "\x8f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e".b end it "[0, 1, ..., 15]" do obj = (0..15).to_a match obj, "\x90\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f".b end it "[0, 1, ..., 22]" do obj = (0..22).to_a match obj, "\x97\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16".b end it "[0, 1, ..., 23]" do obj = (0..23).to_a match obj, "\x98\x18\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17".b end it "{}" do obj = {} match obj, "\xA0".b end it "very simple bignums" do CBOR.decode("\xc2\x40").should == 0 CBOR.decode("\xc2\x41\x00").should == 0 CBOR.decode("\xc2\x41a").should == 97 CBOR.decode("\xc2\x42aa").should == 24929 CBOR.decode("\xc3\x40").should == ~0 CBOR.decode("\xc3\x41\x00").should == ~0 CBOR.decode("\xc3\x41a").should == ~97 CBOR.decode("\xc3\x42aa").should == ~24929 end it "0x982173487123985791827359872948752345" do check_bn(0x982173487123985791827359872948752345, 0xc2) check_bn(-0x982173487123985791827359872948752345, 0xc3) check_bn(0x9821734871239857918273598729487523, 0xc2) check_bn(0x98217348712398579182735987294875, 0xc2) check_bn(0x982173487123985791827359872948, 0xc2) check_bn(0x9821734871239857918273598729, 0xc2) check_bn(0x98217348712398579182735987, 0xc2) check 20, 0x982173487123985791827359872948752345 check 20, -0x982173487123985791827359872948752345 check 19, 0x9821734871239857918273598729487523 check 18, 0x98217348712398579182735987294875 check 18, -0x98217348712398579182735987294875 check 17, 0x982173487123985791827359872948 check 16, 0x9821734871239857918273598729 check 15, 0x98217348712398579182735987 check 15, 0x9821734871239857918273598 check 16, [0x9821734871239857918273598] check 39, 0x982173487123985791827359872948752345982173487123985791827359872948752345 check 3005, 256**3000+4711 # 3001 bignum, 3 string, 1 tag end it "fixnum/bignum switch" do CBOR.encode(CBOR.decode("\xc2\x40")).should == "\x00".b CBOR.encode(CBOR.decode("\xc2\x41\x00")).should == "\x00".b CBOR.encode(CBOR.decode("\xc2\x41a")).should == "\x18a".b CBOR.encode(CBOR.decode("\xc2\x42aa")).should == "\x19aa".b CBOR.encode(CBOR.decode("\xc2\x43aaa")).should == "\x1A\x00aaa".b CBOR.encode(CBOR.decode("\xc2\x44aaaa")).should == "\x1Aaaaa".b CBOR.encode(CBOR.decode("\xc2\x45aaaaa")).should == "\e\x00\x00\x00aaaaa".b CBOR.encode(CBOR.decode("\xc2\x46aaaaaa")).should == "\e\x00\x00aaaaaa".b CBOR.encode(CBOR.decode("\xc2\x47aaaaaaa")).should == "\e\x00aaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x48aaaaaaaa")).should == "\eaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x49\x00aaaaaaaa")).should == "\eaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x49aaaaaaaaa")).should == "\xC2Iaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4a\x00aaaaaaaaa")).should == "\xC2Iaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4aaaaaaaaaaa")).should == "\xC2Jaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4b\x00aaaaaaaaaa")).should == "\xC2Jaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4baaaaaaaaaaa")).should == "\xC2Kaaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4c\x00aaaaaaaaaaa")).should == "\xC2Kaaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4caaaaaaaaaaaa")).should == "\xC2Laaaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4d\x00aaaaaaaaaaaa")).should == "\xC2Laaaaaaaaaaaa".b CBOR.encode(CBOR.decode("\xc2\x4daaaaaaaaaaaaa")).should == "\xC2Maaaaaaaaaaaaa".b end it "a-non-ascii" do if ''.respond_to? :encode match "abc".encode("UTF-32BE"), "cabc" end end it "a" do match "a".encode_as_utf8, "aa" check 2, "a".encode_as_utf8 check_decode "aa", "a".encode_as_utf8 end it "a.b" do if ''.respond_to? :encode match "a".b, "Aa" end check 2, "a".b check_decode "Aa", "a".b end it "[_ ]" do check_decode "\x9f\xff", [] end it "[_ 1]" do check_decode "\x9f\x01\xff", [1] end it "{_ }" do check_decode "\xbf\xff", {} end it "{_ 1 => 2}" do check_decode "\xbf\x01\x02\xff", {1 => 2} end it "{_ 1 => BREAK}" do lambda { check_decode "\xbf\x01\xff", {1 => 2} }.should raise_error(MessagePack::MalformedFormatError) end it "(_ a b)" do check_decode "\x7f\xff", "".encode_as_utf8 check_decode "\x5f\xff", "".b check_decode "\x7faa\xff", "a".encode_as_utf8 check_decode "\x5fAa\xff", "a".b check_decode "\x7faabbb\xff", "abb".encode_as_utf8 check_decode "\x5fAaBbb\xff", "abb".b if ''.respond_to? :encode lambda { check_decode "\x7faaBbb\xff", "abb".encode_as_utf8 }.should raise_error(MessagePack::MalformedFormatError) lambda { check_decode "\x7fAa\xff", "a".encode_as_utf8 }.should raise_error(MessagePack::MalformedFormatError) lambda { check_decode "\x5fAabbb\xff", "abb".b }.should raise_error(MessagePack::MalformedFormatError) lambda { check_decode "\x5faa\xff", "a".b }.should raise_error(MessagePack::MalformedFormatError) end end it "(_ not-a-string)" do lambda { check_decode "\x5f\x00\xff", "".b }.should raise_error(MessagePack::MalformedFormatError) end it "bare break" do lambda { check_decode "\xff", "".b }.should raise_error(MessagePack::MalformedFormatError) lambda { check_decode "\x82\xff\x00\x00", "".b }.should raise_error(MessagePack::MalformedFormatError) lambda { check_decode "\x82\x9f\xff\xff", "".b }.should raise_error(MessagePack::MalformedFormatError) end it "Tagged" do expect { check 10, CBOR::Tagged.new("foo", 2) }.to raise_error(TypeError) check 2, CBOR::Tagged.new(10, 2) check 4, CBOR::Tagged.new(0xBEEF, 2) check 6, CBOR::Tagged.new(0xDEADBEEF, 2) check 10, CBOR::Tagged.new(0xDEADBEEFDEADBEEF, 2) expect { check 10, CBOR::Tagged.new(0x1DEADBEEFDEADBEEF, 2) }.to raise_error(RangeError) end it "Time" do check_decode "\xc1\x19\x12\x67", Time.at(4711) check 6, Time.at(Time.now.to_i) end it "URI" do # check_decode "\xd8\x20\x78\x13http://www.ietf.org", CBOR::Tagged.new(32, "http://www.ietf.org") require 'uri' check_decode "\xd8\x20\x78\x13http://www.ietf.org", URI.parse("http://www.ietf.org") # This doesn't work yet if 'uri' is not required before 'cbor': # check 6, URI.parse("http://www.ietf.org") end it "regexp" do check_decode "\xd8\x23\x63foo", /foo/ check 14, /(?-mix:foo)/ check 6, /foo/ end it "Unknown simple 0" do check_decode "\xf3", CBOR::Simple.new(19) check 1, CBOR::Simple.new(0) end it "Unknown tag 0" do check_decode "\xc0\x00", CBOR::Tagged.new(0, 0) check 11, CBOR::Tagged.new(4711, "Frotzel") end it "Keys as Symbols" do # Experimental! CBOR.decode(CBOR.encode({:a => 1}), :keys_as_symbols).should == {:a => 1} CBOR.decode(CBOR.encode({:a => 1})).should == {"a" => 1} expect { CBOR.decode("\x00", :foobar) }.to raise_error(ArgumentError) end it 'CBOR.decode symbolize_keys' do symbolized_hash = {:a => 'b', :c => 'd'} CBOR.decode(CBOR.encode(symbolized_hash), :symbolize_keys => true).should == symbolized_hash end it 'Unpacker#read symbolize_keys' do unpacker = Unpacker.new(:symbolize_keys => true) symbolized_hash = {:a => 'b', :c => 'd'} unpacker.feed(CBOR.encode(symbolized_hash)).read.should == symbolized_hash end it 'handle outrageous sizes 1' do expect { CBOR.decode("\xa1") }.to raise_error(EOFError) expect { CBOR.decode("\xba\xff\xff\xff\xff") }.to raise_error(EOFError) expect { CBOR.decode("\xbb\xff\xff\xff\xff\xff\xff\xff\xff") }.to raise_error(EOFError) expect { CBOR.decode("\xbb\x01\x01\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) expect { CBOR.decode("\xbb\x00\x00\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) expect { CBOR.decode("\x81") }.to raise_error(EOFError) expect { CBOR.decode("\x9a\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 2' do expect { CBOR.decode("\x9b\xff\xff\xff\xff\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 3' do expect { CBOR.decode("\x9b\x01\x01\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) end it 'handle outrageous sizes 4' do expect { CBOR.decode("\x9b\x00\x00\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) expect { CBOR.decode("\x61") }.to raise_error(EOFError) expect { CBOR.decode("\x7a\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 5' do expect { CBOR.decode("\x7b\xff\xff\xff\xff\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 6' do expect { CBOR.decode("\x7b\x01\x01\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) end it 'handle outrageous sizes 7' do expect { CBOR.decode("\x7b\x00\x00\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) expect { CBOR.decode("\x41") }.to raise_error(EOFError) expect { CBOR.decode("\x5a\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 8' do expect { CBOR.decode("\x5b\xff\xff\xff\xff\xff\xff\xff\xff") }.to raise_error(EOFError) end it 'handle outrageous sizes 9' do expect { CBOR.decode("\x5b\x01\x01\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) end it 'handle outrageous sizes 10' do expect { CBOR.decode("\x5b\x00\x00\x01\x01\x01\x01\x01\x01") }.to raise_error(EOFError) end ## FIXME # it "{0=>0, 1=>1, ..., 14=>14}" do # a = (0..14).to_a; # match Hash[*a.zip(a).flatten], "\x8f\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x04\x04\x0a\x0a" # end # # it "{0=>0, 1=>1, ..., 15=>15}" do # a = (0..15).to_a; # match Hash[*a.zip(a).flatten], "\xde\x00\x10\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x0f\x0f\x04\x04\x0a\x0a" # end ## FIXME # it "fixmap" do # check_map 1, 0 # check_map 1, (1<<4)-1 # end # # it "map 16" do # check_map 3, (1<<4) # check_map 3, (1<<16)-1 # end # # it "map 32" do # check_map 5, (1<<16) # #check_map 5, (1<<32)-1 # memory error # end def check(len, obj) raw = obj.to_cbor.to_s raw.length.should == len obj2 = MessagePack.unpack(raw) obj2.should == obj if obj.respond_to? :encoding obj2.encoding.should == obj.encoding end end def check_raw(overhead, num) check num+overhead, " "*num end def check_array(overhead, num) check num+overhead, Array.new(num) end def check_bn(bn, tag) bnb = bignum_to_bytes(bn < 0 ? ~bn : bn) bnbs = bnb.size match bn, "#{tag.chr}#{(bnbs + 0x40).chr}#{bnb}" end def match(obj, buf) raw = obj.to_cbor.to_s raw.should == buf end def check_decode(c, obj) obj2 = MessagePack.unpack(c) obj2.should == obj if obj.respond_to? :encoding obj2.encoding.should == obj.encoding end end end cbor-0.5.9.8/spec/cases.json0000644000004100000410000000033414567454543015614 0ustar www-datawww-data[false,true,null,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,127,127,255,65535,4294967295,-32,-32,-128,-32768,-2147483648,0.0,-0.0,1.0,-1.0,"a","a","a","","","",[0],[0],[0],[],[],[],{},{},{},{"a":97},{"a":97},{"a":97},[[]],[["a"]]]cbor-0.5.9.8/spec/packer_spec.rb0000644000004100000410000000544214567454543016434 0ustar www-datawww-data# encoding: ascii-8bit require 'spec_helper' require 'stringio' if defined?(Encoding) Encoding.default_external = 'ASCII-8BIT' end describe Packer do let :packer do Packer.new end it 'initialize' do Packer.new Packer.new(nil) Packer.new(StringIO.new) Packer.new({}) Packer.new(StringIO.new, {}) end #it 'Packer' do # Packer(packer).object_id.should == packer.object_id # Packer(nil).class.should == Packer # Packer('').class.should == Packer # Packer('initbuf').to_s.should == 'initbuf' #end it 'write' do packer.write([]) packer.to_s.should == "\x80" end it 'write_nil' do packer.write_nil packer.to_s.should == "\xf6" end it 'write_array_header 0' do packer.write_array_header(0) packer.to_s.should == "\x80" end it 'write_array_header 1' do packer.write_array_header(1) packer.to_s.should == "\x81" end it 'write_map_header 0' do packer.write_map_header(0) packer.to_s.should == "\xa0" end it 'write_map_header 1' do packer.write_map_header(1) packer.to_s.should == "\xa1" end it 'flush' do io = StringIO.new pk = Packer.new(io) pk.write_nil pk.flush pk.to_s.should == '' io.string.should == "\xf6" end it 'buffer' do o1 = packer.buffer.object_id packer.buffer << 'frsyuki' packer.buffer.to_s.should == 'frsyuki' packer.buffer.object_id.should == o1 end it 'to_cbor returns String' do nil.to_cbor.class.should == String true.to_cbor.class.should == String false.to_cbor.class.should == String 1.to_cbor.class.should == String 1.0.to_cbor.class.should == String "".to_cbor.class.should == String Hash.new.to_cbor.class.should == String Array.new.to_cbor.class.should == String end class CustomPack01 def to_cbor(pk=nil) return MessagePack.pack(self, pk) unless pk.class == MessagePack::Packer pk.write_array_header(2) pk.write(1) pk.write(2) return pk end end class CustomPack02 def to_cbor(pk=nil) [1,2].to_cbor(pk) end end it 'calls custom to_cbor method' do MessagePack.pack(CustomPack01.new).should == [1,2].to_cbor MessagePack.pack(CustomPack02.new).should == [1,2].to_cbor CustomPack01.new.to_cbor.should == [1,2].to_cbor CustomPack02.new.to_cbor.should == [1,2].to_cbor end it 'calls custom to_cbor method with io' do s01 = StringIO.new MessagePack.pack(CustomPack01.new, s01) s01.string.should == [1,2].to_cbor s02 = StringIO.new MessagePack.pack(CustomPack02.new, s02) s02.string.should == [1,2].to_cbor s03 = StringIO.new CustomPack01.new.to_cbor(s03) s03.string.should == [1,2].to_cbor s04 = StringIO.new CustomPack02.new.to_cbor(s04) s04.string.should == [1,2].to_cbor end end cbor-0.5.9.8/spec/cases.msg0000644000004100000410000000032514567454543015431 0ustar www-datawww-dataˀ?˿aaaaaaaaaacbor-0.5.9.8/spec/buffer_io_spec.rb0000644000004100000410000001127714567454543017132 0ustar www-datawww-datarequire 'spec_helper' require 'random_compat' require 'stringio' if defined?(Encoding) Encoding.default_external = 'ASCII-8BIT' end describe Buffer do r = Random.new random_seed = r.seed puts "buffer_io random seed: 0x#{random_seed.to_s(16)}" let :source do '' end def set_source(s) source.replace(s) end let :io do StringIO.new(source.dup) end let :buffer do Buffer.new(io) end let :repetition do ENV['SLOW'] ? 3 : 50 end it 'io returns internal io' do buffer.io.should == io end it 'close closes internal io' do io.should_receive(:close) buffer.close end it 'short feed and read all' do set_source 'aa' buffer.read.should == 'aa' end it 'short feed and read short' do set_source 'aa' buffer.read(1).should == 'a' buffer.read(1).should == 'a' buffer.read(1).should == nil end it 'long feed and read all' do set_source ' '*(1024*1024) s = buffer.read s.size.should == source.size s.should == source end it 'long feed and read mixed' do set_source ' '*(1024*1024) buffer.read(10).should == source.slice!(0, 10) buffer.read(10).should == source.slice!(0, 10) buffer.read(10).should == source.slice!(0, 10) s = buffer.read s.size.should == source.size s.should == source end it 'eof' do set_source '' buffer.read.should == '' end it 'eof 2' do set_source 'a' buffer.read.should == 'a' buffer.read.should == '' end it 'write short once and flush' do buffer.write('aa') buffer.flush io.string.should == 'aa' end it 'write short twice and flush' do buffer.write('a') buffer.write('a') buffer.flush io.string.should == 'aa' end it 'write long once and flush' do s = ' '*(1024*1024) buffer.write s buffer.flush io.string.size.should == s.size io.string.should == s end it 'write short multi and flush' do s = ' '*(1024*1024) 1024.times { buffer.write ' '*1024 } buffer.flush io.string.size.should == s.size io.string.should == s end it 'random read' do r = Random.new(random_seed) repetition.times { fragments = [] r.rand(4).times do n = r.rand(1024*1400) s = r.bytes(n) fragments << s end io = StringIO.new(fragments.join) b = Buffer.new(io) fragments.each {|s| x = b.read(s.size) x.size.should == s.size x.should == s } b.empty?.should == true b.read.should == '' } end it 'random read_all' do r = Random.new(random_seed) repetition.times { fragments = [] sx = r.bytes(0) r.rand(4).times do n = r.rand(1024*1400) s = r.bytes(n) fragments << s end io = StringIO.new(fragments.join) b = Buffer.new(io) fragments.each {|s| x = b.read_all(s.size) x.size.should == s.size x.should == s } b.empty?.should == true lambda { b.read_all(1) }.should raise_error(EOFError) } end it 'random skip' do r = Random.new(random_seed) repetition.times { fragments = [] r.rand(4).times do n = r.rand(1024*1400) s = r.bytes(n) fragments << s end io = StringIO.new(fragments.join) b = Buffer.new(io) fragments.each {|s| b.skip(s.size).should == s.size } b.empty?.should == true b.skip(1).should == 0 } end it 'random skip_all' do r = Random.new(random_seed) repetition.times { fragments = [] r.rand(4).times do n = r.rand(1024*1400) s = r.bytes(n) fragments << s end io = StringIO.new(fragments.join) b = Buffer.new(io) fragments.each {|s| lambda { b.skip_all(s.size) }.should_not raise_error() } b.empty?.should == true lambda { b.skip_all(1) }.should raise_error(EOFError) } end it 'random write and flush' do r = Random.new(random_seed) repetition.times { s = r.bytes(0) io = StringIO.new b = Buffer.new(io) r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end (io.string.size + b.size).should == s.size b.flush io.string.size.should == s.size io.string.should == s } end it 'random write and clear' do r = Random.new(random_seed) b = Buffer.new repetition.times { s = r.bytes(0) r.rand(4).times do n = r.rand(1024*1400) x = r.bytes(n) s << x b.write(x) end b.size.should == s.size b.clear } end end cbor-0.5.9.8/Rakefile0000644000004100000410000000441014567454543014335 0ustar www-datawww-data require 'bundler' Bundler::GemHelper.install_tasks require 'fileutils' require 'rspec/core' require 'rspec/core/rake_task' require 'yard' RSpec::Core::RakeTask.new(:spec) do |t| t.rspec_opts = ["-c", "-f documentation"] t.rspec_opts << "-Ilib" t.pattern = 'spec/**/*_spec.rb' t.verbose = true end task :spec => :compile desc 'Run RSpec code examples and measure coverage' task :coverage do |t| ENV['SIMPLE_COV'] = '1' Rake::Task["spec"].invoke end desc 'Generate YARD document' YARD::Rake::YardocTask.new(:doc) do |t| t.files = ['lib/cbor/version.rb','doclib/**/*.rb'] t.options = [] t.options << '--debug' << '--verbose' if $trace end spec = eval File.read("cbor.gemspec") if RUBY_PLATFORM =~ /java/ require 'rake/javaextensiontask' Rake::JavaExtensionTask.new('cbor', spec) do |ext| ext.ext_dir = 'ext/java' #jruby_home = RbConfig::CONFIG['prefix'] #jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/*.jar'] #ext.classpath = jars.map { |x| File.expand_path x }.join ':' end else require 'rake/extensiontask' Rake::ExtensionTask.new('cbor', spec) do |ext| ext.cross_compile = true ext.lib_dir = File.join(*['lib', 'cbor', ENV['FAT_DIR']].compact) #ext.cross_platform = 'i386-mswin32' end end CLEAN.include('lib/cbor/*.jar') CLEAN.include('lib/cbor/cbor.*') task :default => :build ### ## Cross compile memo ## ## Ubuntu Ubuntu 10.04.1 LTS ## # ### install mingw32 cross compiler with w64 support # sudo apt-get install gcc-mingw32 # sudo apt-get install mingw-w64 # ### install rbenv # git clone git://github.com/sstephenson/rbenv.git ~/.rbenv # echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile # echo 'eval "$(rbenv init -)"' >> ~/.bash_profile # exec $SHELL -l # ### install cross-compiled ruby 2.0.0 # rbenv install 2.0.0-p0 # gem install rake-compiler # rake-compiler cross-ruby VERSION=2.0.0-p0 # ### install cross-compiled ruby 1.9.3 # rbenv install 1.9.3-p327 # gem install rake-compiler # rake-compiler cross-ruby VERSION=1.9.3-p327 # ### install cross-compiled ruby 1.8.7 # rbenv install 1.8.7-p371 # gem install rake-compiler # rake-compiler cross-ruby VERSION=1.8.7-p371 # ### build gem # rbenv shell 1.8.7-p371 # gem install bundler && bundle # rake cross native gem RUBY_CC_VERSION=1.8.7:1.9.3:2.0.0 # cbor-0.5.9.8/Gemfile0000644000004100000410000000020714567454543014163 0ustar www-datawww-datasource 'https://rubygems.org/' gemspec group :test do gem "rake" gem 'rake-compiler' gem 'rspec' gem 'json' gem 'yard' end cbor-0.5.9.8/ext/0000755000004100000410000000000014567454543013471 5ustar www-datawww-datacbor-0.5.9.8/ext/cbor/0000755000004100000410000000000014567454543014416 5ustar www-datawww-datacbor-0.5.9.8/ext/cbor/unpacker.c0000644000004100000410000005620714567454543016404 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "unpacker.h" #include "rmem.h" #include /* for ldexp */ /* work around https://bugs.ruby-lang.org/issues/15779 for now * by limiting preallocation to about a Tebibyte * limit is 2**n-1 (n==28) so we can avoid a conditional */ #define SANE_PREALLOCATION_MAX 0xFFFFFFFUL #define SANE_PREALLOCATE(n) (n & SANE_PREALLOCATION_MAX) #if !defined(DISABLE_RMEM) && !defined(DISABLE_UNPACKER_STACK_RMEM) && \ MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE #define UNPACKER_STACK_RMEM #endif #ifdef UNPACKER_STACK_RMEM static msgpack_rmem_t s_stack_rmem; #endif void msgpack_unpacker_static_init() { #ifdef UNPACKER_STACK_RMEM msgpack_rmem_init(&s_stack_rmem); #endif #ifdef COMPAT_HAVE_ENCODING s_enc_utf8 = rb_utf8_encindex(); #endif } void msgpack_unpacker_static_destroy() { #ifdef UNPACKER_STACK_RMEM msgpack_rmem_destroy(&s_stack_rmem); #endif } #define HEAD_BYTE_REQUIRED IB_UNUSED void msgpack_unpacker_init(msgpack_unpacker_t* uk) { memset(uk, 0, sizeof(msgpack_unpacker_t)); msgpack_buffer_init(UNPACKER_BUFFER_(uk)); uk->head_byte = HEAD_BYTE_REQUIRED; uk->last_object = Qnil; uk->reading_raw = Qnil; #ifdef UNPACKER_STACK_RMEM uk->stack = msgpack_rmem_alloc(&s_stack_rmem); /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/ #else /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/ uk->stack = malloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t)); #endif uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY; } void msgpack_unpacker_destroy(msgpack_unpacker_t* uk) { #ifdef UNPACKER_STACK_RMEM msgpack_rmem_free(&s_stack_rmem, uk->stack); #else free(uk->stack); #endif msgpack_buffer_destroy(UNPACKER_BUFFER_(uk)); } void msgpack_unpacker_mark(msgpack_unpacker_t* uk) { rb_gc_mark(uk->last_object); rb_gc_mark(uk->reading_raw); msgpack_unpacker_stack_t* s = uk->stack; msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth; for(; s < send; s++) { rb_gc_mark(s->object); rb_gc_mark(s->key); } /* See MessagePack_Buffer_wrap */ /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */ rb_gc_mark(uk->buffer_ref); } void msgpack_unpacker_reset(msgpack_unpacker_t* uk) { msgpack_buffer_clear(UNPACKER_BUFFER_(uk)); uk->head_byte = HEAD_BYTE_REQUIRED; /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack_depth);*/ uk->stack_depth = 0; uk->last_object = Qnil; uk->reading_raw = Qnil; uk->reading_raw_remaining = 0; } /* head byte functions */ static int read_head_byte(msgpack_unpacker_t* uk) { int r = msgpack_buffer_read_1(UNPACKER_BUFFER_(uk)); if(r == -1) { return PRIMITIVE_EOF; } return uk->head_byte = r; } static inline int get_head_byte(msgpack_unpacker_t* uk) { int b = uk->head_byte; if(b == HEAD_BYTE_REQUIRED) { b = read_head_byte(uk); } return b; } static inline void reset_head_byte(msgpack_unpacker_t* uk) { uk->head_byte = HEAD_BYTE_REQUIRED; } static inline int object_complete(msgpack_unpacker_t* uk, VALUE object) { uk->last_object = object; reset_head_byte(uk); return PRIMITIVE_OBJECT_COMPLETE; } static inline VALUE object_string_encoding_set(VALUE str, int textflag) { #ifdef COMPAT_HAVE_ENCODING //str_modifiable(str); ENCODING_SET(str, textflag ? s_enc_utf8: s_enc_ascii8bit); #endif return str; } static inline int object_complete_string(msgpack_unpacker_t* uk, VALUE str, int textflag) { return object_complete(uk, object_string_encoding_set(str, textflag)); } /* stack funcs */ static inline msgpack_unpacker_stack_t* _msgpack_unpacker_stack_top(msgpack_unpacker_t* uk) { return &uk->stack[uk->stack_depth-1]; } static inline int _msgpack_unpacker_stack_push_tag(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object, uint64_t tag) { reset_head_byte(uk); if(uk->stack_capacity - uk->stack_depth <= 0) { return PRIMITIVE_STACK_TOO_DEEP; } msgpack_unpacker_stack_t* next = &uk->stack[uk->stack_depth]; next->count = count; next->type = type; next->object = object; next->key = Qnil; next->tag = tag; uk->stack_depth++; return PRIMITIVE_CONTAINER_START; } static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object) { return _msgpack_unpacker_stack_push_tag(uk, type, count, object, 0); } static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk) { return --uk->stack_depth; } static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk) { return uk->stack_depth == 0; } #ifdef USE_CASE_RANGE #define SWITCH_RANGE_BEGIN(BYTE) { switch(BYTE) { #define SWITCH_RANGE(BYTE, FROM, TO) } case FROM ... TO: { #define SWITCH_RANGE_DEFAULT } default: { #define SWITCH_RANGE_END } } #else #define SWITCH_RANGE_BEGIN(BYTE) { if(0) { #define SWITCH_RANGE(BYTE, FROM, TO) } else if(FROM <= (BYTE) && (BYTE) <= TO) { #define SWITCH_RANGE_DEFAULT } else { #define SWITCH_RANGE_END } } #endif #define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \ union msgpack_buffer_cast_block_t* cb = msgpack_buffer_read_cast_block(UNPACKER_BUFFER_(uk), n); \ if(cb == NULL) { \ return PRIMITIVE_EOF; \ } static inline bool is_reading_map_key(msgpack_unpacker_t* uk) { if(uk->stack_depth > 0) { msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk); if(top->type == STACK_TYPE_MAP_KEY || top->type == STACK_TYPE_MAP_KEY_INDEF) { return true; } } return false; } static int read_raw_body_cont(msgpack_unpacker_t* uk, int textflag) { size_t length = uk->reading_raw_remaining; if(uk->reading_raw == Qnil) { uk->reading_raw = rb_str_buf_new(SANE_PREALLOCATE(length)); } do { size_t n = msgpack_buffer_read_to_string(UNPACKER_BUFFER_(uk), uk->reading_raw, length); if(n == 0) { return PRIMITIVE_EOF; } /* update reading_raw_remaining everytime because * msgpack_buffer_read_to_string raises IOError */ uk->reading_raw_remaining = length = length - n; } while(length > 0); object_complete_string(uk, uk->reading_raw, textflag); uk->reading_raw = Qnil; return PRIMITIVE_OBJECT_COMPLETE; } static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int textflag) { /* assuming uk->reading_raw == Qnil */ uk->textflag = textflag; /* try optimized read */ size_t length = uk->reading_raw_remaining; if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) { /* don't use zerocopy for hash keys but get a frozen string directly * because rb_hash_aset freezes keys and it causes copying */ bool will_freeze = is_reading_map_key(uk); VALUE string; bool as_symbol = will_freeze && textflag && uk->keys_as_symbols; string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, as_symbol); if (as_symbol) object_complete(uk, string); else { object_complete_string(uk, string, textflag); if (will_freeze) { rb_obj_freeze(string); } } uk->reading_raw_remaining = 0; return PRIMITIVE_OBJECT_COMPLETE; } return read_raw_body_cont(uk, textflag); } /* speedier version of ldexp for 11-bit numbers */ static inline double ldexp11(int mant, int exp) { #if SOMEBODY_FIXED_LDEXP return ldexp(mant, exp); #else union { double d; uint64_t u; } u; u.u = ((mant & 0x3ffULL) << 42) | ((exp + 1033ULL) << 52); return u.d; #endif } #define READ_VAL(uk, ai, val) { \ int n = 1 << ((ai) & 3); \ READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n); \ switch ((ai) & 3) { \ case 0: { \ val = cb->u8; \ break; \ } \ case 1: { \ val = _msgpack_be16(cb->u16); \ break; \ } \ case 2: { \ val = _msgpack_be32(cb->u32); \ break; \ } \ case 3: { \ val = _msgpack_be64(cb->u64); \ break; \ } \ } \ } /* All the cases with an immediate value in the AI */ #define CASE_IMM(n) case ((n*8)): case ((n*8) + 1): case ((n*8) + 2): case ((n*8) + 3): case ((n*8) + 4): case ((n*8) + 5) /* The case with additional information */ #define CASE_AI(n) case ((n*8) + 6) /* The case with the reserved and indefinite ai values */ #define CASE_INDEF(n) case ((n*8) + 7) static int read_primitive(msgpack_unpacker_t* uk) { if(uk->reading_raw_remaining > 0) { return read_raw_body_cont(uk, uk->textflag); } int ib = get_head_byte(uk); if (ib < 0) { return ib; } int ai = IB_AI(ib); uint64_t val = ai; switch (ib >> 2) { CASE_IMM(MT_UNSIGNED): // Positive Fixnum return object_complete(uk, INT2FIX(ai)); CASE_AI(MT_UNSIGNED): READ_VAL(uk, ai, val); return object_complete(uk, rb_ull2inum(val)); CASE_IMM(MT_NEGATIVE): // Negative Fixnum return object_complete(uk, INT2FIX(~ai)); CASE_AI(MT_NEGATIVE): READ_VAL(uk, ai, val); return object_complete(uk, (val & 0x8000000000000000 ? rb_funcall(rb_ull2inum(val), rb_intern("~"), 0) : rb_ll2inum(~val))); CASE_AI(MT_BYTES): CASE_AI(MT_TEXT): READ_VAL(uk, ai, val); CASE_IMM(MT_BYTES): // byte string CASE_IMM(MT_TEXT): // text string if (val == 0) { return object_complete_string(uk, rb_str_buf_new(0), ib & IB_TEXTFLAG); } uk->reading_raw_remaining = val; /* TODO: range checks on val here and below */ return read_raw_body_begin(uk, ib & IB_TEXTFLAG); CASE_AI(MT_ARRAY): READ_VAL(uk, ai, val); CASE_IMM(MT_ARRAY): // array if (val == 0) { return object_complete(uk, rb_ary_new()); } return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, val, rb_ary_new2(SANE_PREALLOCATE(val))); CASE_AI(MT_MAP): READ_VAL(uk, ai, val); CASE_IMM(MT_MAP): // map if (val == 0) { return object_complete(uk, rb_hash_new()); } return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, val*2, rb_hash_new()); CASE_AI(MT_TAG): READ_VAL(uk, ai, val); CASE_IMM(MT_TAG): // tag return _msgpack_unpacker_stack_push_tag(uk, STACK_TYPE_TAG, 1, Qnil, val); case MT_PRIM*8+5: switch(ai) { case VAL_NIL: // nil return object_complete(uk, Qnil); case VAL_FALSE: // false return object_complete(uk, Qfalse); case VAL_TRUE: // true return object_complete(uk, Qtrue); } /* fall through */ case MT_PRIM*8: case MT_PRIM*8+1: case MT_PRIM*8+2: case MT_PRIM*8+3: case MT_PRIM*8+4: return object_complete(uk, rb_struct_new(rb_cCBOR_Simple, INT2FIX(val))); CASE_AI(MT_PRIM): READ_VAL(uk, ai, val); switch (ai) { case AI_2: { // half int exp = (val >> 10) & 0x1f; int mant = val & 0x3ff; double res; if (exp == 0) res = ldexp(mant, -24); else if (exp != 31) res = ldexp11(mant + 1024, exp - 25); else res = mant == 0 ? INFINITY : NAN; return object_complete(uk, rb_float_new(val & 0x8000 ? -res : res)); } case AI_4: // float { union { uint32_t u32; float f; } castbuf = { (uint32_t)val }; return object_complete(uk, rb_float_new(castbuf.f)); } case AI_8: // double { union { uint64_t u64; double d; } castbuf = { val }; return object_complete(uk, rb_float_new(castbuf.d)); } default: return object_complete(uk, rb_struct_new(rb_cCBOR_Simple, INT2FIX(val))); } CASE_INDEF(MT_BYTES): CASE_INDEF(MT_TEXT): /* handle string */ if (ai == AI_INDEF) return _msgpack_unpacker_stack_push(uk, STACK_TYPE_STRING_INDEF, ib & IB_TEXTFLAG, object_string_encoding_set(rb_str_buf_new(0), ib & IB_TEXTFLAG)); /* fall through */ CASE_INDEF(MT_ARRAY): if (ai == AI_INDEF) return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY_INDEF, 0, rb_ary_new2(0)); /* fall through */ CASE_INDEF(MT_MAP): if (ai == AI_INDEF) return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY_INDEF, 0, rb_hash_new()); /* fall through */ CASE_INDEF(MT_PRIM): if (ai == AI_INDEF) return PRIMITIVE_BREAK; /* fall through */ } return PRIMITIVE_INVALID_BYTE; } int msgpack_unpacker_read_container_header(msgpack_unpacker_t* uk, uint64_t* result_size, int ib) { int b = get_head_byte(uk); if(b < 0) { return b; } if(ib <= b && b < (ib + AI_1)) { *result_size = IB_AI(b); } else if((b & ~0x3) == (ib + AI_1)) { uint64_t val; READ_VAL(uk, b, val); *result_size = val; } else { return PRIMITIVE_UNEXPECTED_TYPE; /* including INDEF! */ } reset_head_byte(uk); return 0; } int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint64_t* result_size) { return msgpack_unpacker_read_container_header(uk, result_size, IB_ARRAY); } int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint64_t* result_size) { return msgpack_unpacker_read_container_header(uk, result_size, IB_MAP); } static VALUE msgpack_unpacker_process_tag(uint64_t tag, VALUE v) { VALUE res = v; switch (tag) { case TAG_TIME_EPOCH: { return rb_funcall(rb_cTime, rb_intern("at"), 1, v); } case TAG_RE: { return rb_funcall(rb_cRegexp, rb_intern("new"), 1, v); } case TAG_URI: { if (!rb_const_defined(rb_cObject, rb_intern("URI"))) goto unknown_tag; return rb_funcall(rb_const_get(rb_cObject, rb_intern("URI")), rb_intern("parse"), 1, v); } case TAG_BIGNUM_NEG: case TAG_BIGNUM: /* check object is a byte string */ if (rb_type(v) != T_STRING) break; /* XXX: really should error out here */ #ifdef COMPAT_HAVE_ENCODING if (ENCODING_GET(v) != s_enc_ascii8bit) break; /* XXX: really should error out here */ #endif { char *sp = RSTRING_PTR(v); size_t slen = RSTRING_LEN(v); while (slen && *sp == 0) { slen--; sp++; } #ifdef HAVE_RB_INTEGER_UNPACK res = rb_integer_unpack(sp, slen, 1, 0, INTEGER_PACK_BIG_ENDIAN); /* (const void *words, size_t numwords, size_t wordsize, size_t nails, int flags); */ #else #ifndef CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM int ndig = (slen + SIZEOF_BDIGITS - 1)/SIZEOF_BDIGITS; res = rb_big_new(ndig, 1); /* compute number RSTRING_PTR(v) */ if (ndig) { BDIGIT *ds = RBIGNUM_DIGITS(res); int missbytes = ndig*SIZEOF_BDIGITS - slen; /* 0..SIZEOF_BDIGITS - 1 */ union { char msdig_str[SIZEOF_BDIGITS]; BDIGIT msdig_bd; } u; u.msdig_bd = 0; memcpy(u.msdig_str + missbytes, sp, SIZEOF_BDIGITS - missbytes); ds[ndig-1] = NTOHBDIGIT(u.msdig_bd); sp += SIZEOF_BDIGITS - missbytes; while (--ndig > 0) { memcpy(u.msdig_str, sp, SIZEOF_BDIGITS); ds[ndig-1] = NTOHBDIGIT(u.msdig_bd); sp += SIZEOF_BDIGITS; } } #else { /* This is a slow workaround only... But a working one. */ char *hex = ALLOC_N(char, 2 * slen + 1); char *p = hex; while (slen) { sprintf(p, "%02x", *sp++ & 0xFF); p += 2; slen--; } *p = 0; res = rb_cstr2inum(hex, 16); xfree(hex); } #endif #endif if (tag == TAG_BIGNUM) /* non-negative */ #ifndef CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM return rb_big_norm(res); #else return res; #endif else return rb_funcall(res, rb_intern("~"), 0); /* should be rb_big_neg(), but that is static. */ } } unknown_tag: /* common return for unknown tags */ return rb_struct_new(rb_cCBOR_Tagged, rb_ull2inum(tag), v); } int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth) { while(true) { int r = read_primitive(uk); if(r < 0) { return r; } if(r == PRIMITIVE_CONTAINER_START) { continue; } /* PRIMITIVE_OBJECT_COMPLETE */ if(msgpack_unpacker_stack_is_empty(uk)) { if (r == PRIMITIVE_BREAK) return PRIMITIVE_INVALID_BYTE; return PRIMITIVE_OBJECT_COMPLETE; } container_completed: { msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk); if (top->type <= STACK_TYPE_MAP_VALUE_INDEF && r == PRIMITIVE_BREAK) return PRIMITIVE_INVALID_BYTE; switch(top->type) { case STACK_TYPE_ARRAY: rb_ary_push(top->object, uk->last_object); break; case STACK_TYPE_MAP_KEY: top->key = uk->last_object; top->type = STACK_TYPE_MAP_VALUE; break; case STACK_TYPE_MAP_VALUE: rb_hash_aset(top->object, top->key, uk->last_object); top->type = STACK_TYPE_MAP_KEY; break; case STACK_TYPE_TAG: object_complete(uk, msgpack_unpacker_process_tag(top->tag, uk->last_object)); goto done; case STACK_TYPE_ARRAY_INDEF: if (r == PRIMITIVE_BREAK) goto complete; rb_ary_push(top->object, uk->last_object); continue; case STACK_TYPE_MAP_KEY_INDEF: if (r == PRIMITIVE_BREAK) goto complete; top->key = uk->last_object; top->type = STACK_TYPE_MAP_VALUE_INDEF; continue; case STACK_TYPE_MAP_VALUE_INDEF: rb_hash_aset(top->object, top->key, uk->last_object); top->type = STACK_TYPE_MAP_KEY_INDEF; continue; case STACK_TYPE_STRING_INDEF: if (r == PRIMITIVE_BREAK) { object_complete_string(uk, top->object, (int)top->count); /* use count as textflag */ goto done; } if (!RB_TYPE_P(uk->last_object, T_STRING)) return PRIMITIVE_INVALID_BYTE; #ifdef COMPAT_HAVE_ENCODING /* XXX */ if (ENCODING_GET(top->object) != ENCODING_GET(uk->last_object)) return PRIMITIVE_INVALID_BYTE; #endif rb_str_append(top->object, uk->last_object); continue; } size_t count = --top->count; if(count == 0) { complete:; object_complete(uk, top->object); done:; if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) { return PRIMITIVE_OBJECT_COMPLETE; } goto container_completed; } } } } int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth) { while(true) { int r = read_primitive(uk); if(r < 0) { return r; } if(r == PRIMITIVE_CONTAINER_START) { continue; } /* PRIMITIVE_OBJECT_COMPLETE */ if(msgpack_unpacker_stack_is_empty(uk)) { return PRIMITIVE_OBJECT_COMPLETE; } container_completed: { msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk); /* this section optimized out */ // TODO object_complete still creates objects which should be optimized out /* XXX: check INDEF! */ size_t count = --top->count; if(count == 0) { object_complete(uk, Qnil); if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) { return PRIMITIVE_OBJECT_COMPLETE; } goto container_completed; } } } } /* dead code, but keep it for comparison purposes */ static enum msgpack_unpacker_object_type msgpack_unpacker_object_types_per_mt[] = { TYPE_INTEGER, TYPE_INTEGER, TYPE_RAW, TYPE_RAW, /* XXX */ TYPE_ARRAY, TYPE_MAP, TYPE_INTEGER, /* XXX */ TYPE_NIL /* see below: */ }; static enum msgpack_unpacker_object_type msgpack_unpacker_object_types_per_ai[] = { PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_NIL, PRIMITIVE_INVALID_BYTE, /* XXX */ PRIMITIVE_INVALID_BYTE, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, PRIMITIVE_INVALID_BYTE, }; int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk) { int ib = get_head_byte(uk); if (ib < 0) { return ib; } int t = msgpack_unpacker_object_types_per_mt[IB_MT(ib)]; if (t == TYPE_NIL) { t = msgpack_unpacker_object_types_per_ai[IB_AI(ib)]; } return t; } int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk) { int b = get_head_byte(uk); if(b < 0) { return b; } if (b == IB_NIL) { return 1; } return 0; } cbor-0.5.9.8/ext/cbor/rbinit.c0000644000004100000410000000274114567454543016055 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "buffer_class.h" #include "packer_class.h" #include "unpacker_class.h" #include "core_ext.h" VALUE rb_cCBOR_Tagged; VALUE rb_cCBOR_Simple; void Init_cbor(void) { VALUE mMessagePack = rb_define_module("CBOR"); rb_cCBOR_Tagged = rb_struct_define(NULL, "tag", "value", NULL); rb_define_const(mMessagePack, "Tagged", rb_cCBOR_Tagged); rb_cCBOR_Simple = rb_struct_define(NULL, "value", NULL); rb_define_const(mMessagePack, "Simple", rb_cCBOR_Simple); MessagePack_Buffer_module_init(mMessagePack); MessagePack_Packer_module_init(mMessagePack); MessagePack_Unpacker_module_init(mMessagePack); MessagePack_core_ext_module_init(); } cbor-0.5.9.8/ext/cbor/sysdep_endian.h0000644000004100000410000000373314567454543017422 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_SYSDEP_ENDIAN_H__ #define MSGPACK_RUBY_SYSDEP_ENDIAN_H__ /* including arpa/inet.h requires an extra dll on win32 */ #ifndef _WIN32 #include /* __BYTE_ORDER */ #endif /* * Use following command to add consitions here: * cpp -dM `echo "#include " > test.c; echo test.c` | grep ENDIAN */ #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) /* Mac OS X */ # if defined(_LITTLE_ENDIAN) \ || ( defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) \ && __BYTE_ORDER == __LITTLE_ENDIAN ) /* Linux */ \ || ( defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) /* Solaris */ # define __LITTLE_ENDIAN__ # elif defined(_BIG_ENDIAN) \ || (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) \ && __BYTE_ORDER == __BIG_ENDIAN) /* Linux */ \ || (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) \ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) /* Solaris */ # define __BIG_ENDIAN__ # elif defined(_WIN32) /* Win32 */ # define __LITTLE_ENDIAN__ # endif #endif #endif cbor-0.5.9.8/ext/cbor/packer.h0000644000004100000410000002654414567454543016047 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_PACKER_H__ #define MSGPACK_RUBY_PACKER_H__ #include "buffer.h" #ifndef MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY #define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024) #endif struct msgpack_packer_t; typedef struct msgpack_packer_t msgpack_packer_t; struct msgpack_packer_t { msgpack_buffer_t buffer; VALUE io; ID io_write_all_method; ID to_msgpack_method; VALUE to_msgpack_arg; VALUE buffer_ref; }; #define PACKER_BUFFER_(pk) (&(pk)->buffer) void msgpack_packer_static_init(); void msgpack_packer_static_destroy(); void msgpack_packer_init(msgpack_packer_t* pk); void msgpack_packer_destroy(msgpack_packer_t* pk); void msgpack_packer_mark(msgpack_packer_t* pk); static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk, ID to_msgpack_method, VALUE to_msgpack_arg) { pk->to_msgpack_method = to_msgpack_method; pk->to_msgpack_arg = to_msgpack_arg; } static inline void msgpack_packer_set_io(msgpack_packer_t* pk, VALUE io, ID io_write_all_method) { pk->io = io; pk->io_write_all_method = io_write_all_method; } void msgpack_packer_reset(msgpack_packer_t* pk); static inline void cbor_encoder_write_head(msgpack_packer_t* pk, unsigned int ib, uint64_t n) { if (n < 24) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), ib + (int)n); } else if (n < 256) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3); msgpack_buffer_write_2(PACKER_BUFFER_(pk), ib + 24, n); } else if (n < 65536) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3); uint16_t be = _msgpack_be16(n); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 25, (const void*)&be, 2); } else if (n < 0x100000000LU) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5); uint32_t be = _msgpack_be32(n); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 26, (const void*)&be, 4); } else { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9); uint64_t be = _msgpack_be64(n); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), ib + 27, (const void*)&be, 8); } } static inline void msgpack_packer_write_nil(msgpack_packer_t* pk) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_NIL); } static inline void msgpack_packer_write_true(msgpack_packer_t* pk) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_TRUE); } static inline void msgpack_packer_write_false(msgpack_packer_t* pk) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_FALSE); } static inline void _msgpack_packer_write_long_long64(msgpack_packer_t* pk, long long v) { uint64_t ui = v >> 63; // extend sign to whole length int mt = ui & IB_NEGFLAG; // extract major type ui ^= v; // complement negatives cbor_encoder_write_head(pk, mt, ui); } static inline void msgpack_packer_write_long(msgpack_packer_t* pk, long v) { _msgpack_packer_write_long_long64(pk, v); } static inline void msgpack_packer_write_u64(msgpack_packer_t* pk, uint64_t v) { cbor_encoder_write_head(pk, IB_UNSIGNED, v); } static inline void msgpack_packer_write_double(msgpack_packer_t* pk, double v) { float fv = v; if (fv == v) { /* 32 bits is enough and we aren't NaN */ union { float f; uint32_t u32; char mem[4]; } castbuf = { fv }; int b32 = castbuf.u32; if ((b32 & 0x1FFF) == 0) { /* worth trying half */ int s16 = (b32 >> 16) & 0x8000; int exp = (b32 >> 23) & 0xff; int mant = b32 & 0x7fffff; if (exp == 0 && mant == 0) ; /* 0.0, -0.0 */ else if (exp >= 113 && exp <= 142) /* normalized */ s16 += ((exp - 112) << 10) + (mant >> 13); else if (exp >= 103 && exp < 113) { /* denorm, exp16 = 0 */ if (mant & ((1 << (126 - exp)) - 1)) goto float32; /* loss of precision */ s16 += ((mant + 0x800000) >> (126 - exp)); } else if (exp == 255 && mant == 0) { /* Inf */ s16 += 0x7c00; } else goto float32; /* loss of range */ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 3); uint16_t be = _msgpack_be16(s16); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT2, (const void*)&be, 2); return; } float32: msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 5); castbuf.u32 = _msgpack_be_float(castbuf.u32); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT4, castbuf.mem, 4); } else if (v != v) { /* NaN */ cbor_encoder_write_head(pk, 0xe0, 0x7e00); } else { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 9); union { double d; uint64_t u64; char mem[8]; } castbuf = { v }; castbuf.u64 = _msgpack_be_double(castbuf.u64); msgpack_buffer_write_byte_and_data(PACKER_BUFFER_(pk), IB_FLOAT8, castbuf.mem, 8); } } static inline void msgpack_packer_write_array_header(msgpack_packer_t* pk, uint64_t n) { cbor_encoder_write_head(pk, IB_ARRAY, n); } static inline void msgpack_packer_write_map_header(msgpack_packer_t* pk, uint64_t n) { cbor_encoder_write_head(pk, IB_MAP, n); } void _msgpack_packer_write_string_to_io(msgpack_packer_t* pk, VALUE string); static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v) { int mt = IB_TEXT; /* text string */ #ifdef COMPAT_HAVE_ENCODING int enc = ENCODING_GET(v); if (enc == s_enc_ascii8bit) { mt = IB_BYTES; } else if (enc != s_enc_utf8 && enc != s_enc_usascii) { if(!ENC_CODERANGE_ASCIIONLY(v)) { v = rb_str_encode(v, s_enc_utf8_value, 0, Qnil); } } #endif cbor_encoder_write_head(pk, mt, RSTRING_LEN(v)); msgpack_buffer_append_string(PACKER_BUFFER_(pk), v); } static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE v) { #ifdef HAVE_RB_SYM2STR /* rb_sym2str is added since MRI 2.2.0 */ msgpack_packer_write_string_value(pk, rb_sym2str(v)); #else const char* name = rb_id2name(SYM2ID(v)); /* actual return type of strlen is size_t */ unsigned long len = strlen(name); if(len > 0xffffffffUL) { // TODO rb_eArgError? rb_raise(rb_eArgError, "size of symbol is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL); } cbor_encoder_write_head(pk, IB_TEXT, len); msgpack_buffer_append(PACKER_BUFFER_(pk), name, len); #endif } static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v) { #ifdef JRUBY msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v)); #else msgpack_packer_write_long(pk, FIX2LONG(v)); #endif } static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v) { long len; int ib = IB_UNSIGNED; if (!RBIGNUM_POSITIVE_P(v)) { v = rb_funcall(v, rb_intern("~"), 0); /* should be rb_big_neg(), but that is static. */ ib = IB_NEGATIVE; } #ifdef HAVE_RB_INTEGER_UNPACK len = rb_absint_size(v, NULL); if (len > SIZEOF_LONG_LONG) { /* i.e., need real bignum */ msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_BIGNUM + IB_NEGFLAG_AS_BIT(ib)); cbor_encoder_write_head(pk, IB_BYTES, len); msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), len); char buf[len]; /* XXX */ if (rb_integer_pack(v, buf, len, 1, 0, INTEGER_PACK_BIG_ENDIAN) != 1) rb_raise(rb_eRangeError, "cbor rb_integer_pack() error"); msgpack_buffer_append(PACKER_BUFFER_(pk), buf, len); #else len = RBIGNUM_LEN(v); if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS) { msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), 1); msgpack_buffer_write_1(PACKER_BUFFER_(pk), IB_BIGNUM + IB_NEGFLAG_AS_BIT(ib)); { #ifndef CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM BDIGIT *dp = RBIGNUM_DIGITS(v); BDIGIT *de = dp + len; int nbyte = (len - 1) * SIZEOF_BDIGITS; int nbmsdig = 0; BDIGIT msdig; int i; if ((msdig = de[-1]) == 0) /* todo: check whether that occurs */ rb_raise(rb_eRangeError, "cbor writing unnormalized bignum"); while (msdig) { /* get number of significant bytes in msdig */ nbmsdig++; msdig >>= 8; } nbyte += nbmsdig; cbor_encoder_write_head(pk, IB_BYTES, nbyte); msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), nbyte); /* first digit: */ msdig = de[-1]; while (nbmsdig) { --nbmsdig; msgpack_buffer_write_1(PACKER_BUFFER_(pk), msdig >> (nbmsdig << 3)); } /* rest of the digits: */ for (i = 1; i < len; ++i) { BDIGIT be = NTOHBDIGIT(de[-1-i]); msgpack_buffer_append(PACKER_BUFFER_(pk), (const void*)&be, SIZEOF_BDIGITS); } #else /* This is a slow workaround only... But a working one.*/ size_t nbyte; VALUE hexval = rb_funcall(v, rb_intern("to_s"), 1, INT2FIX(16)); char *hp; int i; if (RSTRING_LEN(hexval) & 1) rb_funcall(hexval, rb_intern("[]="), 3, INT2FIX(0), INT2FIX(0), rb_str_new("0", 1)); nbyte = RSTRING_LEN(hexval) >> 1; hp = RSTRING_PTR(hexval); cbor_encoder_write_head(pk, IB_BYTES, nbyte); msgpack_buffer_ensure_writable(PACKER_BUFFER_(pk), nbyte); for (i = 0; i < nbyte; i++) { int c; sscanf(hp, "%2x", &c); hp += 2; msgpack_buffer_write_1(PACKER_BUFFER_(pk), c); } #endif } #endif } else { cbor_encoder_write_head(pk, ib, rb_big2ull(v)); } #ifdef RB_GC_GUARD RB_GC_GUARD(v); #endif } static inline void msgpack_packer_write_float_value(msgpack_packer_t* pk, VALUE v) { msgpack_packer_write_double(pk, rb_num2dbl(v)); } static inline void msgpack_packer_write_simple_value(msgpack_packer_t* pk, VALUE v) { cbor_encoder_write_head(pk, IB_PRIM, FIX2LONG(rb_struct_aref(v, INT2FIX(0)))); } void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v); void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v); void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v); static inline void msgpack_packer_write_tagged_value(msgpack_packer_t* pk, VALUE v) { cbor_encoder_write_head(pk, IB_TAG, rb_num2ulong(rb_struct_aref(v, INT2FIX(0)))); msgpack_packer_write_value(pk, rb_struct_aref(v, INT2FIX(1))); } static inline void msgpack_packer_write_processed_value(msgpack_packer_t* pk, VALUE v, ID method, int tag) { cbor_encoder_write_head(pk, IB_TAG, tag); msgpack_packer_write_value(pk, rb_funcall(v, method, 0)); } #endif cbor-0.5.9.8/ext/cbor/rmem.c0000644000004100000410000000551014567454543015523 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rmem.h" void msgpack_rmem_init(msgpack_rmem_t* pm) { memset(pm, 0, sizeof(msgpack_rmem_t)); pm->head.pages = malloc(MSGPACK_RMEM_PAGE_SIZE * 32); pm->head.mask = 0xffffffff; /* all bit is 1 = available */ } void msgpack_rmem_destroy(msgpack_rmem_t* pm) { msgpack_rmem_chunk_t* c = pm->array_first; msgpack_rmem_chunk_t* cend = pm->array_last; for(; c != cend; c++) { free(c->pages); } free(pm->head.pages); free(pm->array_first); } void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm) { msgpack_rmem_chunk_t* c = pm->array_first; msgpack_rmem_chunk_t* last = pm->array_last; for(; c != last; c++) { if(_msgpack_rmem_chunk_available(c)) { void* mem = _msgpack_rmem_chunk_alloc(c); /* move to head */ msgpack_rmem_chunk_t tmp = pm->head; pm->head = *c; *c = tmp; return mem; } } if(c == pm->array_end) { size_t capacity = c - pm->array_first; size_t length = last - pm->array_first; capacity = (capacity == 0) ? 8 : capacity * 2; msgpack_rmem_chunk_t* array = realloc(pm->array_first, capacity * sizeof(msgpack_rmem_chunk_t)); pm->array_first = array; pm->array_last = array + length; pm->array_end = array + capacity; } /* allocate new chunk */ c = pm->array_last++; /* move to head */ msgpack_rmem_chunk_t tmp = pm->head; pm->head = *c; *c = tmp; pm->head.mask = 0xffffffff & (~1); /* "& (~1)" means first chunk is already allocated */ pm->head.pages = malloc(MSGPACK_RMEM_PAGE_SIZE * 32); return pm->head.pages; } void _msgpack_rmem_chunk_free(msgpack_rmem_t* pm, msgpack_rmem_chunk_t* c) { if(pm->array_first->mask == 0xffffffff) { /* free and move to last */ pm->array_last--; free(c->pages); *c = *pm->array_last; return; } /* move to first */ msgpack_rmem_chunk_t tmp = *pm->array_first; *pm->array_first = *c; *c = tmp; } cbor-0.5.9.8/ext/cbor/sysdep_types.h0000644000004100000410000000254314567454543017326 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_SYSDEP_TYPES_H__ #define MSGPACK_RUBY_SYSDEP_TYPES_H__ #include #include #include #if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #elif defined(_MSC_VER) // && _MSC_VER >= 1600 #include #else #include #include #endif #endif cbor-0.5.9.8/ext/cbor/buffer.h0000644000004100000410000003053714567454543016050 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_BUFFER_H__ #define MSGPACK_RUBY_BUFFER_H__ #include "cbor.h" #include "compat.h" #include "sysdep.h" #ifdef COMPAT_HAVE_ENCODING /* see compat.h*/ extern int s_enc_ascii8bit; extern int s_enc_usascii; extern int s_enc_utf8; extern VALUE s_enc_utf8_value; #endif extern VALUE rb_cCBOR_Tagged; extern VALUE rb_cCBOR_Simple; #ifndef MSGPACK_BUFFER_STRING_WRITE_REFERENCE_DEFAULT #define MSGPACK_BUFFER_STRING_WRITE_REFERENCE_DEFAULT (512*1024) #endif /* at least 23 (RSTRING_EMBED_LEN_MAX) bytes */ #ifndef MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM #define MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM 256 #endif #ifndef MSGPACK_BUFFER_STRING_READ_REFERENCE_DEFAULT #define MSGPACK_BUFFER_STRING_READ_REFERENCE_DEFAULT 256 #endif /* at least 23 (RSTRING_EMBED_LEN_MAX) bytes */ #ifndef MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM #define MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM 256 #endif #ifndef MSGPACK_BUFFER_IO_BUFFER_SIZE_DEFAULT #define MSGPACK_BUFFER_IO_BUFFER_SIZE_DEFAULT (32*1024) #endif #ifndef MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM #define MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM (1024) #endif #define NO_MAPPED_STRING ((VALUE)0) struct msgpack_buffer_chunk_t; typedef struct msgpack_buffer_chunk_t msgpack_buffer_chunk_t; struct msgpack_buffer_t; typedef struct msgpack_buffer_t msgpack_buffer_t; /* * msgpack_buffer_chunk_t * +----------------+ * | filled | free | * +---------+------+ * ^ first ^ last */ struct msgpack_buffer_chunk_t { char* first; char* last; void* mem; msgpack_buffer_chunk_t* next; VALUE mapped_string; /* RBString or NO_MAPPED_STRING */ }; union msgpack_buffer_cast_block_t { char buffer[8]; uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; int8_t i8; int16_t i16; int32_t i32; int64_t i64; float f; double d; }; struct msgpack_buffer_t { char* read_buffer; char* tail_buffer_end; msgpack_buffer_chunk_t tail; msgpack_buffer_chunk_t* head; msgpack_buffer_chunk_t* free_list; #ifndef DISABLE_RMEM char* rmem_last; char* rmem_end; void** rmem_owner; #endif union msgpack_buffer_cast_block_t cast_block; VALUE io; VALUE io_buffer; ID io_write_all_method; ID io_partial_read_method; size_t write_reference_threshold; size_t read_reference_threshold; size_t io_buffer_size; VALUE owner; }; /* * initialization functions */ void msgpack_buffer_static_init(); void msgpack_buffer_static_destroy(); void msgpack_buffer_init(msgpack_buffer_t* b); void msgpack_buffer_destroy(msgpack_buffer_t* b); void msgpack_buffer_mark(msgpack_buffer_t* b); void msgpack_buffer_clear(msgpack_buffer_t* b); static inline void msgpack_buffer_set_write_reference_threshold(msgpack_buffer_t* b, size_t length) { if(length < MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) { length = MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM; } b->write_reference_threshold = length; } static inline void msgpack_buffer_set_read_reference_threshold(msgpack_buffer_t* b, size_t length) { if(length < MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM) { length = MSGPACK_BUFFER_STRING_READ_REFERENCE_MINIMUM; } b->read_reference_threshold = length; } static inline void msgpack_buffer_set_io_buffer_size(msgpack_buffer_t* b, size_t length) { if(length < MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM) { length = MSGPACK_BUFFER_IO_BUFFER_SIZE_MINIMUM; } b->io_buffer_size = length; } static inline void msgpack_buffer_reset_io(msgpack_buffer_t* b) { b->io = Qnil; } static inline bool msgpack_buffer_has_io(msgpack_buffer_t* b) { return b->io != Qnil; } static inline void msgpack_buffer_reset(msgpack_buffer_t* b) { msgpack_buffer_clear(b); msgpack_buffer_reset_io(b); } /* * writer functions */ static inline size_t msgpack_buffer_writable_size(const msgpack_buffer_t* b) { return b->tail_buffer_end - b->tail.last; } static inline void msgpack_buffer_write_1(msgpack_buffer_t* b, int byte) { (*b->tail.last++) = (char) byte; } static inline void msgpack_buffer_write_2(msgpack_buffer_t* b, int byte1, unsigned char byte2) { *(b->tail.last++) = (char) byte1; *(b->tail.last++) = (char) byte2; } static inline void msgpack_buffer_write_byte_and_data(msgpack_buffer_t* b, int byte, const void* data, size_t length) { (*b->tail.last++) = (char) byte; memcpy(b->tail.last, data, length); b->tail.last += length; } void _msgpack_buffer_expand(msgpack_buffer_t* b, const char* data, size_t length, bool use_flush); size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method, bool consume); static inline size_t msgpack_buffer_flush(msgpack_buffer_t* b) { if(b->io == Qnil) { return 0; } return msgpack_buffer_flush_to_io(b, b->io, b->io_write_all_method, true); } static inline void msgpack_buffer_ensure_writable(msgpack_buffer_t* b, size_t require) { if(msgpack_buffer_writable_size(b) < require) { _msgpack_buffer_expand(b, NULL, require, true); } } static inline void _msgpack_buffer_append_impl(msgpack_buffer_t* b, const char* data, size_t length, bool flush_to_io) { if(length == 0) { return; } if(length <= msgpack_buffer_writable_size(b)) { memcpy(b->tail.last, data, length); b->tail.last += length; return; } _msgpack_buffer_expand(b, data, length, flush_to_io); } static inline void msgpack_buffer_append(msgpack_buffer_t* b, const char* data, size_t length) { _msgpack_buffer_append_impl(b, data, length, true); } static inline void msgpack_buffer_append_nonblock(msgpack_buffer_t* b, const char* data, size_t length) { _msgpack_buffer_append_impl(b, data, length, false); } void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string); static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE string) { size_t length = RSTRING_LEN(string); if(length > b->write_reference_threshold) { _msgpack_buffer_append_long_string(b, string); } else { msgpack_buffer_append(b, RSTRING_PTR(string), length); } return length; } /* * IO functions */ size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b); size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length); size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length); /* * reader functions */ static inline size_t msgpack_buffer_top_readable_size(const msgpack_buffer_t* b) { return b->head->last - b->read_buffer; } size_t msgpack_buffer_all_readable_size(const msgpack_buffer_t* b); bool _msgpack_buffer_shift_chunk(msgpack_buffer_t* b); static inline void _msgpack_buffer_consumed(msgpack_buffer_t* b, size_t length) { b->read_buffer += length; if(b->read_buffer >= b->head->last) { _msgpack_buffer_shift_chunk(b); } } static inline int msgpack_buffer_peek_top_1(msgpack_buffer_t* b) { return (int) (unsigned char) b->read_buffer[0]; } static inline int msgpack_buffer_read_top_1(msgpack_buffer_t* b) { int r = (int) (unsigned char) b->read_buffer[0]; _msgpack_buffer_consumed(b, 1); return r; } static inline int msgpack_buffer_read_1(msgpack_buffer_t* b) { if(msgpack_buffer_top_readable_size(b) <= 0) { if(b->io == Qnil) { return -1; } _msgpack_buffer_feed_from_io(b); } int r = (int) (unsigned char) b->read_buffer[0]; _msgpack_buffer_consumed(b, 1); return r; } /* * bulk read / skip functions */ size_t msgpack_buffer_read_nonblock(msgpack_buffer_t* b, char* buffer, size_t length); static inline bool msgpack_buffer_ensure_readable(msgpack_buffer_t* b, size_t require) { if(msgpack_buffer_top_readable_size(b) < require) { size_t sz = msgpack_buffer_all_readable_size(b); if(sz < require) { if(b->io == Qnil) { return false; } do { size_t rl = _msgpack_buffer_feed_from_io(b); sz += rl; } while(sz < require); } } return true; } bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length); static inline bool msgpack_buffer_read_all(msgpack_buffer_t* b, char* buffer, size_t length) { size_t avail = msgpack_buffer_top_readable_size(b); if(avail < length) { return _msgpack_buffer_read_all2(b, buffer, length); } memcpy(buffer, b->read_buffer, length); _msgpack_buffer_consumed(b, length); return true; } static inline size_t msgpack_buffer_skip_nonblock(msgpack_buffer_t* b, size_t length) { size_t avail = msgpack_buffer_top_readable_size(b); if(avail < length) { return msgpack_buffer_read_nonblock(b, NULL, length); } _msgpack_buffer_consumed(b, length); return length; } static inline union msgpack_buffer_cast_block_t* msgpack_buffer_read_cast_block(msgpack_buffer_t* b, size_t n) { if(!msgpack_buffer_read_all(b, b->cast_block.buffer, n)) { return NULL; } return &b->cast_block; } size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string, size_t length); static inline size_t msgpack_buffer_read_to_string(msgpack_buffer_t* b, VALUE string, size_t length) { if(length == 0) { return 0; } size_t avail = msgpack_buffer_top_readable_size(b); if(avail > 0) { return msgpack_buffer_read_to_string_nonblock(b, string, length); } else if(b->io != Qnil) { return _msgpack_buffer_read_from_io_to_string(b, string, length); } else { return 0; } } static inline size_t msgpack_buffer_skip(msgpack_buffer_t* b, size_t length) { if(length == 0) { return 0; } size_t avail = msgpack_buffer_top_readable_size(b); if(avail > 0) { return msgpack_buffer_skip_nonblock(b, length); } else if(b->io != Qnil) { return _msgpack_buffer_skip_from_io(b, length); } else { return 0; } } VALUE msgpack_buffer_all_as_string(msgpack_buffer_t* b); VALUE msgpack_buffer_all_as_string_array(msgpack_buffer_t* b); static inline VALUE _msgpack_buffer_refer_head_mapped_string(msgpack_buffer_t* b, size_t length) { size_t offset = b->read_buffer - b->head->first; return rb_str_substr(b->head->mapped_string, offset, length); } static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_t length, bool will_be_frozen, bool as_symbol) { #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE /* optimize */ if(!will_be_frozen && b->head->mapped_string != NO_MAPPED_STRING && length >= b->read_reference_threshold) { VALUE result = _msgpack_buffer_refer_head_mapped_string(b, length); _msgpack_buffer_consumed(b, length); return result; } #endif VALUE result; if (as_symbol) { #ifndef HAVE_RB_STR_INTERN #ifndef HAVE_RB_INTERN_STR /* MRI 1.8 doesn't have rb_intern_str or rb_intern2, hack it... */ char *tmp = xmalloc(length+1); memcpy(tmp, b->read_buffer, length); tmp[length] = 0; result = ID2SYM(rb_intern(tmp)); xfree(tmp); #else result = ID2SYM(rb_intern2(b->read_buffer, length)); /* FIXME: This is stuck at ASCII encoding */ #endif #else /* enable GC-able symbols here: */ result = rb_str_intern(rb_str_new(b->read_buffer, length)); #endif /* todo: rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc) */ } else { result = rb_str_new(b->read_buffer, length); /* todo: use rb_enc_str_new(const char *ptr, long len, rb_encoding *enc) :: */ } _msgpack_buffer_consumed(b, length); return result; } #endif cbor-0.5.9.8/ext/cbor/packer_class.h0000644000004100000410000000206414567454543017223 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_PACKER_CLASS_H__ #define MSGPACK_RUBY_PACKER_CLASS_H__ #include "packer.h" extern VALUE cMessagePack_Packer; void MessagePack_Packer_module_init(VALUE mMessagePack); VALUE MessagePack_pack(int argc, VALUE* argv); #endif cbor-0.5.9.8/ext/cbor/rmem.h0000644000004100000410000000616314567454543015535 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_RMEM_H__ #define MSGPACK_RUBY_RMEM_H__ #include "compat.h" #include "sysdep.h" #ifndef MSGPACK_RMEM_PAGE_SIZE #define MSGPACK_RMEM_PAGE_SIZE (4*1024) #endif struct msgpack_rmem_t; typedef struct msgpack_rmem_t msgpack_rmem_t; struct msgpack_rmem_chunk_t; typedef struct msgpack_rmem_chunk_t msgpack_rmem_chunk_t; /* * a chunk contains 32 pages. * size of each buffer is MSGPACK_RMEM_PAGE_SIZE bytes. */ struct msgpack_rmem_chunk_t { unsigned int mask; char* pages; }; struct msgpack_rmem_t { msgpack_rmem_chunk_t head; msgpack_rmem_chunk_t* array_first; msgpack_rmem_chunk_t* array_last; msgpack_rmem_chunk_t* array_end; }; /* assert MSGPACK_RMEM_PAGE_SIZE % sysconf(_SC_PAGE_SIZE) == 0 */ void msgpack_rmem_init(msgpack_rmem_t* pm); void msgpack_rmem_destroy(msgpack_rmem_t* pm); void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm); #define _msgpack_rmem_chunk_available(c) ((c)->mask != 0) static inline void* _msgpack_rmem_chunk_alloc(msgpack_rmem_chunk_t* c) { _msgpack_bsp32(pos, c->mask); (c)->mask &= ~(1 << pos); return ((char*)(c)->pages) + (pos * (MSGPACK_RMEM_PAGE_SIZE)); } static inline bool _msgpack_rmem_chunk_try_free(msgpack_rmem_chunk_t* c, void* mem) { ptrdiff_t pdiff = ((char*)(mem)) - ((char*)(c)->pages); if(0 <= pdiff && pdiff < MSGPACK_RMEM_PAGE_SIZE * 32) { size_t pos = pdiff / MSGPACK_RMEM_PAGE_SIZE; (c)->mask |= (1 << pos); return true; } return false; } static inline void* msgpack_rmem_alloc(msgpack_rmem_t* pm) { if(_msgpack_rmem_chunk_available(&pm->head)) { return _msgpack_rmem_chunk_alloc(&pm->head); } return _msgpack_rmem_alloc2(pm); } void _msgpack_rmem_chunk_free(msgpack_rmem_t* pm, msgpack_rmem_chunk_t* c); static inline bool msgpack_rmem_free(msgpack_rmem_t* pm, void* mem) { if(_msgpack_rmem_chunk_try_free(&pm->head, mem)) { return true; } /* search from last */ msgpack_rmem_chunk_t* c = pm->array_last - 1; msgpack_rmem_chunk_t* before_first = pm->array_first - 1; for(; c != before_first; c--) { if(_msgpack_rmem_chunk_try_free(c, mem)) { if(c != pm->array_first && c->mask == 0xffffffff) { _msgpack_rmem_chunk_free(pm, c); } return true; } } return false; } #endif cbor-0.5.9.8/ext/cbor/cbor.h0000644000004100000410000000332614567454543015520 0ustar www-datawww-data#ifndef CBOR_RUBY_BUFFER_H__ #define CBOR_RUBY_BUFFER_H__ /* The 8 major types */ #define MT_UNSIGNED 0 #define MT_NEGATIVE 1 #define MT_BYTES 2 #define MT_TEXT 3 #define MT_ARRAY 4 #define MT_MAP 5 #define MT_TAG 6 #define MT_PRIM 7 /* The initial bytes resulting from those */ #define IB_UNSIGNED (MT_UNSIGNED << 5) #define IB_NEGATIVE (MT_NEGATIVE << 5) #define IB_BYTES (MT_BYTES << 5) #define IB_TEXT (MT_TEXT << 5) #define IB_ARRAY (MT_ARRAY << 5) #define IB_MAP (MT_MAP << 5) #define IB_TAG (MT_TAG << 5) #define IB_PRIM (MT_PRIM << 5) #define IB_NEGFLAG (IB_NEGATIVE - IB_UNSIGNED) #define IB_NEGFLAG_AS_BIT(ib) ((ib) >> 5) #define IB_TEXTFLAG (IB_TEXT - IB_BYTES) #define IB_AI(ib) ((ib) & 0x1F) #define IB_MT(ib) ((ib) >> 5) /* Tag numbers handled by this implementation */ #define TAG_TIME_EPOCH 1 #define TAG_BIGNUM 2 #define TAG_BIGNUM_NEG 3 #define TAG_URI 32 #define TAG_RE 35 /* Initial bytes of those tag numbers */ #define IB_TIME_EPOCH (IB_TAG + TAG_TIME_EPOCH) #define IB_BIGNUM (IB_TAG + TAG_BIGNUM) #define IB_BIGNUM_NEG (IB_TAG + TAG_BIGNUM_NEG) /* TAG_URI and TAG_RE are non-immediate tags */ /* Simple values handled by this implementation */ #define VAL_NIL 22 #define VAL_FALSE 20 #define VAL_TRUE 21 /* Initial bytes of those simple values */ #define IB_NIL (IB_PRIM + VAL_NIL) #define IB_FALSE (IB_PRIM + VAL_FALSE) #define IB_TRUE (IB_PRIM + VAL_TRUE) /* AI values with more data in head */ #define AI_1 24 #define AI_2 25 #define AI_4 26 #define AI_8 27 #define AI_INDEF 31 #define IB_BREAK (IB_PRIM + AI_INDEF) /* For */ #define IB_UNUSED (IB_TAG + AI_INDEF) /* Floating point initial bytes */ #define IB_FLOAT2 (IB_PRIM + AI_2) #define IB_FLOAT4 (IB_PRIM + AI_4) #define IB_FLOAT8 (IB_PRIM + AI_8) #endif cbor-0.5.9.8/ext/cbor/compat.h0000644000004100000410000000711314567454543016054 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_COMPAT_H__ #define MSGPACK_RUBY_COMPAT_H__ #include "ruby.h" #if defined(HAVE_RUBY_ST_H) # include "ruby/st.h" /* ruby hash on Ruby 1.9 */ #elif defined(HAVE_ST_H) # include "st.h" /* ruby hash on Ruby 1.8 */ #endif /* * COMPAT_HAVE_ENCODING */ #ifdef HAVE_RUBY_ENCODING_H # include "ruby/encoding.h" # define COMPAT_HAVE_ENCODING #endif #if defined(__MACRUBY__) /* MacRuby */ # undef COMPAT_HAVE_ENCODING #endif /* * define STR_DUP_LIKELY_DOES_COPY * check rb_str_dup actually copies the string or not */ #if defined(RUBY_VM) && defined(FL_ALL) && defined(FL_USER1) && defined(FL_USER3) /* MRI 1.9 */ # define STR_DUP_LIKELY_DOES_COPY(str) FL_ALL(str, FL_USER1|FL_USER3) /* same as STR_ASSOC_P(str) */ #elif defined(FL_TEST) && defined(ELTS_SHARED) /* MRI 1.8 */ # define STR_DUP_LIKELY_DOES_COPY(str) (!FL_TEST(str, ELTS_SHARED)) //#elif defined(RUBINIUS) || defined(JRUBY) /* Rubinius and JRuby */ #else # define STR_DUP_LIKELY_DOES_COPY(str) (1) #endif /* * SIZET2NUM */ #ifndef SIZET2NUM /* MRI 1.8 */ # define SIZET2NUM(v) ULL2NUM(v) #endif /* * rb_errinfo() */ #if defined(RUBY_VM) /* MRI 1.9 */ # define COMPAT_RERAISE rb_exc_raise(rb_errinfo()) #elif defined(JRUBY) /* JRuby */ # define COMPAT_RERAISE rb_exc_raise(rb_gv_get("$!")) #else /* MRI 1.8 and Rubinius */ # define COMPAT_RERAISE rb_exc_raise(ruby_errinfo) #endif /* * RBIGNUM_POSITIVE_P */ #ifndef RBIGNUM_POSITIVE_P # if defined(RUBINIUS) /* Rubinius <= v1.2.3 */ # define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue) # elif defined(JRUBY) /* JRuby */ # define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue) # define rb_big2ull(b) rb_num2ull(b) /*#define rb_big2ll(b) rb_num2ll(b)*/ # else /* MRI 1.8 */ # define RBIGNUM_POSITIVE_P(b) (RBIGNUM(b)->sign) # endif #endif #ifndef HAVE_RB_INTEGER_UNPACK /* More MRI 1.8 */ #ifndef RBIGNUM_LEN #define RBIGNUM_LEN(b) (RBIGNUM(b)->len) #endif #ifndef RBIGNUM_DIGITS #ifndef RBIGNUM #define CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM #endif #define RBIGNUM_DIGITS(b) (RBIGNUM(b)->digits) #endif #ifndef HAVE_RB_BIG_NEW /* not really worth fixing any more... */ #define CANT_DO_BIGNUMS_FAST_ON_THIS_PLATFORM /* gross 1.8.7 hack thanks to Mathieu Bouchard */ #define rb_big_new(len, sign) rb_funcall(INT2FIX(1),rb_intern("<<"),1,INT2FIX(len > 0 ? ((len) * SIZEOF_BDIGITS * 8) - 1 : 0)); #endif #endif #ifndef RB_TYPE_P #define RB_TYPE_P(obj, type) (TYPE(obj) == (type)) #endif /* * RSTRING_PTR, RSTRING_LEN */ #ifndef RSTRING_PTR /* MRI 1.8.5 */ # define RSTRING_PTR(s) (RSTRING(s)->ptr) #endif #ifndef RSTRING_LEN /* MRI 1.8.5 */ # define RSTRING_LEN(s) (RSTRING(s)->len) #endif #endif cbor-0.5.9.8/ext/cbor/packer_class.c0000644000004100000410000001764614567454543017232 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "compat.h" #include "ruby.h" #include "packer.h" #include "packer_class.h" #include "buffer_class.h" VALUE cMessagePack_Packer; static ID s_to_msgpack; static ID s_write; //static VALUE s_packer_value; //static msgpack_packer_t* s_packer; #define PACKER(from, name) \ msgpack_packer_t* name; \ Data_Get_Struct(from, msgpack_packer_t, name); \ if(name == NULL) { \ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \ } static void Packer_free(msgpack_packer_t* pk) { if(pk == NULL) { return; } msgpack_packer_destroy(pk); xfree(pk); } static VALUE Packer_alloc(VALUE klass) { msgpack_packer_t* pk = ALLOC_N(msgpack_packer_t, 1); msgpack_packer_init(pk); VALUE self = Data_Wrap_Struct(klass, msgpack_packer_mark, Packer_free, pk); msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self); pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self); return self; } static VALUE Packer_initialize(int argc, VALUE* argv, VALUE self) { VALUE io = Qnil; VALUE options = Qnil; if(argc == 0 || (argc == 1 && argv[0] == Qnil)) { /* Qnil */ } else if(argc == 1) { VALUE v = argv[0]; if(rb_type(v) == T_HASH) { options = v; } else { io = v; } } else if(argc == 2) { io = argv[0]; options = argv[1]; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(io)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); } PACKER(self, pk); if(io != Qnil || options != Qnil) { MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, options); } // TODO options return self; } static VALUE Packer_buffer(VALUE self) { PACKER(self, pk); return pk->buffer_ref; } static VALUE Packer_write(VALUE self, VALUE v) { PACKER(self, pk); msgpack_packer_write_value(pk, v); return self; } static VALUE Packer_write_nil(VALUE self) { PACKER(self, pk); msgpack_packer_write_nil(pk); return self; } static VALUE Packer_write_array_header(VALUE self, VALUE n) { PACKER(self, pk); msgpack_packer_write_array_header(pk, NUM2UINT(n)); return self; } static VALUE Packer_write_map_header(VALUE self, VALUE n) { PACKER(self, pk); msgpack_packer_write_map_header(pk, NUM2UINT(n)); return self; } static VALUE Packer_flush(VALUE self) { PACKER(self, pk); msgpack_buffer_flush(PACKER_BUFFER_(pk)); return self; } static VALUE Packer_clear(VALUE self) { PACKER(self, pk); msgpack_buffer_clear(PACKER_BUFFER_(pk)); return Qnil; } static VALUE Packer_size(VALUE self) { PACKER(self, pk); size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk)); return SIZET2NUM(size); } static VALUE Packer_empty_p(VALUE self) { PACKER(self, pk); if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) { return Qtrue; } else { return Qfalse; } } static VALUE Packer_to_str(VALUE self) { PACKER(self, pk); return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk)); } static VALUE Packer_to_a(VALUE self) { PACKER(self, pk); return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk)); } static VALUE Packer_write_to(VALUE self, VALUE io) { PACKER(self, pk); size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true); return ULONG2NUM(sz); } //static VALUE Packer_append(VALUE self, VALUE string_or_buffer) //{ // PACKER(self, pk); // // // TODO if string_or_buffer is a Buffer // VALUE string = string_or_buffer; // // msgpack_buffer_append_string(PACKER_BUFFER_(pk), string); // // return self; //} VALUE MessagePack_pack(int argc, VALUE* argv) { // TODO options VALUE v; VALUE io = Qnil; switch(argc) { case 2: io = argv[1]; /* pass-through */ case 1: v = argv[0]; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc); } VALUE self = Packer_alloc(cMessagePack_Packer); PACKER(self, pk); //msgpack_packer_reset(s_packer); //msgpack_buffer_reset_io(PACKER_BUFFER_(s_packer)); if(io != Qnil) { MessagePack_Buffer_initialize(PACKER_BUFFER_(pk), io, Qnil); } msgpack_packer_write_value(pk, v); VALUE retval; if(io != Qnil) { msgpack_buffer_flush(PACKER_BUFFER_(pk)); retval = Qnil; } else { retval = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk)); } msgpack_buffer_clear(PACKER_BUFFER_(pk)); /* to free rmem before GC */ #ifdef RB_GC_GUARD /* This prevents compilers from optimizing out the `self` variable * from stack. Otherwise GC free()s it. */ RB_GC_GUARD(self); #endif return retval; } static VALUE MessagePack_dump_module_method(int argc, VALUE* argv, VALUE mod) { UNUSED(mod); return MessagePack_pack(argc, argv); } static VALUE MessagePack_pack_module_method(int argc, VALUE* argv, VALUE mod) { UNUSED(mod); return MessagePack_pack(argc, argv); } void MessagePack_Packer_module_init(VALUE mMessagePack) { s_to_msgpack = rb_intern("to_cbor"); s_write = rb_intern("write"); msgpack_packer_static_init(); cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject); rb_define_alloc_func(cMessagePack_Packer, Packer_alloc); rb_define_method(cMessagePack_Packer, "initialize", Packer_initialize, -1); rb_define_method(cMessagePack_Packer, "buffer", Packer_buffer, 0); rb_define_method(cMessagePack_Packer, "write", Packer_write, 1); rb_define_alias(cMessagePack_Packer, "pack", "write"); rb_define_method(cMessagePack_Packer, "write_nil", Packer_write_nil, 0); rb_define_method(cMessagePack_Packer, "write_array_header", Packer_write_array_header, 1); rb_define_method(cMessagePack_Packer, "write_map_header", Packer_write_map_header, 1); rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0); /* delegation methods */ rb_define_method(cMessagePack_Packer, "clear", Packer_clear, 0); rb_define_method(cMessagePack_Packer, "size", Packer_size, 0); rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0); rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1); rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0); rb_define_alias(cMessagePack_Packer, "to_s", "to_str"); rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0); //rb_define_method(cMessagePack_Packer, "append", Packer_append, 1); //rb_define_alias(cMessagePack_Packer, "<<", "append"); //s_packer_value = Packer_alloc(cMessagePack_Packer); //rb_gc_register_address(&s_packer_value); //Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer); /* MessagePack.pack(x) */ rb_define_module_function(mMessagePack, "pack", MessagePack_pack_module_method, -1); rb_define_module_function(mMessagePack, "encode", MessagePack_pack_module_method, -1); rb_define_module_function(mMessagePack, "dump", MessagePack_dump_module_method, -1); } cbor-0.5.9.8/ext/cbor/packer.c0000644000004100000410000001025314567454543016030 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "packer.h" #ifdef RUBINIUS static ID s_to_iter; static ID s_next; static ID s_key; static ID s_value; #endif void msgpack_packer_static_init() { #ifdef RUBINIUS s_to_iter = rb_intern("to_iter"); s_next = rb_intern("next"); s_key = rb_intern("key"); s_value = rb_intern("value"); #endif } void msgpack_packer_static_destroy() { } void msgpack_packer_init(msgpack_packer_t* pk) { memset(pk, 0, sizeof(msgpack_packer_t)); msgpack_buffer_init(PACKER_BUFFER_(pk)); pk->io = Qnil; } void msgpack_packer_destroy(msgpack_packer_t* pk) { msgpack_buffer_destroy(PACKER_BUFFER_(pk)); } void msgpack_packer_mark(msgpack_packer_t* pk) { rb_gc_mark(pk->io); /* See MessagePack_Buffer_wrap */ /* msgpack_buffer_mark(PACKER_BUFFER_(pk)); */ rb_gc_mark(pk->buffer_ref); } void msgpack_packer_reset(msgpack_packer_t* pk) { msgpack_buffer_clear(PACKER_BUFFER_(pk)); pk->io = Qnil; pk->io_write_all_method = 0; pk->buffer_ref = Qnil; } void msgpack_packer_write_array_value(msgpack_packer_t* pk, VALUE v) { /* actual return type of RARRAY_LEN is long */ unsigned long len = RARRAY_LEN(v); msgpack_packer_write_array_header(pk, len); unsigned long i; for(i=0; i < len; ++i) { VALUE e = rb_ary_entry(v, i); msgpack_packer_write_value(pk, e); } } static int write_hash_foreach(VALUE key, VALUE value, VALUE pk_value) { if (key == Qundef) { return ST_CONTINUE; } msgpack_packer_t* pk = (msgpack_packer_t*) pk_value; msgpack_packer_write_value(pk, key); msgpack_packer_write_value(pk, value); return ST_CONTINUE; } void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v) { /* actual return type of RHASH_SIZE is long (if SIZEOF_LONG == SIZEOF_VOIDP * or long long (if SIZEOF_LONG_LONG == SIZEOF_VOIDP. See st.h. */ unsigned long len = RHASH_SIZE(v); msgpack_packer_write_map_header(pk, len); #ifdef RUBINIUS VALUE iter = rb_funcall(v, s_to_iter, 0); VALUE entry = Qnil; while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) { VALUE key = rb_funcall(entry, s_key, 0); VALUE val = rb_funcall(entry, s_value, 0); write_hash_foreach(key, val, (VALUE) pk); } #else rb_hash_foreach(v, write_hash_foreach, (VALUE) pk); #endif } static void _msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v) { rb_funcall(v, pk->to_msgpack_method, 1, pk->to_msgpack_arg); } void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v) { switch(rb_type(v)) { case T_NIL: msgpack_packer_write_nil(pk); break; case T_TRUE: msgpack_packer_write_true(pk); break; case T_FALSE: msgpack_packer_write_false(pk); break; case T_FIXNUM: msgpack_packer_write_fixnum_value(pk, v); break; case T_SYMBOL: msgpack_packer_write_symbol_value(pk, v); break; case T_STRING: msgpack_packer_write_string_value(pk, v); break; case T_ARRAY: msgpack_packer_write_array_value(pk, v); break; case T_HASH: msgpack_packer_write_hash_value(pk, v); break; case T_BIGNUM: msgpack_packer_write_bignum_value(pk, v); break; case T_FLOAT: msgpack_packer_write_float_value(pk, v); break; default: _msgpack_packer_write_other_value(pk, v); } } cbor-0.5.9.8/ext/cbor/unpacker_class.c0000644000004100000410000002633314567454543017566 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "unpacker.h" #include "unpacker_class.h" #include "buffer_class.h" VALUE cMessagePack_Unpacker; //static VALUE s_unpacker_value; //static msgpack_unpacker_t* s_unpacker; static VALUE eUnpackError; static VALUE eMalformedFormatError; static VALUE eStackError; static VALUE eTypeError; #define UNPACKER(from, name) \ msgpack_unpacker_t *name = NULL; \ Data_Get_Struct(from, msgpack_unpacker_t, name); \ if(name == NULL) { \ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \ } static void Unpacker_free(msgpack_unpacker_t* uk) { if(uk == NULL) { return; } msgpack_unpacker_destroy(uk); xfree(uk); } static VALUE Unpacker_alloc(VALUE klass) { msgpack_unpacker_t* uk = ALLOC_N(msgpack_unpacker_t, 1); msgpack_unpacker_init(uk); VALUE self = Data_Wrap_Struct(klass, msgpack_unpacker_mark, Unpacker_free, uk); uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self); return self; } static VALUE Unpacker_initialize(int argc, VALUE* argv, VALUE self) { VALUE io = Qnil; VALUE options = Qnil; if(argc == 0 || (argc == 1 && argv[0] == Qnil)) { /* Qnil */ } else if(argc == 1) { VALUE v = argv[0]; if(rb_type(v) == T_HASH) { options = v; } else { io = v; } } else if(argc == 2) { io = argv[0]; options = argv[1]; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); } UNPACKER(self, uk); if(io != Qnil || options != Qnil) { MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, options); if (options != Qnil) { VALUE v; v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys"))); uk->keys_as_symbols = RTEST(v); } } // TODO options return self; } static void raise_unpacker_error(int r) { switch(r) { case PRIMITIVE_EOF: rb_raise(rb_eEOFError, "end of buffer reached"); case PRIMITIVE_INVALID_BYTE: rb_raise(eMalformedFormatError, "invalid byte"); case PRIMITIVE_STACK_TOO_DEEP: rb_raise(eStackError, "stack level too deep"); case PRIMITIVE_UNEXPECTED_TYPE: rb_raise(eTypeError, "unexpected type"); default: rb_raise(eUnpackError, "logically unknown error %d", r); } } static VALUE Unpacker_buffer(VALUE self) { UNPACKER(self, uk); return uk->buffer_ref; } static VALUE Unpacker_read(VALUE self) { UNPACKER(self, uk); int r = msgpack_unpacker_read(uk, 0); if(r < 0) { raise_unpacker_error(r); } return msgpack_unpacker_get_last_object(uk); } static VALUE Unpacker_skip(VALUE self) { UNPACKER(self, uk); int r = msgpack_unpacker_skip(uk, 0); if(r < 0) { raise_unpacker_error(r); } return Qnil; } static VALUE Unpacker_skip_nil(VALUE self) { UNPACKER(self, uk); int r = msgpack_unpacker_skip_nil(uk); if(r < 0) { raise_unpacker_error(r); } if(r) { return Qtrue; } return Qfalse; } static VALUE Unpacker_read_array_header(VALUE self) { UNPACKER(self, uk); uint64_t size; int r = msgpack_unpacker_read_array_header(uk, &size); if(r < 0) { raise_unpacker_error(r); } return rb_ull2inum(size); } static VALUE Unpacker_read_map_header(VALUE self) { UNPACKER(self, uk); uint64_t size; int r = msgpack_unpacker_read_map_header(uk, &size); if(r < 0) { raise_unpacker_error((int)r); } return rb_ull2inum(size); } #if 0 static VALUE Unpacker_peek_next_type(VALUE self) { UNPACKER(self, uk); int r = msgpack_unpacker_peek_next_object_type(uk); if(r < 0) { raise_unpacker_error(r); } switch((enum msgpack_unpacker_object_type) r) { case TYPE_NIL: return rb_intern("nil"); case TYPE_BOOLEAN: return rb_intern("boolean"); case TYPE_INTEGER: return rb_intern("integer"); case TYPE_FLOAT: return rb_intern("float"); case TYPE_RAW: return rb_intern("raw"); case TYPE_ARRAY: return rb_intern("array"); case TYPE_MAP: return rb_intern("map"); default: rb_raise(eUnpackError, "logically unknown type %d", r); } } #endif static VALUE Unpacker_feed(VALUE self, VALUE data) { UNPACKER(self, uk); StringValue(data); msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data); return self; } static VALUE Unpacker_each_impl(VALUE self) { UNPACKER(self, uk); while(true) { int r = msgpack_unpacker_read(uk, 0); if(r < 0) { if(r == PRIMITIVE_EOF) { return Qnil; } raise_unpacker_error(r); } VALUE v = msgpack_unpacker_get_last_object(uk); #ifdef JRUBY /* TODO JRuby's rb_yield behaves differently from Ruby 1.9.3 or Rubinius. */ if(rb_type(v) == T_ARRAY) { v = rb_ary_new3(1, v); } #endif rb_yield(v); } } static VALUE Unpacker_rescue_EOFError(VALUE self, VALUE error) { UNUSED(self); UNUSED(error); return Qnil; } static VALUE Unpacker_each(VALUE self) { UNPACKER(self, uk); #ifdef RETURN_ENUMERATOR RETURN_ENUMERATOR(self, 0, 0); #endif if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) { /* rescue EOFError only if io is set */ return rb_rescue2(Unpacker_each_impl, self, Unpacker_rescue_EOFError, self, rb_eEOFError, NULL); } else { return Unpacker_each_impl(self); } } static VALUE Unpacker_feed_each(VALUE self, VALUE data) { // TODO optimize Unpacker_feed(self, data); return Unpacker_each(self); } static VALUE Unpacker_reset(VALUE self) { UNPACKER(self, uk); msgpack_unpacker_reset(uk); return Qnil; } VALUE MessagePack_unpack(int argc, VALUE* argv) { VALUE src; VALUE options = Qnil; bool keys_as_symbols = false; switch(argc) { case 2: options = argv[1]; /* Experimental! */ if (options == ID2SYM(rb_intern("keys_as_symbols"))) /* backward compat */ keys_as_symbols = true; else if (options != Qnil) { VALUE v; if (!RB_TYPE_P(options, T_HASH)) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options)); } v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys"))); keys_as_symbols = RTEST(v); } /* fall through */ case 1: src = argv[0]; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } VALUE io = Qnil; if(rb_type(src) != T_STRING) { io = src; src = Qnil; } VALUE self = Unpacker_alloc(cMessagePack_Unpacker); UNPACKER(self, uk); //msgpack_unpacker_reset(s_unpacker); //msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker)); /* prefer reference than copying */ msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0); uk->keys_as_symbols = keys_as_symbols; if(io != Qnil) { MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, Qnil); } if(src != Qnil) { /* prefer reference than copying; see MessagePack_Unpacker_module_init */ msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src); } int r = msgpack_unpacker_read(uk, 0); if(r < 0) { raise_unpacker_error(r); } /* raise if extra bytes follow */ if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)) > 0) { rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object"); } #ifdef RB_GC_GUARD /* This prevents compilers from optimizing out the `self` variable * from stack. Otherwise GC free()s it. */ RB_GC_GUARD(self); #endif return msgpack_unpacker_get_last_object(uk); } static VALUE MessagePack_load_module_method(int argc, VALUE* argv, VALUE mod) { UNUSED(mod); return MessagePack_unpack(argc, argv); } static VALUE MessagePack_unpack_module_method(int argc, VALUE* argv, VALUE mod) { UNUSED(mod); return MessagePack_unpack(argc, argv); } void MessagePack_Unpacker_module_init(VALUE mMessagePack) { msgpack_unpacker_static_init(); cMessagePack_Unpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject); eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError); eMalformedFormatError = rb_define_class_under(mMessagePack, "MalformedFormatError", eUnpackError); eStackError = rb_define_class_under(mMessagePack, "StackError", eUnpackError); eTypeError = rb_define_class_under(mMessagePack, "TypeError", rb_eStandardError); rb_define_alloc_func(cMessagePack_Unpacker, Unpacker_alloc); rb_define_method(cMessagePack_Unpacker, "initialize", Unpacker_initialize, -1); rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0); rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0); rb_define_alias(cMessagePack_Unpacker, "unpack", "read"); rb_define_method(cMessagePack_Unpacker, "skip", Unpacker_skip, 0); rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0); rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0); rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0); //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1); rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0); rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1); rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0); //s_unpacker_value = Unpacker_alloc(cMessagePack_Unpacker); //rb_gc_register_address(&s_unpacker_value); //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker); /* prefer reference than copying */ //msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0); /* MessagePack.unpack(x) */ rb_define_module_function(mMessagePack, "load", MessagePack_load_module_method, -1); rb_define_module_function(mMessagePack, "unpack", MessagePack_unpack_module_method, -1); rb_define_module_function(mMessagePack, "decode", MessagePack_unpack_module_method, -1); } cbor-0.5.9.8/ext/cbor/buffer_class.c0000644000004100000410000003030314567454543017217 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "compat.h" #include "ruby.h" #include "buffer.h" #include "buffer_class.h" VALUE cMessagePack_Buffer; static ID s_read; static ID s_readpartial; static ID s_write; static ID s_append; static ID s_close; #define BUFFER(from, name) \ msgpack_buffer_t *name = NULL; \ Data_Get_Struct(from, msgpack_buffer_t, name); \ if(name == NULL) { \ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \ } #define CHECK_STRING_TYPE(value) \ value = rb_check_string_type(value); \ if( NIL_P(value) ) { \ rb_raise(rb_eTypeError, "instance of String needed"); \ } static void Buffer_free(void* data) { if(data == NULL) { return; } msgpack_buffer_t* b = (msgpack_buffer_t*) data; msgpack_buffer_destroy(b); xfree(b); } static VALUE Buffer_alloc(VALUE klass) { msgpack_buffer_t* b = ALLOC_N(msgpack_buffer_t, 1); msgpack_buffer_init(b); return Data_Wrap_Struct(klass, msgpack_buffer_mark, Buffer_free, b); } static ID get_partial_read_method(VALUE io) { if(rb_respond_to(io, s_readpartial)) { return s_readpartial; } else if(rb_respond_to(io, s_read)) { return s_read; } else { return s_read; } } static ID get_write_all_method(VALUE io) { if(rb_respond_to(io, s_write)) { return s_write; } else if(rb_respond_to(io, s_append)) { return s_append; } else { return s_write; } } void MessagePack_Buffer_initialize(msgpack_buffer_t* b, VALUE io, VALUE options) { b->io = io; b->io_partial_read_method = get_partial_read_method(io); b->io_write_all_method = get_write_all_method(io); if(options != Qnil) { VALUE v; v = rb_hash_aref(options, ID2SYM(rb_intern("read_reference_threshold"))); if(v != Qnil) { msgpack_buffer_set_read_reference_threshold(b, NUM2ULONG(v)); } v = rb_hash_aref(options, ID2SYM(rb_intern("write_reference_threshold"))); if(v != Qnil) { msgpack_buffer_set_write_reference_threshold(b, NUM2ULONG(v)); } v = rb_hash_aref(options, ID2SYM(rb_intern("io_buffer_size"))); if(v != Qnil) { msgpack_buffer_set_io_buffer_size(b, NUM2ULONG(v)); } } } VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner) { b->owner = owner; return Data_Wrap_Struct(cMessagePack_Buffer, msgpack_buffer_mark, NULL, b); } static VALUE Buffer_initialize(int argc, VALUE* argv, VALUE self) { VALUE io = Qnil; VALUE options = Qnil; if(argc == 0 || (argc == 1 && argv[0] == Qnil)) { /* Qnil */ } else if(argc == 1) { VALUE v = argv[0]; if(rb_type(v) == T_HASH) { options = v; } else { io = v; } } else if(argc == 2) { io = argv[0]; options = argv[1]; if(rb_type(options) != T_HASH) { rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(io)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); } BUFFER(self, b); MessagePack_Buffer_initialize(b, io, options); return self; } static VALUE Buffer_clear(VALUE self) { BUFFER(self, b); msgpack_buffer_clear(b); return Qnil; } static VALUE Buffer_size(VALUE self) { BUFFER(self, b); size_t size = msgpack_buffer_all_readable_size(b); return SIZET2NUM(size); } static VALUE Buffer_empty_p(VALUE self) { BUFFER(self, b); if(msgpack_buffer_top_readable_size(b) == 0) { return Qtrue; } else { return Qfalse; } } static VALUE Buffer_write(VALUE self, VALUE string_or_buffer) { BUFFER(self, b); VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer StringValue(string); size_t length = msgpack_buffer_append_string(b, string); return SIZET2NUM(length); } static VALUE Buffer_append(VALUE self, VALUE string_or_buffer) { BUFFER(self, b); VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer StringValue(string); msgpack_buffer_append_string(b, string); return self; } #define MAKE_EMPTY_STRING(orig) \ if(orig == Qnil) { \ orig = rb_str_buf_new(0); \ } else { \ rb_str_resize(orig, 0); \ } static VALUE read_until_eof_rescue(VALUE args) { msgpack_buffer_t* b = (void*) ((VALUE*) args)[0]; VALUE out = ((VALUE*) args)[1]; unsigned long max = ((VALUE*) args)[2]; size_t* sz = (void*) ((VALUE*) args)[3]; while(true) { size_t rl; if(max == 0) { if(out == Qnil) { rl = msgpack_buffer_skip(b, b->io_buffer_size); } else { rl = msgpack_buffer_read_to_string(b, out, b->io_buffer_size); } if(rl == 0) { break; } *sz += rl; } else { if(out == Qnil) { rl = msgpack_buffer_skip(b, max); } else { rl = msgpack_buffer_read_to_string(b, out, max); } if(rl == 0) { break; } *sz += rl; if(max <= rl) { break; } else { max -= rl; } } } return Qnil; } static VALUE read_until_eof_error(VALUE args, VALUE error) { /* ignore EOFError */ UNUSED(args); UNUSED(error); return Qnil; } static inline size_t read_until_eof(msgpack_buffer_t* b, VALUE out, unsigned long max) { if(msgpack_buffer_has_io(b)) { size_t sz = 0; VALUE args[4] = { (VALUE)(void*) b, out, (VALUE) max, (VALUE)(void*) &sz }; rb_rescue2(read_until_eof_rescue, (VALUE)(void*) args, read_until_eof_error, (VALUE)(void*) args, rb_eEOFError, NULL); return sz; } else { if(max == 0) { max = ULONG_MAX; } if(out == Qnil) { return msgpack_buffer_skip_nonblock(b, max); } else { return msgpack_buffer_read_to_string_nonblock(b, out, max); } } } static inline VALUE read_all(msgpack_buffer_t* b, VALUE out) { #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE if(out == Qnil && !msgpack_buffer_has_io(b)) { /* same as to_s && clear; optimize */ VALUE str = msgpack_buffer_all_as_string(b); msgpack_buffer_clear(b); return str; } #endif MAKE_EMPTY_STRING(out); read_until_eof(b, out, 0); return out; } static VALUE Buffer_skip(VALUE self, VALUE sn) { BUFFER(self, b); unsigned long n = FIX2ULONG(sn); /* do nothing */ if(n == 0) { return ULONG2NUM(0); } size_t sz = read_until_eof(b, Qnil, n); return ULONG2NUM(sz); } static VALUE Buffer_skip_all(VALUE self, VALUE sn) { BUFFER(self, b); unsigned long n = FIX2ULONG(sn); /* do nothing */ if(n == 0) { return self; } if(!msgpack_buffer_ensure_readable(b, n)) { rb_raise(rb_eEOFError, "end of buffer reached"); } msgpack_buffer_skip_nonblock(b, n); return self; } static VALUE Buffer_read_all(int argc, VALUE* argv, VALUE self) { VALUE out = Qnil; unsigned long n = 0; bool all = false; switch(argc) { case 2: out = argv[1]; /* pass through */ case 1: n = FIX2ULONG(argv[0]); break; case 0: all = true; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); } BUFFER(self, b); if(out != Qnil) { CHECK_STRING_TYPE(out); } if(all) { return read_all(b, out); } if(n == 0) { /* do nothing */ MAKE_EMPTY_STRING(out); return out; } if(!msgpack_buffer_ensure_readable(b, n)) { rb_raise(rb_eEOFError, "end of buffer reached"); } MAKE_EMPTY_STRING(out); msgpack_buffer_read_to_string_nonblock(b, out, n); return out; } static VALUE Buffer_read(int argc, VALUE* argv, VALUE self) { VALUE out = Qnil; unsigned long n = -1; bool all = false; switch(argc) { case 2: out = argv[1]; /* pass through */ case 1: n = FIX2ULONG(argv[0]); break; case 0: all = true; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); } BUFFER(self, b); if(out != Qnil) { CHECK_STRING_TYPE(out); } if(all) { return read_all(b, out); } if(n == 0) { /* do nothing */ MAKE_EMPTY_STRING(out); return out; } #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE if(!msgpack_buffer_has_io(b) && out == Qnil && msgpack_buffer_all_readable_size(b) <= n) { /* same as to_s && clear; optimize */ VALUE str = msgpack_buffer_all_as_string(b); msgpack_buffer_clear(b); if(RSTRING_LEN(str) == 0) { return Qnil; } else { return str; } } #endif MAKE_EMPTY_STRING(out); read_until_eof(b, out, n); if(RSTRING_LEN(out) == 0) { return Qnil; } else { return out; } } static VALUE Buffer_to_str(VALUE self) { BUFFER(self, b); return msgpack_buffer_all_as_string(b); } static VALUE Buffer_to_a(VALUE self) { BUFFER(self, b); return msgpack_buffer_all_as_string_array(b); } static VALUE Buffer_flush(VALUE self) { BUFFER(self, b); msgpack_buffer_flush(b); return self; } static VALUE Buffer_io(VALUE self) { BUFFER(self, b); return b->io; } static VALUE Buffer_close(VALUE self) { BUFFER(self, b); if(b->io != Qnil) { return rb_funcall(b->io, s_close, 0); } return Qnil; } static VALUE Buffer_write_to(VALUE self, VALUE io) { BUFFER(self, b); size_t sz = msgpack_buffer_flush_to_io(b, io, s_write, true); return ULONG2NUM(sz); } void MessagePack_Buffer_module_init(VALUE mMessagePack) { s_read = rb_intern("read"); s_readpartial = rb_intern("readpartial"); s_write = rb_intern("write"); s_append = rb_intern("<<"); s_close = rb_intern("close"); msgpack_buffer_static_init(); cMessagePack_Buffer = rb_define_class_under(mMessagePack, "Buffer", rb_cObject); rb_define_alloc_func(cMessagePack_Buffer, Buffer_alloc); rb_define_method(cMessagePack_Buffer, "initialize", Buffer_initialize, -1); rb_define_method(cMessagePack_Buffer, "clear", Buffer_clear, 0); rb_define_method(cMessagePack_Buffer, "size", Buffer_size, 0); rb_define_method(cMessagePack_Buffer, "empty?", Buffer_empty_p, 0); rb_define_method(cMessagePack_Buffer, "write", Buffer_write, 1); rb_define_method(cMessagePack_Buffer, "<<", Buffer_append, 1); rb_define_method(cMessagePack_Buffer, "skip", Buffer_skip, 1); rb_define_method(cMessagePack_Buffer, "skip_all", Buffer_skip_all, 1); rb_define_method(cMessagePack_Buffer, "read", Buffer_read, -1); rb_define_method(cMessagePack_Buffer, "read_all", Buffer_read_all, -1); rb_define_method(cMessagePack_Buffer, "io", Buffer_io, 0); rb_define_method(cMessagePack_Buffer, "flush", Buffer_flush, 0); rb_define_method(cMessagePack_Buffer, "close", Buffer_close, 0); rb_define_method(cMessagePack_Buffer, "write_to", Buffer_write_to, 1); rb_define_method(cMessagePack_Buffer, "to_str", Buffer_to_str, 0); rb_define_alias(cMessagePack_Buffer, "to_s", "to_str"); rb_define_method(cMessagePack_Buffer, "to_a", Buffer_to_a, 0); } cbor-0.5.9.8/ext/cbor/sysdep.h0000644000004100000410000000736614567454543016112 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_SYSDEP_H__ #define MSGPACK_RUBY_SYSDEP_H__ #include "renamer.h" #include "sysdep_types.h" #include "sysdep_endian.h" #define UNUSED(var) ((void)var) #ifdef __LITTLE_ENDIAN__ /* _msgpack_be16 */ #ifdef _WIN32 # if defined(ntohs) # define _msgpack_be16(x) ntohs(x) # elif defined(_byteswap_ushort) || (defined(_MSC_VER) && _MSC_VER >= 1400) # define _msgpack_be16(x) ((uint16_t)_byteswap_ushort((unsigned short)x)) # else # define _msgpack_be16(x) ( \ ((((uint16_t)x) << 8) & 0x0000ff00U ) | \ ((((uint16_t)x) >> 8) & 0x000000ffU ) ) # endif #else # define _msgpack_be16(x) ntohs(x) #endif /* _msgpack_be32 */ #ifdef _WIN32 # if defined(ntohl) # define _msgpack_be32(x) ntohl(x) # elif defined(_byteswap_ulong) || (defined(_MSC_VER) && _MSC_VER >= 1400) # define _msgpack_be32(x) ((uint32_t)_byteswap_ulong((unsigned long)x)) # else # define _msgpack_be32(x) \ ( ((((uint32_t)x) << 24) ) | \ ((((uint32_t)x) << 8) & 0x00ff0000U ) | \ ((((uint32_t)x) >> 8) & 0x0000ff00U ) | \ ((((uint32_t)x) >> 24) ) ) # endif #else # define _msgpack_be32(x) ntohl(x) #endif /* _msgpack_be64 */ #if defined(_byteswap_uint64) || (defined(_MSC_VER) && _MSC_VER >= 1400) # define _msgpack_be64(x) (_byteswap_uint64(x)) #elif defined(bswap_64) # define _msgpack_be64(x) bswap_64(x) #elif defined(__DARWIN_OSSwapInt64) # define _msgpack_be64(x) __DARWIN_OSSwapInt64(x) #else #define _msgpack_be64(x) \ ( ((((uint64_t)x) << 56) ) | \ ((((uint64_t)x) << 40) & 0x00ff000000000000ULL ) | \ ((((uint64_t)x) << 24) & 0x0000ff0000000000ULL ) | \ ((((uint64_t)x) << 8) & 0x000000ff00000000ULL ) | \ ((((uint64_t)x) >> 8) & 0x00000000ff000000ULL ) | \ ((((uint64_t)x) >> 24) & 0x0000000000ff0000ULL ) | \ ((((uint64_t)x) >> 40) & 0x000000000000ff00ULL ) | \ ((((uint64_t)x) >> 56) ) ) #endif #else /* big endian */ #define _msgpack_be16(x) (x) #define _msgpack_be32(x) (x) #define _msgpack_be64(x) (x) #endif /* _msgpack_be_float */ #define _msgpack_be_float(x) _msgpack_be32(x) /* _msgpack_be_double */ #if defined(__arm__) && !(__ARM_EABI__) /* ARM OABI */ #define _msgpack_be_double(x) \ ( (((x) & 0xFFFFFFFFUL) << 32UL) | ((x) >> 32UL) ) #else /* the other ABI */ #define _msgpack_be_double(x) _msgpack_be64(x) #endif /* _msgpack_bsp32 */ #if defined(_MSC_VER) #define _msgpack_bsp32(name, val) \ long name; \ _BitScanForward(&name, val) #else #define _msgpack_bsp32(name, val) \ int name = __builtin_ctz(val) /* TODO default impl for _msgpack_bsp32 */ #endif #ifndef HAVE_RB_INTEGER_UNPACK #if SIZEOF_BDIGITS == 2 #define NTOHBDIGIT _msgpack_be16 #elif SIZEOF_BDIGITS == 4 #define NTOHBDIGIT _msgpack_be32 #elif SIZEOF_BDIGITS == 8 #define NTOHBDIGIT _msgpack_be64 #else #error this size of bignum digits SIZEOF_BDIGITS not implemented #endif #endif #endif cbor-0.5.9.8/ext/cbor/unpacker_class.h0000644000004100000410000000210014567454543017555 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_UNPACKER_CLASS_H__ #define MSGPACK_RUBY_UNPACKER_CLASS_H__ #include "unpacker.h" extern VALUE cMessagePack_Unpacker; void MessagePack_Unpacker_module_init(VALUE mMessagePack); VALUE MessagePack_unpack(int argc, VALUE* argv); #endif cbor-0.5.9.8/ext/cbor/renamer.h0000644000004100000410000000626614567454543016232 0ustar www-datawww-data#define MessagePack_Buffer_initialize CBOR_Buffer_initialize #define MessagePack_Buffer_module_init CBOR_Buffer_module_init #define MessagePack_Buffer_wrap CBOR_Buffer_wrap #define MessagePack_Packer_module_init CBOR_Packer_module_init #define MessagePack_Unpacker_module_init CBOR_Unpacker_module_init #define MessagePack_core_ext_module_init CBOR_core_ext_module_init #define MessagePack_pack CBOR_pack #define MessagePack_unpack CBOR_unpack #define _msgpack_buffer_append_long_string _CBOR_buffer_append_long_string #define _msgpack_buffer_expand _CBOR_buffer_expand #define _msgpack_buffer_feed_from_io _CBOR_buffer_feed_from_io #define _msgpack_buffer_read_all2 _CBOR_buffer_read_all2 #define _msgpack_buffer_read_from_io_to_string _CBOR_buffer_read_from_io_to_string #define _msgpack_buffer_shift_chunk _CBOR_buffer_shift_chunk #define _msgpack_buffer_skip_from_io _CBOR_buffer_skip_from_io #define _msgpack_rmem_alloc2 _CBOR_rmem_alloc2 #define _msgpack_rmem_chunk_free _CBOR_rmem_chunk_free #define cMessagePack_Buffer cCBOR_Buffer #define cMessagePack_Packer cCBOR_Packer #define cMessagePack_Unpacker cCBOR_Unpacker #define msgpack_buffer_all_as_string CBOR_buffer_all_as_string #define msgpack_buffer_all_as_string_array CBOR_buffer_all_as_string_array #define msgpack_buffer_all_readable_size CBOR_buffer_all_readable_size #define msgpack_buffer_clear CBOR_buffer_clear #define msgpack_buffer_destroy CBOR_buffer_destroy #define msgpack_buffer_flush_to_io CBOR_buffer_flush_to_io #define msgpack_buffer_init CBOR_buffer_init #define msgpack_buffer_mark CBOR_buffer_mark #define msgpack_buffer_read_nonblock CBOR_buffer_read_nonblock #define msgpack_buffer_read_to_string_nonblock CBOR_buffer_read_to_string_nonblock #define msgpack_buffer_static_destroy CBOR_buffer_static_destroy #define msgpack_buffer_static_init CBOR_buffer_static_init #define msgpack_packer_destroy CBOR_packer_destroy #define msgpack_packer_init CBOR_packer_init #define msgpack_packer_mark CBOR_packer_mark #define msgpack_packer_reset CBOR_packer_reset #define msgpack_packer_static_destroy CBOR_packer_static_destroy #define msgpack_packer_static_init CBOR_packer_static_init #define msgpack_packer_write_array_value CBOR_packer_write_array_value #define msgpack_packer_write_hash_value CBOR_packer_write_hash_value #define msgpack_packer_write_value CBOR_packer_write_value #define msgpack_rmem_destroy CBOR_rmem_destroy #define msgpack_rmem_init CBOR_rmem_init #define msgpack_unpacker_destroy CBOR_unpacker_destroy #define msgpack_unpacker_init CBOR_unpacker_init #define msgpack_unpacker_mark CBOR_unpacker_mark #define msgpack_unpacker_peek_next_object_type CBOR_unpacker_peek_next_object_type #define msgpack_unpacker_read CBOR_unpacker_read #define msgpack_unpacker_read_array_header CBOR_unpacker_read_array_header #define msgpack_unpacker_read_container_header CBOR_unpacker_read_container_header #define msgpack_unpacker_read_map_header CBOR_unpacker_read_map_header #define msgpack_unpacker_reset CBOR_unpacker_reset #define msgpack_unpacker_skip CBOR_unpacker_skip #define msgpack_unpacker_skip_nil CBOR_unpacker_skip_nil #define msgpack_unpacker_static_destroy CBOR_unpacker_static_destroy #define msgpack_unpacker_static_init CBOR_unpacker_static_init cbor-0.5.9.8/ext/cbor/core_ext.h0000644000004100000410000000171114567454543016377 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_CORE_EXT_H__ #define MSGPACK_RUBY_CORE_EXT_H__ #include "compat.h" void MessagePack_core_ext_module_init(); #endif cbor-0.5.9.8/ext/cbor/buffer.c0000644000004100000410000004336114567454543016042 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "buffer.h" #include "rmem.h" #ifdef COMPAT_HAVE_ENCODING /* see compat.h*/ int s_enc_ascii8bit; int s_enc_usascii; int s_enc_utf8; VALUE s_enc_utf8_value; #endif #ifndef HAVE_RB_STR_REPLACE static ID s_replace; #endif #ifndef DISABLE_RMEM static msgpack_rmem_t s_rmem; #endif void msgpack_buffer_static_init() { #ifndef DISABLE_RMEM msgpack_rmem_init(&s_rmem); #endif #ifndef HAVE_RB_STR_REPLACE s_replace = rb_intern("replace"); #endif #ifdef COMPAT_HAVE_ENCODING s_enc_ascii8bit = rb_ascii8bit_encindex(); s_enc_usascii = rb_usascii_encindex(); s_enc_utf8 = rb_utf8_encindex(); s_enc_utf8_value = rb_enc_from_encoding(rb_utf8_encoding()); #endif } void msgpack_buffer_static_destroy() { #ifndef DISABLE_RMEM msgpack_rmem_destroy(&s_rmem); #endif } void msgpack_buffer_init(msgpack_buffer_t* b) { memset(b, 0, sizeof(msgpack_buffer_t)); b->head = &b->tail; b->write_reference_threshold = MSGPACK_BUFFER_STRING_WRITE_REFERENCE_DEFAULT; b->read_reference_threshold = MSGPACK_BUFFER_STRING_READ_REFERENCE_DEFAULT; b->io_buffer_size = MSGPACK_BUFFER_IO_BUFFER_SIZE_DEFAULT; b->io = Qnil; b->io_buffer = Qnil; } static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c) { if(c->mem != NULL) { #ifndef DISABLE_RMEM if(!msgpack_rmem_free(&s_rmem, c->mem)) { free(c->mem); } /* no needs to update rmem_owner because chunks will not be * free()ed (left in free_list) and thus *rmem_owner is * always valid. */ #else free(c->mem); #endif } c->first = NULL; c->last = NULL; c->mem = NULL; } void msgpack_buffer_destroy(msgpack_buffer_t* b) { /* head is always available */ msgpack_buffer_chunk_t* c = b->head; while(c != &b->tail) { msgpack_buffer_chunk_t* n = c->next; _msgpack_buffer_chunk_destroy(c); free(c); c = n; } _msgpack_buffer_chunk_destroy(c); c = b->free_list; while(c != NULL) { msgpack_buffer_chunk_t* n = c->next; free(c); c = n; } } void msgpack_buffer_mark(msgpack_buffer_t* b) { /* head is always available */ msgpack_buffer_chunk_t* c = b->head; while(c != &b->tail) { rb_gc_mark(c->mapped_string); c = c->next; } rb_gc_mark(c->mapped_string); rb_gc_mark(b->io); rb_gc_mark(b->io_buffer); rb_gc_mark(b->owner); } bool _msgpack_buffer_shift_chunk(msgpack_buffer_t* b) { _msgpack_buffer_chunk_destroy(b->head); if(b->head == &b->tail) { /* list becomes empty. don't add head to free_list * because head should be always available */ b->tail_buffer_end = NULL; b->read_buffer = NULL; return false; } /* add head to free_list */ msgpack_buffer_chunk_t* next_head = b->head->next; b->head->next = b->free_list; b->free_list = b->head; b->head = next_head; b->read_buffer = next_head->first; return true; } void msgpack_buffer_clear(msgpack_buffer_t* b) { while(_msgpack_buffer_shift_chunk(b)) { ; } } size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string, size_t length) { size_t avail = msgpack_buffer_top_readable_size(b); #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE /* optimize */ if(length <= avail && RSTRING_LEN(string) == 0 && b->head->mapped_string != NO_MAPPED_STRING && length >= b->read_reference_threshold) { VALUE s = _msgpack_buffer_refer_head_mapped_string(b, length); #ifndef HAVE_RB_STR_REPLACE /* TODO MRI 1.8 */ rb_funcall(string, s_replace, 1, s); #else rb_str_replace(string, s); #endif /* here doesn't have to call ENCODING_SET because * encoding of s is always ASCII-8BIT */ _msgpack_buffer_consumed(b, length); return length; } #endif size_t const length_orig = length; while(true) { if(length <= avail) { rb_str_buf_cat(string, b->read_buffer, length); _msgpack_buffer_consumed(b, length); return length_orig; } rb_str_buf_cat(string, b->read_buffer, avail); length -= avail; if(!_msgpack_buffer_shift_chunk(b)) { return length_orig - length; } avail = msgpack_buffer_top_readable_size(b); } } size_t msgpack_buffer_read_nonblock(msgpack_buffer_t* b, char* buffer, size_t length) { /* buffer == NULL means skip */ size_t const length_orig = length; while(true) { size_t avail = msgpack_buffer_top_readable_size(b); if(length <= avail) { if(buffer != NULL) { memcpy(buffer, b->read_buffer, length); } _msgpack_buffer_consumed(b, length); return length_orig; } if(buffer != NULL) { memcpy(buffer, b->read_buffer, avail); buffer += avail; } length -= avail; if(!_msgpack_buffer_shift_chunk(b)) { return length_orig - length; } } } size_t msgpack_buffer_all_readable_size(const msgpack_buffer_t* b) { size_t sz = msgpack_buffer_top_readable_size(b); if(b->head == &b->tail) { return sz; } msgpack_buffer_chunk_t* c = b->head->next; while(true) { sz += c->last - c->first; if(c == &b->tail) { return sz; } c = c->next; } } bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length) { if(!msgpack_buffer_ensure_readable(b, length)) { return false; } msgpack_buffer_read_nonblock(b, buffer, length); return true; } static inline msgpack_buffer_chunk_t* _msgpack_buffer_alloc_new_chunk(msgpack_buffer_t* b) { msgpack_buffer_chunk_t* reuse = b->free_list; if(reuse == NULL) { return malloc(sizeof(msgpack_buffer_chunk_t)); } b->free_list = b->free_list->next; return reuse; } static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b) { if(b->head == &b->tail) { if(b->tail.first == NULL) { /* empty buffer */ return; } msgpack_buffer_chunk_t* nc = _msgpack_buffer_alloc_new_chunk(b); *nc = b->tail; b->head = nc; nc->next = &b->tail; } else { /* search node before tail */ msgpack_buffer_chunk_t* before_tail = b->head; while(before_tail->next != &b->tail) { before_tail = before_tail->next; } msgpack_buffer_chunk_t* nc = _msgpack_buffer_alloc_new_chunk(b); #ifndef DISABLE_RMEM #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT if(b->rmem_last == b->tail_buffer_end) { /* reuse unused rmem space */ size_t unused = b->tail_buffer_end - b->tail.last; b->rmem_last -= unused; } #endif #endif /* rebuild tail */ *nc = b->tail; before_tail->next = nc; nc->next = &b->tail; } } static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string) { VALUE mapped_string = rb_str_dup(string); #ifdef COMPAT_HAVE_ENCODING ENCODING_SET(mapped_string, s_enc_ascii8bit); #endif _msgpack_buffer_add_new_chunk(b); char* data = RSTRING_PTR(mapped_string); size_t length = RSTRING_LEN(mapped_string); b->tail.first = (char*) data; b->tail.last = (char*) data + length; b->tail.mapped_string = mapped_string; b->tail.mem = NULL; /* msgpack_buffer_writable_size should return 0 for mapped chunk */ b->tail_buffer_end = b->tail.last; /* consider read_buffer */ if(b->head == &b->tail) { b->read_buffer = b->tail.first; } } void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string) { size_t length = RSTRING_LEN(string); if(b->io != Qnil) { msgpack_buffer_flush(b); rb_funcall(b->io, b->io_write_all_method, 1, string); } else if(!STR_DUP_LIKELY_DOES_COPY(string)) { _msgpack_buffer_append_reference(b, string); } else { msgpack_buffer_append(b, RSTRING_PTR(string), length); } } static inline void* _msgpack_buffer_chunk_malloc( msgpack_buffer_t* b, msgpack_buffer_chunk_t* c, size_t required_size, size_t* allocated_size) { #ifndef DISABLE_RMEM if(required_size <= MSGPACK_RMEM_PAGE_SIZE) { #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT if((size_t)(b->rmem_end - b->rmem_last) < required_size) { #endif /* alloc new rmem page */ *allocated_size = MSGPACK_RMEM_PAGE_SIZE; char* buffer = msgpack_rmem_alloc(&s_rmem); c->mem = buffer; /* update rmem owner */ b->rmem_owner = &c->mem; b->rmem_last = b->rmem_end = buffer + MSGPACK_RMEM_PAGE_SIZE; return buffer; #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT } else { /* reuse unused rmem */ *allocated_size = (size_t)(b->rmem_end - b->rmem_last); char* buffer = b->rmem_last; b->rmem_last = b->rmem_end; /* update rmem owner */ c->mem = *b->rmem_owner; *b->rmem_owner = NULL; b->rmem_owner = &c->mem; return buffer; } #endif } #else if(required_size < 72) { required_size = 72; } #endif // TODO alignment? *allocated_size = required_size; void* mem = malloc(required_size); c->mem = mem; return mem; } static inline void* _msgpack_buffer_chunk_realloc( msgpack_buffer_t* b, msgpack_buffer_chunk_t* c, void* mem, size_t required_size, size_t* current_size) { if(mem == NULL) { return _msgpack_buffer_chunk_malloc(b, c, required_size, current_size); } size_t next_size = *current_size * 2; while(next_size < required_size) { next_size *= 2; } *current_size = next_size; mem = realloc(mem, next_size); c->mem = mem; return mem; } void _msgpack_buffer_expand(msgpack_buffer_t* b, const char* data, size_t length, bool flush_to_io) { if(flush_to_io && b->io != Qnil) { msgpack_buffer_flush(b); if(msgpack_buffer_writable_size(b) >= length) { /* data == NULL means ensure_writable */ if(data != NULL) { size_t tail_avail = msgpack_buffer_writable_size(b); memcpy(b->tail.last, data, length); b->tail.last += tail_avail; } return; } } /* data == NULL means ensure_writable */ if(data != NULL) { size_t tail_avail = msgpack_buffer_writable_size(b); memcpy(b->tail.last, data, tail_avail); b->tail.last += tail_avail; data += tail_avail; length -= tail_avail; } size_t capacity = b->tail.last - b->tail.first; /* can't realloc mapped chunk or rmem page */ if(b->tail.mapped_string != NO_MAPPED_STRING #ifndef DISABLE_RMEM || capacity <= MSGPACK_RMEM_PAGE_SIZE #endif ) { /* allocate new chunk */ _msgpack_buffer_add_new_chunk(b); char* mem = _msgpack_buffer_chunk_malloc(b, &b->tail, length, &capacity); char* last = mem; if(data != NULL) { memcpy(mem, data, length); last += length; } /* rebuild tail chunk */ b->tail.first = mem; b->tail.last = last; b->tail.mapped_string = NO_MAPPED_STRING; b->tail_buffer_end = mem + capacity; /* consider read_buffer */ if(b->head == &b->tail) { b->read_buffer = b->tail.first; } } else { /* realloc malloc()ed chunk or NULL */ size_t tail_filled = b->tail.last - b->tail.first; char* mem = _msgpack_buffer_chunk_realloc(b, &b->tail, b->tail.first, tail_filled+length, &capacity); char* last = mem + tail_filled; if(data != NULL) { memcpy(last, data, length); last += length; } /* consider read_buffer */ if(b->head == &b->tail) { size_t read_offset = b->read_buffer - b->head->first; b->read_buffer = mem + read_offset; } /* rebuild tail chunk */ b->tail.first = mem; b->tail.last = last; b->tail_buffer_end = mem + capacity; } } static inline VALUE _msgpack_buffer_head_chunk_as_string(msgpack_buffer_t* b) { size_t length = b->head->last - b->read_buffer; if(length == 0) { return rb_str_buf_new(0); } if(b->head->mapped_string != NO_MAPPED_STRING) { return _msgpack_buffer_refer_head_mapped_string(b, length); } return rb_str_new(b->read_buffer, length); } static inline VALUE _msgpack_buffer_chunk_as_string(msgpack_buffer_chunk_t* c) { size_t chunk_size = c->last - c->first; if(chunk_size == 0) { return rb_str_buf_new(0); } if(c->mapped_string != NO_MAPPED_STRING) { return rb_str_dup(c->mapped_string); } return rb_str_new(c->first, chunk_size); } VALUE msgpack_buffer_all_as_string(msgpack_buffer_t* b) { if(b->head == &b->tail) { return _msgpack_buffer_head_chunk_as_string(b); } size_t length = msgpack_buffer_all_readable_size(b); VALUE string = rb_str_new(NULL, length); char* buffer = RSTRING_PTR(string); size_t avail = msgpack_buffer_top_readable_size(b); memcpy(buffer, b->read_buffer, avail); buffer += avail; length -= avail; msgpack_buffer_chunk_t* c = b->head->next; while(true) { avail = c->last - c->first; memcpy(buffer, c->first, avail); if(length <= avail) { return string; } buffer += avail; length -= avail; c = c->next; } } VALUE msgpack_buffer_all_as_string_array(msgpack_buffer_t* b) { if(b->head == &b->tail) { VALUE s = msgpack_buffer_all_as_string(b); VALUE ary = rb_ary_new3(1, s); return ary; } /* TODO optimize ary construction */ VALUE ary = rb_ary_new(); VALUE s = _msgpack_buffer_head_chunk_as_string(b); rb_ary_push(ary, s); msgpack_buffer_chunk_t* c = b->head->next; while(true) { s = _msgpack_buffer_chunk_as_string(c); rb_ary_push(ary, s); if(c == &b->tail) { return ary; } c = c->next; } return ary; } size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method, bool consume) { if(msgpack_buffer_top_readable_size(b) == 0) { return 0; } VALUE s = _msgpack_buffer_head_chunk_as_string(b); rb_funcall(io, write_method, 1, s); size_t sz = RSTRING_LEN(s); if(consume) { while(_msgpack_buffer_shift_chunk(b)) { s = _msgpack_buffer_chunk_as_string(b->head); rb_funcall(io, write_method, 1, s); sz += RSTRING_LEN(s); } return sz; } else { if(b->head == &b->tail) { return sz; } msgpack_buffer_chunk_t* c = b->head->next; while(true) { s = _msgpack_buffer_chunk_as_string(c); rb_funcall(io, write_method, 1, s); sz += RSTRING_LEN(s); if(c == &b->tail) { return sz; } c = c->next; } } } size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b) { if(b->io_buffer == Qnil) { b->io_buffer = rb_funcall(b->io, b->io_partial_read_method, 1, LONG2NUM(b->io_buffer_size)); if(b->io_buffer == Qnil) { rb_raise(rb_eEOFError, "IO reached end of file"); } StringValue(b->io_buffer); } else { VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(b->io_buffer_size), b->io_buffer); if(ret == Qnil) { rb_raise(rb_eEOFError, "IO reached end of file"); } } size_t len = RSTRING_LEN(b->io_buffer); if(len == 0) { rb_raise(rb_eEOFError, "IO reached end of file"); } /* TODO zero-copy optimize? */ msgpack_buffer_append_nonblock(b, RSTRING_PTR(b->io_buffer), len); return len; } size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length) { if(RSTRING_LEN(string) == 0) { /* direct read */ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), string); if(ret == Qnil) { return 0; } return RSTRING_LEN(string); } /* copy via io_buffer */ if(b->io_buffer == Qnil) { b->io_buffer = rb_str_buf_new(0); } VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer); if(ret == Qnil) { return 0; } size_t rl = RSTRING_LEN(b->io_buffer); rb_str_buf_cat(string, (const void*)RSTRING_PTR(b->io_buffer), rl); return rl; } size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length) { if(b->io_buffer == Qnil) { b->io_buffer = rb_str_buf_new(0); } VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer); if(ret == Qnil) { return 0; } return RSTRING_LEN(b->io_buffer); } cbor-0.5.9.8/ext/cbor/core_ext.c0000644000004100000410000001360314567454543016375 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "core_ext.h" #include "packer.h" #include "packer_class.h" static inline VALUE delegete_to_pack(int argc, VALUE* argv, VALUE self) { if(argc == 0) { return MessagePack_pack(1, &self); } else if(argc == 1) { /* write to io */ VALUE argv2[2]; argv2[0] = self; argv2[1] = argv[0]; return MessagePack_pack(2, argv2); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); } } #define ENSURE_PACKER(argc, argv, packer, pk) \ if(argc != 1 || rb_class_of(argv[0]) != cMessagePack_Packer) { \ return delegete_to_pack(argc, argv, self); \ } \ VALUE packer = argv[0]; \ msgpack_packer_t *pk; \ Data_Get_Struct(packer, msgpack_packer_t, pk); static VALUE NilClass_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_nil(pk); return packer; } static VALUE TrueClass_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_true(pk); return packer; } static VALUE FalseClass_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_false(pk); return packer; } #ifdef RUBY_INTEGER_UNIFICATION static VALUE Integer_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); if (FIXNUM_P(self)) msgpack_packer_write_fixnum_value(pk, self); else msgpack_packer_write_bignum_value(pk, self); return packer; } #else static VALUE Fixnum_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_fixnum_value(pk, self); return packer; } static VALUE Bignum_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_bignum_value(pk, self); return packer; } #endif static VALUE Float_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_float_value(pk, self); return packer; } static VALUE String_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_string_value(pk, self); return packer; } static VALUE Array_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_array_value(pk, self); return packer; } static VALUE Hash_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_hash_value(pk, self); return packer; } static VALUE Symbol_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_symbol_value(pk, self); return packer; } static VALUE Simple_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_simple_value(pk, self); return packer; } static VALUE Tagged_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_tagged_value(pk, self); return packer; } static VALUE Regexp_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_processed_value(pk, self, rb_intern("source"), TAG_RE); return packer; } static VALUE URI_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_processed_value(pk, self, rb_intern("to_s"), TAG_URI); return packer; } static VALUE Time_to_msgpack(int argc, VALUE* argv, VALUE self) { ENSURE_PACKER(argc, argv, packer, pk); msgpack_packer_write_processed_value(pk, self, rb_intern("to_i"), TAG_TIME_EPOCH); return packer; } void MessagePack_core_ext_module_init() { rb_define_method(rb_cNilClass, "to_cbor", NilClass_to_msgpack, -1); rb_define_method(rb_cTrueClass, "to_cbor", TrueClass_to_msgpack, -1); rb_define_method(rb_cFalseClass, "to_cbor", FalseClass_to_msgpack, -1); #ifdef RUBY_INTEGER_UNIFICATION rb_define_method(rb_cInteger, "to_cbor", Integer_to_msgpack, -1); #else rb_define_method(rb_cFixnum, "to_cbor", Fixnum_to_msgpack, -1); rb_define_method(rb_cBignum, "to_cbor", Bignum_to_msgpack, -1); #endif rb_define_method(rb_cFloat, "to_cbor", Float_to_msgpack, -1); rb_define_method(rb_cString, "to_cbor", String_to_msgpack, -1); rb_define_method(rb_cArray, "to_cbor", Array_to_msgpack, -1); rb_define_method(rb_cHash, "to_cbor", Hash_to_msgpack, -1); rb_define_method(rb_cSymbol, "to_cbor", Symbol_to_msgpack, -1); rb_define_method(rb_cTime, "to_cbor", Time_to_msgpack, -1); rb_define_method(rb_cRegexp, "to_cbor", Regexp_to_msgpack, -1); if (rb_const_defined(rb_cObject, rb_intern("URI"))) { rb_define_method(rb_const_get(rb_cObject, rb_intern("URI")), "to_cbor", URI_to_msgpack, -1); } rb_define_method(rb_cCBOR_Simple, "to_cbor", Simple_to_msgpack, -1); rb_define_method(rb_cCBOR_Tagged, "to_cbor", Tagged_to_msgpack, -1); } cbor-0.5.9.8/ext/cbor/unpacker.h0000644000004100000410000000643714567454543016411 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_UNPACKER_H__ #define MSGPACK_RUBY_UNPACKER_H__ #include "buffer.h" #ifndef MSGPACK_UNPACKER_STACK_CAPACITY #define MSGPACK_UNPACKER_STACK_CAPACITY 128 #endif struct msgpack_unpacker_t; typedef struct msgpack_unpacker_t msgpack_unpacker_t; enum stack_type_t { STACK_TYPE_ARRAY, STACK_TYPE_MAP_KEY, STACK_TYPE_MAP_VALUE, STACK_TYPE_TAG, /* > TAG = indef */ STACK_TYPE_MAP_VALUE_INDEF, /* Cannot BREAK up to here */ STACK_TYPE_MAP_KEY_INDEF, STACK_TYPE_ARRAY_INDEF, STACK_TYPE_STRING_INDEF, }; typedef struct { size_t count; enum stack_type_t type; VALUE object; VALUE key; uint64_t tag; /* could be union... */ } msgpack_unpacker_stack_t; #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */ struct msgpack_unpacker_t { msgpack_buffer_t buffer; unsigned int head_byte; msgpack_unpacker_stack_t* stack; size_t stack_depth; size_t stack_capacity; VALUE last_object; VALUE reading_raw; size_t reading_raw_remaining; int textflag; bool keys_as_symbols; /* Experimental */ VALUE buffer_ref; }; #define UNPACKER_BUFFER_(uk) (&(uk)->buffer) enum msgpack_unpacker_object_type { TYPE_NIL = 0, TYPE_BOOLEAN, TYPE_INTEGER, TYPE_FLOAT, TYPE_RAW, TYPE_ARRAY, TYPE_MAP, }; void msgpack_unpacker_static_init(); void msgpack_unpacker_static_destroy(); void msgpack_unpacker_init(msgpack_unpacker_t* uk); void msgpack_unpacker_destroy(msgpack_unpacker_t* uk); void msgpack_unpacker_mark(msgpack_unpacker_t* uk); void msgpack_unpacker_reset(msgpack_unpacker_t* uk); /* error codes */ #define PRIMITIVE_CONTAINER_START 1 #define PRIMITIVE_OBJECT_COMPLETE 0 #define PRIMITIVE_EOF -1 #define PRIMITIVE_INVALID_BYTE -2 #define PRIMITIVE_STACK_TOO_DEEP -3 #define PRIMITIVE_UNEXPECTED_TYPE -4 #define PRIMITIVE_BREAK 2 int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth); int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth); static inline VALUE msgpack_unpacker_get_last_object(msgpack_unpacker_t* uk) { return uk->last_object; } int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk); int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk); int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint64_t* result_size); int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint64_t* result_size); #endif cbor-0.5.9.8/ext/cbor/buffer_class.h0000644000004100000410000000223114567454543017223 0ustar www-datawww-data/* * CBOR for Ruby * * Copyright (C) 2013 Carsten Bormann * * Licensed under the Apache License, Version 2.0 (the "License"). * * Based on: ***********/ /* * MessagePack for Ruby * * Copyright (C) 2008-2013 Sadayuki Furuhashi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSGPACK_RUBY_BUFFER_CLASS_H__ #define MSGPACK_RUBY_BUFFER_CLASS_H__ #include "buffer.h" extern VALUE cMessagePack_Buffer; void MessagePack_Buffer_module_init(VALUE mMessagePack); VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner); void MessagePack_Buffer_initialize(msgpack_buffer_t* b, VALUE io, VALUE options); #endif cbor-0.5.9.8/ext/cbor/extconf.rb0000644000004100000410000000162414567454543016414 0ustar www-datawww-datarequire 'mkmf' have_header("ruby/st.h") have_header("st.h") have_func("rb_str_replace", ["ruby.h"]) have_func("rb_big_new", ["ruby.h"]) have_func("rb_intern_str", ["ruby.h"]) have_func("rb_sym2str", ["ruby.h"]) have_func("rb_str_intern", ["ruby.h"]) have_func("rb_integer_unpack", ["ruby.h"]) $CFLAGS << %[ -I.. -Wall -O3 -g -std=c99] #$CFLAGS << %[ -DDISABLE_RMEM] #$CFLAGS << %[ -DDISABLE_RMEM_REUSE_INTERNAL_FRAGMENT] #$CFLAGS << %[ -DDISABLE_BUFFER_READ_REFERENCE_OPTIMIZE] #$CFLAGS << %[ -DDISABLE_BUFFER_READ_TO_S_OPTIMIZE] if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' # msgpack-ruby doesn't modify data came from RSTRING_PTR(str) $CFLAGS << %[ -DRSTRING_NOT_MODIFIED] # Rubinius C extensions don't grab GVL while rmem is not thread safe $CFLAGS << %[ -DDISABLE_RMEM] end if warnflags = CONFIG['warnflags'] warnflags.slice!(/ -Wdeclaration-after-statement/) end create_makefile('cbor/cbor') cbor-0.5.9.8/ChangeLog0000644000004100000410000000640414567454543014447 0ustar www-datawww-data2016-04-11 Carsten Bormann * 0.5.9.1: Fix WIN32 problem inherited from upstream 2014-12-13 Carsten Bormann * 0.5.9.0: Upstream fixes; prepare for Ruby 2.2 (use GC-able symbols for :keys_as_symbols, use rb_integer_pack if available) 2014-12-12 Carsten Bormann * 0.5.8.0: Upstream fixes (including {symbolize_keys: true} as an alternative for :keys_as_symbols); README updates. 2014-02-09 Carsten Bormann * 0.5.6.4: Add more checking for bare indefinite breaks and non-strings inside indefinite strings. 2013-08-17 Carsten Bormann * First version of CBOR variant of this code. 2013-09-23 version 0.5.6: * Fixed "can't modify frozen String" exception in Unpacker with ruby 2.1.0-dev * Getting work with Ruby v2.0 on Windows (Thank you @thegreendroid) * Fixed EOFError handling in Unpacker 2013-05-12 version 0.5.5: * Fixed SEGV problem in to_msgpack * Fixed a possible race condition in MessagePack.load when it loads data from IO * mingw32 package includes binary for ruby-2.0.0 2013-03-15 version 0.5.4: * Added missing MessagePack::Unpacker#reset method 2013-02-14 version 0.5.3: * Fixed segfault problem on Buffer#clear (reuse rmem internal fragment optimization) * Fixed segfault problem on Buffer (rmem free code) 2013-02-07 version 0.5.2: * Fixed invalid pack/unpack on 32bit architecture such as Win32 * Disable rmem on Rubinius because rmem is not thread safe 2012-12-23 version 0.5.1: * Fixed compile error with Rubinius 2.0.0-dev * Optimized msgpack_packer_write_hash for Rubinius 2012-12-20 version 0.5.0: * Rewrote all code and improved performance significantly * Added MessagePack::Buffer class * Added MessagePack::Packer class * Added Packer#buffer and Unpacker#buffer accessors which return MessagePack::Buffer * Added Packer#write_{array,map}_header and Unpacker#read_{array,map}_header methods * Added Packer#write_nil and Unpacker#skip_nil methods * Added Packer#write -> #pack alias and Unpacker#read method * Added exception classes - UnpackError, MalformedFormatError, StackError and TypeError * Added MessagePack.dup -> .pack and MessagePack.load -> .unpack aliases * Added Packer#empty?, #size and #clear methods * Added Packer#write_to(io) method to flush serialized data to IO efficiently * Added Unpacker#skip method to skip an object efficiently * Removed obsoleted Unpacker#fill, #execute, #execute_limit, #finished? and #data methods * Removed obsoleted Unapcker#stream and #stream= methods. Use unpacker.buffer.io instead 2012-05-05 version 0.4.7: * Fixed serialization of double values on ARM OABI architectures * Fixed byteorder problem on big-endian platforms * Don't use MRI internals in the Ruby extension for Rubinius * Detect whether st.h is present and don't use RUBY_VM as the condition for Rubinius 2011-08-08 version 0.4.6: * Fixed compile error problem on Mac OS X Lion 2011-05-09 version 0.4.5: * Improves compatibility with JRuby 2010-11-28 version 0.4.4: * Adds Unpacker#feed_each method * Improves compatibility with Rubinius * Improves compatibility with ruby-1.8.5 * Encodings of String instances to UTF-8 on Ruby 1.9 2010-06-29 version 0.4.3: * Adds MessagePack::VERSION constant * Fixes SEGV problem caused by GC bug at MessagePack_Unpacker_mark cbor-0.5.9.8/.travis.yml0000644000004100000410000000046414567454543015006 0ustar www-datawww-datalanguage: ruby rvm: - 2.0.0 - 2.1.10 - 2.2.10 - 2.3.8 - 2.4.6 - 2.5.5 - 2.6.3 - ruby-head matrix: allow_failures: - rvm: 2.0.0 - rvm: 2.1.10 - rvm: 2.2.10 - rvm: ruby-head gemfile: - Gemfile script: "bundle exec rake spec" notifications: irc: "irc.freenode.org#coap" cbor-0.5.9.8/doclib/0000755000004100000410000000000014567454543014125 5ustar www-datawww-datacbor-0.5.9.8/doclib/cbor.rb0000644000004100000410000000270714567454543015405 0ustar www-datawww-datamodule CBOR # # Serializes an object into an IO or String. # # @overload encode(obj) # @return [String] serialized data # # @overload encode(obj, io) # @return [IO] # def self.encode(arg) end # # Serializes an object into an IO or String. Alias of encode. # # @overload dump(obj) # @return [String] serialized data # # @overload dump(obj, io) # @return [IO] # def self.dump(arg) end # # Serializes an object into an IO or String. Alias of encode. # # @overload dump(obj) # @return [String] serialized data # # @overload dump(obj, io) # @return [IO] # def self.pack(arg) end # # Deserializes an object from an IO or String. # # @overload decode(string) # @param string [String] data to deserialize # # @overload decode(io) # @param io [IO] # # @return [Object] deserialized object # def self.decode(arg) end # # Deserializes an object from an IO or String. Alias of decode. # # @overload load(string) # @param string [String] data to deserialize # # @overload load(io) # @param io [IO] # # @return [Object] deserialized object # def self.load(arg) end # # Deserializes an object from an IO or String. Alias of decode. # # @overload unpack(string) # @param string [String] data to deserialize # # @overload unpack(io) # @param io [IO] # # @return [Object] deserialized object # def self.unpack(arg) end end cbor-0.5.9.8/doclib/cbor/0000755000004100000410000000000014567454543015052 5ustar www-datawww-datacbor-0.5.9.8/doclib/cbor/unpacker.rb0000644000004100000410000000656214567454543017220 0ustar www-datawww-datamodule CBOR # # CBOR::Unpacker is an interface to deserialize objects from an internal buffer, # which is a CBOR::Buffer. # class Unpacker # # Creates a CBOR::Unpacker instance. # # @overload initialize(options={}) # @param options [Hash] # # @overload initialize(io, options={}) # @param io [IO] # @param options [Hash] # This unpacker reads data from the _io_ to fill the internal buffer. # _io_ must respond to readpartial(length [,string]) or read(length [,string]) method. # # See Buffer#initialize for supported options. # def initialize(*args) end # # Internal buffer # # @return [CBOR::Buffer] # attr_reader :buffer # # Deserializes an object from internal buffer and returns it. # # If there're not enough buffer, this method raises EOFError. # If data format is invalid, this method raises CBOR::MalformedFormatError. # If the stack is too deep, this method raises CBOR::StackError. # # @return [Object] deserialized object # def read end alias unpack read # # Deserializes an object and ignores it. This method is faster than _read_. # # This method could raise same errors with _read_. # # @return nil # def skip end # # Deserializes a nil value if it exists and returns _true_. # Otherwise, if a byte exists but the byte doesn't represent nil value, # returns _false_. # # If there're not enough buffer, this method raises EOFError. # # @return [Boolean] # def skip_nil end # # Read a header of an array and returns its size. # It converts a serialized array into a stream of elements. # # If the serialized object is not an array, it raises CBOR::TypeError. # If there're not enough buffer, this method raises EOFError. # # @return [Integer] size of the array # def read_array_header end # # Reads a header of an map and returns its size. # It converts a serialized map into a stream of key-value pairs. # # If the serialized object is not a map, it raises CBOR::TypeError. # If there're not enough buffer, this method raises EOFError. # # @return [Integer] size of the map # def read_map_header end # # Appends data into the internal buffer. # This method calls buffer.append(data). # # @param data [String] # @return [Unpacker] self # def feed(data) end # # Repeats to deserialize objects. # # It repeats until the internal buffer does not include any complete objects. # # If the an IO is set, it repeats to read data from the IO when the buffer # becomes empty until the IO raises EOFError. # # This method could raise same errors with _read_ excepting EOFError. # # @yieldparam object [Object] deserialized object # @return nil # def each(&block) end # # Appends data into the internal buffer and repeats to deserialize objects. # This method is equals to feed(data) && each. # # @param data [String] # @yieldparam object [Object] deserialized object # @return nil # def feed_each(data, &block) end # # Resets deserialization state of the unpacker and clears the internal buffer. # # @return nil # def reset end end end cbor-0.5.9.8/doclib/cbor/error.rb0000644000004100000410000000027614567454543016535 0ustar www-datawww-datamodule CBOR class UnpackError < StandardError end class MalformedFormatError < UnpackError end class StackError < UnpackError end class TypeError < StandardError end end cbor-0.5.9.8/doclib/cbor/core_ext.rb0000644000004100000410000000356614567454543017221 0ustar www-datawww-data class NilClass # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class TrueClass # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class FalseClass # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Fixnum < Integer # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Bignum < Integer # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Float < Numeric # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class String # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Array # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Hash # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Time # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class Regexp # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end class URI # # Same as CBOR.encode(self[, io]). This method is only defined if # the class URI was defined when the CBOR extension was loaded, so # +require "uri"+ before +require "cbor"+ if you need this. # # @return [String] serialized data # def to_cbor(io=nil) end end class Symbol # # Same as CBOR.encode(self[, io]). # # @return [String] serialized data # def to_cbor(io=nil) end end cbor-0.5.9.8/doclib/cbor/buffer.rb0000644000004100000410000001154014567454543016651 0ustar www-datawww-datamodule CBOR class Buffer # # Creates a CBOR::Buffer instance. # # @overload initialize(options={}) # @param options [Hash] # # @overload initialize(io, options={}) # @param io [IO] # @param options [Hash] # This buffer writes written data into the IO when it is filled. # This buffer reads data from the IO when it is empty. # # _io_ must respond to readpartial(length, [,string]) or read(string) method and # write(string) or append(string) method. # # Supported options: # # * *:io_buffer_size* buffer size to read data from the internal IO. (default: 32768) # * *: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) # * *: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) # def initialize(*args) end # # Makes the buffer empty # # @return nil # def clear end # # Returns byte size of the buffer. # # @return nil # def size end # # Returns _true_ if the buffer is empty. # This method is slightly faster than _size_. # # @return [Boolean] # def empty? end # # Appends the given data to the buffer. # # @param data [String] # @return [Integer] byte size written # def write(data) end # # Appends the given data to the buffer. # # @param data [String] # @return [Buffer] self # def <<(data) end # # Consumes _n_ bytes from the head of the buffer and returns consumed data. # If the size of the buffer is less than _n_, it reads all of data in the buffer. # # If _n_ is 0, it does nothing and returns an empty string. # If the optional _buffer_ argument is given, the content of the string will be replaced with the consumed data. # # @overload read # # @overload read(n) # @param n [Integer] bytes to read # # @overload read(n, buffer) # @param n [Integer] bytes to read # @param buffer [String] buffer to read into # # @return [String] # def read(n) end # # Consumes _n_ bytes from the head of the buffer and returns consumed data. # If the size of the buffer is less than _n_, it does nothing and raises EOFError. # # If _n_ is 0, it does nothing and returns an empty string. # If the optional _buffer_ argument is given, the content of the string will be replaced with the consumed data. # # @overload read_all # # @overload read_all(n) # @param n [Integer] bytes to read # # @overload read_all(n, buffer) # @param n [Integer] bytes to read # @param buffer [String] buffer to read into # # @return [String] # def read_all(n, buffer=nil) end # # Consumes _n_ bytes from the head of the buffer. # If the size of the buffer is less than _n_, it skips all of data in the buffer and returns integer less than _n_. # # If _n_ is 0, it does nothing and returns _0_. # # @param n [Integer] byte size to skip # @return [Integer] byte size actually skipped # def skip(n) end # # Consumes _n_ bytes from the head of the buffer. # If the size of the buffer is less than _n_, it does nothing and raises EOFError. # If _n_ is 0, it does nothing. # # @param n [Integer] byte size to skip # @return [Buffer] self # def skip_all(n) end # # Returns all data in the buffer as a string. # Destructive update to the returned string does NOT effect the buffer. # # @return [String] # def to_str end # # Returns content of the buffer as an array of strings. # # This method is sometimes faster than to_s because the internal # structure of the buffer is a queue of buffer chunks. # # @return [Array] array of strings # def to_a end # # Internal io # # @return IO # attr_reader :io # # Flushes data in the internal buffer to the internal IO. # If internal IO is not set, it does nothing. # # @return [Buffer] self # def flush end # # Closes internal IO if its set. # If internal IO is not set, it does nothing # # @return nil # def close end # # Writes all of data in the internal buffer into the given IO. # This method consumes and removes data from the internal buffer. # _io_ must respond to write(data) method. # # @param io [IO] # @return [Integer] byte size of written data # def write_to(io) end end end cbor-0.5.9.8/doclib/cbor/packer.rb0000644000004100000410000000556014567454543016652 0ustar www-datawww-datamodule CBOR # # CBOR::Packer is an interface to serialize objects into an internal buffer, # which is a CBOR::Buffer. # class Packer # # Creates a CBOR::Packer instance. # See Buffer#initialize for supported options. # # @overload initialize(options={}) # @param options [Hash] # # @overload initialize(io, options={}) # @param io [IO] # @param options [Hash] # This packer writes serialzied objects into the IO when the internal buffer is filled. # _io_ must respond to write(string) or append(string) method. # def initialize(*args) end # # Internal buffer # # @return CBOR::Buffer # attr_reader :buffer # # Serializes an object into internal buffer. # # If it could not serialize the object, it raises # NoMethodError: undefined method `to_cbor' for #. # # @param obj [Object] object to serialize # @return [Packer] self # def write(obj) end alias pack write # # Serializes a nil object. Same as write(nil). # def write_nil end # # Write a header of an array whose size is _n_. # For example, write_array_header(1).write(true) is same as write([ true ]). # # @return [Packer] self # def write_array_header(n) end # # Write a header of an map whose size is _n_. # For example, write_map_header(1).write('key').write(true) is same as write('key'=>true). # # @return [Packer] self # def write_map_header(n) end # # Flushes data in the internal buffer to the internal IO. Same as _buffer.flush. # If internal IO is not set, it does nothing. # # @return [Packer] self # def flush end # # Makes the internal buffer empty. Same as _buffer.clear_. # # @return nil # def clear end # # Returns size of the internal buffer. Same as buffer.size. # # @return [Integer] # def size end # # Returns _true_ if the internal buffer is empty. Same as buffer.empty?. # This method is slightly faster than _size_. # # @return [Boolean] # def empty? end # # Returns all data in the buffer as a string. Same as buffer.to_str. # # @return [String] # def to_str end alias to_s to_str # # Returns content of the internal buffer as an array of strings. Same as buffer.to_a. # This method is faster than _to_str_. # # @return [Array] array of strings # def to_a end # # Writes all of data in the internal buffer into the given IO. Same as buffer.write_to(io). # This method consumes and removes data from the internal buffer. # _io_ must respond to write(data) method. # # @param io [IO] # @return [Integer] byte size of written data # def write_to(io) end end end cbor-0.5.9.8/doclib/cbor/tagged.rb0000644000004100000410000000055214567454543016634 0ustar www-datawww-datamodule CBOR # # CBOR::Tagged is used to carry around tagged values that don't map # into Ruby classes (false, true, nil are the ones that do). class Tagged # @param tag [Integer] The integer number of the tag # @param value [Object] The value that is being tagged def initialize(tag, value) end attr_reader :tag, :value end end cbor-0.5.9.8/doclib/cbor/simple.rb0000644000004100000410000000045714567454543016676 0ustar www-datawww-datamodule CBOR # # CBOR::Simple is used to carry around simple values that don't map # into Ruby classes (false, true, nil are the ones that do). class Simple # @param value [Integer] The integer number of the simple value def initialize(value) end attr_reader :value end end