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) );
+	}
+}