thrift 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +175 -17
  3. data/benchmark/benchmark.rb +22 -8
  4. data/benchmark/client.rb +49 -6
  5. data/benchmark/server.rb +45 -7
  6. data/benchmark/thin_server.rb +1 -0
  7. data/ext/binary_protocol_accelerated.c +76 -19
  8. data/ext/compact_protocol.c +80 -15
  9. data/ext/constants.h +12 -0
  10. data/ext/extconf.rb +10 -9
  11. data/ext/memory_buffer.c +7 -7
  12. data/ext/protocol.c +29 -0
  13. data/ext/protocol.h +35 -0
  14. data/ext/struct.c +36 -5
  15. data/ext/thrift_native.c +27 -3
  16. data/lib/thrift/bytes.rb +68 -101
  17. data/lib/thrift/client.rb +61 -9
  18. data/lib/thrift/exceptions.rb +5 -5
  19. data/lib/thrift/multiplexed_processor.rb +6 -6
  20. data/lib/thrift/processor.rb +6 -6
  21. data/lib/thrift/protocol/base_protocol.rb +37 -15
  22. data/lib/thrift/protocol/binary_protocol.rb +25 -9
  23. data/lib/thrift/protocol/binary_protocol_accelerated.rb +5 -5
  24. data/lib/thrift/protocol/compact_protocol.rb +61 -37
  25. data/lib/thrift/protocol/header_protocol.rb +320 -0
  26. data/lib/thrift/protocol/json_protocol.rb +26 -16
  27. data/lib/thrift/protocol/multiplexed_protocol.rb +5 -5
  28. data/lib/thrift/protocol/protocol_decorator.rb +12 -4
  29. data/lib/thrift/serializer/deserializer.rb +5 -5
  30. data/lib/thrift/serializer/serializer.rb +4 -5
  31. data/lib/thrift/server/base_server.rb +4 -4
  32. data/lib/thrift/server/mongrel_http_server.rb +6 -6
  33. data/lib/thrift/server/nonblocking_server.rb +8 -8
  34. data/lib/thrift/server/simple_server.rb +4 -4
  35. data/lib/thrift/server/thin_http_server.rb +3 -3
  36. data/lib/thrift/server/thread_pool_server.rb +6 -6
  37. data/lib/thrift/server/threaded_server.rb +4 -4
  38. data/lib/thrift/struct.rb +11 -11
  39. data/lib/thrift/struct_union.rb +19 -9
  40. data/lib/thrift/thrift_native.rb +1 -1
  41. data/lib/thrift/transport/base_server_transport.rb +5 -5
  42. data/lib/thrift/transport/base_transport.rb +12 -12
  43. data/lib/thrift/transport/buffered_transport.rb +6 -6
  44. data/lib/thrift/transport/framed_transport.rb +7 -7
  45. data/lib/thrift/transport/header_transport.rb +516 -0
  46. data/lib/thrift/transport/http_client_transport.rb +1 -1
  47. data/lib/thrift/transport/io_stream_transport.rb +3 -3
  48. data/lib/thrift/transport/memory_buffer_transport.rb +6 -6
  49. data/lib/thrift/transport/server_socket.rb +8 -5
  50. data/lib/thrift/transport/socket.rb +58 -31
  51. data/lib/thrift/transport/ssl_server_socket.rb +1 -1
  52. data/lib/thrift/transport/ssl_socket.rb +2 -2
  53. data/lib/thrift/transport/unix_server_socket.rb +4 -4
  54. data/lib/thrift/transport/unix_socket.rb +6 -6
  55. data/lib/thrift/types.rb +9 -6
  56. data/lib/thrift/union.rb +14 -8
  57. data/lib/thrift/uuid.rb +49 -0
  58. data/lib/thrift.rb +3 -1
  59. data/spec/ThriftSpec.thrift +5 -1
  60. data/spec/base_protocol_spec.rb +1 -2
  61. data/spec/base_transport_spec.rb +6 -7
  62. data/spec/binary_protocol_spec.rb +0 -2
  63. data/spec/binary_protocol_spec_shared.rb +129 -142
  64. data/spec/bytes_spec.rb +57 -118
  65. data/spec/client_spec.rb +85 -19
  66. data/spec/compact_protocol_spec.rb +54 -16
  67. data/spec/constants_demo_spec.rb +101 -0
  68. data/spec/exception_spec.rb +0 -1
  69. data/spec/header_protocol_spec.rb +475 -0
  70. data/spec/header_transport_spec.rb +386 -0
  71. data/spec/http_client_spec.rb +4 -6
  72. data/spec/json_protocol_spec.rb +47 -47
  73. data/spec/namespaced_spec.rb +0 -1
  74. data/spec/nonblocking_server_spec.rb +102 -4
  75. data/spec/processor_spec.rb +0 -1
  76. data/spec/serializer_spec.rb +0 -1
  77. data/spec/server_socket_spec.rb +1 -1
  78. data/spec/server_spec.rb +8 -9
  79. data/spec/socket_spec.rb +0 -1
  80. data/spec/socket_spec_shared.rb +72 -9
  81. data/spec/spec_helper.rb +1 -1
  82. data/spec/ssl_server_socket_spec.rb +12 -1
  83. data/spec/ssl_socket_spec.rb +10 -1
  84. data/spec/struct_nested_containers_spec.rb +1 -2
  85. data/spec/struct_spec.rb +113 -9
  86. data/spec/support/header_protocol_helper.rb +54 -0
  87. data/spec/thin_http_server_spec.rb +3 -18
  88. data/spec/types_spec.rb +25 -26
  89. data/spec/union_spec.rb +69 -11
  90. data/spec/unix_socket_spec.rb +1 -2
  91. data/spec/uuid_validation_spec.rb +238 -0
  92. data/test/fuzz/Makefile.am +173 -0
  93. data/test/fuzz/README.md +149 -0
  94. data/test/fuzz/fuzz_common.rb +95 -0
  95. data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +3 -4
  96. data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +6 -13
  97. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +22 -0
  98. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +22 -0
  99. data/test/fuzz/fuzz_parse_compact_protocol.rb +22 -0
  100. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +22 -0
  101. data/test/fuzz/fuzz_parse_json_protocol.rb +22 -0
  102. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +22 -0
  103. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +22 -0
  104. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +22 -0
  105. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +22 -0
  106. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +22 -0
  107. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +22 -0
  108. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +22 -0
  109. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +22 -0
  110. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +22 -0
  111. data/test/fuzz/fuzz_tracer.rb +28 -0
  112. metadata +106 -37
