2
2
3
3
% % API
4
4
-export ([decode_packet /2 ]).
5
+ -export ([decode_two_task /2 ]).
5
6
-export ([decode_token /2 ]).
6
7
-export ([decode_helper /3 ]).
7
8
@@ -31,7 +32,7 @@ decode_packet(<<PacketSize:16, _PacketFlags:16, Type, _Flags:8, 0:16, Rest/bits>
31
32
decode_packet (_ ,_ ) ->
32
33
{error , more }.
33
34
34
- decode_token (<<Token , Data /binary >>, Acc ) ->
35
+ decode_two_task (<<Token , Data /binary >>, Acc ) ->
35
36
case Token of
36
37
? TTI_DCB -> decode_token (dcb , Data , Acc );
37
38
? TTI_IOV -> decode_token (iov , Data , Acc );
@@ -45,30 +46,8 @@ decode_token(<<Token, Data/binary>>, Acc) ->
45
46
? TTI_FOB -> {error , fob }; % return
46
47
_ ->
47
48
{error , <<Token , (hd (binary :split (Data , <<0 >>)))/binary >>}
48
- end ;
49
- decode_token (net , {Data , EnvOpts }) ->
50
- Values = lists :map (fun (L ) -> list_to_tuple (string :tokens (L , " =" )) end ,
51
- string :tokens (binary_to_list (hd (binary :split (Data , <<0 >>))), " ()" )),
52
- Host = proplists :get_value (" HOST" , Values ),
53
- Port = proplists :get_value (" PORT" , Values ),
54
- {ok , [{host , Host }, {port , list_to_integer (Port )}]++ EnvOpts };
55
- decode_token (rpa , Data ) ->
56
- Num = decode_ub4 (Data ),
57
- Values = decode_keyval (decode_next (Data ), Num , []),
58
- SessKey = get_value (" AUTH_SESSKEY" , Values ),
59
- Salt = get_value (" AUTH_VFR_DATA" , Values ),
60
- Type = get_value (" AUTH_VFR_DATA" , Values , 3 ),
61
- DerivedSalt = get_value (" AUTH_PBKDF2_CSK_SALT" , Values ),
62
- Logon = # logon {type = Type , auth = SessKey , salt = Salt , der_salt = DerivedSalt },
63
- case get_value (" AUTH_SVR_RESPONSE" , Values ) of
64
- undefined ->
65
- {? TTI_SESS , Logon };
66
- Resp ->
67
- Value = get_value (" AUTH_VERSION_NO" , Values ),
68
- SessId = get_value (" AUTH_SESSION_ID" , Values ),
69
- Ver = decode_version (Value ),
70
- {? TTI_AUTH , Resp , Ver , SessId }
71
- end ;
49
+ end .
50
+
72
51
decode_token (oac , Data ) ->
73
52
DataType = decode_ub1 (Data ),
74
53
A = decode_next (ub1 ,Data ), % data type
@@ -87,17 +66,7 @@ decode_token(oac, Data) ->
87
66
M = decode_next (ub1 ,L ), % character set form
88
67
N = decode_next (ub4 ,M ), % mxlc
89
68
{N , DataType , Length , Scale , Charset };
90
- decode_token (wrn , Data ) ->
91
- A = decode_next (ub2 ,Data ), % error number
92
- Length = decode_ub2 (A ),
93
- B = decode_next (ub2 ,A ), % length of error message
94
- C = decode_next (ub2 ,B ), % flags
95
- decode_next (ub1 , C , Length ).
96
-
97
- decode_token (dcb , Data , {Ver , _RowFormat , Type }) when is_atom (Type ) ->
98
- {A , RowFormat } = decode_token (dcb , decode_next (Data ), Ver ),
99
- decode_token (A , {0 , RowFormat , []});
100
- decode_token (dcb , Data , Ver ) ->
69
+ decode_token (dcb , Data ) ->
101
70
A = decode_next (ub4 ,Data ),
102
71
Num = decode_ub4 (A ),
103
72
B = decode_next (ub4 ,A ),
@@ -106,21 +75,50 @@ decode_token(dcb, Data, Ver) ->
106
75
0 -> B ;
107
76
_ -> decode_next (ub1 ,B )
108
77
end ,
109
- {RowFormat , D } = decode_token (uds , C , {Ver , [], Num }),
78
+ {RowFormat , D } = decode_token (uds , C , {[], Num }),
110
79
E = decode_next (dalc ,D ), % flag
111
80
F = decode_next (ub4 ,E ), % mdbz
112
81
G = decode_next (ub4 ,F ), % mnpr
113
82
J = decode_next (ub4 ,G ), % mxpr
114
83
K = decode_next (ub4 ,J ),
115
- L =
116
- case Ver of
117
- 10 -> K ;
118
- _ -> decode_next (dalc ,K )
119
- end ,
84
+ L = decode_next (dalc ,K ),
120
85
{L , RowFormat };
121
- decode_token (uds , Data , {_Ver , RowFormat , 0 }) ->
86
+ decode_token (net , {Data , EnvOpts }) ->
87
+ Values = lists :map (fun (L ) -> list_to_tuple (string :tokens (L , " =" )) end ,
88
+ string :tokens (binary_to_list (hd (binary :split (Data , <<0 >>))), " ()" )),
89
+ Host = proplists :get_value (" HOST" , Values ),
90
+ Port = proplists :get_value (" PORT" , Values ),
91
+ {ok , [{host , Host }, {port , list_to_integer (Port )}]++ EnvOpts };
92
+ decode_token (rpa , Data ) ->
93
+ Num = decode_ub4 (Data ),
94
+ Values = decode_keyval (decode_next (Data ), Num , []),
95
+ SessKey = get_value (" AUTH_SESSKEY" , Values ),
96
+ Salt = get_value (" AUTH_VFR_DATA" , Values ),
97
+ Type = get_value (" AUTH_VFR_DATA" , Values , 3 ),
98
+ DerivedSalt = get_value (" AUTH_PBKDF2_CSK_SALT" , Values ),
99
+ Logon = # logon {type = Type , auth = SessKey , salt = Salt , der_salt = DerivedSalt },
100
+ case get_value (" AUTH_SVR_RESPONSE" , Values ) of
101
+ undefined ->
102
+ {? TTI_SESS , Logon };
103
+ Resp ->
104
+ Value = get_value (" AUTH_VERSION_NO" , Values ),
105
+ SessId = get_value (" AUTH_SESSION_ID" , Values ),
106
+ Ver = decode_version (Value ),
107
+ {? TTI_AUTH , Resp , Ver , SessId }
108
+ end ;
109
+ decode_token (wrn , Data ) ->
110
+ A = decode_next (ub2 ,Data ), % error number
111
+ Length = decode_ub2 (A ),
112
+ B = decode_next (ub2 ,A ), % length of error message
113
+ C = decode_next (ub2 ,B ), % flags
114
+ decode_next (ub1 , C , Length ).
115
+
116
+ decode_token (dcb , Data , {_Cursor , _RowFormat , Type }) when is_atom (Type ) ->
117
+ {A , RowFormat } = decode_token (dcb , decode_next (Data )),
118
+ decode_two_task (A , {0 , RowFormat , []});
119
+ decode_token (uds , Data , {RowFormat , 0 }) ->
122
120
{lists :reverse (RowFormat ), Data };
123
- decode_token (uds , Data , {Ver , RowFormat , Num }) ->
121
+ decode_token (uds , Data , {RowFormat , Num }) ->
124
122
{A , DataType , Length , Scale , Charset } = decode_token (oac , Data ),
125
123
B = decode_next (ub1 ,A ), % nulls allowed
126
124
C = decode_next (ub1 ,B ), % v7 length of name
@@ -129,16 +127,12 @@ decode_token(uds, Data, {Ver, RowFormat, Num}) ->
129
127
E = decode_next (dalc ,D ), % schema name
130
128
F = decode_next (dalc ,E ), % type name
131
129
G = decode_next (ub2 ,F ), % column position
132
- J =
133
- case Ver of
134
- 10 -> G ;
135
- _ -> decode_next (ub4 ,G )
136
- end ,
137
- decode_token (uds , J , {Ver , [# format {column_name = list_to_binary (Column ),
130
+ J = decode_next (ub4 ,G ),
131
+ decode_token (uds , J , {[# format {column_name = list_to_binary (Column ),
138
132
data_type = DataType ,data_length = Length ,data_scale = Scale ,charset = Charset }|RowFormat ], Num - 1 });
139
133
decode_token (rxh , Data , {Cursor , RowFormat , Type }) when is_atom (Type ) ->
140
134
A = decode_next (rxh ,Data ),
141
- decode_token (A , {Cursor , RowFormat , [0 ], []});
135
+ decode_two_task (A , {Cursor , RowFormat , [0 ], []});
142
136
decode_token (rxh , Data , {Cursor , RowFormat , Rows }) ->
143
137
A = decode_next (ub1 ,Data ), % flag
144
138
B = decode_next (ub2 ,A ), % num requests
@@ -152,40 +146,40 @@ decode_token(rxh, Data, {Cursor, RowFormat, Rows}) ->
152
146
_ -> decode_bvc (list_to_binary (Bitvec ), RowFormat , [])
153
147
end ,
154
148
F = decode_next (rxh ,Data ),
155
- decode_token (F , {Cursor , RowFormat , Bvc , Rows });
156
- decode_token (iov , Data , {Ver , RowFormat , Type }) when is_atom (Type ) ->
149
+ decode_two_task (F , {Cursor , RowFormat , Bvc , Rows });
150
+ decode_token (iov , Data , {Cursor , RowFormat , Type }) when is_atom (Type ) ->
157
151
A = decode_next (ub1 ,Data ),
158
152
Num = decode_ub2 (A ),
159
153
<<Mode :Num /binary , Rest /bits >> = decode_next (rxh ,Data ),
160
154
case binary :matches (Mode ,[<<16 >>,<<48 >>]) of
161
- [] -> decode_token (Rest , {0 , [], []}); % proc_result
155
+ [] -> decode_two_task (Rest , {0 , [], []}); % proc_result
162
156
_ ->
163
157
Bind = lists :zip (binary_to_list (Mode ), RowFormat ),
164
- decode_token (Rest , {Ver , [decode_param (B ) || B <- Bind ], Type })
158
+ decode_two_task (Rest , {Cursor , [decode_param (B ) || B <- Bind ], Type })
165
159
end ;
166
- decode_token (rxd , Data , {Ver , _RowFormat , fetch }) ->
167
- {A , CursorRowFormat } = decode_token (dcb , decode_next (ub1 ,Data ), Ver ),
160
+ decode_token (rxd , Data , {_Cursor , _RowFormat , fetch }) ->
161
+ {A , CursorRowFormat } = decode_token (dcb , decode_next (ub1 ,Data )),
168
162
Cursor = decode_ub4 (A ),
169
163
B = decode_next (ub4 ,A ),
170
164
{{Cursor , CursorRowFormat }, decode_next (ub2 ,B )};
171
- decode_token (rxd , Data , {Ver , _RowFormat , cursor }) ->
172
- {A , _CursorRowFormat } = decode_token (dcb , decode_next (ub1 ,Data ), Ver ),
165
+ decode_token (rxd , Data , {_Cursor , _RowFormat , cursor }) ->
166
+ {A , _CursorRowFormat } = decode_token (dcb , decode_next (ub1 ,Data )),
173
167
{decode_ub4 (A ), decode_next (ub4 ,A )};
174
- decode_token (rxd , Data , {Ver , RowFormat , Type }) when is_atom (Type ) ->
175
- case decode_data (Data , [], {[], RowFormat , Ver , Type }) of
168
+ decode_token (rxd , Data , {_Cursor , RowFormat , Type }) when is_atom (Type ) ->
169
+ case decode_data (Data , [], {[], RowFormat , Type }) of
176
170
{{Cursor , CursorRowFormat }, A } ->
177
- decode_token (A , {Cursor , CursorRowFormat , []}); % fetch cursor
178
- {Rows , A } -> decode_token (A , {0 , RowFormat , Rows }) % proc_result
171
+ decode_two_task (A , {Cursor , CursorRowFormat , []}); % fetch cursor
172
+ {Rows , A } -> decode_two_task (A , {0 , RowFormat , Rows }) % proc_result
179
173
end ;
180
174
decode_token (rxd , Data , {Cursor , RowFormat , Bvc , Rows }) ->
181
175
LastRow = last (Rows ),
182
176
{A , Row } = decode_rxd (Data , RowFormat , 1 , Bvc , LastRow , []),
183
- decode_token (A , {Cursor , RowFormat , Bvc , Rows ++ [Row ]});
177
+ decode_two_task (A , {Cursor , RowFormat , Bvc , Rows ++ [Row ]});
184
178
decode_token (bvc , Data , {Cursor , RowFormat , _Bvc , Rows }) ->
185
179
A = decode_next (ub2 ,Data ),
186
180
{Bvc , Num } = decode_bvc (A , RowFormat , []),
187
181
B = decode_next (ub1 , A , Num ),
188
- decode_token (B , {Cursor , RowFormat , Bvc , Rows });
182
+ decode_two_task (B , {Cursor , RowFormat , Bvc , Rows });
189
183
decode_token (lob , Data , _Loc ) ->
190
184
try decode_chr (Data ) of
191
185
Value -> {ok , Value }
@@ -194,7 +188,7 @@ decode_token(lob, Data, _Loc) ->
194
188
end ;
195
189
decode_token (rpa , Data , []) ->
196
190
{ok , [decode_ub4 (Data )]};
197
- decode_token (rpa , Data , {_Ver , RowFormat , Type }) when is_atom (Type ) ->
191
+ decode_token (rpa , Data , {_Cursor , RowFormat , Type }) when is_atom (Type ) ->
198
192
decode_token (rpa , Data , {0 , RowFormat , []});
199
193
decode_token (rpa , Data , {0 , RowFormat , Rows }) ->
200
194
Cursor =
@@ -207,15 +201,15 @@ decode_token(rpa, Data, {0, RowFormat, Rows}) ->
207
201
decode_ub4 (C )
208
202
end ,
209
203
D = decode_next (rpa ,Data ),
210
- decode_token (D , {Cursor , RowFormat , Rows });
204
+ decode_two_task (D , {Cursor , RowFormat , Rows });
211
205
decode_token (rpa , Data , {Cursor , RowFormat , _Bvc , Rows }) ->
212
206
decode_token (rpa , Data , {Cursor , RowFormat , Rows });
213
207
decode_token (rpa , Data , {Cursor , RowFormat , Rows }) ->
214
208
A = decode_next (rpa ,Data ),
215
- decode_token (A , {Cursor , RowFormat , Rows });
209
+ decode_two_task (A , {Cursor , RowFormat , Rows });
216
210
decode_token (oer , Data , []) ->
217
211
decode_token (oer , Data , {0 , [], []});
218
- decode_token (oer , Data , {_Ver , RowFormat , Type }) when is_atom (Type ) ->
212
+ decode_token (oer , Data , {_Cursor , RowFormat , Type }) when is_atom (Type ) ->
219
213
decode_token (oer , Data , {0 , RowFormat , []});
220
214
decode_token (oer , Data , {Cursor , RowFormat , _Bvc , Rows }) ->
221
215
decode_token (oer , Data , {Cursor , RowFormat , Rows });
@@ -369,22 +363,22 @@ decode_bvc(Data, Acc, Num, I) when is_list(Acc) ->
369
363
Bvc = decode_bvc (decode_ub1 (Data ), {}, 0 , I ),
370
364
decode_bvc (decode_next (ub1 ,Data ), Acc ++ tuple_to_list (Bvc ), Num - 1 , I + 1 ).
371
365
372
- decode_data (Data , Values , {[], [], _Ver , _Type }) ->
366
+ decode_data (Data , Values , {[], [], _Type }) ->
373
367
{lists :reverse (Values ), Data };
374
- decode_data (Data , _Values , {DefCol , [], _Ver , _Type }) ->
368
+ decode_data (Data , _Values , {DefCol , [], _Type }) ->
375
369
{DefCol , Data };
376
- decode_data (Data , Values , {DefCol , [# format {param = in }|RestRowFormat ], Ver , Type }) ->
377
- decode_data (Data , Values , {DefCol , RestRowFormat , Ver , Type });
378
- decode_data (Data , Values , {_DefCol , [# format {data_type = ? TNS_TYPE_REFCURSOR }|RestRowFormat ], Ver , Type }) ->
379
- {DefCol , Bin } = decode_token (rxd , Data , {Ver , [], fetch }),
380
- decode_data (Bin , Values , {DefCol , RestRowFormat , Ver , Type });
381
- decode_data (Data , Values , {DefCol , [ValueFormat |RestRowFormat ], Ver , Type = return }) ->
370
+ decode_data (Data , Values , {DefCol , [# format {param = in }|RestRowFormat ], Type }) ->
371
+ decode_data (Data , Values , {DefCol , RestRowFormat , Type });
372
+ decode_data (Data , Values , {_DefCol , [# format {data_type = ? TNS_TYPE_REFCURSOR }|RestRowFormat ], Type }) ->
373
+ {DefCol , Bin } = decode_token (rxd , Data , {0 , [], fetch }),
374
+ decode_data (Bin , Values , {DefCol , RestRowFormat , Type });
375
+ decode_data (Data , Values , {DefCol , [ValueFormat |RestRowFormat ], Type = return }) ->
382
376
Num = decode_ub4 (Data ),
383
377
{Value , RestData } = decode_data (decode_next (ub4 ,Data ), ValueFormat , [], Num , Type ),
384
- decode_data (RestData , [Value |Values ], {DefCol , RestRowFormat , Ver , Type });
385
- decode_data (Data , Values , {DefCol , [ValueFormat |RestRowFormat ], Ver , Type = block }) ->
378
+ decode_data (RestData , [Value |Values ], {DefCol , RestRowFormat , Type });
379
+ decode_data (Data , Values , {DefCol , [ValueFormat |RestRowFormat ], Type = block }) ->
386
380
{Value , RestData } = decode_data (Data , ValueFormat ),
387
- decode_data (decode_next (ub2 ,RestData ), [Value |Values ], {DefCol , RestRowFormat , Ver , Type }).
381
+ decode_data (decode_next (ub2 ,RestData ), [Value |Values ], {DefCol , RestRowFormat , Type }).
388
382
389
383
decode_data (Data , _ValueFormat , Values , 0 , _Type ) ->
390
384
{lists :reverse (Values ), Data };
0 commit comments