Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "pfc-lite.h" | |
| 2 #include "base64.h" | |
| 3 #include "string_base.h" | |
| 4 | |
| 5 namespace bitWriter { | |
| 6 static void set_bit(t_uint8 * p_stream,size_t p_offset, bool state) { | |
| 7 t_uint8 mask = 1 << (7-(p_offset&7)); | |
| 8 t_uint8 & byte = p_stream[p_offset>>3]; | |
| 9 byte = (byte & ~mask) | (state ? mask : 0); | |
| 10 } | |
| 11 static void set_bits(t_uint8 * stream, t_size offset, t_size word, t_size bits) { | |
| 12 for(t_size walk = 0; walk < bits; ++walk) { | |
| 13 t_uint8 bit = (t_uint8)((word >> (bits - walk - 1))&1); | |
| 14 set_bit(stream, offset+walk, bit != 0); | |
| 15 } | |
| 16 } | |
| 17 }; | |
| 18 | |
| 19 namespace pfc { | |
| 20 static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| 21 | |
| 22 static constexpr uint8_t alphabetRev[256] = | |
| 23 {0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 24 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 25 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F | |
| 26 ,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 27 ,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E | |
| 28 ,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 29 ,0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28 | |
| 30 ,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 31 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 32 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 33 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 34 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 35 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 36 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 37 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 38 ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF | |
| 39 }; | |
| 40 | |
| 41 size_t base64_strlen( const char * text ) { | |
| 42 size_t ret = 0; | |
| 43 for ( size_t w = 0; ;++w ) { | |
| 44 uint8_t c = (uint8_t) text[w]; | |
| 45 if (c == 0) break; | |
| 46 if ( alphabetRev[c] != 0xFF ) ++ret; | |
| 47 } | |
| 48 return ret; | |
| 49 } | |
| 50 t_size base64_decode_estimate(const char * text) { | |
| 51 t_size textLen = base64_strlen(text); | |
| 52 return textLen * 3 / 4; | |
| 53 } | |
| 54 | |
| 55 mem_block base64_decode(const char* text) { | |
| 56 mem_block ret; ret.resize(base64_decode_estimate(text)); | |
| 57 base64_decode(text, ret.ptr()); | |
| 58 return ret; | |
| 59 } | |
| 60 | |
| 61 void base64_decode(const char * text, void * out) { | |
| 62 | |
| 63 size_t outWritePtr = 0; | |
| 64 size_t inTemp = 0; | |
| 65 uint8_t temp[3]; | |
| 66 for ( size_t textWalk = 0 ; ; ++ textWalk ) { | |
| 67 const uint8_t c = (uint8_t) text[textWalk]; | |
| 68 if (c == 0) break; | |
| 69 const uint8_t v = alphabetRev[ c ]; | |
| 70 if ( v != 0xFF ) { | |
| 71 PFC_ASSERT( inTemp + 6 <= 24 ); | |
| 72 bitWriter::set_bits(temp,inTemp,v,6); | |
| 73 inTemp += 6; | |
| 74 if ( inTemp == 24 ) { | |
| 75 memcpy( (uint8_t*) out + outWritePtr, temp, 3 ); | |
| 76 outWritePtr += 3; | |
| 77 inTemp = 0; | |
| 78 } | |
| 79 } | |
| 80 } | |
| 81 if ( inTemp > 0 ) { | |
| 82 size_t delta = inTemp / 8; | |
| 83 memcpy( (uint8_t*) out + outWritePtr, temp, delta ); | |
| 84 outWritePtr += delta; | |
| 85 inTemp = 0; | |
| 86 } | |
| 87 #if PFC_DEBUG | |
| 88 size_t estimated = base64_decode_estimate( text ) ; | |
| 89 PFC_ASSERT( outWritePtr == estimated ); | |
| 90 #endif | |
| 91 } | |
| 92 void base64_encode(pfc::string_base & out, const void * in, t_size inSize) { | |
| 93 out.reset(); base64_encode_append(out, in, inSize); | |
| 94 } | |
| 95 void base64_encode_append(pfc::string_base & out, const void * in, t_size inSize) { | |
| 96 int shift = 0; | |
| 97 int accum = 0; | |
| 98 const t_uint8 * inPtr = reinterpret_cast<const t_uint8*>(in); | |
| 99 | |
| 100 for(t_size walk = 0; walk < inSize; ++walk) { | |
| 101 accum <<= 8; | |
| 102 shift += 8; | |
| 103 accum |= inPtr[walk]; | |
| 104 while ( shift >= 6 ) { | |
| 105 shift -= 6; | |
| 106 out << format_char( alphabet[(accum >> shift) & 0x3F] ); | |
| 107 } | |
| 108 } | |
| 109 if (shift == 4) { | |
| 110 out << format_char( alphabet[(accum & 0xF)<<2] ) << "="; | |
| 111 } else if (shift == 2) { | |
| 112 out << format_char( alphabet[(accum & 0x3)<<4] ) << "=="; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 void base64_decode_to_string( pfc::string_base & out, const char * text ) { | |
| 117 char * ptr = out.lock_buffer( base64_decode_estimate( text ) ); | |
| 118 base64_decode(text, ptr); | |
| 119 out.unlock_buffer(); | |
| 120 } | |
| 121 void base64_encode_from_string( pfc::string_base & out, const char * in ) { | |
| 122 base64_encode( out, in, strlen(in) ); | |
| 123 } | |
| 124 } |
