@@ -97,6 +97,7 @@ def write_value_v4(buffer, value, type)
9797 when :bigint , :counter then write_bigint ( buffer , value )
9898 when :blob then write_blob ( buffer , value )
9999 when :boolean then write_boolean ( buffer , value )
100+ when :custom then write_custom ( buffer , value , type )
100101 when :decimal then write_decimal ( buffer , value )
101102 when :double then write_double ( buffer , value )
102103 when :float then write_float ( buffer , value )
@@ -221,19 +222,19 @@ def read_type_v4(buffer)
221222 end
222223 end
223224
224- def read_values_v4 ( buffer , column_metadata )
225+ def read_values_v4 ( buffer , column_metadata , custom_type_handlers )
225226 ::Array . new ( buffer . read_int ) do |_i |
226227 row = ::Hash . new
227228
228229 column_metadata . each do |( _ , _ , column , type ) |
229- row [ column ] = read_value_v4 ( buffer , type )
230+ row [ column ] = read_value_v4 ( buffer , type , custom_type_handlers )
230231 end
231232
232233 row
233234 end
234235 end
235236
236- def read_value_v4 ( buffer , type )
237+ def read_value_v4 ( buffer , type , custom_type_handlers )
237238 case type . kind
238239 when :ascii then read_ascii ( buffer )
239240 when :bigint , :counter then read_bigint ( buffer )
@@ -253,11 +254,12 @@ def read_value_v4(buffer, type)
253254 when :smallint then read_smallint ( buffer )
254255 when :time then read_time ( buffer )
255256 when :date then read_date ( buffer )
257+ when :custom then read_custom ( buffer , type , custom_type_handlers )
256258 when :list
257259 return nil unless read_size ( buffer )
258260
259261 value_type = type . value_type
260- ::Array . new ( buffer . read_signed_int ) { read_value_v4 ( buffer , value_type ) }
262+ ::Array . new ( buffer . read_signed_int ) { read_value_v4 ( buffer , value_type , custom_type_handlers ) }
261263 when :map
262264 return nil unless read_size ( buffer )
263265
@@ -266,7 +268,7 @@ def read_value_v4(buffer, type)
266268 value = ::Hash . new
267269
268270 buffer . read_signed_int . times do
269- value [ read_value_v4 ( buffer , key_type ) ] = read_value_v4 ( buffer , value_type )
271+ value [ read_value_v4 ( buffer , key_type , custom_type_handlers ) ] = read_value_v4 ( buffer , value_type , custom_type_handlers )
270272 end
271273
272274 value
@@ -277,7 +279,7 @@ def read_value_v4(buffer, type)
277279 value = ::Set . new
278280
279281 buffer . read_signed_int . times do
280- value << read_value_v4 ( buffer , value_type )
282+ value << read_value_v4 ( buffer , value_type , custom_type_handlers )
281283 end
282284
283285 value
@@ -295,7 +297,7 @@ def read_value_v4(buffer, type)
295297 values [ field . name ] = if length - buffer . length >= size
296298 nil
297299 else
298- read_value_v4 ( buffer , field . type )
300+ read_value_v4 ( buffer , field . type , custom_type_handlers )
299301 end
300302 end
301303
@@ -308,7 +310,7 @@ def read_value_v4(buffer, type)
308310
309311 members . each do |member_type |
310312 break if buffer . empty?
311- values << read_value_v4 ( buffer , member_type )
313+ values << read_value_v4 ( buffer , member_type , custom_type_handlers )
312314 end
313315
314316 values . fill ( nil , values . length , ( members . length - values . length ) )
@@ -774,6 +776,15 @@ def read_boolean(buffer)
774776 read_size ( buffer ) && buffer . read ( 1 ) == Constants ::TRUE_BYTE
775777 end
776778
779+ def read_custom ( buffer , type , custom_type_handlers )
780+ # Lookup the type-name to get the Class that can deserialize buffer data into a custom domain object.
781+ unless custom_type_handlers && custom_type_handlers . key? ( type )
782+ raise Errors ::DecodingError , %(Unsupported custom column type: #{ type . name } )
783+ end
784+ num_bytes = read_size ( buffer )
785+ custom_type_handlers [ type ] . deserialize ( buffer . read ( num_bytes ) ) if num_bytes && num_bytes > 0
786+ end
787+
777788 def read_decimal ( buffer )
778789 size = read_size ( buffer )
779790 size && buffer . read_decimal ( size )
@@ -860,6 +871,15 @@ def write_boolean(buffer, value)
860871 buffer . append ( value ? Constants ::TRUE_BYTE : Constants ::FALSE_BYTE )
861872 end
862873
874+ def write_custom ( buffer , value , type )
875+ # Verify that the given type-name matches the value's cql type name.
876+ if value . class . type != type
877+ raise Errors ::EncodingError , "type mismatch: value is a #{ value . type } and column is a #{ type } "
878+ end
879+
880+ buffer . append_bytes ( value . serialize )
881+ end
882+
863883 def write_decimal ( buffer , value )
864884 buffer . append_bytes ( CqlByteBuffer . new . append_decimal ( value ) )
865885 end
0 commit comments