cgul_base64.h File Reference

base64 encode and decode More...

#include "cgul_common.h"
#include "cgul_exception.h"
Include dependency graph for cgul_base64.h:
This graph shows which files directly or indirectly include this file:

Typedefs

typedef typedefCGUL_BEGIN_C struct cgul_base64 * cgul_base64_t
 

Functions

CGUL_EXPORT cgul_base64_t cgul_base64__new (cgul_exception_t *cex)
 
CGUL_EXPORT void cgul_base64__delete (cgul_base64_t b64)
 
CGUL_EXPORT size_t cgul_base64__get_line_length_max (cgul_exception_t *cex, cgul_base64_t b64)
 
CGUL_EXPORT void cgul_base64__set_line_length_max (cgul_exception_t *cex, cgul_base64_t b64, size_t line_length_max)
 
CGUL_EXPORT int cgul_base64__get_strict_decode (cgul_exception_t *cex, cgul_base64_t b64)
 
CGUL_EXPORT void cgul_base64__set_strict_decode (cgul_exception_t *cex, cgul_base64_t b64, int strict_decode)
 
CGUL_EXPORT void cgul_base64__encode (cgul_exception_t *cex, cgul_base64_t b64, const void *buf, size_t buf_size)
 
CGUL_EXPORT void cgul_base64__encode_finish (cgul_exception_t *cex, cgul_base64_t b64)
 
CGUL_EXPORT char * cgul_base64__get_encode_conversion (cgul_exception_t *cex, cgul_base64_t b64, size_t *buf_size)
 
CGUL_EXPORT void cgul_base64__decode (cgul_exception_t *cex, cgul_base64_t b64, const void *buf, size_t buf_size)
 
CGUL_EXPORT void cgul_base64__decode_finish (cgul_exception_t *cex, cgul_base64_t b64)
 
CGUL_EXPORT char * cgul_base64__get_decode_conversion (cgul_exception_t *cex, cgul_base64_t b64, size_t *buf_size)
 

Detailed Description

Routines to base64 encode and decode as per RFC 3548:

ftp://ftp.rfc-editor.org/in-notes/rfc3548.txt
Author
Paul Serice

Typedef Documentation

§ cgul_base64_t

typedef typedefCGUL_BEGIN_C struct cgul_base64* cgul_base64_t

Opaque pointer to a cgul_base64 instance.

Function Documentation

§ cgul_base64__new()

CGUL_EXPORT cgul_base64_t cgul_base64__new ( cgul_exception_t cex)

Create a new cgul_base64 object. The caller is responsible for freeing the object by calling cgul_base64__delete(). If memory cannot be allocated, NULL will be returned and an exception will be thrown.

Parameters
[in,out]cexc-style exception
Returns
new cgul_base64 instance

§ cgul_base64__delete()

CGUL_EXPORT void cgul_base64__delete ( cgul_base64_t  b64)

cgul_base64__delete() frees all internally allocated memory. Do not try to access "b64" after calling this method.

Parameters
b64cgul_base64 instance

§ cgul_base64__get_line_length_max()

CGUL_EXPORT size_t cgul_base64__get_line_length_max ( cgul_exception_t cex,
cgul_base64_t  b64 
)

Get the line length that determines when a '\n' character is to be embedded. A value of zero means no '\n' character will be embedded.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
Returns
maximum line length for encoded lines

§ cgul_base64__set_line_length_max()

CGUL_EXPORT void cgul_base64__set_line_length_max ( cgul_exception_t cex,
cgul_base64_t  b64,
size_t  line_length_max 
)

Set the line length that determines when a '\n' character is to be embedded. A value of zero (which is the default) means no '\n' character will be embedded. The line_length_max value only plays a part when encoding binary data into a base64 text stream.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
[in]line_length_maxmaximum line length

§ cgul_base64__get_strict_decode()

CGUL_EXPORT int cgul_base64__get_strict_decode ( cgul_exception_t cex,
cgul_base64_t  b64 
)

Return whether this cgul_base64 object is in strict_decode mode. In this mode, the exhortation in RFC 3548 to reject any non-base64-alphabetic character is honored. This includes '\n' characters. Thus, if you want to decode MIME, you want to disable strict_decode mode. By default strict_decode mode is off.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
Returns
strict decode mode

§ cgul_base64__set_strict_decode()

CGUL_EXPORT void cgul_base64__set_strict_decode ( cgul_exception_t cex,
cgul_base64_t  b64,
int  strict_decode 
)

Set whether this cgul_base64 object is in strict_decode mode.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
[in]strict_decodestrict decode mode

§ cgul_base64__encode()

CGUL_EXPORT void cgul_base64__encode ( cgul_exception_t cex,
cgul_base64_t  b64,
const void *  buf,
size_t  buf_size 
)

Base64 encode buf_size bytes in buf. Each new call to this function clears the cgul_base64 object's internal buffer except for the remainder. So, you must call cgul_base64__get_encode_conversion() before calling this method again.

NOTE: This method is idempotent only if buf_size is a multiple of 3. The reason is that base64 needs exactly 3 8-bit values to generate exactly 4 6-bit values. Thus, if you feed cgul_base64__encode() a buffer that has 1 or 2 bytes remaining, those bytes will be internally saved and used the next time you call this method. Generally, this is the behavior you want when encoding large files.

This class is designed to make it possible and efficient to encode large streams of data without using large amounts of memory. Because of this, it works one block at a time remembering any remainder between blocks.

