class Thrift::JsonProtocol

Public Class Methods

new(trans) click to toggle source
Calls superclass method Thrift::BaseProtocol::new
    # File lib/thrift/protocol/json_protocol.rb
153 def initialize(trans)
154   super(trans)
155   @context = JSONContext.new
156   @contexts = Array.new
157   @reader = LookaheadReader.new(trans)
158 end
read_syntax_char(reader, ch) click to toggle source

Read 1 character from the trans and verify that it is the expected character ch. Throw a protocol exception if it is not.

    # File lib/thrift/protocol/json_protocol.rb
225 def self.read_syntax_char(reader, ch)
226   ch2 = reader.read
227   if (ch2 != ch)
228     raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected \'#{ch}\' got \'#{ch2}\'.")
229   end
230 end

Public Instance Methods

get_type_id_for_type_name(name) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
189 def get_type_id_for_type_name(name)
190   if (name == "tf")
191     result = Types::BOOL
192   elsif (name == "i8")
193     result = Types::BYTE
194   elsif (name == "i16")
195     result = Types::I16
196   elsif (name == "i32")
197     result = Types::I32
198   elsif (name == "i64")
199     result = Types::I64
200   elsif (name == "dbl")
201     result = Types::DOUBLE
202   elsif (name == "str")
203     result = Types::STRING
204   elsif (name == "rec")
205     result = Types::STRUCT
206   elsif (name == "map")
207     result = Types::MAP
208   elsif (name == "set")
209     result = Types::SET
210   elsif (name == "lst")
211     result = Types::LIST
212   else
213     result = Types::STOP
214   end
215   if (result == Types::STOP)
216     raise NotImplementedError
217   end
218   return result
219 end
get_type_name_for_type_id(id) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
160 def get_type_name_for_type_id(id)
161   case id
162   when Types::BOOL
163     "tf"
164   when Types::BYTE
165     "i8"
166   when Types::I16
167     "i16"
168   when Types::I32
169     "i32"
170   when Types::I64
171     "i64"
172   when Types::DOUBLE
173     "dbl"
174   when Types::STRING
175     "str"
176   when Types::STRUCT
177     "rec"
178   when Types::MAP
179     "map"
180   when Types::SET
181     "set"
182   when Types::LIST
183     "lst"
184   else
185     raise NotImplementedError
186   end
187 end
is_json_numeric(ch) click to toggle source

Return true if the character ch is in [-+0-9.Ee]; false otherwise

    # File lib/thrift/protocol/json_protocol.rb
233 def is_json_numeric(ch)
234   case ch
235   when '+', '-', '.', '0' .. '9', 'E', "e"
236     return true
237   else
238     return false
239   end
240 end
pop_context() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
247 def pop_context
248   @context = @contexts.pop
249 end
push_context(context) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
242 def push_context(context)
243   @contexts.push(@context)
244   @context = context
245 end
read_binary() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
768 def read_binary
769   read_json_base64
770 end
read_bool() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
739 def read_bool
740   byte = read_byte
741   byte != 0
742 end
read_byte() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
744 def read_byte
745   read_json_integer
746 end
read_double() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
760 def read_double
761   read_json_double
762 end
read_field_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
690 def read_field_begin
691   # Check if we hit the end of the list
692   ch = @reader.peek
693   if (ch == @@kJSONObjectEnd)
694     field_type = Types::STOP
695   else
696     field_id = read_json_integer
697     read_json_object_start
698     field_type = get_type_id_for_type_name(read_json_string)
699   end
700   [nil, field_type, field_id]
701 end
read_field_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
703 def read_field_end
704   read_json_object_end
705 end
read_i16() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
748 def read_i16
749   read_json_integer
750 end
read_i32() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
752 def read_i32
753   read_json_integer
754 end
read_i64() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
756 def read_i64
757   read_json_integer
758 end
read_json_array_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
657 def read_json_array_end
658   read_json_syntax_char(@@kJSONArrayEnd)
659   pop_context
660   nil
661 end
read_json_array_start() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
650 def read_json_array_start
651   @context.read(@reader)
652   read_json_syntax_char(@@kJSONArrayStart)
653   push_context(JSONListContext.new)
654   nil
655 end
read_json_base64() click to toggle source

Reads a block of base64 characters, decoding it, and returns via str

    # File lib/thrift/protocol/json_protocol.rb
549 def read_json_base64
550   str = read_json_string
551   m = str.length % 4
552   if m != 0
553     # Add missing padding
554     (4 - m).times do
555       str += '='
556     end
557   end
558   Base64.strict_decode64(str)
559 end
read_json_double() click to toggle source

Reads a JSON number or string and interprets it as a double.

    # File lib/thrift/protocol/json_protocol.rb
