mirror of
https://github.com/taglib/taglib.git
synced 2025-07-18 21:14:23 -04:00
add base64 encoder/decoder to bytevector
This commit is contained in:
@ -950,6 +950,98 @@ ByteVector ByteVector::toHex() const
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ByteVector & ByteVector::fromBase64()
|
||||
{
|
||||
static const unsigned char base64[256]={
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x3e,0x80,0x80,0x80,0x3f,
|
||||
0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x80,0x80,0x80,0xff,0x80,0x80,
|
||||
0x80,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,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,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,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
|
||||
};
|
||||
|
||||
detach();
|
||||
uint len = size();
|
||||
const unsigned char * src = (unsigned char*) data();
|
||||
unsigned char * dst = (unsigned char*) data();
|
||||
while(4<=len) {
|
||||
if(base64[src[0]]==0x80) break;
|
||||
if(base64[src[1]]==0x80) break;
|
||||
if(base64[src[2]]==0x80) break;
|
||||
if(base64[src[3]]==0x80) break;
|
||||
*dst++=((base64[src[0]]<<2)&0xfc)|((base64[src[1]]>>4)&0x03);
|
||||
if(src[2]!='=') {
|
||||
*dst++=((base64[src[1]]&0x0f)<<4)|((base64[src[2]]>>2)&0x0f);
|
||||
if(src[3]!='=') {
|
||||
*dst++=((base64[src[2]]&0x03)<<6)|(base64[src[3]]&0x3f);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
src+=4;
|
||||
len-=4;
|
||||
}
|
||||
resize(dst-(unsigned char*)data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ByteVector ByteVector::toBase64() const
|
||||
{
|
||||
static const char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
if (size()) {
|
||||
uint len=size();
|
||||
ByteVector output(4 * ((len-1)/3+1)); // note roundup
|
||||
|
||||
const char * src = data();
|
||||
char * dst = output.data();
|
||||
while(3<=len) {
|
||||
*dst++=alphabet[(src[0]>>2)&0x3f];
|
||||
*dst++=alphabet[((src[0]&0x03)<<4)|((src[1]>>4)&0x0f)];
|
||||
*dst++=alphabet[((src[1]&0x0f)<<2)|((src[2]>>6)&0x03)];
|
||||
*dst++=alphabet[src[2]&0x3f];
|
||||
src+=3;
|
||||
len-=3;
|
||||
}
|
||||
if(len) {
|
||||
*dst++=alphabet[(src[0]>>2)&0x3f];
|
||||
if(len>1) {
|
||||
*dst++=alphabet[((src[0]&0x03)<<4)|((src[1]>>4)&0x0f)];
|
||||
*dst++=alphabet[((src[1]&0x0f)<<2)];
|
||||
}
|
||||
else {
|
||||
*dst++=alphabet[(src[0]&0x03)<<4];
|
||||
*dst++='=';
|
||||
}
|
||||
*dst++='=';
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -573,6 +573,19 @@ namespace TagLib {
|
||||
*/
|
||||
ByteVector toHex() const;
|
||||
|
||||
/*!
|
||||
* Returns a base64 encoded copy of the byte vector
|
||||
*/
|
||||
ByteVector toBase64() const;
|
||||
|
||||
/*!
|
||||
* Decodes the base64 encoded byte vector in-memory. Returns a reference
|
||||
* to this vector. Calls detach before decoding.
|
||||
*/
|
||||
ByteVector & fromBase64();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If this ByteVector is being shared via implicit sharing, do a deep copy
|
||||
|
@ -43,6 +43,7 @@ class TestByteVector : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testReplace);
|
||||
CPPUNIT_TEST(testIterator);
|
||||
CPPUNIT_TEST(testResize);
|
||||
CPPUNIT_TEST(testBase64);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -379,6 +380,45 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(-1, c.find('C'));
|
||||
}
|
||||
|
||||
void testBase64()
|
||||
{
|
||||
ByteVector sempty;
|
||||
ByteVector t0("a"); // test 1 byte
|
||||
ByteVector t1("any carnal pleasure.");
|
||||
ByteVector t2("any carnal pleasure");
|
||||
ByteVector t3("any carnal pleasur");
|
||||
ByteVector s0("a"); // test 1 byte
|
||||
ByteVector s1("any carnal pleasure.");
|
||||
ByteVector s2("any carnal pleasure");
|
||||
ByteVector s3("any carnal pleasur");
|
||||
ByteVector eempty;
|
||||
ByteVector e0("YQ==");
|
||||
ByteVector e1("YW55IGNhcm5hbCBwbGVhc3VyZS4=");
|
||||
ByteVector e2("YW55IGNhcm5hbCBwbGVhc3VyZQ==");
|
||||
ByteVector e3("YW55IGNhcm5hbCBwbGVhc3Vy");
|
||||
|
||||
// Encode
|
||||
CPPUNIT_ASSERT_EQUAL(eempty, sempty.toBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(e0, s0.toBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(e1, s1.toBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(e2, s2.toBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(e3, s3.toBase64());
|
||||
|
||||
// Decode
|
||||
CPPUNIT_ASSERT_EQUAL(sempty, eempty.toBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(s0, e0.fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(s1, e1.fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(s2, e2.fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(s3, e3.fromBase64());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(t0, s0.toBase64().fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(t1, s1.toBase64().fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(t2, s2.toBase64().fromBase64());
|
||||
CPPUNIT_ASSERT_EQUAL(t3, s3.toBase64().fromBase64());
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);
|
||||
|
Reference in New Issue
Block a user