class Marshal::NFREEZE
Public Class Methods
new()
click to toggle source
# File lib/nfreeze.rb, line 81 def initialize buf = "".encode Encoding::BINARY @io = StringIO.new buf @seen = Hash.new end
Public Instance Methods
nfreeze(obj)
click to toggle source
# File lib/nfreeze.rb, line 72 def nfreeze obj @io.rewind @io.write "\x5\x8" recur obj return @io.string end
Private Instance Methods
dump(x)
click to toggle source
# File lib/nfreeze.rb, line 115 def dump x @io.write x.chr end
dump_array(obj)
click to toggle source
# File lib/nfreeze.rb, line 119 def dump_array obj len = obj.length if len > 2147483647 raise ArgumentError, "#{len} elems array is too big for perl" else @io.write [2, len].pack('cN') obj.each do |i| recur i, :ref end end end
dump_double(obj)
click to toggle source
# File lib/nfreeze.rb, line 154 def dump_double obj @io.write [7, obj].pack('cd') end
dump_hash(obj)
click to toggle source
# File lib/nfreeze.rb, line 131 def dump_hash obj len = obj.keys.length if len > 2147483647 raise ArgumentError, "#{len} elems hash is too big for perl" else @io.write [3, len].pack('cN') obj.each_pair do |k, v| case k when String then len = k.bytesize if len > 2147483647 raise ArgumentError, "#{len} octets key is too big for perl" else recur v, :ref @io.write [len, k].pack('NA*') end else raise ArgumentError, "non-string keys cant be represented:"+ k.inspect end end end end
dump_int(obj)
click to toggle source
# File lib/nfreeze.rb, line 158 def dump_int obj case obj when (-2147483648 ... 2147483648) then @io.write [9, obj].pack('cN') else raise ArgumentError, "#{obj.inspect} is too big for perl" end end
dump_string(obj)
click to toggle source
# File lib/nfreeze.rb, line 166 def dump_string obj # Perl can only understand Unicodes newobj = obj.encode Encoding::UTF_8 newlen = newobj.bytesize if newlen > 2147483647 raise ArgumentError, "#{newlen} octets string is too big for perl" else @io.write [24, newlen, newobj].pack('cNA*') end end
recur(obj, refp = false)
click to toggle source
# File lib/nfreeze.rb, line 87 def recur obj, refp = false # We are not implementing Torjan's topological sort algorithm here # because our restriction is stronger than just unable to represent # infinite loops; we can only serlalize pure trees. if @seen.has_key? obj.object_id raise ArgumentError, "cyclic data structures not supportted for now"+ obj.inspect else case obj when NilClass, Integer, String then # immediates else @seen.store obj.object_id, nil end end case obj when NilClass then dump 14 when TrueClass then dump 15 when FalseClass then dump 16 when Integer then dump_int obj when Float then dump_double obj when String then dump_string obj when Array then dump 4 if refp; dump_array obj when Hash then dump 4 if refp; dump_hash obj else raise ArgumentError, "unsupported class encountered: #{obj.inspect}" end end