| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 1 | open Thrift | 
|  | 2 |  | 
|  | 3 | module P = Protocol | 
|  | 4 |  | 
|  | 5 | let get_byte i b = 255 land (i lsr (8*b)) | 
|  | 6 | let get_byte64 i b = 255 land (Int64.to_int (Int64.shift_right i (8*b))) | 
|  | 7 |  | 
|  | 8 |  | 
|  | 9 | let tv = P.t_type_to_i | 
|  | 10 | let vt = P.t_type_of_i | 
|  | 11 |  | 
|  | 12 |  | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 13 | let comp_int b n = | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 14 | let s = ref 0l in | 
|  | 15 | let sb = 32 - 8*n in | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 16 | for i=0 to (n-1) do | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 17 | s:= Int32.logor !s (Int32.shift_left (Int32.of_int (int_of_char b.[i])) (8*(n-1-i))) | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 18 | done; | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 19 | Int32.to_int (Int32.shift_right (Int32.shift_left !s sb) sb) | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 20 |  | 
|  | 21 | let comp_int64 b n = | 
|  | 22 | let s = ref 0L in | 
|  | 23 | for i=0 to (n-1) do | 
|  | 24 | s:=Int64.logor !s (Int64.shift_left (Int64.of_int (int_of_char b.[i])) (8*(n-1-i))) | 
|  | 25 | done; | 
|  | 26 | !s | 
|  | 27 |  | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 28 | let version_mask = 0xffff0000 | 
|  | 29 | let version_1 = 0x80010000 | 
|  | 30 |  | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 31 | class t trans = | 
|  | 32 | object (self) | 
|  | 33 | inherit P.t trans | 
|  | 34 | val ibyte = String.create 8 | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 35 | method writeBool b = | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 36 | ibyte.[0] <- char_of_int (if b then 1 else 0); | 
|  | 37 | trans#write ibyte 0 1 | 
|  | 38 | method writeByte i = | 
|  | 39 | ibyte.[0] <- char_of_int (get_byte i 0); | 
|  | 40 | trans#write ibyte 0 1 | 
|  | 41 | method writeI16 i = | 
|  | 42 | let gb = get_byte i in | 
|  | 43 | ibyte.[1] <- char_of_int (gb 0); | 
|  | 44 | ibyte.[0] <- char_of_int (gb 1); | 
|  | 45 | trans#write ibyte 0 2 | 
|  | 46 | method writeI32 i = | 
|  | 47 | let gb = get_byte i in | 
|  | 48 | for i=0 to 3 do | 
|  | 49 | ibyte.[3-i] <- char_of_int (gb i) | 
|  | 50 | done; | 
|  | 51 | trans#write ibyte 0 4 | 
|  | 52 | method writeI64 i= | 
|  | 53 | let gb = get_byte64 i in | 
|  | 54 | for i=0 to 7 do | 
|  | 55 | ibyte.[7-i] <- char_of_int (gb i) | 
|  | 56 | done; | 
|  | 57 | trans#write ibyte 0 8 | 
|  | 58 | method writeDouble d = | 
|  | 59 | self#writeI64 (Int64.bits_of_float d) | 
|  | 60 | method writeString s= | 
|  | 61 | let n = String.length s in | 
|  | 62 | self#writeI32(n); | 
|  | 63 | trans#write s 0 n | 
|  | 64 | method writeBinary a = self#writeString a | 
|  | 65 | method writeMessageBegin (n,t,s) = | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 66 | self#writeI32 (version_1 lor (P.message_type_to_i t)); | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 67 | self#writeString n; | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 68 | self#writeI32 s | 
|  | 69 | method writeMessageEnd = () | 
|  | 70 | method writeStructBegin s = () | 
|  | 71 | method writeStructEnd = () | 
|  | 72 | method writeFieldBegin (n,t,i) = | 
|  | 73 | self#writeByte (tv t); | 
|  | 74 | self#writeI16 i | 
|  | 75 | method writeFieldEnd = () | 
|  | 76 | method writeFieldStop = | 
|  | 77 | self#writeByte (tv (Protocol.T_STOP)) | 
|  | 78 | method writeMapBegin (k,v,s) = | 
|  | 79 | self#writeByte (tv k); | 
|  | 80 | self#writeByte (tv v); | 
|  | 81 | self#writeI32 s | 
|  | 82 | method writeMapEnd = () | 
|  | 83 | method writeListBegin (t,s) = | 
|  | 84 | self#writeByte (tv t); | 
|  | 85 | self#writeI32 s | 
|  | 86 | method writeListEnd = () | 
|  | 87 | method writeSetBegin (t,s) = | 
|  | 88 | self#writeByte (tv t); | 
|  | 89 | self#writeI32 s | 
|  | 90 | method writeSetEnd = () | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 91 | method readByte = | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 92 | ignore (trans#readAll ibyte 0 1); | 
|  | 93 | (comp_int ibyte 1) | 
|  | 94 | method readI16 = | 
|  | 95 | ignore (trans#readAll ibyte 0 2); | 
|  | 96 | comp_int ibyte 2 | 
|  | 97 | method readI32 = | 
|  | 98 | ignore (trans#readAll ibyte 0 4); | 
|  | 99 | comp_int ibyte 4 | 
|  | 100 | method readI64 = | 
|  | 101 | ignore (trans#readAll ibyte 0 8); | 
|  | 102 | comp_int64 ibyte 8 | 
|  | 103 | method readDouble = | 
|  | 104 | Int64.float_of_bits (self#readI64) | 
|  | 105 | method readBool = | 
|  | 106 | self#readByte = 1 | 
|  | 107 | method readString = | 
|  | 108 | let sz = self#readI32 in | 
|  | 109 | let buf = String.create sz in | 
|  | 110 | ignore (trans#readAll buf 0 sz); | 
|  | 111 | buf | 
|  | 112 | method readBinary = self#readString | 
|  | 113 | method readMessageBegin = | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 114 | let ver = self#readI32 in | 
|  | 115 | if (ver land version_mask != version_1) then | 
|  | 116 | (print_int ver; | 
| iproctor | e470aa3 | 2007-08-10 20:48:12 +0000 | [diff] [blame] | 117 | raise (P.E (P.BAD_VERSION, "Missing version identifier"))) | 
| iproctor | d4de1e9 | 2007-07-24 19:47:55 +0000 | [diff] [blame] | 118 | else | 
|  | 119 | let s = self#readString in | 
|  | 120 | let mt = P.message_type_of_i (ver land 0xFF) in | 
|  | 121 | (s,mt, self#readI32) | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 122 | method readMessageEnd = () | 
|  | 123 | method readStructBegin = | 
|  | 124 | "" | 
|  | 125 | method readStructEnd = () | 
|  | 126 | method readFieldBegin = | 
| David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 127 | let t = (vt (self#readByte)) | 
| iproctor | 9a41a0c | 2007-07-16 21:59:24 +0000 | [diff] [blame] | 128 | in | 
|  | 129 | if t != P.T_STOP then | 
|  | 130 | ("",t,self#readI16) | 
|  | 131 | else ("",t,0); | 
|  | 132 | method readFieldEnd = () | 
|  | 133 | method readMapBegin = | 
|  | 134 | let kt = vt (self#readByte) in | 
|  | 135 | let vt = vt (self#readByte) in | 
|  | 136 | (kt,vt, self#readI32) | 
|  | 137 | method readMapEnd = () | 
|  | 138 | method readListBegin = | 
|  | 139 | let t = vt (self#readByte) in | 
|  | 140 | (t,self#readI32) | 
|  | 141 | method readListEnd = () | 
|  | 142 | method readSetBegin = | 
|  | 143 | let t = vt (self#readByte) in | 
|  | 144 | (t, self#readI32); | 
|  | 145 | method readSetEnd = () | 
|  | 146 | end | 
|  | 147 |  | 
|  | 148 | class factory = | 
|  | 149 | object | 
|  | 150 | inherit P.factory | 
|  | 151 | method getProtocol tr = new t tr | 
|  | 152 | end |