@@ -1,4 +1,4 @@
1
- #
1
+ #
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -6,16 +6,16 @@
6
6
  # to you under the Apache License, Version 2.0 (the
7
7
  # "License"); you may not use this file except in compliance
8
8
  # with the License. You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing,
13
13
  # software distributed under the License is distributed on an
14
14
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #
19
19
 
20
20
  # this require is to make generated struct definitions happy
21
21
  require 'set'
@@ -33,7 +33,7 @@ module Thrift
33
33
 
34
34
  attr_reader :type
35
35
 
36
- def initialize(type=UNKNOWN, message=nil)
36
+ def initialize(type = UNKNOWN, message = nil)
37
37
  super(message)
38
38
  @type = type
39
39
  end
@@ -116,7 +116,7 @@ module Thrift
116
116
  raise NotImplementedError
117
117
  end
118
118
 
119
- # Writes a Thrift String. In Ruby 1.9+, the String passed will be transcoded to UTF-8.
119
+ # Writes a Thrift String. The String passed will be transcoded to UTF-8.
120
120
  #
121
121
  # str - The String to write.
122
122
  #
@@ -127,7 +127,7 @@ module Thrift
127
127
  raise NotImplementedError
128
128
  end
129
129
 
130
- # Writes a Thrift Binary (Thrift String with no encoding). In Ruby 1.9+, the String passed
130
+ # Writes a Thrift Binary (Thrift String with no encoding). The String passed
131
131
  # will forced into BINARY encoding.
132
132
  #
133
133
  # buf - The String to write.
@@ -137,6 +137,15 @@ module Thrift
137
137
  raise NotImplementedError
138
138
  end
139
139
 
140
+ # Writes a UUID as 16 bytes.
141
+ #
142
+ # uuid - The UUID string to write (e.g. "550e8400-e29b-41d4-a716-446655440000").
143
+ #
144
+ # Returns nothing.
145
+ def write_uuid(uuid)
146
+ raise NotImplementedError
147
+ end
148
+
140
149
  def read_message_begin
141
150
  raise NotImplementedError
142
151
  end