599 def read_json_double
600   @context.read(@reader)
601   num = 0
602   if (@reader.peek == @@kJSONStringDelimiter)
603     str = read_json_string(true)
604     # Check for NaN, Infinity and -Infinity
605     if (str == @@kThriftNan)
606       num = (+1.0/0.0)/(+1.0/0.0)
607     elsif (str == @@kThriftInfinity)
608       num = +1.0/0.0
609     elsif (str == @@kThriftNegativeInfinity)
610       num = -1.0/0.0
611     else
612       if (!@context.escapeNum)
613         # Raise exception -- we should not be in a string in this case
614         raise ProtocolException.new(ProtocolException::INVALID_DATA, "Numeric data unexpectedly quoted")
615       end
616       begin
617         num = Float(str)
618       rescue
619         raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"")
620       end
621     end
622   else
623     if (@context.escapeNum)
624       # This will throw - we should have had a quote if escapeNum == true
625       read_json_syntax_char(@@kJSONStringDelimiter)
626     end
627     str = read_json_numeric_chars
628     begin
629       num = Float(str)
630     rescue
631       raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"")
632     end
633   end
634   return num
635 end
read_json_escape_char() click to toggle source

Decodes the four hex parts of a JSON escaped string character and returns the character via out.

Note - this only supports Unicode characters in the BMP (U+0000 to U+FFFF); characters above the BMP are encoded as two escape sequences (surrogate pairs), which is not yet implemented

    # File lib/thrift/protocol/json_protocol.rb
495 def read_json_escape_char
496   str = @reader.read
497   str += @reader.read
498   str += @reader.read
499   str += @reader.read
500   if RUBY_VERSION >= '1.9'
501     str.hex.chr(Encoding::UTF_8)
502   else
503     str.hex.chr
504   end
505 end
read_json_integer() click to toggle source

Reads a sequence of characters and assembles them into a number, returning them via num

    # File lib/thrift/protocol/json_protocol.rb
578 def read_json_integer
579   @context.read(@reader)
580   if (@context.escapeNum)
581     read_json_syntax_char(@@kJSONStringDelimiter)
582   end
583   str = read_json_numeric_chars
584 
585   begin
586     num = Integer(str);
587   rescue
588     raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"")
589   end
590 
591   if (@context.escapeNum)
592     read_json_syntax_char(@@kJSONStringDelimiter)
593   end
594 
595   return num
596 end
read_json_numeric_chars() click to toggle source

Reads a sequence of characters, stopping at the first one that is not a valid JSON numeric character.

    # File lib/thrift/protocol/json_protocol.rb
563 def read_json_numeric_chars
564   str = ""
565   while (true)
566     ch = @reader.peek
567     if (!is_json_numeric(ch))
568       break;
569     end
570     ch = @reader.read
571     str += ch
572   end
573   return str
574 end
read_json_object_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
644 def read_json_object_end
645   read_json_syntax_char(@@kJSONObjectEnd)
646   pop_context
647   nil
648 end
read_json_object_start() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
637 def read_json_object_start
638   @context.read(@reader)
639   read_json_syntax_char(@@kJSONObjectStart)
640   push_context(JSONPairContext.new)
641   nil
642 end
read_json_string(skipContext = false) click to toggle source

Decodes a JSON string, including unescaping, and returns the string via str

    # File lib/thrift/protocol/json_protocol.rb
508 def read_json_string(skipContext = false)
509   # This string's characters must match up with the elements in escape_char_vals.
510   # I don't have '/' on this list even though it appears on www.json.org --
511   # it is not in the RFC -> it is. See RFC 4627
512   escape_chars = "\"\\/bfnrt"
513 
514   # The elements of this array must match up with the sequence of characters in
515   # escape_chars
516   escape_char_vals = [
517     "\"", "\\", "\/", "\b", "\f", "\n", "\r", "\t",
518   ]
519 
520   if !skipContext
521     @context.read(@reader)
522   end
523   read_json_syntax_char(@@kJSONStringDelimiter)
524   ch = ""
525   str = ""
526   while (true)
527     ch = @reader.read
528     if (ch == @@kJSONStringDelimiter)
529       break
530     end
531     if (ch == @@kJSONBackslash)
532       ch = @reader.read
533       if (ch == 'u')
534         ch = read_json_escape_char
535       else
536         pos = escape_chars.index(ch);
537         if (pos.nil?) # not found
538           raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected control char, got \'#{ch}\'.")
539         end
540         ch = escape_char_vals[pos]
541       end
542     end
543     str += ch
544   end
545   return str
546 end
read_json_syntax_char(ch) click to toggle source

