class static */
| 1547 | // bad input is rejected. |
| 1548 | |
| 1549 | /* class static */ void |
| 1550 | XMPUtils::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; |
nothing calls this directly
no test coverage detected