@@ -197,14 +206,14 @@ module Thrift
197
206
  raise NotImplementedError
198
207
  end
199
208
 
200
- # Reads a Thrift String. In Ruby 1.9+, all Strings will be returned with an Encoding of UTF-8.
209
+ # Reads a Thrift String. All Strings will be returned with an Encoding of UTF-8.
201
210
  #
202
211
  # Returns a String.
203
212
  def read_string
204
213
  raise NotImplementedError
205
214
  end
206
215
 
207
- # Reads a Thrift Binary (Thrift String without encoding). In Ruby 1.9+, all Strings will be returned
216
+ # Reads a Thrift Binary (Thrift String without encoding). All Strings will be returned
208
217
  # with an Encoding of BINARY.
209
218
  #
210
219
  # Returns a String.
@@ -212,6 +221,13 @@ module Thrift
212
221
  raise NotImplementedError
213
222
  end
214
223
 
224
+ # Reads a UUID as 16 bytes and returns it as a string.
225
+ #
226
+ # Returns a String (e.g. "550e8400-e29b-41d4-a716-446655440000").
227
+ def read_uuid
228
+ raise NotImplementedError
229
+ end
230
+
215
231
  # Writes a field based on the field information, field ID and value.
216
232
  #
217
233
  # field_info - A Hash containing the definition of the field:
@@ -251,9 +267,9 @@ module Thrift
251
267
  #
252
268
  # Returns nothing.
253
269
  def write_type(field_info, value)
254
- # if field_info is a Fixnum, assume it is a Thrift::Types constant
270
+ # if field_info is a Integer, assume it is a Thrift::Types constant
255
271
  # convert it into a field_info Hash for backwards compatibility
256
- if field_info.is_a? Fixnum
272
+ if field_info.is_a? Integer
257
273
  field_info = {:type => field_info}
258
274
  end
259
275
 
@@ -276,6 +292,8 @@ module Thrift
276
292
  else
277
293
  write_string(value)
278
294
  end
295
+ when Types::UUID
296
+ write_uuid(value)
279
297
  when Types::STRUCT
280
298
  value.write(self)
281
299
  else
@@ -291,9 +309,9 @@ module Thrift
291
309
  #
292
310
  # Returns the value read; object type varies based on field_info[:type].
293
311
  def read_type(field_info)
294
- # if field_info is a Fixnum, assume it is a Thrift::Types constant
312
+ # if field_info is a Integer, assume it is a Thrift::Types constant
295
313
  # convert it into a field_info Hash for backwards compatibility
296
- if field_info.is_a? Fixnum
314
+ if field_info.is_a? Integer
297
315
  field_info = {:type => field_info}
298
316
  end
299
317
 
@@ -316,6 +334,8 @@ module Thrift
316
334
  else
317
335
  read_string
318
336
  end
337
+ when Types::UUID
338
+ read_uuid
319
339
  else
320
340
  raise NotImplementedError
321
341
  end
@@ -337,6 +357,8 @@ module Thrift
337
357
  read_double
338
358
  when Types::STRING
339
359
  read_string
360
+ when Types::UUID
361
+ read_uuid
340
362
  when Types::STRUCT
341
363
  read_struct_begin
342
364
  while true
@@ -369,7 +391,7 @@ module Thrift
369
391
  raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid data')
370
392
  end
371
393
  end
372
-
394
+
373
395
  def to_s
374
396
  "#{trans.to_s}"
375
397
  end
@@ -379,7 +401,7 @@ module Thrift
379
401
  def get_protocol(trans)
380
402
  raise NotImplementedError
381
403
  end
382
-
404
+
383
405
  def to_s
384
406
  "base"
385
407
  end
@@ -1,4 +1,4 @@
1
- #
1
+ #
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -6,26 +6,26 @@
6
6
  # to you under the Apache License, Version 2.0 (the
7
7
  # "License"); you may not use this file except in compliance
8
8
  # with the License. You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing,
13
13
  # software distributed under the License is distributed on an
14
14
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #
19
19
 
20
20
  module Thrift
21
21
  class BinaryProtocol < BaseProtocol
22
22
  VERSION_MASK = 0xffff0000
23
23
  VERSION_1 = 0x80010000
24
24
  TYPE_MASK = 0x000000ff
25
-
25
+
26
26
  attr_reader :strict_read, :strict_write
27
27
 
