v / vlib / picohttpparser / misc.v
75 lines · 67 sloc · 2.36 KB · 008aaad99981918c51194d7aaaaaccb4c258f244
Raw
1module picohttpparser
2
3// vfmt off
4const g_digits_lut = [
5 `0`, `0`, `0`, `1`, `0`, `2`, `0`, `3`, `0`, `4`, `0`, `5`, `0`, `6`, `0`, `7`, `0`, `8`, `0`, `9`,
6 `1`, `0`, `1`, `1`, `1`, `2`, `1`, `3`, `1`, `4`, `1`, `5`, `1`, `6`, `1`, `7`, `1`, `8`, `1`, `9`,
7 `2`, `0`, `2`, `1`, `2`, `2`, `2`, `3`, `2`, `4`, `2`, `5`, `2`, `6`, `2`, `7`, `2`, `8`, `2`, `9`,
8 `3`, `0`, `3`, `1`, `3`, `2`, `3`, `3`, `3`, `4`, `3`, `5`, `3`, `6`, `3`, `7`, `3`, `8`, `3`, `9`,
9 `4`, `0`, `4`, `1`, `4`, `2`, `4`, `3`, `4`, `4`, `4`, `5`, `4`, `6`, `4`, `7`, `4`, `8`, `4`, `9`,
10 `5`, `0`, `5`, `1`, `5`, `2`, `5`, `3`, `5`, `4`, `5`, `5`, `5`, `6`, `5`, `7`, `5`, `8`, `5`, `9`,
11 `6`, `0`, `6`, `1`, `6`, `2`, `6`, `3`, `6`, `4`, `6`, `5`, `6`, `6`, `6`, `7`, `6`, `8`, `6`, `9`,
12 `7`, `0`, `7`, `1`, `7`, `2`, `7`, `3`, `7`, `4`, `7`, `5`, `7`, `6`, `7`, `7`, `7`, `8`, `7`, `9`,
13 `8`, `0`, `8`, `1`, `8`, `2`, `8`, `3`, `8`, `4`, `8`, `5`, `8`, `6`, `8`, `7`, `8`, `8`, `8`, `9`,
14 `9`, `0`, `9`, `1`, `9`, `2`, `9`, `3`, `9`, `4`, `9`, `5`, `9`, `6`, `9`, `7`, `9`, `8`, `9`, `9`,
15]!
16// vfmt on
17
18// u64toa converts `value` to an ASCII string and stores it at `buf_start`.
19// It returns the length of the ASCII string (branch lookup table implementation).
20// Note: `buf_start` should point to a memory buffer, that is *at least* 9 bytes long.
21@[direct_array_access; unsafe]
22pub fn u64toa(buf_start &u8, value u64) !int {
23 mut buf := unsafe { buf_start }
24 // set maximum length to 100MB
25 if value >= 100_000_000 {
26 return error('Maximum size of 100MB exceeded!')
27 }
28
29 v := u32(value)
30 if v < 10_000 {
31 d1 := u32((v / 100) << 1)
32 d2 := u32((v % 100) << 1)
33 unsafe {
34 if v >= 1000 {
35 *buf++ = g_digits_lut[d1]
36 }
37 if v >= 100 {
38 *buf++ = g_digits_lut[d1 + 1]
39 }
40 if v >= 10 {
41 *buf++ = g_digits_lut[d2]
42 }
43 *buf++ = g_digits_lut[d2 + 1]
44 }
45 } else {
46 b := v / 10_000
47 c := v % 10_000
48
49 d1 := u32((b / 100) << 1)
50 d2 := u32((b % 100) << 1)
51
52 d3 := u32((c / 100) << 1)
53 d4 := u32((c % 100) << 1)
54
55 unsafe {
56 if value >= 10_000_000 {
57 *buf++ = g_digits_lut[d1]
58 }
59 if value >= 1_000_000 {
60 *buf++ = g_digits_lut[d1 + 1]
61 }
62 if value >= 100_000 {
63 *buf++ = g_digits_lut[d2]
64 }
65 *buf++ = g_digits_lut[d2 + 1]
66
67 *buf++ = g_digits_lut[d3]
68 *buf++ = g_digits_lut[d3 + 1]
69 *buf++ = g_digits_lut[d4]
70 *buf++ = g_digits_lut[d4 + 1]
71 }
72 }
73
74 return unsafe { buf - buf_start }
75}
76