68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/mplight.rb', line 68
def put obj
case obj
when nil then write_fmt 0xc0
when false then write_fmt 0xc2
when true then write_fmt 0xc3
when Integer then
if obj >= 0 then
case obj
when ...0x80 then write_fmt obj
when ...0x100 then write_fmt 0xcc ; write_pack obj, "C"
when ...0x10000 then write_fmt 0xcd ; write_pack obj, "S>"
when ...0x100000000 then write_fmt 0xce ; write_pack obj, "L>"
when ...0x10000000000000000 then write_fmt 0xcf ; write_pack obj, "Q>"
else raise ArgumentError, "Integer too large: #{obj}"
end
else
case obj
when -0x20... then write_fmt obj+256
when -0x80... then write_fmt 0xd0 ; write_pack obj, "c"
when -0x8000... then write_fmt 0xd1 ; write_pack obj, "s>"
when -0x80000000... then write_fmt 0xd2 ; write_pack obj, "l>"
when -0x8000000000000000... then write_fmt 0xd3 ; write_pack obj, "q>"
else raise ArgumentError, "Integer too large: #{obj}"
end
end
when Float then
case
when false then write_fmt 0xca ; write_pack obj, "g"
else write_fmt 0xcb ; write_pack obj, "G"
end
when String then
if obj.encoding == Encoding::ASCII_8BIT then
l = obj.size
case l
when ...0x100 then write_fmt 0xc4 ; write_pack l, "C"
when ...0x10000 then write_fmt 0xc5 ; write_pack l, "S>"
when ...0x100000000 then write_fmt 0xc6 ; write_pack l, "L>"
else raise ArgumentError, "Byte array too long: #{l} bytes"
end
else
obj = obj.encode Encoding::UTF_8 unless obj.encoding == Encoding::UTF_8
l = obj.bytesize
case l
when ...0x20 then write_fmt 0xa0+l
when ...0x100 then write_fmt 0xd9 ; write_pack l, "C"
when ...0x10000 then write_fmt 0xda ; write_pack l, "S>"
when ...0x100000000 then write_fmt 0xdb ; write_pack l, "L>"
else raise ArgumentError, "String too long: #{l} bytes"
end
end
write_pack obj, "A*"
when Array then
l = obj.length
case l
when ...0x10 then write_fmt 0x90+l
when ...0x10000 then write_fmt 0xdc ; write_pack l, "S>"
when ...0x100000000 then write_fmt 0xdd ; write_pack l, "L>"
else raise ArgumentError, "Array too long: #{l} elements"
end
obj.each { |o| put o }
when Hash then
l = obj.length
case l
when ...0x10 then write_fmt 0x80+l
when ...0x10000 then write_fmt 0xde ; write_pack l, "S>"
when ...0x100000000 then write_fmt 0xdf ; write_pack l, "L>"
else raise ArgumentError, "Hash too long: #{l} keys"
end
obj.each { |k,v| put k ; put v }
when Symbol then
put obj.to_s
else
type, data = dump obj
type or return put obj.to_s
l = data.bytesize
case l
when 0x01 then write_fmt 0xd4 ; write_pack type, "c"
when 0x02 then write_fmt 0xd5 ; write_pack type, "c"
when 0x04 then write_fmt 0xd6 ; write_pack type, "c"
when 0x08 then write_fmt 0xd7 ; write_pack type, "c"
when 0x10 then write_fmt 0xd8 ; write_pack type, "c"
when ...0x100 then write_fmt 0xc7 ; write_pack l, "C" ; write_pack type, "c"
when ...0x10000 then write_fmt 0xc8 ; write_pack l, "S>" ; write_pack type, "c"
when ...0x100000000 then write_fmt 0xc9 ; write_pack l, "L>" ; write_pack type, "c"
else raise ArgumentError, "Object too large: #{l} bytes"
end
write_pack data, "A*"
end
self
end
|