28
- def initialize(trans, strict_read=true, strict_write=true)
28
+ def initialize(trans, strict_read = true, strict_write = true)
29
29
  super(trans)
30
30
  @strict_read = strict_read
31
31
  @strict_write = strict_write
@@ -36,7 +36,7 @@ module Thrift
36
36
  end
37
37
 
38
38
  def write_message_begin(name, type, seqid)
39
- # this is necessary because we added (needed) bounds checking to
39
+ # this is necessary because we added (needed) bounds checking to
40
40
  # write_i32, and 0x80010000 is too big for that.
41
41
  if strict_write
42
42
  write_i16(VERSION_1 >> 16)
@@ -82,20 +82,24 @@ module Thrift
82
82
  end
83
83
 
84
84
  def write_byte(byte)
85
+ raise 'nil argument not allowed!' if byte.nil?
85
86
  raise RangeError if byte < -2**31 || byte >= 2**32
86
87
  trans.write([byte].pack('c'))
87
88
  end
88
89
 
89
90
  def write_i16(i16)
91
+ raise 'nil argument not allowed!' if i16.nil?
90
92
  trans.write([i16].pack('n'))
91
93
  end
92
94
 
93
95
  def write_i32(i32)
96
+ raise 'nil argument not allowed!' if i32.nil?
94
97
  raise RangeError if i32 < -2**31 || i32 >= 2**31
95
98
  trans.write([i32].pack('N'))
96
99
  end
97
100
 
98
101
  def write_i64(i64)
102
+ raise 'nil argument not allowed!' if i64.nil?
99
103
  raise RangeError if i64 < -2**63 || i64 >= 2**64
100
104
  hi = i64 >> 32
101
105
  lo = i64 & 0xffffffff
@@ -103,19 +107,27 @@ module Thrift
103
107
  end
104
108
 
105
109
  def write_double(dub)
110
+ raise 'nil argument not allowed!' if dub.nil?
106
111
  trans.write([dub].pack('G'))
107
112
  end
108
113
 
109
114
  def write_string(str)
115
+ raise 'nil argument not allowed!' if str.nil?
110
116
  buf = Bytes.convert_to_utf8_byte_buffer(str)
111
117
  write_binary(buf)
112
118
  end
113
119
 
114
120
  def write_binary(buf)
121
+ raise 'nil argument not allowed!' if buf.nil?
115
122
  write_i32(buf.bytesize)
116
123
  trans.write(buf)
117
124
  end
118
125
 
126
+ def write_uuid(uuid)
127
+ UUID.validate_uuid!(uuid)
128
+ trans.write(UUID.uuid_bytes(uuid))
129
+ end
130
+
119
131
  def read_message_begin
120
132
  version = read_i32
121
133
  if version < 0
@@ -226,7 +238,11 @@ module Thrift
226
238
  size = read_i32
227
239
  trans.read_all(size)
228
240
  end
229
-
241
+
242
+ def read_uuid
243
+ UUID.uuid_from_bytes(trans.read_all(16))
244
+ end
245
+
230
246
  def to_s
231
247
  "binary(#{super.to_s})"
232
248
  end
@@ -236,7 +252,7 @@ module Thrift
236
252
  def get_protocol(trans)
237
253
  return Thrift::BinaryProtocol.new(trans)
238
254
  end
239
-
255
+
240
256
  def to_s
241
257
  "binary"
242
258
  end
@@ -1,4 +1,4 @@
1
- #
1
+ #
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -6,20 +6,20 @@
6
6
  # to you under the Apache License, Version 2.0 (the
7
7
  # "License"); you may not use this file except in compliance
8
8
  # with the License. You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing,
13
13
  # software distributed under the License is distributed on an
14
14
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #
19
19
 
20
20
  =begin
21
21
  The only change required for a transport to support BinaryProtocolAccelerated is to implement 2 methods:
22
- * borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
22
+ * borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
23
23
  or the default buffer size if no argument is given
24
24
  * consume!(size), which removes size bytes from the front of the buffer
25
25
 
@@ -1,4 +1,4 @@
1
- #
1
+ #
2
2
  # Licensed to the Apache Software Foundation (ASF) under one
3
3
  # or more contributor license agreements. See the NOTICE file
4
4
  # distributed with this work for additional information
@@ -6,16 +6,16 @@
6
6
  # to you under the Apache License, Version 2.0 (the
