MCPcopy Create free account
hub / github.com/Exiv2/exiv2 / DecodeFromBase64

Method DecodeFromBase64

xmpsdk/src/XMPUtils.cpp:1549–1663  ·  view source on GitHub ↗

class static */

Source from the content-addressed store, hash-verified

1547// bad input is rejected.
1548
1549/* class static */ void
1550XMPUtils::DecodeFromBase64 ( XMP_StringPtr encodedStr,
1551 XMP_StringLen encodedLen,
1552 XMP_StringPtr * rawStr,
1553 XMP_StringLen * rawLen )
1554{
1555 if ( (encodedStr == 0) && (encodedLen != 0) ) XMP_Throw ( "Null encoded data buffer", kXMPErr_BadParam );
1556 if ( encodedLen == 0 ) {
1557 *rawStr = 0;
1558 *rawLen = 0;
1559 return;
1560 }
1561
1562 unsigned char ch, rawChunk[3];
1563 unsigned long inStr, inChunk, inLimit, merge, padding;
1564
1565 XMP_StringLen outputSize = (encodedLen / 4) * 3; // Only a close approximation.
1566
1567 sBase64Str->erase();
1568 sBase64Str->reserve ( outputSize );
1569
1570
1571 // ----------------------------------------------------------------------------------------
1572 // Each 8 bits of input produces 6 bits of output, so 4 input bytes become 3 output bytes.
1573 // Process all but the last 4 data bytes first, then deal with the final chunk. Whitespace
1574 // in the input must be ignored. The first loop finds where the last 4 data bytes start and
1575 // counts the number of padding equal signs.
1576
1577 padding = 0;
1578 for ( inStr = 0, inLimit = encodedLen; (inStr < 4) && (inLimit > 0); ) {
1579 inLimit -= 1; // ! Don't do in the loop control, the decr/test order is wrong.
1580 ch = encodedStr[inLimit];
1581 if ( ch == '=' ) {
1582 padding += 1; // The equal sign padding is a data byte.
1583 } else if ( DecodeBase64Char(ch) == 0xFF ) {
1584 continue; // Ignore whitespace, don't increment inStr.
1585 } else {
1586 inStr += 1;
1587 }
1588 }
1589
1590 // ! Be careful to count whitespace that is immediately before the final data. Otherwise
1591 // ! middle portion will absorb the final data and mess up the final chunk processing.
1592
1593 while ( (inLimit > 0) && (DecodeBase64Char(encodedStr[inLimit-1]) == 0xFF) ) --inLimit;
1594
1595 if ( inStr == 0 ) return; // Nothing but whitespace.
1596 if ( padding > 2 ) XMP_Throw ( "Invalid encoded string", kXMPErr_BadParam );
1597
1598 // -------------------------------------------------------------------------------------------
1599 // Now process all but the last chunk. The limit ensures that we have at least 4 data bytes
1600 // left when entering the output loop, so the inner loop will succeed without overrunning the
1601 // end of the data. At the end of the outer loop we might be past inLimit though.
1602
1603 inStr = 0;
1604 while ( inStr < inLimit ) {
1605
1606 merge = 0;

Callers

nothing calls this directly

Calls 5

DecodeBase64CharFunction · 0.85
reserveMethod · 0.80
c_strMethod · 0.80
eraseMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected