//---------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 2000. // // File: base64.cxx // // Contents: Contains the implementation of base64 encoding. // //---------------------------------------------------------------------------- #include #include "cadsxml.hxx" #define NL_STR "\r\n" #define NL_STR_LEN 2 #define OCTETS_PER_GROUP 3 #define SEXTETS_PER_GROUP 4 #define BASE64_PAD_CHAR '=' #define BASE64_PAD_INDEX 64 /* NOTE: the pad character base64Alphabet[BASE64_PAD_INDEX] doesn't */ /* really belong the strict definition of the Base64 character set */ static char base64Alphabet[65] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' }; //--------------------------------------------------------------------------- // Function: encodeGroup // // Synopsis: Performs base64 encoding of a group of 3 bytes. // // Arguments: // // inBufPtr Pointer to data to encode // encodeBufPtr Encoded data // inBufLen Number of bytes in inBufPtr // // Returns: Number of encoded sextets // // Modifies: encodeBufPtr to store the encoded data. // //-------------------------------------------------------------------------- static int encodeGroup ( char *inBufPtr, /* input buffer to encode (3 8-bit octets) */ char *encodeBufPtr, /* encode buffer (4 6-bit sextets) */ int inBufLen ) { int i; unsigned char octet; if (inBufLen > OCTETS_PER_GROUP) return(0); /* perform base64 encoding (convert 3 8-bit groups to 4 6-bit groups) */ memset(encodeBufPtr, 0, SEXTETS_PER_GROUP); for (i=0; i> 2); *(encodeBufPtr+1) |= (char)((octet & 0x3) << 4); break; case 1: *(encodeBufPtr+1) |= (char)(octet >> 4); *(encodeBufPtr+2) |= (char)((octet & 0xf) << 2); break; case 2: *(encodeBufPtr+2) |= (char)(octet >> 6); *(encodeBufPtr+3) |= (char)(octet & 0x3f); break; } } /* perform padding for incomplete octet groups */ switch (inBufLen) { case 1: *(encodeBufPtr+2) = BASE64_PAD_INDEX; /* the missing break is intentional! */ case 2: *(encodeBufPtr+3) = BASE64_PAD_INDEX; break; default: break; } /* translate all base64 codes into characters from the base64 alphabet */ for (i=0; i terminated) // // Returns : 0 if successful, -1 otherwise. // // Modifies: *inBytesPtr to return the number of bytes encoded. // *outBytesPtr to return number of bytes placed in outBufPtr. // outBufPtr returns the encoded data. // //-------------------------------------------------------------------------- int encodeBase64Buffer ( char *inBufPtr, int *inBytesPtr, WCHAR *outBufPtr, int *outBytesPtr, int outLineLen ) { int i, ret, bytesToEncode, outBufSize, startOffset, encodeLen; int octetCount, lineCount, outOfSpace; char inBuf[OCTETS_PER_GROUP], encodeBuf[SEXTETS_PER_GROUP+NL_STR_LEN]; char *ptr; bytesToEncode = *inBytesPtr; outBufSize = *outBytesPtr; *inBytesPtr = 0; *outBytesPtr = 0; if (bytesToEncode <= 0 || outBufSize <= 0) return(-1); startOffset = -1; octetCount = lineCount = outOfSpace = 0; for (i=0; i < bytesToEncode && !outOfSpace; i++) { ptr = inBufPtr + i; if (startOffset < 0) startOffset = i; inBuf[octetCount++] = *ptr; /* encode the octet group if sufficient octets have been accumulated */ /* or if we're on the last byte */ if (octetCount == OCTETS_PER_GROUP || (i == bytesToEncode-1)) { /* encode the input octet group into an sextet group */ encodeLen = encodeGroup(inBuf, encodeBuf, octetCount); lineCount += encodeLen; if (lineCount >= outLineLen) { memcpy(&encodeBuf[encodeLen], NL_STR, NL_STR_LEN); encodeLen += NL_STR_LEN; lineCount = 0; } if (*outBytesPtr + encodeLen > outBufSize) outOfSpace = 1; else { /* write decoded octets to output buffer */ ret = mbstowcs(outBufPtr + *outBytesPtr, encodeBuf, encodeLen); *outBytesPtr += encodeLen; *inBytesPtr += i - startOffset + 1; startOffset = -1; octetCount = 0; } } } // Null terminate output if(*outBytesPtr < outBufSize) { *(outBufPtr + *outBytesPtr) = L'\0'; (*outBytesPtr)++; } return(0); }