Mercurial > foo_out_sdl
diff foosdk/sdk/pfc/base64.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/pfc/base64.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,124 @@ +#include "pfc-lite.h" +#include "base64.h" +#include "string_base.h" + +namespace bitWriter { + static void set_bit(t_uint8 * p_stream,size_t p_offset, bool state) { + t_uint8 mask = 1 << (7-(p_offset&7)); + t_uint8 & byte = p_stream[p_offset>>3]; + byte = (byte & ~mask) | (state ? mask : 0); + } + static void set_bits(t_uint8 * stream, t_size offset, t_size word, t_size bits) { + for(t_size walk = 0; walk < bits; ++walk) { + t_uint8 bit = (t_uint8)((word >> (bits - walk - 1))&1); + set_bit(stream, offset+walk, bit != 0); + } + } +}; + +namespace pfc { + static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + static constexpr uint8_t alphabetRev[256] = + {0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F + ,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E + ,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28 + ,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + }; + + size_t base64_strlen( const char * text ) { + size_t ret = 0; + for ( size_t w = 0; ;++w ) { + uint8_t c = (uint8_t) text[w]; + if (c == 0) break; + if ( alphabetRev[c] != 0xFF ) ++ret; + } + return ret; + } + t_size base64_decode_estimate(const char * text) { + t_size textLen = base64_strlen(text); + return textLen * 3 / 4; + } + + mem_block base64_decode(const char* text) { + mem_block ret; ret.resize(base64_decode_estimate(text)); + base64_decode(text, ret.ptr()); + return ret; + } + + void base64_decode(const char * text, void * out) { + + size_t outWritePtr = 0; + size_t inTemp = 0; + uint8_t temp[3]; + for ( size_t textWalk = 0 ; ; ++ textWalk ) { + const uint8_t c = (uint8_t) text[textWalk]; + if (c == 0) break; + const uint8_t v = alphabetRev[ c ]; + if ( v != 0xFF ) { + PFC_ASSERT( inTemp + 6 <= 24 ); + bitWriter::set_bits(temp,inTemp,v,6); + inTemp += 6; + if ( inTemp == 24 ) { + memcpy( (uint8_t*) out + outWritePtr, temp, 3 ); + outWritePtr += 3; + inTemp = 0; + } + } + } + if ( inTemp > 0 ) { + size_t delta = inTemp / 8; + memcpy( (uint8_t*) out + outWritePtr, temp, delta ); + outWritePtr += delta; + inTemp = 0; + } +#if PFC_DEBUG + size_t estimated = base64_decode_estimate( text ) ; + PFC_ASSERT( outWritePtr == estimated ); +#endif + } + void base64_encode(pfc::string_base & out, const void * in, t_size inSize) { + out.reset(); base64_encode_append(out, in, inSize); + } + void base64_encode_append(pfc::string_base & out, const void * in, t_size inSize) { + int shift = 0; + int accum = 0; + const t_uint8 * inPtr = reinterpret_cast<const t_uint8*>(in); + + for(t_size walk = 0; walk < inSize; ++walk) { + accum <<= 8; + shift += 8; + accum |= inPtr[walk]; + while ( shift >= 6 ) { + shift -= 6; + out << format_char( alphabet[(accum >> shift) & 0x3F] ); + } + } + if (shift == 4) { + out << format_char( alphabet[(accum & 0xF)<<2] ) << "="; + } else if (shift == 2) { + out << format_char( alphabet[(accum & 0x3)<<4] ) << "=="; + } + } + + void base64_decode_to_string( pfc::string_base & out, const char * text ) { + char * ptr = out.lock_buffer( base64_decode_estimate( text ) ); + base64_decode(text, ptr); + out.unlock_buffer(); + } + void base64_encode_from_string( pfc::string_base & out, const char * in ) { + base64_encode( out, in, strlen(in) ); + } +}
