ob64 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/main.yml +78 -16
  4. data/.standard.yml +1 -2
  5. data/CHANGELOG.md +19 -1
  6. data/Gemfile +1 -1
  7. data/README.md +65 -21
  8. data/benchmark.rb +62 -95
  9. data/bin/rake +27 -0
  10. data/ext/ob64/extconf.rb +0 -42
  11. data/ext/ob64/ob64.h +3 -1
  12. data/ext/ob64/ob64_ext.c +80 -23
  13. data/ext/ob64/ob64_pack.c +289 -0
  14. data/ext/ob64/pack_base64.c +5209 -0
  15. data/ext/ob64/pack_base64.h +36 -0
  16. data/ext/ob64/pack_generic.h +151 -0
  17. data/ext/ob64/pack_simd.h +22 -0
  18. data/ext/ob64/pack_uuencode.c +1741 -0
  19. data/ext/ob64/pack_uuencode.h +18 -0
  20. data/lib/ob64/core_ext.rb +2 -25
  21. data/lib/ob64/version.rb +1 -1
  22. data/lib/ob64.rb +218 -70
  23. data/ob64.gemspec +3 -5
  24. metadata +18 -73
  25. data/.gitmodules +0 -3
  26. data/ext/ob64/libbase64.h +0 -1
  27. data/vendor/libbase64/.gitignore +0 -12
  28. data/vendor/libbase64/.travis.yml +0 -71
  29. data/vendor/libbase64/CMakeLists.txt +0 -264
  30. data/vendor/libbase64/LICENSE +0 -28
  31. data/vendor/libbase64/Makefile +0 -93
  32. data/vendor/libbase64/README.md +0 -474
  33. data/vendor/libbase64/base64-benchmarks.png +0 -0
  34. data/vendor/libbase64/bin/base64.c +0 -132
  35. data/vendor/libbase64/cmake/Modules/TargetArch.cmake +0 -29
  36. data/vendor/libbase64/cmake/Modules/TargetSIMDInstructionSet.cmake +0 -34
  37. data/vendor/libbase64/cmake/base64-config.cmake.in +0 -5
  38. data/vendor/libbase64/cmake/config.h.in +0 -25
  39. data/vendor/libbase64/cmake/test-arch.c +0 -35
  40. data/vendor/libbase64/include/libbase64.h +0 -145
  41. data/vendor/libbase64/lib/arch/avx/codec.c +0 -42
  42. data/vendor/libbase64/lib/arch/avx2/codec.c +0 -42
  43. data/vendor/libbase64/lib/arch/avx2/dec_loop.c +0 -110
  44. data/vendor/libbase64/lib/arch/avx2/dec_reshuffle.c +0 -34
  45. data/vendor/libbase64/lib/arch/avx2/enc_loop.c +0 -89
  46. data/vendor/libbase64/lib/arch/avx2/enc_reshuffle.c +0 -83
  47. data/vendor/libbase64/lib/arch/avx2/enc_translate.c +0 -30
  48. data/vendor/libbase64/lib/arch/generic/32/dec_loop.c +0 -86
  49. data/vendor/libbase64/lib/arch/generic/32/enc_loop.c +0 -73
  50. data/vendor/libbase64/lib/arch/generic/64/enc_loop.c +0 -77
  51. data/vendor/libbase64/lib/arch/generic/codec.c +0 -39
  52. data/vendor/libbase64/lib/arch/generic/dec_head.c +0 -37
  53. data/vendor/libbase64/lib/arch/generic/dec_tail.c +0 -91
  54. data/vendor/libbase64/lib/arch/generic/enc_head.c +0 -24
  55. data/vendor/libbase64/lib/arch/generic/enc_tail.c +0 -34
  56. data/vendor/libbase64/lib/arch/neon32/codec.c +0 -72
  57. data/vendor/libbase64/lib/arch/neon32/dec_loop.c +0 -106
  58. data/vendor/libbase64/lib/arch/neon32/enc_loop.c +0 -58
  59. data/vendor/libbase64/lib/arch/neon32/enc_reshuffle.c +0 -54
  60. data/vendor/libbase64/lib/arch/neon32/enc_translate.c +0 -57
  61. data/vendor/libbase64/lib/arch/neon64/codec.c +0 -70
  62. data/vendor/libbase64/lib/arch/neon64/dec_loop.c +0 -129
  63. data/vendor/libbase64/lib/arch/neon64/enc_loop.c +0 -66
  64. data/vendor/libbase64/lib/arch/neon64/enc_reshuffle.c +0 -54
  65. data/vendor/libbase64/lib/arch/sse41/codec.c +0 -42
  66. data/vendor/libbase64/lib/arch/sse42/codec.c +0 -42
  67. data/vendor/libbase64/lib/arch/ssse3/codec.c +0 -42
  68. data/vendor/libbase64/lib/arch/ssse3/dec_loop.c +0 -173
  69. data/vendor/libbase64/lib/arch/ssse3/dec_reshuffle.c +0 -33
  70. data/vendor/libbase64/lib/arch/ssse3/enc_loop.c +0 -67
  71. data/vendor/libbase64/lib/arch/ssse3/enc_reshuffle.c +0 -48
  72. data/vendor/libbase64/lib/arch/ssse3/enc_translate.c +0 -33
  73. data/vendor/libbase64/lib/codec_choose.c +0 -281
  74. data/vendor/libbase64/lib/codecs.h +0 -65
  75. data/vendor/libbase64/lib/env.h +0 -67
  76. data/vendor/libbase64/lib/exports.txt +0 -7
  77. data/vendor/libbase64/lib/lib.c +0 -164
  78. data/vendor/libbase64/lib/lib_openmp.c +0 -149
  79. data/vendor/libbase64/lib/tables/.gitignore +0 -1
  80. data/vendor/libbase64/lib/tables/Makefile +0 -17
  81. data/vendor/libbase64/lib/tables/table_dec_32bit.h +0 -393
  82. data/vendor/libbase64/lib/tables/table_enc_12bit.h +0 -1031
  83. data/vendor/libbase64/lib/tables/table_enc_12bit.py +0 -45
  84. data/vendor/libbase64/lib/tables/table_generator.c +0 -184
  85. data/vendor/libbase64/lib/tables/tables.c +0 -40
  86. data/vendor/libbase64/lib/tables/tables.h +0 -23