Reads 1 byte and verifies that it matches ch.

    # File lib/thrift/protocol/json_protocol.rb
485 def read_json_syntax_char(ch)
486   JsonProtocol::read_syntax_char(@reader, ch)
487 end
read_list_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
721 def read_list_begin
722   read_json_array_start
723   [get_type_id_for_type_name(read_json_string), read_json_integer]
724 end
read_list_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
726 def read_list_end
727   read_json_array_end
728 end
read_map_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
707 def read_map_begin
708   read_json_array_start
709   key_type = get_type_id_for_type_name(read_json_string)
710   val_type = get_type_id_for_type_name(read_json_string)
711   size = read_json_integer
712   read_json_object_start
713   [key_type, val_type, size]
714 end
read_map_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
716 def read_map_end
717   read_json_object_end
718   read_json_array_end
719 end
read_message_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
663 def read_message_begin
664   read_json_array_start
665   version = read_json_integer
666   if (version != @@kThriftVersion1)
667     raise ProtocolException.new(ProtocolException::BAD_VERSION, 'Message contained bad version.')
668   end
669   name = read_json_string
670   message_type = read_json_integer
671   seqid = read_json_integer
672   [name, message_type, seqid]
673 end
read_message_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
675 def read_message_end
676   read_json_array_end
677   nil
678 end
read_set_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
730 def read_set_begin
731   read_json_array_start
732   [get_type_id_for_type_name(read_json_string), read_json_integer]
733 end
read_set_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
735 def read_set_end
736   read_json_array_end
737 end
read_string() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
764 def read_string
765   read_json_string
766 end
read_struct_begin() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
680 def read_struct_begin
681   read_json_object_start
682   nil
683 end
read_struct_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
685 def read_struct_end
686   read_json_object_end
687   nil
688 end
to_s() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
772 def to_s
773   "json(#{super.to_s})"
774 end
write_binary(str) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
476 def write_binary(str)
477   write_json_base64(str)
478 end
write_bool(bool) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
448 def write_bool(bool)
449   write_json_integer(bool ? 1 : 0)
450 end
write_byte(byte) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
452 def write_byte(byte)
453   write_json_integer(byte)
454 end
write_double(dub) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
468 def write_double(dub)
469   write_json_double(dub)
470 end
write_field_begin(name, type, id) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
403 def write_field_begin(name, type, id)
404   write_json_integer(id)
405   write_json_object_start
406   write_json_string(get_type_name_for_type_id(type))
407 end
write_field_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
409 def write_field_end
410   write_json_object_end
411 end
write_field_stop() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
413 def write_field_stop; nil; end
write_i16(i16) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
456 def write_i16(i16)
457   write_json_integer(i16)
458 end
write_i32(i32) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
460 def write_i32(i32)
461   write_json_integer(i32)
462 end
write_i64(i64) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
464 def write_i64(i64)
465   write_json_integer(i64)
466 end
write_json_array_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
378 def write_json_array_end
379   pop_context
380   trans.write(@@kJSONArrayEnd)
381 end
write_json_array_start() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
372 def write_json_array_start
373   @context.write(trans)
374   trans.write(@@kJSONArrayStart)
375   push_context(JSONListContext.new);
376 end
write_json_base64(str) click to toggle source

Write out the contents of the string as JSON string, base64-encoding the string’s contents, and escaping as appropriate

    # File lib/thrift/protocol/json_protocol.rb
311 def write_json_base64(str)
312   @context.write(trans)
313   trans.write(@@kJSONStringDelimiter)
314   trans.write(Base64.strict_encode64(str))
315   trans.write(@@kJSONStringDelimiter)
316 end
write_json_char(ch) click to toggle source

Write the character ch as part of a JSON string, escaping as appropriate.

    # File lib/thrift/protocol/json_protocol.rb
262 def write_json_char(ch)
263   # This table describes the handling for the first 0x30 characters
264   # 0 : escape using "\u00xx" notation
265   # 1 : just output index
266   # <other> : escape using "\<other>" notation
267   kJSONCharTable = [
268       # 0 1 2 3 4 5 6 7 8 9 A B C D E F
269       0, 0, 0, 0, 0, 0, 0, 0,'b','t','n', 0,'f','r', 0, 0, # 0
270       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1
271       1, 1,'"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 2
272   ]
273 
274   ch_value = ch[0]
275   if (ch_value.kind_of? String)
276     ch_value = ch.bytes.first
277   end
278   if (ch_value >= 0x30)
279     if (ch == @@kJSONBackslash) # Only special character >= 0x30 is '\'
280       trans.write(@@kJSONBackslash)
281       trans.write(@@kJSONBackslash)
282     else
283       trans.write(ch)
284     end
285   else
286     outCh = kJSONCharTable[ch_value];
287     # Check if regular character, backslash escaped, or JSON escaped
288     if outCh.kind_of? String
289       trans.write(@@kJSONBackslash)
290       trans.write(outCh)
291     elsif outCh == 1
292       trans.write(ch)
293     else
294       write_json_escape_char(ch)
295     end
296   end
297 end
write_json_double(num) click to toggle source

