| (* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| *) |
| |
| open Thrift |
| |
| module P = Protocol |
| |
| let get_byte i b = 255 land (i lsr (8*b)) |
| let get_byte64 i b = 255 land (Int64.to_int (Int64.shift_right i (8*b))) |
| |
| |
| let tv = P.t_type_to_i |
| let vt = P.t_type_of_i |
| |
| |
| let comp_int b n = |
| let s = ref 0l in |
| let sb = 32 - 8*n in |
| for i=0 to (n-1) do |
| s:= Int32.logor !s (Int32.shift_left (Int32.of_int (int_of_char b.[i])) (8*(n-1-i))) |
| done; |
| Int32.to_int (Int32.shift_right (Int32.shift_left !s sb) sb) |
| |
| let comp_int64 b n = |
| let s = ref 0L in |
| for i=0 to (n-1) do |
| s:=Int64.logor !s (Int64.shift_left (Int64.of_int (int_of_char b.[i])) (8*(n-1-i))) |
| done; |
| !s |
| |
| let version_mask = 0xffff0000 |
| let version_1 = 0x80010000 |
| |
| class t trans = |
| object (self) |
| inherit P.t trans |
| val ibyte = String.create 8 |
| method writeBool b = |
| ibyte.[0] <- char_of_int (if b then 1 else 0); |
| trans#write ibyte 0 1 |
| method writeByte i = |
| ibyte.[0] <- char_of_int (get_byte i 0); |
| trans#write ibyte 0 1 |
| method writeI16 i = |
| let gb = get_byte i in |
| ibyte.[1] <- char_of_int (gb 0); |
| ibyte.[0] <- char_of_int (gb 1); |
| trans#write ibyte 0 2 |
| method writeI32 i = |
| let gb = get_byte i in |
| for i=0 to 3 do |
| ibyte.[3-i] <- char_of_int (gb i) |
| done; |
| trans#write ibyte 0 4 |
| method writeI64 i= |
| let gb = get_byte64 i in |
| for i=0 to 7 do |
| ibyte.[7-i] <- char_of_int (gb i) |
| done; |
| trans#write ibyte 0 8 |
| method writeDouble d = |
| self#writeI64 (Int64.bits_of_float d) |
| method writeString s= |
| let n = String.length s in |
| self#writeI32(n); |
| trans#write s 0 n |
| method writeBinary a = self#writeString a |
| method writeMessageBegin (n,t,s) = |
| self#writeI32 (version_1 lor (P.message_type_to_i t)); |
| self#writeString n; |
| self#writeI32 s |
| method writeMessageEnd = () |
| method writeStructBegin s = () |
| method writeStructEnd = () |
| method writeFieldBegin (n,t,i) = |
| self#writeByte (tv t); |
| self#writeI16 i |
| method writeFieldEnd = () |
| method writeFieldStop = |
| self#writeByte (tv (Protocol.T_STOP)) |
| method writeMapBegin (k,v,s) = |
| self#writeByte (tv k); |
| self#writeByte (tv v); |
| self#writeI32 s |
| method writeMapEnd = () |
| method writeListBegin (t,s) = |
| self#writeByte (tv t); |
| self#writeI32 s |
| method writeListEnd = () |
| method writeSetBegin (t,s) = |
| self#writeByte (tv t); |
| self#writeI32 s |
| method writeSetEnd = () |
| method readByte = |
| ignore (trans#readAll ibyte 0 1); |
| (comp_int ibyte 1) |
| method readI16 = |
| ignore (trans#readAll ibyte 0 2); |
| comp_int ibyte 2 |
| method readI32 = |
| ignore (trans#readAll ibyte 0 4); |
| comp_int ibyte 4 |
| method readI64 = |
| ignore (trans#readAll ibyte 0 8); |
| comp_int64 ibyte 8 |
| method readDouble = |
| Int64.float_of_bits (self#readI64) |
| method readBool = |
| self#readByte = 1 |
| method readString = |
| let sz = self#readI32 in |
| let buf = String.create sz in |
| ignore (trans#readAll buf 0 sz); |
| buf |
| method readBinary = self#readString |
| method readMessageBegin = |
| let ver = self#readI32 in |
| if (ver land version_mask != version_1) then |
| (print_int ver; |
| raise (P.E (P.BAD_VERSION, "Missing version identifier"))) |
| else |
| let s = self#readString in |
| let mt = P.message_type_of_i (ver land 0xFF) in |
| (s,mt, self#readI32) |
| method readMessageEnd = () |
| method readStructBegin = |
| "" |
| method readStructEnd = () |
| method readFieldBegin = |
| let t = (vt (self#readByte)) |
| in |
| if t != P.T_STOP then |
| ("",t,self#readI16) |
| else ("",t,0); |
| method readFieldEnd = () |
| method readMapBegin = |
| let kt = vt (self#readByte) in |
| let vt = vt (self#readByte) in |
| (kt,vt, self#readI32) |
| method readMapEnd = () |
| method readListBegin = |
| let t = vt (self#readByte) in |
| (t,self#readI32) |
| method readListEnd = () |
| method readSetBegin = |
| let t = vt (self#readByte) in |
| (t, self#readI32); |
| method readSetEnd = () |
| end |
| |
| class factory = |
| object |
| inherit P.factory |
| method getProtocol tr = new t tr |
| end |