| 1 | module picohttpparser |
| 2 | |
| 3 | // vfmt off |
| 4 | const 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] |
| 22 | pub 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 | |