Convert the given double to a JSON string, which is either the number, “NaN” or “Infinity” or “-Infinity”.

    # File lib/thrift/protocol/json_protocol.rb
334 def write_json_double(num)
335   @context.write(trans)
336   # Normalize output of thrift::to_string for NaNs and Infinities
337   special = false;
338   if (num.nan?)
339     special = true;
340     val = @@kThriftNan;
341   elsif (num.infinite?)
342     special = true;
343     val = @@kThriftInfinity;
344     if (num < 0.0)
345       val = @@kThriftNegativeInfinity;
346     end
347   else
348     val = num.to_s
349   end
350 
351   escapeNum = special || @context.escapeNum
352   if (escapeNum)
353     trans.write(@@kJSONStringDelimiter)
354   end
355   trans.write(val)
356   if (escapeNum)
357     trans.write(@@kJSONStringDelimiter)
358   end
359 end
write_json_escape_char(ch) click to toggle source

Write the character ch as a JSON escape sequence (“u00xx”)

    # File lib/thrift/protocol/json_protocol.rb
252 def write_json_escape_char(ch)
253   trans.write('\\u')
254   ch_value = ch[0]
255   if (ch_value.kind_of? String)
256     ch_value = ch.bytes.first
257   end
258   trans.write(ch_value.to_s(16).rjust(4,'0'))
259 end
write_json_integer(num) click to toggle source

Convert the given integer type to a JSON number, or a string if the context requires it (eg: key in a map pair).

    # File lib/thrift/protocol/json_protocol.rb
320 def write_json_integer(num)
321   @context.write(trans)
322   escapeNum = @context.escapeNum
323   if (escapeNum)
324     trans.write(@@kJSONStringDelimiter)
325   end
326   trans.write(num.to_s);
327   if (escapeNum)
328     trans.write(@@kJSONStringDelimiter)
329   end
330 end
write_json_object_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
367 def write_json_object_end
368   pop_context
369   trans.write(@@kJSONObjectEnd)
370 end
write_json_object_start() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
361 def write_json_object_start
362   @context.write(trans)
363   trans.write(@@kJSONObjectStart)
364   push_context(JSONPairContext.new);
365 end
write_json_string(str) click to toggle source

Write out the contents of the string str as a JSON string, escaping characters as appropriate.

    # File lib/thrift/protocol/json_protocol.rb
300 def write_json_string(str)
301   @context.write(trans)
302   trans.write(@@kJSONStringDelimiter)
303   str.split('').each do |ch|
304     write_json_char(ch)
305   end
306   trans.write(@@kJSONStringDelimiter)
307 end
write_list_begin(etype, size) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
428 def write_list_begin(etype, size)
429   write_json_array_start
430   write_json_string(get_type_name_for_type_id(etype))
431   write_json_integer(size)
432 end
write_list_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
434 def write_list_end
435   write_json_array_end
436 end
write_map_begin(ktype, vtype, size) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
415 def write_map_begin(ktype, vtype, size)
416   write_json_array_start
417   write_json_string(get_type_name_for_type_id(ktype))
418   write_json_string(get_type_name_for_type_id(vtype))
419   write_json_integer(size)
420   write_json_object_start
421 end
write_map_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
423 def write_map_end
424   write_json_object_end
425   write_json_array_end
426 end
write_message_begin(name, type, seqid) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
383 def write_message_begin(name, type, seqid)
384   write_json_array_start
385   write_json_integer(@@kThriftVersion1)
386   write_json_string(name)
387   write_json_integer(type)
388   write_json_integer(seqid)
389 end
write_message_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
391 def write_message_end
392   write_json_array_end
393 end
write_set_begin(etype, size) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
438 def write_set_begin(etype, size)
439   write_json_array_start
440   write_json_string(get_type_name_for_type_id(etype))
441   write_json_integer(size)
442 end
write_set_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
444 def write_set_end
445   write_json_array_end
446 end
write_string(str) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
472 def write_string(str)
473   write_json_string(str)
474 end
write_struct_begin(name) click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
395 def write_struct_begin(name)
396   write_json_object_start
397 end
write_struct_end() click to toggle source
    # File lib/thrift/protocol/json_protocol.rb
399 def write_struct_end
400   write_json_object_end
401 end