aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/base64/plain64
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/base64/plain64
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/base64/plain64')
-rw-r--r--contrib/libs/base64/plain64/.yandex_meta/licenses.list.txt62
-rw-r--r--contrib/libs/base64/plain64/codec_plain.c35
-rw-r--r--contrib/libs/base64/plain64/codecs.h42
-rw-r--r--contrib/libs/base64/plain64/dec_head.c29
-rw-r--r--contrib/libs/base64/plain64/dec_tail.c65
-rw-r--r--contrib/libs/base64/plain64/dec_uint64.c70
-rw-r--r--contrib/libs/base64/plain64/enc_head.c23
-rw-r--r--contrib/libs/base64/plain64/enc_tail.c28
-rw-r--r--contrib/libs/base64/plain64/enc_uint64.c31
-rw-r--r--contrib/libs/base64/plain64/lib.c121
-rw-r--r--contrib/libs/base64/plain64/libbase64.h89
-rw-r--r--contrib/libs/base64/plain64/ya.make27
12 files changed, 622 insertions, 0 deletions
diff --git a/contrib/libs/base64/plain64/.yandex_meta/licenses.list.txt b/contrib/libs/base64/plain64/.yandex_meta/licenses.list.txt
new file mode 100644
index 0000000000..6308eed322
--- /dev/null
+++ b/contrib/libs/base64/plain64/.yandex_meta/licenses.list.txt
@@ -0,0 +1,62 @@
+====================BSD-2-Clause====================
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+- Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+====================BSD-2-Clause AND MIT====================
+## License
+
+This repository is licensed under the
+[BSD 2-clause License](http://opensource.org/licenses/BSD-2-Clause). See the
+LICENSE file.
+
+====================COPYRIGHT====================
+Copyright (c) 2013-2015, Alfred Klomp
+All rights reserved.
+
+
+====================File: LICENSE====================
+Copyright (c) 2013-2015, Alfred Klomp
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+- Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/contrib/libs/base64/plain64/codec_plain.c b/contrib/libs/base64/plain64/codec_plain.c
new file mode 100644
index 0000000000..26a5af9097
--- /dev/null
+++ b/contrib/libs/base64/plain64/codec_plain.c
@@ -0,0 +1,35 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libbase64.h"
+#include "codecs.h"
+
+void
+plain64_base64_stream_encode
+ ( struct plain64_base64_state *state
+ , const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ )
+{
+ #include "enc_head.c"
+ #include "enc_uint64.c"
+ #include "enc_tail.c"
+}
+
+int
+plain64_base64_stream_decode
+ ( struct plain64_base64_state *state
+ , const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ )
+{
+ #include "dec_head.c"
+ #include "dec_uint64.c"
+ #include "dec_tail.c"
+}
diff --git a/contrib/libs/base64/plain64/codecs.h b/contrib/libs/base64/plain64/codecs.h
new file mode 100644
index 0000000000..25430f04c0
--- /dev/null
+++ b/contrib/libs/base64/plain64/codecs.h
@@ -0,0 +1,42 @@
+#pragma once
+
+// Define machine endianness. This is for GCC:
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+ #define PLAIN64_LITTLE_ENDIAN 1
+#else
+ #define PLAIN64_LITTLE_ENDIAN 0
+#endif
+
+// This is for Clang:
+#ifdef __LITTLE_ENDIAN__
+ #define PLAIN64_LITTLE_ENDIAN 1
+#endif
+
+#ifdef __BIG_ENDIAN__
+ #define PLAIN64_LITTLE_ENDIAN 0
+#endif
+
+// Endian conversion functions
+#if PLAIN64_LITTLE_ENDIAN
+#if defined(_WIN64) || defined(__WIN32__) || defined(_WIN32)
+ #define cpu_to_be32(x) _byteswap_ulong(x)
+ #define cpu_to_be64(x) _byteswap_uint64(x)
+ #define be32_to_cpu(x) _byteswap_ulong(x)
+ #define be64_to_cpu(x) _byteswap_uint64(x)
+#else
+ #define cpu_to_be32(x) __builtin_bswap32(x)
+ #define cpu_to_be64(x) __builtin_bswap64(x)
+ #define be32_to_cpu(x) __builtin_bswap32(x)
+ #define be64_to_cpu(x) __builtin_bswap64(x)
+#endif
+#else
+ #define cpu_to_be32(x) (x)
+ #define cpu_to_be64(x) (x)
+ #define be32_to_cpu(x) (x)
+ #define be64_to_cpu(x) (x)
+#endif
+
+// These tables are used by all codecs
+// for fallback plain encoding/decoding:
+extern const uint8_t plain64_base64_table_enc[];
+extern const uint8_t plain64_base64_table_dec[];
diff --git a/contrib/libs/base64/plain64/dec_head.c b/contrib/libs/base64/plain64/dec_head.c
new file mode 100644
index 0000000000..b505833d52
--- /dev/null
+++ b/contrib/libs/base64/plain64/dec_head.c
@@ -0,0 +1,29 @@
+int ret = 0;
+const uint8_t *c = (const uint8_t *)src;
+uint8_t *o = (uint8_t *)out;
+uint8_t q;
+
+// Use local temporaries to avoid cache thrashing:
+size_t outl = 0;
+struct plain64_base64_state st;
+st.eof = state->eof;
+st.bytes = state->bytes;
+st.carry = state->carry;
+
+// If we previously saw an EOF or an invalid character, bail out:
+if (st.eof) {
+ *outlen = 0;
+ return 0;
+}
+
+// Turn four 6-bit numbers into three bytes:
+// out[0] = 11111122
+// out[1] = 22223333
+// out[2] = 33444444
+
+// Duff's device again:
+switch (st.bytes)
+{
+ for (;;)
+ {
+ case 0:
diff --git a/contrib/libs/base64/plain64/dec_tail.c b/contrib/libs/base64/plain64/dec_tail.c
new file mode 100644
index 0000000000..7db2408190
--- /dev/null
+++ b/contrib/libs/base64/plain64/dec_tail.c
@@ -0,0 +1,65 @@
+ if (srclen-- == 0) {
+ ret = 1;
+ break;
+ }
+ if ((q = plain64_base64_table_dec[*c++]) >= 254) {
+ st.eof = 1;
+ // Treat character '=' as invalid for byte 0:
+ break;
+ }
+ st.carry = q << 2;
+ st.bytes++;
+
+ case 1: if (srclen-- == 0) {
+ ret = 1;
+ break;
+ }
+ if ((q = plain64_base64_table_dec[*c++]) >= 254) {
+ st.eof = 1;
+ // Treat character '=' as invalid for byte 1:
+ break;
+ }
+ *o++ = st.carry | (q >> 4);
+ st.carry = q << 4;
+ st.bytes++;
+ outl++;
+
+ case 2: if (srclen-- == 0) {
+ ret = 1;
+ break;
+ }
+ if ((q = plain64_base64_table_dec[*c++]) >= 254) {
+ st.eof = 1;
+ // When q == 254, the input char is '='. Return 1 and EOF.
+ // Technically, should check if next byte is also '=', but never mind.
+ // When q == 255, the input char is invalid. Return 0 and EOF.
+ ret = (q == 254) ? 1 : 0;
+ break;
+ }
+ *o++ = st.carry | (q >> 2);
+ st.carry = q << 6;
+ st.bytes++;
+ outl++;
+
+ case 3: if (srclen-- == 0) {
+ ret = 1;
+ break;
+ }
+ if ((q = plain64_base64_table_dec[*c++]) >= 254) {
+ st.eof = 1;
+ // When q == 254, the input char is '='. Return 1 and EOF.
+ // When q == 255, the input char is invalid. Return 0 and EOF.
+ ret = (q == 254) ? 1 : 0;
+ break;
+ }
+ *o++ = st.carry | q;
+ st.carry = 0;
+ st.bytes = 0;
+ outl++;
+ }
+}
+state->eof = st.eof;
+state->bytes = st.bytes;
+state->carry = st.carry;
+*outlen = outl;
+return ret;
diff --git a/contrib/libs/base64/plain64/dec_uint64.c b/contrib/libs/base64/plain64/dec_uint64.c
new file mode 100644
index 0000000000..fe26e9881b
--- /dev/null
+++ b/contrib/libs/base64/plain64/dec_uint64.c
@@ -0,0 +1,70 @@
+// If we have native uint64's, pick off 8 bytes at a time for as long as we
+// can, but make sure that we quit before seeing any == markers at the end of
+// the string. Also, because we write two zeroes at the end of the output,
+// ensure that there are at least 3 valid bytes of input data remaining to
+// close the gap. 8 + 2 + 3 = 13 bytes:
+while (srclen >= 13)
+{
+ uint64_t str, res, dec;
+
+ // Load string:
+ //str = *(uint64_t *)c;
+ memcpy(&str, c, sizeof(str));
+
+ // Shuffle bytes to 64-bit bigendian:
+ str = cpu_to_be64(str);
+
+ // Lookup each byte in the decoding table; if we encounter any
+ // "invalid" values, fall back on the bytewise code:
+ if ((dec = plain64_base64_table_dec[str >> 56]) > 63) {
+ break;
+ }
+ res = dec << 58;
+
+ if ((dec = plain64_base64_table_dec[(str >> 48) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 52;
+
+ if ((dec = plain64_base64_table_dec[(str >> 40) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 46;
+
+ if ((dec = plain64_base64_table_dec[(str >> 32) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 40;
+
+ if ((dec = plain64_base64_table_dec[(str >> 24) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 34;
+
+ if ((dec = plain64_base64_table_dec[(str >> 16) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 28;
+
+ if ((dec = plain64_base64_table_dec[(str >> 8) & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 22;
+
+ if ((dec = plain64_base64_table_dec[str & 0xFF]) > 63) {
+ break;
+ }
+ res |= dec << 16;
+
+ // Reshuffle and repack into 6-byte output format:
+ res = be64_to_cpu(res);
+
+ // Store back:
+ //*(uint64_t *)o = res;
+ memcpy(o, &res, sizeof(res));
+
+ c += 8;
+ o += 6;
+ outl += 6;
+ srclen -= 8;
+}
diff --git a/contrib/libs/base64/plain64/enc_head.c b/contrib/libs/base64/plain64/enc_head.c
new file mode 100644
index 0000000000..037a1fff99
--- /dev/null
+++ b/contrib/libs/base64/plain64/enc_head.c
@@ -0,0 +1,23 @@
+// Assume that *out is large enough to contain the output.
+// Theoretically it should be 4/3 the length of src.
+const uint8_t *c = (const uint8_t *)src;
+uint8_t *o = (uint8_t *)out;
+
+// Use local temporaries to avoid cache thrashing:
+size_t outl = 0;
+struct plain64_base64_state st;
+st.bytes = state->bytes;
+st.carry = state->carry;
+
+// Turn three bytes into four 6-bit numbers:
+// in[0] = 00111111
+// in[1] = 00112222
+// in[2] = 00222233
+// in[3] = 00333333
+
+// Duff's device, a for() loop inside a switch() statement. Legal!
+switch (st.bytes)
+{
+ for (;;)
+ {
+ case 0:
diff --git a/contrib/libs/base64/plain64/enc_tail.c b/contrib/libs/base64/plain64/enc_tail.c
new file mode 100644
index 0000000000..f98414b777
--- /dev/null
+++ b/contrib/libs/base64/plain64/enc_tail.c
@@ -0,0 +1,28 @@
+ if (srclen-- == 0) {
+ break;
+ }
+ *o++ = plain64_base64_table_enc[*c >> 2];
+ st.carry = (*c++ << 4) & 0x30;
+ st.bytes++;
+ outl += 1;
+
+ case 1: if (srclen-- == 0) {
+ break;
+ }
+ *o++ = plain64_base64_table_enc[st.carry | (*c >> 4)];
+ st.carry = (*c++ << 2) & 0x3C;
+ st.bytes++;
+ outl += 1;
+
+ case 2: if (srclen-- == 0) {
+ break;
+ }
+ *o++ = plain64_base64_table_enc[st.carry | (*c >> 6)];
+ *o++ = plain64_base64_table_enc[*c++ & 0x3F];
+ st.bytes = 0;
+ outl += 2;
+ }
+}
+state->bytes = st.bytes;
+state->carry = st.carry;
+*outlen = outl;
diff --git a/contrib/libs/base64/plain64/enc_uint64.c b/contrib/libs/base64/plain64/enc_uint64.c
new file mode 100644
index 0000000000..3d5955af24
--- /dev/null
+++ b/contrib/libs/base64/plain64/enc_uint64.c
@@ -0,0 +1,31 @@
+// If we have 64-bit ints, pick off 6 bytes at a time for as long as we can,
+// but ensure that there are at least 8 bytes available to avoid segfaulting:
+while (srclen >= 8)
+{
+ // Load string:
+ //uint64_t str = *(uint64_t *)c;
+ uint64_t str;
+
+ memcpy(&str, c, sizeof(str));
+
+ // Reorder to 64-bit big-endian, if not already in that format. The
+ // workset must be in big-endian, otherwise the shifted bits do not
+ // carry over properly among adjacent bytes:
+ str = cpu_to_be64(str);
+
+ // Shift input by 6 bytes each round and mask in only the lower 6 bits;
+ // look up the character in the Base64 encoding table and write it to
+ // the output location:
+ *o++ = plain64_base64_table_enc[(str >> 58) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 52) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 46) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 40) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 34) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 28) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 22) & 0x3F];
+ *o++ = plain64_base64_table_enc[(str >> 16) & 0x3F];
+
+ c += 6; // 6 bytes of input
+ outl += 8; // 8 bytes of output
+ srclen -= 6;
+}
diff --git a/contrib/libs/base64/plain64/lib.c b/contrib/libs/base64/plain64/lib.c
new file mode 100644
index 0000000000..99d91d2c3c
--- /dev/null
+++ b/contrib/libs/base64/plain64/lib.c
@@ -0,0 +1,121 @@
+#include <stdint.h>
+#include <stddef.h>
+
+#include "libbase64.h"
+#include "codecs.h"
+
+const uint8_t
+plain64_base64_table_enc[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+// In the lookup table below, note that the value for '=' (character 61) is
+// 254, not 255. This character is used for in-band signaling of the end of
+// the datastream, and we will use that later. The characters A-Z, a-z, 0-9
+// and + / are mapped to their "decoded" values. The other bytes all map to
+// the value 255, which flags them as "invalid input".
+
+const uint8_t
+plain64_base64_table_dec[] =
+{
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0..15
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 16..31
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 254, 62, 255, 63, // 32..47
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, // 48..63
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64..79
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, // 80..95
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96..111
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, // 112..127
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 128..143
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+};
+
+void
+plain64_base64_stream_encode_init (struct plain64_base64_state *state)
+{
+ state->eof = 0;
+ state->bytes = 0;
+ state->carry = 0;
+}
+
+void
+plain64_base64_stream_encode_final
+ ( struct plain64_base64_state *state
+ , char *out
+ , size_t *outlen
+ )
+{
+ uint8_t *o = (uint8_t *)out;
+
+ if (state->bytes == 1) {
+ *o++ = plain64_base64_table_enc[state->carry];
+ *o++ = '=';
+ *o++ = '=';
+ *outlen = 3;
+ return;
+ }
+ if (state->bytes == 2) {
+ *o++ = plain64_base64_table_enc[state->carry];
+ *o++ = '=';
+ *outlen = 2;
+ return;
+ }
+ *outlen = 0;
+}
+
+void
+plain64_base64_stream_decode_init (struct plain64_base64_state *state)
+{
+ state->eof = 0;
+ state->bytes = 0;
+ state->carry = 0;
+}
+
+void
+plain64_base64_encode
+ ( const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ )
+{
+ size_t s;
+ size_t t;
+ struct plain64_base64_state state;
+
+ // Init the stream reader:
+ plain64_base64_stream_encode_init(&state);
+
+ // Feed the whole string to the stream reader:
+ plain64_base64_stream_encode(&state, src, srclen, out, &s);
+
+ // Finalize the stream by writing trailer if any:
+ plain64_base64_stream_encode_final(&state, out + s, &t);
+
+ // Final output length is stream length plus tail:
+ *outlen = s + t;
+}
+
+int
+plain64_base64_decode
+ ( const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ )
+{
+ struct plain64_base64_state state;
+
+ // Init the stream reader:
+ plain64_base64_stream_decode_init(&state);
+
+ // Feed the whole string to the stream reader:
+ return plain64_base64_stream_decode(&state, src, srclen, out, outlen);
+}
diff --git a/contrib/libs/base64/plain64/libbase64.h b/contrib/libs/base64/plain64/libbase64.h
new file mode 100644
index 0000000000..27a9ce8626
--- /dev/null
+++ b/contrib/libs/base64/plain64/libbase64.h
@@ -0,0 +1,89 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct plain64_base64_state {
+ int eof;
+ int bytes;
+ unsigned char carry;
+};
+
+/* Wrapper function to encode a plain string of given length. Output is written
+ * to *out without trailing zero. Output length in bytes is written to *outlen.
+ * The buffer in `out` has been allocated by the caller and is at least 4/3 the
+ * size of the input. See above for `flags`; set to 0 for default operation: */
+void plain64_base64_encode
+ ( const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ ) ;
+
+/* Call this before calling base64_stream_encode() to init the state. See above
+ * for `flags`; set to 0 for default operation: */
+void plain64_base64_stream_encode_init
+ ( struct plain64_base64_state *state
+ ) ;
+
+/* Encodes the block of data of given length at `src`, into the buffer at
+ * `out`. Caller is responsible for allocating a large enough out-buffer; it
+ * must be at least 4/3 the size of the in-buffer, but take some margin. Places
+ * the number of new bytes written into `outlen` (which is set to zero when the
+ * function starts). Does not zero-terminate or finalize the output. */
+void plain64_base64_stream_encode
+ ( struct plain64_base64_state *state
+ , const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ ) ;
+
+/* Finalizes the output begun by previous calls to `base64_stream_encode()`.
+ * Adds the required end-of-stream markers if appropriate. `outlen` is modified
+ * and will contain the number of new bytes written at `out` (which will quite
+ * often be zero). */
+void plain64_base64_stream_encode_final
+ ( struct plain64_base64_state *state
+ , char *out
+ , size_t *outlen
+ ) ;
+
+/* Wrapper function to decode a plain string of given length. Output is written
+ * to *out without trailing zero. Output length in bytes is written to *outlen.
+ * The buffer in `out` has been allocated by the caller and is at least 3/4 the
+ * size of the input. See above for `flags`, set to 0 for default operation: */
+int plain64_base64_decode
+ ( const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ ) ;
+
+/* Call this before calling base64_stream_decode() to init the state. See above
+ * for `flags`; set to 0 for default operation: */
+void plain64_base64_stream_decode_init
+ ( struct plain64_base64_state *state
+ ) ;
+
+/* Decodes the block of data of given length at `src`, into the buffer at
+ * `out`. Caller is responsible for allocating a large enough out-buffer; it
+ * must be at least 3/4 the size of the in-buffer, but take some margin. Places
+ * the number of new bytes written into `outlen` (which is set to zero when the
+ * function starts). Does not zero-terminate the output. Returns 1 if all is
+ * well, and 0 if a decoding error was found, such as an invalid character.
+ * Returns -1 if the chosen codec is not included in the current build. Used by
+ * the test harness to check whether a codec is available for testing. */
+int plain64_base64_stream_decode
+ ( struct plain64_base64_state *state
+ , const char *src
+ , size_t srclen
+ , char *out
+ , size_t *outlen
+ ) ;
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/contrib/libs/base64/plain64/ya.make b/contrib/libs/base64/plain64/ya.make
new file mode 100644
index 0000000000..1f5a9ad204
--- /dev/null
+++ b/contrib/libs/base64/plain64/ya.make
@@ -0,0 +1,27 @@
+OWNER(
+ yazevnul
+ g:contrib
+ g:cpp-contrib
+)
+
+LIBRARY()
+
+LICENSE(
+ BSD-2-Clause AND
+ MIT
+)
+
+LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+
+NO_UTIL()
+
+SRCS(
+ codec_plain.c
+ lib.c
+)
+
+IF (OS_LINUX OR OS_DARWIN)
+ CONLYFLAGS(-std=c11)
+ENDIF()
+
+END()