@@ -0,0 +1,36 @@
1
+ #ifndef PACK_BASE64_H
2
+ #define PACK_BASE64_H
3
+
4
+ #include <stddef.h>
5
+
6
+ /* Flags for SIMD-accelerated codec */
7
+ #define PACK_BASE64_URL_SAFE (1 << 0) /* use URL-safe alphabet (RFC 4648 §5) */
8
+ #define PACK_BASE64_LOOSE (1 << 1) /* accept both padded and unpadded input */
9
+
10
+ /* Codecs, worst to best; scalar is plain C */
11
+ enum pack_codec {
12
+ PACK_CODEC_SCALAR,
13
+ PACK_CODEC_AVX2,
14
+ PACK_CODEC_AVX512,
15
+ PACK_CODEC_NEON64,
16
+ PACK_CODECS
17
+ };
18
+
19
+ int pack_codec_runnable(enum pack_codec codec);
20
+ enum pack_codec pack_codec_current(void);
21
+ /* Caller ensures the codec is runnable */
22
+ void pack_codec_set(enum pack_codec codec);
23
+
24
+ /* SIMD-accelerated streaming codec (strict, unwrapped) */
25
+ void pack_base64_init(void);
26
+ size_t pack_base64_encode(const char *src, size_t srclen, char *out, int flags);
27
+ int pack_base64_decode(const char *src, size_t srclen, char *out, size_t *outlen, int flags);
28
+
29
+ /* RFC 2045 codec (m with line wrapping, lenient decode) */
30
+ /* Lines end in "\r\n" if crlf, "\n" otherwise */
31
+ size_t pack_base64_encode_rfc2045(const char *src, size_t srclen, char *out, int bytes_per_line, int crlf);
32
+ size_t pack_base64_decode_rfc2045(const char *src, size_t srclen, char *out);
33
+ /* Length pack_base64_decode_rfc2045 would return; reads all of src */
34
+ size_t pack_base64_decoded_length_rfc2045(const char *src, size_t srclen);
35
+
36
+ #endif /* PACK_BASE64_H */
@@ -0,0 +1,151 @@
1
+ /**********************************************************************
2
+
3
+ Derived from aklomp/base64; license: see pack_base64.c.
4
+
5
+ pack_generic.h - Shared portability macros and generic inner loops
6
+ for pack_base64.c and pack_uuencode.c
7
+
8
+ Extracted from the duplicated code in both codecs. Everything here
9
+ is either a macro or a static-inline function so that the compiler
10
+ can inline the hot inner loops into each codec's outer loop.
11
+
12
+ **********************************************************************/
13
+
14
+ #ifndef RUBY_PACK_GENERIC_H
15
+ #define RUBY_PACK_GENERIC_H
16
+
17
+ #include <stdint.h>
18
+ #include <stddef.h>
19
+ #include <string.h>
20
+
21
+ /* ======================================================================
22
+ * Portability macros
23
+ * ====================================================================== */
24
+
25
+ /* Endian detection */
26
+ #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
27
+ # if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
28
+ # define PACK_LITTLE_ENDIAN 1
29
+ # else
30
+ # define PACK_LITTLE_ENDIAN 0
31
+ # endif
32
+ #else
33
+ # define PACK_LITTLE_ENDIAN 0
34
+ #endif
35
+
36
+ #ifdef __LITTLE_ENDIAN__
37
+ # undef PACK_LITTLE_ENDIAN
38
+ # define PACK_LITTLE_ENDIAN 1
39
+ #endif
40
+
41
+ #ifdef __BIG_ENDIAN__
42
+ # undef PACK_LITTLE_ENDIAN
43
+ # define PACK_LITTLE_ENDIAN 0
44
+ #endif
45
+
46
+ /* Endian conversion */
47
+ #if PACK_LITTLE_ENDIAN
48
+ # define PACK_HTOBE32(x) __builtin_bswap32(x)
49
+ # define PACK_HTOBE64(x) __builtin_bswap64(x)
50
+ #else
51
+ # define PACK_HTOBE32(x) (x)
52
+ # define PACK_HTOBE64(x) (x)
53
+ #endif
54
+
55
+ /* Word size detection */
56
+ #if defined(__x86_64__) || defined(__aarch64__) || defined(_M_X64) || defined(_M_ARM64)
57
+ # define PACK_WORDSIZE 64
58
+ #elif SIZE_MAX == UINT64_MAX
59
+ # define PACK_WORDSIZE 64
60
+ #elif SIZE_MAX == UINT32_MAX
61
+ # define PACK_WORDSIZE 32
62
+ #else
63
+ # define PACK_WORDSIZE 32
64
+ #endif
65
+
66
+ /* Force inline */
67
+ #ifdef _MSC_VER
68
+ # define PACK_FORCE_INLINE __forceinline
69
+ #else
70
+ # define PACK_FORCE_INLINE inline __attribute__((always_inline))
71
+ #endif
72
+
73
+ /* ======================================================================
74
+ * Generic inner loop functions (table-parameterized)
75
+ * ====================================================================== */
76
+
77
+ /* 64-bit encode inner: reads 8 bytes, consumes 6, produces 8 */
78
+ #if PACK_WORDSIZE == 64
79
+ static PACK_FORCE_INLINE void
80
+ pack_enc_loop_64_inner(const uint8_t **s, uint8_t **o, const uint16_t *enc_12bit)
81
+ {
82
+ uint64_t src;
83
+
84
+ memcpy(&src, *s, sizeof(src));
85
+ src = PACK_HTOBE64(src);
86
+
87
+ const size_t index0 = (src >> 52) & 0xFFFU;
88
+ const size_t index1 = (src >> 40) & 0xFFFU;
89
+ const size_t index2 = (src >> 28) & 0xFFFU;
90
+ const size_t index3 = (src >> 16) & 0xFFFU;
91
+
92
+ memcpy(*o + 0, enc_12bit + index0, 2);
93
+ memcpy(*o + 2, enc_12bit + index1, 2);
94
+ memcpy(*o + 4, enc_12bit + index2, 2);
95
+ memcpy(*o + 6, enc_12bit + index3, 2);
96
+
97
+ *s += 6;
98
+ *o += 8;
99
+ }
100
+ #endif
101
+
102
+ /* 32-bit encode inner: reads 4 bytes, consumes 3, produces 4 */
103
+ static PACK_FORCE_INLINE void
104
+ pack_enc_loop_32_inner(const uint8_t **s, uint8_t **o, const uint16_t *enc_12bit)
105
+ {
106
+ uint32_t src;
107
+
108
+ memcpy(&src, *s, sizeof(src));
109
+ src = PACK_HTOBE32(src);
110
+
111
+ const size_t index0 = (src >> 20) & 0xFFFU;
112
+ const size_t index1 = (src >> 8) & 0xFFFU;
113
+
114
+ memcpy(*o + 0, enc_12bit + index0, 2);
115
+ memcpy(*o + 2, enc_12bit + index1, 2);
116
+
117
+ *s += 3;
118
+ *o += 4;
119
+ }
120
+
121
+ /* 32-bit decode inner: reads 4 encoded bytes, writes 3 decoded bytes.
122
+ * Returns 1 on success, 0 on invalid input. */
123
+ static PACK_FORCE_INLINE int
124
+ pack_dec_loop_32_inner(const uint8_t **s, uint8_t **o,
125
+ const uint32_t *d0, const uint32_t *d1,
126
+ const uint32_t *d2, const uint32_t *d3)
127
+ {
128
+ const uint32_t str
129
+ = d0[(*s)[0]]
130
+ | d1[(*s)[1]]
131
+ | d2[(*s)[2]]
132
+ | d3[(*s)[3]];
133
+
134
+ #if PACK_LITTLE_ENDIAN
135
+ if (str & UINT32_C(0x80000000)) {
136
+ return 0;
137
+ }
138
+ #else
139
+ if (str & UINT32_C(1)) {
140
+ return 0;
141
+ }
142
+ #endif
143
+ memcpy(*o, &str, sizeof(str));
144
+
145
+ *s += 4;
146
+ *o += 3;
147
+
148
+ return 1;
149
+ }
150
+
151
+ #endif /* RUBY_PACK_GENERIC_H */
@@ -0,0 +1,22 @@
1
+ #ifndef PACK_SIMD_H
2
+ #define PACK_SIMD_H
3
+
4
+ #include <stddef.h>
5
+ #include <stdint.h>
6
+
7
+ /* Selects the uuencode alphabet in bulk loops; base64 otherwise */
8
+ #define PACK_ALPHABET_UU (1 << 8)
9
+
10
+ /*
11
+ * A SIMD codec's bulk loop. Consumes whole blocks only, advancing *s and *o
12
+ * and adjusting *slen and *olen; the caller handles what is left. Decode
13
+ * loops stop before a block holding an invalid char.
14
+ */
15
+ typedef void (*pack_bulk_loop)(const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen, int flags);
16
+
17
+ /* Bulk encode loop of the current codec; NULL for scalar */
18
+ pack_bulk_loop pack_simd_enc_loop(void);
19
+ /* Bulk decode loop of the current codec; NULL for scalar */
20
+ pack_bulk_loop pack_simd_dec_loop(void);
21
+
22
+ #endif /* PACK_SIMD_H */