@@ -14,6 +14,7 @@ import (
14
14
"encoding/binary"
15
15
"fmt"
16
16
"io"
17
+ "strconv"
17
18
"strings"
18
19
"sync"
19
20
"sync/atomic"
@@ -227,87 +228,55 @@ var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
227
228
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
228
229
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
229
230
230
- func formatBinaryDateTime (src []byte , length uint8 , justTime bool ) (driver.Value , error ) {
231
+ func formatBinaryDateTime (src []byte , length uint8 ) (driver.Value , error ) {
231
232
// length expects the deterministic length of the zero value,
232
233
// negative time and 100+ hours are automatically added if needed
233
234
if len (src ) == 0 {
234
- if justTime {
235
- return zeroDateTime [11 : 11 + length ], nil
236
- }
237
235
return zeroDateTime [:length ], nil
238
236
}
239
- var dst []byte // return value
240
- var pt , p1 , p2 , p3 byte // current digit pair
241
- var zOffs byte // offset of value in zeroDateTime
242
- if justTime {
243
- switch length {
244
- case
245
- 8 , // time (can be up to 10 when negative and 100+ hours)
246
- 10 , 11 , 12 , 13 , 14 , 15 : // time with fractional seconds
247
- default :
248
- return nil , fmt .Errorf ("illegal TIME length %d" , length )
249
- }
250
- switch len (src ) {
251
- case 8 , 12 :
252
- default :
253
- return nil , fmt .Errorf ("invalid TIME packet length %d" , len (src ))
254
- }
255
- // +2 to enable negative time and 100+ hours
256
- dst = make ([]byte , 0 , length + 2 )
257
- if src [0 ] == 1 {
258
- dst = append (dst , '-' )
259
- }
260
- if src [1 ] != 0 {
261
- hour := uint16 (src [1 ])* 24 + uint16 (src [5 ])
262
- pt = byte (hour / 100 )
263
- p1 = byte (hour - 100 * uint16 (pt ))
264
- dst = append (dst , digits01 [pt ])
265
- } else {
266
- p1 = src [5 ]
267
- }
268
- zOffs = 11
269
- src = src [6 :]
270
- } else {
271
- switch length {
272
- case 10 , 19 , 21 , 22 , 23 , 24 , 25 , 26 :
273
- default :
274
- t := "DATE"
275
- if length > 10 {
276
- t += "TIME"
277
- }
278
- return nil , fmt .Errorf ("illegal %s length %d" , t , length )
279
- }
280
- switch len (src ) {
281
- case 4 , 7 , 11 :
282
- default :
283
- t := "DATE"
284
- if length > 10 {
285
- t += "TIME"
286
- }
287
- return nil , fmt .Errorf ("illegal %s packet length %d" , t , len (src ))
288
- }
289
- dst = make ([]byte , 0 , length )
290
- // start with the date
291
- year := binary .LittleEndian .Uint16 (src [:2 ])
292
- pt = byte (year / 100 )
293
- p1 = byte (year - 100 * uint16 (pt ))
294
- p2 , p3 = src [2 ], src [3 ]
295
- dst = append (dst ,
296
- digits10 [pt ], digits01 [pt ],
297
- digits10 [p1 ], digits01 [p1 ], '-' ,
298
- digits10 [p2 ], digits01 [p2 ], '-' ,
299
- digits10 [p3 ], digits01 [p3 ],
300
- )
301
- if length == 10 {
302
- return dst , nil
237
+ var dst []byte // return value
238
+ var p1 , p2 , p3 byte // current digit pair
239
+
240
+ switch length {
241
+ case 10 , 19 , 21 , 22 , 23 , 24 , 25 , 26 :
242
+ default :
243
+ t := "DATE"
244
+ if length > 10 {
245
+ t += "TIME"
303
246
}
304
- if len (src ) == 4 {
305
- return append (dst , zeroDateTime [10 :length ]... ), nil
247
+ return nil , fmt .Errorf ("illegal %s length %d" , t , length )
248
+ }
249
+ switch len (src ) {
250
+ case 4 , 7 , 11 :
251
+ default :
252
+ t := "DATE"
253
+ if length > 10 {
254
+ t += "TIME"
306
255
}
307
- dst = append (dst , ' ' )
308
- p1 = src [4 ] // hour
309
- src = src [5 :]
256
+ return nil , fmt .Errorf ("illegal %s packet length %d" , t , len (src ))
257
+ }
258
+ dst = make ([]byte , 0 , length )
259
+ // start with the date
260
+ year := binary .LittleEndian .Uint16 (src [:2 ])
261
+ pt := year / 100
262
+ p1 = byte (year - 100 * uint16 (pt ))
263
+ p2 , p3 = src [2 ], src [3 ]
264
+ dst = append (dst ,
265
+ digits10 [pt ], digits01 [pt ],
266
+ digits10 [p1 ], digits01 [p1 ], '-' ,
267
+ digits10 [p2 ], digits01 [p2 ], '-' ,
268
+ digits10 [p3 ], digits01 [p3 ],
269
+ )
270
+ if length == 10 {
271
+ return dst , nil
310
272
}
273
+ if len (src ) == 4 {
274
+ return append (dst , zeroDateTime [10 :length ]... ), nil
275
+ }
276
+ dst = append (dst , ' ' )
277
+ p1 = src [4 ] // hour
278
+ src = src [5 :]
279
+
311
280
// p1 is 2-digit hour, src is after hour
312
281
p2 , p3 = src [0 ], src [1 ]
313
282
dst = append (dst ,
@@ -320,15 +289,104 @@ func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value
320
289
}
321
290
src = src [2 :]
322
291
if len (src ) == 0 {
323
- return append (dst , zeroDateTime [19 :zOffs + length ]... ), nil
292
+ return append (dst , zeroDateTime [19 :length ]... ), nil
293
+ }
294
+ microsecs := binary .LittleEndian .Uint32 (src [:4 ])
295
+ p1 = byte (microsecs / 10000 )
296
+ microsecs -= 10000 * uint32 (p1 )
297
+ p2 = byte (microsecs / 100 )
298
+ microsecs -= 100 * uint32 (p2 )
299
+ p3 = byte (microsecs )
300
+ switch decimals := length - 20 ; decimals {
301
+ default :
302
+ return append (dst , '.' ,
303
+ digits10 [p1 ], digits01 [p1 ],
304
+ digits10 [p2 ], digits01 [p2 ],
305
+ digits10 [p3 ], digits01 [p3 ],
306
+ ), nil
307
+ case 1 :
308
+ return append (dst , '.' ,
309
+ digits10 [p1 ],
310
+ ), nil
311
+ case 2 :
312
+ return append (dst , '.' ,
313
+ digits10 [p1 ], digits01 [p1 ],
314
+ ), nil
315
+ case 3 :
316
+ return append (dst , '.' ,
317
+ digits10 [p1 ], digits01 [p1 ],
318
+ digits10 [p2 ],
319
+ ), nil
320
+ case 4 :
321
+ return append (dst , '.' ,
322
+ digits10 [p1 ], digits01 [p1 ],
323
+ digits10 [p2 ], digits01 [p2 ],
324
+ ), nil
325
+ case 5 :
326
+ return append (dst , '.' ,
327
+ digits10 [p1 ], digits01 [p1 ],
328
+ digits10 [p2 ], digits01 [p2 ],
329
+ digits10 [p3 ],
330
+ ), nil
331
+ }
332
+ }
333
+
334
+ func formatBinaryTime (src []byte , length uint8 ) (driver.Value , error ) {
335
+ // length expects the deterministic length of the zero value,
336
+ // negative time and 100+ hours are automatically added if needed
337
+ if len (src ) == 0 {
338
+ return zeroDateTime [11 : 11 + length ], nil
339
+ }
340
+ var dst []byte // return value
341
+
342
+ switch length {
343
+ case
344
+ 8 , // time (can be up to 10 when negative and 100+ hours)
345
+ 10 , 11 , 12 , 13 , 14 , 15 : // time with fractional seconds
346
+ default :
347
+ return nil , fmt .Errorf ("illegal TIME length %d" , length )
348
+ }
349
+ switch len (src ) {
350
+ case 8 , 12 :
351
+ default :
352
+ return nil , fmt .Errorf ("invalid TIME packet length %d" , len (src ))
353
+ }
354
+ // +2 to enable negative time and 100+ hours
355
+ dst = make ([]byte , 0 , length + 2 )
356
+ if src [0 ] == 1 {
357
+ dst = append (dst , '-' )
358
+ }
359
+ days := binary .LittleEndian .Uint32 (src [1 :5 ])
360
+ hours := int64 (days )* 24 + int64 (src [5 ])
361
+
362
+ if hours >= 100 {
363
+ dst = strconv .AppendInt (dst , hours , 10 )
364
+ } else {
365
+ dst = append (dst , digits10 [hours ], digits01 [hours ])
366
+ }
367
+
368
+ min , sec := src [6 ], src [7 ]
369
+ dst = append (dst ,
370
+ digits10 [min ], digits01 [min ], ':' ,
371
+ digits10 [sec ], digits01 [sec ],
372
+ )
373
+
374
+ decimals := length - 9
375
+ if decimals <= 0 {
376
+ return dst , nil
377
+ }
378
+
379
+ src = src [8 :]
380
+ if len (src ) == 0 {
381
+ return append (dst , zeroDateTime [19 :length ]... ), nil
324
382
}
325
383
microsecs := binary .LittleEndian .Uint32 (src [:4 ])
326
384
p1 = byte (microsecs / 10000 )
327
385
microsecs -= 10000 * uint32 (p1 )
328
386
p2 = byte (microsecs / 100 )
329
387
microsecs -= 100 * uint32 (p2 )
330
388
p3 = byte (microsecs )
331
- switch decimals := zOffs + length - 20 ; decimals {
389
+ switch decimals {
332
390
default :
333
391
return append (dst , '.' ,
334
392
digits10 [p1 ], digits01 [p1 ],
@@ -425,7 +483,7 @@ func readLengthEncodedString(b []byte) ([]byte, bool, int, error) {
425
483
426
484
// Check data length
427
485
if len (b ) >= n {
428
- return b [n - int (num ) : n : n ], false , n , nil
486
+ return b [n - int (num ) : n : n ], false , n , nil
429
487
}
430
488
return nil , false , n , io .EOF
431
489
}
0 commit comments