Source file mp_raw_data.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
type row_data =
| Row_data_data of string
| Row_data_null
| Row_data_binary of Bitstring.t
let row_data_to_string p =
let v =
match p with
| Row_data_data d -> d
| Row_data_null -> "NULL"
| Row_data_binary b -> Bitstring.string_of_bitstring b
in
Printf.sprintf "row_data : %s\n" v
let binary data field_packet =
let field_type = field_packet.Mp_field_packet.field_type in
let (length_bits, data) =
match field_type with
| Mp_field_packet.Field_type_tiny -> (Int64.of_int (1 * 8), data)
| Mp_field_packet.Field_type_short
| Mp_field_packet.Field_type_year -> (Int64.of_int (2 * 8), data)
| Mp_field_packet.Field_type_float
| Mp_field_packet.Field_type_long -> (Int64.of_int (4 * 8), data)
| Mp_field_packet.Field_type_int24 -> (Int64.of_int (4 * 8), data)
| Mp_field_packet.Field_type_double
| Mp_field_packet.Field_type_longlong -> (Int64.of_int (8 * 8), data)
| Mp_field_packet.Field_type_newdecimal
| Mp_field_packet.Field_type_datetime
| Mp_field_packet.Field_type_time
| Mp_field_packet.Field_type_date
| Mp_field_packet.Field_type_timestamp
| Mp_field_packet.Field_type_string
| Mp_field_packet.Field_type_var_string
| Mp_field_packet.Field_type_blob
| Mp_field_packet.Field_type_long_blob
| Mp_field_packet.Field_type_medium_blob
| Mp_field_packet.Field_type_tiny_blob
| Mp_field_packet.Field_type_bit
| Mp_field_packet.Field_type_geometry -> (
let (l, d) = Mp_binary.length_coded_binary data in
(Int64.mul l (Int64.of_int 8), d)
)
| _ -> assert false
in
let length_rest = (Bitstring.bitstring_length data) - (Int64.to_int length_bits) in
match%bitstring data with
| {| value : (Int64.to_int length_bits) : bitstring;
rest : length_rest : bitstring |} -> (value, rest)
let raw_data_packet_binary list_field_packet list_null_fields bits =
let nb_columns = List.length list_field_packet in
let count_columns = ref 0 in
let data = ref bits in
let l = ref [] in
let () =
while (Bitstring.bitstring_length !data > 0 || !count_columns < nb_columns) do
let (v, rest) =
if (List.length list_null_fields > 0) then
if (List.nth list_null_fields !count_columns) then
let () = incr count_columns in
(Row_data_null, !data)
else
let (v, rest) = binary !data (List.nth list_field_packet !count_columns) in
let () = incr count_columns in
(Row_data_binary v, rest)
else
let (v, rest) = binary !data (List.nth list_field_packet !count_columns) in
let () = incr count_columns in
(Row_data_binary v, rest)
in
let () = l := v :: !l in
data := rest
done
in
List.rev !l
let null_bytes bits =
let nb_bytes = (Bitstring.bitstring_length bits) / 8 in
if (nb_bytes > 0) then (
let byte b l =
match%bitstring b with
| {| bit0 : 1 : int;
bit1 : 1 : int;
bit2 : 1 : int;
bit3 : 1 : int;
bit4 : 1 : int;
bit5 : 1 : int;
bit6 : 1 : int;
bit7 : 1 : int |} -> (
l := bit7 :: !l;
l := bit6 :: !l;
l := bit5 :: !l;
l := bit4 :: !l;
l := bit3 :: !l;
l := bit2 :: !l;
l := bit1 :: !l;
l := bit0 :: !l;
)
in
let l = ref [] in
let () =
for i = 0 to (nb_bytes - 1) do
byte (Bitstring.subbitstring bits (i * 8) 8) l
done
in
List.rev !l
)
else (
[]
)
let raw_data_packet list_field_packet type_sent count_rows bits =
let binary_encoding = ref false in
let bits =
match type_sent with
| Mp_com.Fetch ->
if (count_rows > 0) then
if (Bitstring.bitstring_length bits > 0) then (
let length_rest = (Bitstring.bitstring_length bits) - 8 in
match%bitstring bits with
| {| test : 1*8 : int, unsigned;
rest : length_rest : bitstring |} -> (
if (test = 0) then
let () = binary_encoding := true in
rest
else
bits
)
) else
bits
else
let () = binary_encoding := true in
bits
| _ ->
if (Bitstring.bitstring_length bits > 0) then (
let length_rest = (Bitstring.bitstring_length bits) - 8 in
match%bitstring bits with
| {| test : 1*8 : int, unsigned;
rest : length_rest : bitstring |} -> (
if (test = 0) then
let () = binary_encoding := true in
rest
else
bits
)
) else
bits
in
if (!binary_encoding) then (
let nb_null_bits = ((((List.length list_field_packet) + 7 + 2) / 8) * 8) in
let length_rest = (Bitstring.bitstring_length bits) - nb_null_bits in
match%bitstring bits with
| {| null_bits : nb_null_bits : bitstring;
rest : length_rest : bitstring |} -> (
let list_null_fields = null_bytes null_bits in
let list_null_fields =
match list_null_fields with
| [] -> []
| _ :: _ :: l -> l
| _ -> assert false
in
raw_data_packet_binary list_field_packet list_null_fields rest
)
) else (
let data = ref bits in
let l = ref [] in
let () =
while (Bitstring.bitstring_length !data > 0) do
let null_value = ref false in
let () =
if (Bitstring.bitstring_length !data >= 8) then (
match%bitstring !data with
| {| test : 1*8 : int, unsigned, bigendian |} -> (
if (test = 251) then
null_value := true
)
)
in
let (v, rest) =
if !null_value then (
let length_rest = (Bitstring.bitstring_length !data) - 8 in
match%bitstring !data with
| {| _ : 1*8 : int, unsigned, bigendian;
rest : length_rest : bitstring |} -> (Row_data_null, rest)
) else (
let (v, rest) = Mp_string.length_coded_string !data in
(Row_data_data v, rest)
)
in
let () = l := v :: !l in
data := rest
done
in
List.rev !l
)