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