ob64 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/main.yml +77 -16
- data/.standard.yml +1 -2
- data/CHANGELOG.md +14 -1
- data/README.md +57 -19
- data/benchmark.rb +60 -95
- data/ext/ob64/extconf.rb +0 -42
- data/ext/ob64/ob64.h +3 -1
- data/ext/ob64/ob64_ext.c +80 -23
- data/ext/ob64/ob64_pack.c +228 -0
- data/ext/ob64/pack_base64.c +5182 -0
- data/ext/ob64/pack_base64.h +33 -0
- data/ext/ob64/pack_generic.h +151 -0
- data/ext/ob64/pack_simd.h +22 -0
- data/ext/ob64/pack_uuencode.c +1741 -0
- data/ext/ob64/pack_uuencode.h +18 -0
- data/lib/ob64/core_ext.rb +2 -25
- data/lib/ob64/version.rb +1 -1
- data/lib/ob64.rb +149 -70
- data/ob64.gemspec +3 -5
- metadata +17 -73
- data/.gitmodules +0 -3
- data/ext/ob64/libbase64.h +0 -1
- data/vendor/libbase64/.gitignore +0 -12
- data/vendor/libbase64/.travis.yml +0 -71
- data/vendor/libbase64/CMakeLists.txt +0 -264
- data/vendor/libbase64/LICENSE +0 -28
- data/vendor/libbase64/Makefile +0 -93
- data/vendor/libbase64/README.md +0 -474
- data/vendor/libbase64/base64-benchmarks.png +0 -0
- data/vendor/libbase64/bin/base64.c +0 -132
- data/vendor/libbase64/cmake/Modules/TargetArch.cmake +0 -29
- data/vendor/libbase64/cmake/Modules/TargetSIMDInstructionSet.cmake +0 -34
- data/vendor/libbase64/cmake/base64-config.cmake.in +0 -5
- data/vendor/libbase64/cmake/config.h.in +0 -25
- data/vendor/libbase64/cmake/test-arch.c +0 -35
- data/vendor/libbase64/include/libbase64.h +0 -145
- data/vendor/libbase64/lib/arch/avx/codec.c +0 -42
- data/vendor/libbase64/lib/arch/avx2/codec.c +0 -42
- data/vendor/libbase64/lib/arch/avx2/dec_loop.c +0 -110
- data/vendor/libbase64/lib/arch/avx2/dec_reshuffle.c +0 -34
- data/vendor/libbase64/lib/arch/avx2/enc_loop.c +0 -89
- data/vendor/libbase64/lib/arch/avx2/enc_reshuffle.c +0 -83
- data/vendor/libbase64/lib/arch/avx2/enc_translate.c +0 -30
- data/vendor/libbase64/lib/arch/generic/32/dec_loop.c +0 -86
- data/vendor/libbase64/lib/arch/generic/32/enc_loop.c +0 -73
- data/vendor/libbase64/lib/arch/generic/64/enc_loop.c +0 -77
- data/vendor/libbase64/lib/arch/generic/codec.c +0 -39
- data/vendor/libbase64/lib/arch/generic/dec_head.c +0 -37
- data/vendor/libbase64/lib/arch/generic/dec_tail.c +0 -91
- data/vendor/libbase64/lib/arch/generic/enc_head.c +0 -24
- data/vendor/libbase64/lib/arch/generic/enc_tail.c +0 -34
- data/vendor/libbase64/lib/arch/neon32/codec.c +0 -72
- data/vendor/libbase64/lib/arch/neon32/dec_loop.c +0 -106
- data/vendor/libbase64/lib/arch/neon32/enc_loop.c +0 -58
- data/vendor/libbase64/lib/arch/neon32/enc_reshuffle.c +0 -54
- data/vendor/libbase64/lib/arch/neon32/enc_translate.c +0 -57
- data/vendor/libbase64/lib/arch/neon64/codec.c +0 -70
- data/vendor/libbase64/lib/arch/neon64/dec_loop.c +0 -129
- data/vendor/libbase64/lib/arch/neon64/enc_loop.c +0 -66
- data/vendor/libbase64/lib/arch/neon64/enc_reshuffle.c +0 -54
- data/vendor/libbase64/lib/arch/sse41/codec.c +0 -42
- data/vendor/libbase64/lib/arch/sse42/codec.c +0 -42
- data/vendor/libbase64/lib/arch/ssse3/codec.c +0 -42
- data/vendor/libbase64/lib/arch/ssse3/dec_loop.c +0 -173
- data/vendor/libbase64/lib/arch/ssse3/dec_reshuffle.c +0 -33
- data/vendor/libbase64/lib/arch/ssse3/enc_loop.c +0 -67
- data/vendor/libbase64/lib/arch/ssse3/enc_reshuffle.c +0 -48
- data/vendor/libbase64/lib/arch/ssse3/enc_translate.c +0 -33
- data/vendor/libbase64/lib/codec_choose.c +0 -281
- data/vendor/libbase64/lib/codecs.h +0 -65
- data/vendor/libbase64/lib/env.h +0 -67
- data/vendor/libbase64/lib/exports.txt +0 -7
- data/vendor/libbase64/lib/lib.c +0 -164
- data/vendor/libbase64/lib/lib_openmp.c +0 -149
- data/vendor/libbase64/lib/tables/.gitignore +0 -1
- data/vendor/libbase64/lib/tables/Makefile +0 -17
- data/vendor/libbase64/lib/tables/table_dec_32bit.h +0 -393
- data/vendor/libbase64/lib/tables/table_enc_12bit.h +0 -1031
- data/vendor/libbase64/lib/tables/table_enc_12bit.py +0 -45
- data/vendor/libbase64/lib/tables/table_generator.c +0 -184
- data/vendor/libbase64/lib/tables/tables.c +0 -40
- data/vendor/libbase64/lib/tables/tables.h +0 -23
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
size_t pack_base64_encode_rfc2045(const char *src, size_t srclen, char *out, int bytes_per_line);
|
|
31
|
+
size_t pack_base64_decode_rfc2045(const char *src, size_t srclen, char *out);
|
|
32
|
+
|
|
33
|
+
#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 */
|