7
7
  # "License"); you may not use this file except in compliance
8
8
  # with the License. You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing,
13
13
  # software distributed under the License is distributed on an
14
14
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
15
  # KIND, either express or implied. See the License for the
16
16
  # specific language governing permissions and limitations
17
17
  # under the License.
18
- #
18
+ #
19
19
 
20
20
  module Thrift
21
21
  class CompactProtocol < BaseProtocol
@@ -27,11 +27,11 @@ module Thrift
27
27
  TYPE_BITS = 0x07
28
28
  TYPE_SHIFT_AMOUNT = 5
29
29
 
30
- TSTOP = ["", Types::STOP, 0]
30
+ TSTOP = [nil, Types::STOP, 0]
31
31
 
32
- #
32
+ #
33
33
  # All of the on-wire type codes.
34
- #
34
+ #
35
35
  class CompactTypes
36
36
  BOOLEAN_TRUE = 0x01
37
37
  BOOLEAN_FALSE = 0x02
@@ -45,11 +45,12 @@ module Thrift
45
45
  SET = 0x0A
46
46
  MAP = 0x0B
47
47
  STRUCT = 0x0C
48
-
48
+ UUID = 0x0D
49
+
49
50
  def self.is_bool_type?(b)
50
51
  (b & 0x0f) == BOOLEAN_TRUE || (b & 0x0f) == BOOLEAN_FALSE
51
52
  end
52
-
53
+
53
54
  COMPACT_TO_TTYPE = {
54
55
  Types::STOP => Types::STOP,
55
56
  BOOLEAN_FALSE => Types::BOOL,
@@ -63,7 +64,8 @@ module Thrift
63
64
  LIST => Types::LIST,
64
65
  SET => Types::SET,
65
66
  MAP => Types::MAP,
66
- STRUCT => Types::STRUCT
67
+ STRUCT => Types::STRUCT,
68
+ UUID => Types::UUID
67
69
  }
68
70
 
69
71
  TTYPE_TO_COMPACT = {
@@ -78,15 +80,16 @@ module Thrift
78
80
  Types::LIST => LIST,
79
81
  Types::SET => SET,
80
82
  Types::MAP => MAP,
81
- Types::STRUCT => STRUCT
83
+ Types::STRUCT => STRUCT,
84
+ Types::UUID => UUID
82
85
  }
83
-
86
+
84
87
  def self.get_ttype(compact_type)
85
88
  val = COMPACT_TO_TTYPE[compact_type & 0x0f]
86
89
  raise "don't know what type: #{compact_type & 0x0f}" unless val
87
90
  val
88
91
  end
89
-
92
+
90
93
  def self.get_compact_type(ttype)
91
94
  val = TTYPE_TO_COMPACT[ttype]
92
95
  raise "don't know what type: #{ttype & 0x0f}" unless val
@@ -107,7 +110,7 @@ module Thrift
107
110
  def write_message_begin(name, type, seqid)
108
111
  write_byte(PROTOCOL_ID)
109
112
  write_byte((VERSION & VERSION_MASK) | ((type << TYPE_SHIFT_AMOUNT) & TYPE_MASK))
110
- write_varint32(seqid)
113
+ write_varint32(message_seqid_to_varint32(seqid))
111
114
  write_string(name)
112
115
  nil
113
116
  end
@@ -132,14 +135,14 @@ module Thrift
132
135
  nil
133
136
  end
134
137
 
135
- #
136
- # The workhorse of writeFieldBegin. It has the option of doing a
137
- # 'type override' of the type header. This is used specifically in the
138
+ #
139
+ # The workhorse of writeFieldBegin. It has the option of doing a
140
+ # 'type override' of the type header. This is used specifically in the
138
141
  # boolean field case.
139
- #
140
- def write_field_begin_internal(type, id, type_override=nil)
142
+ #
143
+ def write_field_begin_internal(type, id, type_override = nil)
141
144
  last_id = @last_field.pop
142
-
145
+
143
146
  # if there's a type override, use that.
144
147
  typeToWrite = type_override || CompactTypes.get_compact_type(type)
145
148
 
@@ -220,20 +223,25 @@ module Thrift
220
223
  @trans.write(buf)
221
224
  end
222
225
 
226
+ def write_uuid(uuid)
227
+ UUID.validate_uuid!(uuid)
228
+ trans.write(UUID.uuid_bytes(uuid))
229
+ end
230
+
223
231
  def read_message_begin
