dec_uint64.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // If we have native uint64's, pick off 8 bytes at a time for as long as we
  2. // can, but make sure that we quit before seeing any == markers at the end of
  3. // the string. Also, because we write two zeroes at the end of the output,
  4. // ensure that there are at least 3 valid bytes of input data remaining to
  5. // close the gap. 8 + 2 + 3 = 13 bytes:
  6. while (srclen >= 13)
  7. {
  8. uint64_t str, res, dec;
  9. // Load string:
  10. str = *(uint64_t *)c;
  11. // Shuffle bytes to 64-bit bigendian:
  12. str = cpu_to_be64(str);
  13. // Lookup each byte in the decoding table; if we encounter any
  14. // "invalid" values, fall back on the bytewise code:
  15. if ((dec = neon64_base64_table_dec[str >> 56]) > 63) {
  16. break;
  17. }
  18. res = dec << 58;
  19. if ((dec = neon64_base64_table_dec[(str >> 48) & 0xFF]) > 63) {
  20. break;
  21. }
  22. res |= dec << 52;
  23. if ((dec = neon64_base64_table_dec[(str >> 40) & 0xFF]) > 63) {
  24. break;
  25. }
  26. res |= dec << 46;
  27. if ((dec = neon64_base64_table_dec[(str >> 32) & 0xFF]) > 63) {
  28. break;
  29. }
  30. res |= dec << 40;
  31. if ((dec = neon64_base64_table_dec[(str >> 24) & 0xFF]) > 63) {
  32. break;
  33. }
  34. res |= dec << 34;
  35. if ((dec = neon64_base64_table_dec[(str >> 16) & 0xFF]) > 63) {
  36. break;
  37. }
  38. res |= dec << 28;
  39. if ((dec = neon64_base64_table_dec[(str >> 8) & 0xFF]) > 63) {
  40. break;
  41. }
  42. res |= dec << 22;
  43. if ((dec = neon64_base64_table_dec[str & 0xFF]) > 63) {
  44. break;
  45. }
  46. res |= dec << 16;
  47. // Reshuffle and repack into 6-byte output format:
  48. res = be64_to_cpu(res);
  49. // Store back:
  50. *(uint64_t *)o = res;
  51. c += 8;
  52. o += 6;
  53. outl += 6;
  54. srclen -= 8;
  55. }