Telodendria/src/include/Base64.h
2022-07-29 15:36:21 -04:00

155 lines
5.7 KiB
C

/*
* Copyright (C) 2022 Jordan Bancino <@jordan:bancino.net>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Base64.h: An efficient base64 encoder and decoder that supports
* both regular base64, and the Matrix spec's "unpadded base64."
*/
#ifndef TELODENDRIA_BASE64_H
#define TELODENDRIA_BASE64_H
#include <stddef.h>
/*
* Compute the encoded size, including padding, of an input with the
* provided size.
*
* Params:
*
* (size_t) The size of the input data to be encoded.
*
* Return: The size of the string needed to hold the data in its
* encoded form. Note that base64 is not compression; base64 strings
* are actually 25% larger than the unencoded input.
*/
extern size_t
Base64EncodedSize(size_t);
/*
* Compute the decoded size of the provide base64 input and length.
*
* Note that both the size and the actual base64 string itself is
* needed for this computation, unlike Base64EncodedSize(). This is
* because base64 strings are padded, and that padding is used in the
* calculations.
*
* Params:
*
* (const char *) A padded base64 string. If you are dealing with
* potentially user-provided base64, you should call
* Base64Pad() on it to normalize it before computing
* the decoded size.
* (size_t) The length of the base64 string. Instead of scanning the
* string for a null terminator, and then working backwards,
* the length of the string must be passed here.
*
* Return: The number of bytes that can be decoded from this base64
* string. Note that this will be smaller than the length of the base64
* string because base64 is larger than the unencoded form.
*/
extern size_t
Base64DecodedSize(const char *, size_t);
/*
* Copy the given input string to a new string, base64 encoding it in
* the process. This function will produce standard padded base64. If
* you want unpadded base64, call Base64Unpad() on the return value
* of this function.
*
* Params:
*
* (const char *) The raw, unencoded input to be encoded as base64.
* (size_t) The length of the unencoded input string.
*
* Return: A new string, allocated on the heap, that holds the base64
* representation of the input. This string must be free()-ed when it
* is no longer needed. If the allocation of the proper size fails,
* or the input is inaccessible, then this function will return NULL.
*/
extern char *
Base64Encode(const char *, size_t);
/*
* Decode a standard padded base64 string. This function expects that
* the input will be padded, so if you are recieving untrusted input,
* you should run Base64Pad() on it before attempting to decode it.
*
* Params:
*
* (const char *) The base64 string to decode.
* (size_t) The length of the base64 string to decode.
*
* Return: A new string, allocated on the heap, that contains the
* decoded string, or NULL if a decoding error occurred.
*/
extern char *
Base64Decode(const char *, size_t);
/*
* Remove the padding from a base64 string. This is to implement the
* Matrix spec's "unpadded base64" functionality. When base64 strings
* are sent to other servers and clients, their padding must be
* stripped.
*
* Params:
*
* (char *) The base64 string to remove padding from. Note that
* this string is modified in place.
* (size_t) The length of the provided base64 string.
*
*/
extern void
Base64Unpad(char *, size_t);
/*
* Pad a base64 string in place. This is to implement the Matrix spec's
* "unpadded base64." As we will most likely be getting unpadded base64
* from clients and other servers, we should pad it before attempting
* to decode it.
*
* I technically could have just had the decoder accept unpadded as
* well as padded strings, but Matrix is the only thing I know of that
* actually makes "unpadded" base64 a thing, so I thought it best to
* make it clear in this library that unpadded base64 is an extension,
* not the norm.
*
* Params:
*
* (char **) A pointer to a base64 string pointer. The reason we
* take a pointer pointer is because the string may need
* to be reallocated, as characters may be added to the
* end of it. If the string is reallocated, then the
* passed pointer must be updated. If the string is not
* reallocated, the original pointer is not touched.
* (size_t) The length of the given base64 string.
*
* Return: Whether or not the pad operation was successful. This
* function will fail if a larger string cannot be allocated when it
* is needed. Note that not all cases require the string to be
* reallocated.
*/
extern int
Base64Pad(char **, size_t);
#endif /* TELODENDRIA_BASE64_H */