Module: Rencoder::Encoder
- Included in:
- Coder
- Defined in:
- lib/rencoder/encoder.rb
Defined Under Namespace
Classes: EncodingError
Instance Method Summary collapse
- #encode(object) ⇒ Object
- #encode_array(object) ⇒ Object
- #encode_boolean(object) ⇒ Object
- #encode_float(object) ⇒ Object
- #encode_hash(object) ⇒ Object
- #encode_integer(object) ⇒ Object
- #encode_nil(object) ⇒ Object
- #encode_string(object) ⇒ Object
Instance Method Details
#encode(object) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/rencoder/encoder.rb', line 5 def encode(object) case object when String, Symbol then encode_string(object) when Fixnum then encode_integer(object) when Float then encode_float(object) when TrueClass, FalseClass then encode_boolean(object) when NilClass then encode_nil(object) when Array then encode_array(object) when Hash then encode_hash(object) else raise EncodingError, "Unable to serialize '#{object.class}'" end end |
#encode_array(object) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/rencoder/encoder.rb', line 72 def encode_array(object) array_data = object.map { |item| encode(item) }.join if object.size < LIST_FIXED_COUNT (LIST_FIXED_START + object.size).chr + array_data else CHR_LIST.chr + array_data + CHR_TERM.chr end end |
#encode_boolean(object) ⇒ Object
68 69 70 |
# File 'lib/rencoder/encoder.rb', line 68 def encode_boolean(object) [object ? CHR_TRUE : CHR_FALSE].pack('C') end |
#encode_float(object) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/rencoder/encoder.rb', line 44 def encode_float(object) # Always serialize floats as 64-bit, since single-precision serialization is a poo # If you don't believe me try this: # # [1.1].pack('F').unpack('F').first # => 1.100000023841858 # if [:float32] # not recommended [CHR_FLOAT32, object].pack('Cg') else [CHR_FLOAT64, object].pack('CG') end end |
#encode_hash(object) ⇒ Object
82 83 84 85 86 87 88 89 90 |
# File 'lib/rencoder/encoder.rb', line 82 def encode_hash(object) hash_data = object.map { |key, value| encode(key) + encode(value) }.join if object.size < DICT_FIXED_COUNT (DICT_FIXED_START + object.size).chr + hash_data else CHR_DICT.chr + hash_data + CHR_TERM.chr end end |
#encode_integer(object) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/rencoder/encoder.rb', line 19 def encode_integer(object) case object when (0...INT_POS_FIXED_COUNT) # predefined positive intger [INT_POS_FIXED_START + object].pack('C') when (-INT_NEG_FIXED_COUNT...0) # predefined negative integer [INT_NEG_FIXED_START-1-object].pack('C') when (-128...128) [CHR_INT1, object].pack('Cc') # 8-bit signed when (-32768...32768) [CHR_INT2, object].pack('Cs>') # 16-bit signed when (-2147483648...2147483648) [CHR_INT4, object].pack('Cl>') # 32-bit signed when (-9223372036854775808...9223372036854775808) [CHR_INT8, object].pack('Cq>') # 64-bit signed else # encode as ASCII bytes = object.to_s.bytes if bytes.size >= MAX_INT_LENGTH raise EncodingError, "Unable to serialize Fixnum #{object} due to overflow" end [CHR_INT, *bytes, CHR_TERM].pack('C*') end end |
#encode_nil(object) ⇒ Object
92 93 94 |
# File 'lib/rencoder/encoder.rb', line 92 def encode_nil(object) [CHR_NONE].pack('C') end |
#encode_string(object) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/rencoder/encoder.rb', line 58 def encode_string(object) bytes = object.to_s if bytes.size < STR_FIXED_COUNT (STR_FIXED_START + bytes.size).chr + bytes else "#{bytes.bytesize.to_s}:#{bytes}" end end |