The downside of this is that this class is less than optimal for doing one-shot encoding. Thus, if you want to encode a single, small block of memory, the least you will have to do is the following:

    // Encode the first (and only) block.
    cgul_base64__encode(&cex, b64, block, block_size);
    s = cgul_base64__get_encode_conversion(&cex, b64, NULL);
    cgul_libc_printf(&cex, "%s", s);
    // Flush the remainder.
    cgul_base64__encode_finish(&cex, b64);
    s = cgul_base64__get_encode_conversion(&cex, b64, NULL);
    cgul_libc_printf(&cex, "%s", s);
Parameters
[in,out]cexc-style exception
[in]b64cgul_base64 instance
[in]bufbinary buffer to encode
[in]buf_sizesize in bytes of buf

§ cgul_base64__encode_finish()

CGUL_EXPORT void cgul_base64__encode_finish ( cgul_exception_t cex,
cgul_base64_t  b64 
)

Call this method after you have fed all the data to cgul_base64__encode(). This method will flush the 1 or 2 bytes that possibly remain after calling cgul_base64__encode(). It will also insert padding at the end of output as required by the base64 specification. You can retrieve the data by calling cgul_base64__get_encode_conversion() as usual. You can continue to use cgul_base64__encode() after calling this method (provided this method does not throw an exception). The internal buffer will simply be empty when you start encoding data again.

Parameters
[in,out]cexc-style exception
[in]b64cgul_base64 instance

§ cgul_base64__get_encode_conversion()

CGUL_EXPORT char* cgul_base64__get_encode_conversion ( cgul_exception_t cex,
cgul_base64_t  b64,
size_t *  buf_size 
)

For efficiency, this method returns a pointer to the cgul_base64 object's internal encoding buffer. (This buffer can be treated as a valid C-style string.) If buf_size is not NULL, the count of valid bytes (not including the trailing NULL-terminator) in the buffer will be returned.

You should call this method immediately after every call to either cgul_base64__encode() or cgul_base64__encode_finish().

The location of the internal buffer in memory can change during each encoding or decoding operation. Thus, you should always call this method immediately before trying to access the internal buffer. Do not cache a pointer to the internal buffer. Also, do not call free() on the pointer that is returned.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
[out]buf_sizesize of the internal encoding buffer
Returns
internal encoding buffer

§ cgul_base64__decode()

CGUL_EXPORT void cgul_base64__decode ( cgul_exception_t cex,
cgul_base64_t  b64,
const void *  buf,
size_t  buf_size 
)

Base64 decode buf_size bytes in buf. Each new call to this function clears the cgul_base64 object's internal buffer except for the remainder. So, you must call cgul_base64__get_decode_conversion() before calling this method again.

NOTE: This method is idempotent only if buf_size is a multiple of 4. The reason is that base64 needs exactly 4 6-bit values to generate exactly 3 8-bit values. Thus, if you feed this method a buffer that has 1, 2, or 3 bytes remaining, those bytes will be internally saved and used the next time you call this method. Generally, this is the behavior you want when decoding large files.

This class is designed to make it possible and efficient to decode large streams of data without using large amounts of memory. Because of this, it works one block at a time remembering any remainder between blocks.

The downside of this is that this class is less than optimal for doing one-shot decoding. Thus, if you want to decode a single, small block of memory, the least you will have to do is the following:

    // Decode the first (and only) block.
    cgul_base64__decode(&cex, b64, block, block_size);
    s = cgul_base64__get_decode_conversion(&cex, b64, NULL);
    cgul_libc_printf(&cex, "%s", s);
    // Flush the remainder.
    cgul_base64__decode_finish(&cex, b64);
    s = cgul_base64__get_decode_conversion(&cex, b64, NULL);
    cgul_libc_printf(&cex, "%s", s);
Parameters
[in,out]cexc-style exception
[in]b64cgul_base64 instance
[in]bufbase64 buffer to decode
[in]buf_sizesize in bytes of buf

§ cgul_base64__decode_finish()

CGUL_EXPORT void cgul_base64__decode_finish ( cgul_exception_t cex,
cgul_base64_t  b64 
)

Call this method after you have fed all the data to cgul_base64__decode(). This method will flush the 1, 2, or 3 bytes that possibly remain after calling cgul_base64__decode(). You can retrieve the data by calling cgul_base64__get_decode_conversion() as usual. You can continue to use cgul_base64__decode() after calling this method (provided this method does not throw an exception). The internal buffer will simply be empty when you start decoding data again.

Parameters
[in,out]cexc-style exception
[in]b64cgul_base64 instance

§ cgul_base64__get_decode_conversion()

CGUL_EXPORT char* cgul_base64__get_decode_conversion ( cgul_exception_t cex,
cgul_base64_t  b64,
size_t *  buf_size 
)

For efficiency, this method returns a pointer to the cgul_base64 object's internal decoding buffer. (This buffer can be treated as a valid C-style string.) If buf_size is not NULL, the count of valid bytes (not including the trailing NULL-terminator) in the buffer will be returned.

You should call this method immediately after every call to either cgul_base64__decode() or cgul_base64__decode_finish().

The location of the internal buffer in memory can change during each encoding or decoding operation. Thus, you should always call this method immediately before trying to access the internal buffer. Do not cache a pointer to the internal buffer. Also, do not call free() on the pointer that is returned.

Parameters
[in]cexc-style exception
[in]b64cgul_base64 instance
[out]buf_sizesize of the internal decoding buffer
Returns
internal decoding buffer