224
232
  protocol_id = read_byte()
225
233
  if protocol_id != PROTOCOL_ID
226
234
  raise ProtocolException.new("Expected protocol id #{PROTOCOL_ID} but got #{protocol_id}")
227
235
  end
228
-
236
+
229
237
  version_and_type = read_byte()
230
238
  version = version_and_type & VERSION_MASK
231
239
  if (version != VERSION)
232
240
  raise ProtocolException.new("Expected version #{VERSION} but got #{version}");
233
241
  end
234
-
242
+
235
243
  type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS
236
- seqid = read_varint32()
244
+ seqid = message_seqid_from_varint32(read_varint32())
237
245
  messageName = read_string()
238
246
  [messageName, type, seqid]
239
247
  end
@@ -276,7 +284,7 @@ module Thrift
276
284
 
277
285
  # push the new field onto the field stack so we can keep the deltas going.
278
286
  @last_field.push(field_id)
279
- ["", CompactTypes.get_ttype(type & 0x0f), field_id]
287
+ [nil, CompactTypes.get_ttype(type & 0x0f), field_id]
280
288
  end
281
289
  end
282
290
 
@@ -345,17 +353,21 @@ module Thrift
345
353
  size = read_varint32()
346
354
  trans.read_all(size)
347
355
  end
348
-
356
+
357
+ def read_uuid
358
+ UUID.uuid_from_bytes(trans.read_all(16))
359
+ end
360
+
349
361
  def to_s
350
362
  "compact(#{super.to_s})"
351
363
  end
352
364
 
353
365
  private
354
-
355
- #
356
- # Abstract method for writing the start of lists and sets. List and sets on
366
+
367
+ #
368
+ # Abstract method for writing the start of lists and sets. List and sets on
357
369
  # the wire differ only by the type indicator.
358
- #
370
+ #
359
371
  def write_collection_begin(elem_type, size)
360
372
  if size <= 14
361
373
  write_byte(size << 4 | CompactTypes.get_compact_type(elem_type))
@@ -387,7 +399,7 @@ module Thrift
387
399
 
388
400
  def write_varint64(n)
389
401
  while true
390
- if (n & EVERYTHING_ELSE_MASK) == 0 #TODO need to find a way to make this into a long...
402
+ if (n & EVERYTHING_ELSE_MASK) == 0 # TODO need to find a way to make this into a long...
391
403
  write_byte(n)
392
404
  break
393
405
  else
@@ -396,11 +408,11 @@ module Thrift
396
408
  end
397
409
  end
398
410
  end
399
-
411
+
400
412
  def read_varint32()
401
413
  read_varint64()
402
414
  end
403
-
415
+
404
416
  def read_varint64()
405
417
  shift = 0
406
418
  result = 0
@@ -412,30 +424,42 @@ module Thrift
412
424
  end
413
425
  result
414
426
  end
415
-
427
+
416
428
  def int_to_zig_zag(n)
417
429
  (n << 1) ^ (n >> 31)
418
430
  end
419
-
431
+
420
432
  def long_to_zig_zag(l)
421
433
  # puts "zz encoded #{l} to #{(l << 1) ^ (l >> 63)}"
422
434
  (l << 1) ^ (l >> 63)
423
435
  end
424
-
436
+
425
437
  def zig_zag_to_int(n)
426
438
  (n >> 1) ^ -(n & 1)
427
439
  end
428
-
440
+
429
441
  def zig_zag_to_long(n)
430
442
  (n >> 1) ^ -(n & 1)
431
443
  end
444
+
445
+ def message_seqid_to_varint32(seqid)
446
+ if seqid < -(2**31) || seqid > (2**31) - 1
447
+ raise RangeError, "seqid must be a signed int32"
448
+ end
449
+
450
+ seqid < 0 ? seqid + (2**32) : seqid
451
+ end
452
+
453
+ def message_seqid_from_varint32(seqid)
454
+ seqid > 0x7fffffff ? seqid - (2**32) : seqid
455
+ end
432
456
  end
433
457
 
434
458
  class CompactProtocolFactory < BaseProtocolFactory
435
459
  def get_protocol(trans)
436
460
  CompactProtocol.new(trans)
437
461
  end
438
-
462
+
439
463
  def to_s
440
464
  "compact"
441
465
  end