/** * Translates a binary buffer into a BASE64 encoded string using the specified * character to value mapping. The returned string is guaranteed to be a 7-bit * ASCII string. If buffer is empty, returns an empty string. Only returns NULL * if memory allocation fails. The caller will have to deallocate the returned * string with MEM_Free */ Char * BASE64_Encode(const void * data, size_t n, int flags) { const char* encodeMap = ((flags & BASE64_URLSAFE) ? base64_safeEncodeMap : base64_encodeMap); size_t alloc = ((n+2)/3)*4 + 1; Char * dest = MEM_NewArray(Char, alloc); if (dest) { const char * buf = (const char *)data; Char * p = dest; size_t off; /* encode the bulk of the data */ for (off=0; (off+3)<=n; off+=3) { *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_3(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_4(buf,off)]; } /* manage the last few bytes */ switch (n%3) { case 0: break; case 1: *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2_1(buf,off)]; if (flags & BASE64_PAD) { *p++ = '='; *p++ = '='; } break; case 2: *p++ = encodeMap[BASE64_ENCODE_1(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_2(buf,off)]; *p++ = encodeMap[BASE64_ENCODE_3_1(buf,off)]; if (flags & BASE64_PAD) *p++ = '='; break; } /* null terminate the destination string */ *p = 0; ASSERT(StrLen(dest) < (size_t)alloc); } return dest; }
/** * The same as BASE64_Encode but stores encoded data into a string buffer. * Does not destroy the original contents of the string buffer. The * Base64 string is appended to it. Returns pointer to string buffer * data, NULL on memory allocation failure */ Str BASE64_EncodeStr(const void * data, size_t size, StrBuf * sb, int flags) { const char* encodeMap = ((flags & BASE64_URLSAFE) ? base64_safeEncodeMap : base64_encodeMap); size_t alloc = ((size+2)/3)*4; if (STRBUF_Alloc(sb, STRBUF_Length(sb)+alloc)) { const char * buf = (const char *)data; size_t off; /* encode the bulk of the data */ for (off=0; (off+3)<=size; off+=3) { STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_4(buf,off)]); } /* manage last one or two bytes */ switch (size%3) { case 0: break; case 1: STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2_1(buf,off)]); if (flags & BASE64_PAD) { STRBUF_AppendChar(sb,'='); STRBUF_AppendChar(sb,'='); } break; case 2: STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_3_1(buf,off)]); if (flags & BASE64_PAD) STRBUF_AppendChar(sb,'='); break; } return STRBUF_Text(sb); } /* could not allocate memory */ return NULL; }
/***************************************************************************** * FUNCTION * applib_base64_part_encode_finish * DESCRIPTION * This function finish the part-by-part BASE64 encode. * PARAMETERS * cntx [IN] Part process context * dest [IN/OUT] Encoded data * destl [IN] Destination buffer length * RETURNS * negative : parameter error or buffer NOT enough * otherwise : length of encoded bytes *****************************************************************************/ kal_int32 applib_base64_part_encode_finish( applib_base64_part_context* cntx, kal_char *dst, kal_int32 dstl) { /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ if (cntx == NULL || cntx->buf_cnt > 2) { BASE64_ASSERT(0); return -1; } /* no unprocessed data */ if (cntx->buf_cnt == 0) { if (cntx->wrap_max > 0 && cntx->wrap_count > 0) { if (dstl < 2) { BASE64_ASSERT(0); return -1; } dst[0] = '\r'; dst[1] = '\n'; return 2; } else { return 0; } } if (dst == NULL || dstl < 4) { BASE64_ASSERT(0); return -1; } if (cntx->buf_cnt == 1) { BASE64_ENCODE_1(dst,cntx->buf); } else if (cntx->buf_cnt == 2) { BASE64_ENCODE_2(dst,cntx->buf); } else { BASE64_ASSERT(0); } if (cntx->wrap_max > 0 && cntx->wrap_count > 0) { if (dstl < 6) { BASE64_ASSERT(0); return -1; } dst[4] = '\r'; dst[5] = '\n'; return 6; } else { return 4; } }