From c11a0bd2abef4c9536432664600ce6b6ed6ccbe4 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Mon, 15 Jun 2015 01:04:48 +0300 Subject: error handling refactoring + more docs --- include/aesni/buffer.h | 8 ++-- include/aesni/error.h | 120 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 111 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/aesni/buffer.h b/include/aesni/buffer.h index 6222f4f..fff616f 100644 --- a/include/aesni/buffer.h +++ b/include/aesni/buffer.h @@ -18,20 +18,20 @@ extern "C" { #endif -int aesni_encrypt_buffer_ecb128( +AesNI_StatusCode aesni_encrypt_buffer_ecb128( const void* src, size_t src_size, void* dest, size_t* dest_size, AesNI_KeySchedule128* key_schedule, - AesNI_ErrorDetails*); -int aesni_decrypt_buffer_ecb128( + AesNI_ErrorDetails* err_details); +AesNI_StatusCode aesni_decrypt_buffer_ecb128( const void* src, size_t src_size, void* dest, size_t* dest_size, AesNI_KeySchedule128* inverted_schedule, - AesNI_ErrorDetails*); + AesNI_ErrorDetails* err_details); #ifdef __cplusplus } diff --git a/include/aesni/error.h b/include/aesni/error.h index 91bf168..56a1da1 100644 --- a/include/aesni/error.h +++ b/include/aesni/error.h @@ -9,6 +9,28 @@ #pragma once +/** + * \defgroup aesni_error_handling Error handling + * \ingroup aesni + * \brief Error data structures and formatting functions. + * + * Some library functions cannot fail, which is simple. + * Other functions return an error code. + * You can check if a function exited with an error by passing the returned + * error code to aesni_is_error(). + * + * Some possibly-may-fail functions accept a pointer to an "error details" + * structure. + * This pointer can always be `NULL`. + * In this case, simply an error code is returned. + * Otherwise, the error details structure is filled with appropriate info about + * the error, possibly including a few details like invalid arguments names, + * etc. + * + * You can format an error details structure using the formatting functions. + * \{ + */ + #include #ifdef __cplusplus @@ -16,45 +38,117 @@ extern "C" { #endif +/** + * \brief API status codes. + */ typedef enum { - AESNI_ERROR_SUCCESS, + AESNI_SUCCESS, ///< Indicates an operation + + AESNI_ERROR_NULL_ARGUMENT, ///< Invalid argument value NULL - AESNI_ERROR_NULL_ARGUMENT, + AESNI_ERROR_INVALID_PKCS7_PADDING, ///< Invalid PKCS7 padding +} +AesNI_StatusCode; - AESNI_ERROR_INVALID_PKCS7_PADDING, +static __inline int aesni_is_error(AesNI_StatusCode ec) +{ + return ec != AESNI_SUCCESS; } -AesNI_ErrorCode; -const char* aesni_strerror(AesNI_ErrorCode); +/** + * \brief Retrieves a simple error message for an error code. + * + * For example, + * \code{.c} + * printf("%s\n", aesni_strerror(AESNI_ERROR_NULL_ARGUMENT)); + * \endcode + * would print + * \code + * Invalid argument value NULL + * \endcode + * + * \param[in] ec The error code. + * \return A pointer to a statically-allocated C string. + */ +const char* aesni_strerror(AesNI_StatusCode ec); +/** + * \brief Stores error details: error code & possibly a few parameters. + */ typedef struct { - AesNI_ErrorCode ec; + AesNI_StatusCode ec; ///< Error code union { struct { - char arg_name[32]; + char arg_name[32]; ///< Name of the NULL argument } - null_arg; + null_arg; ///< `NULL` argument error parameters } params; } AesNI_ErrorDetails; -static __inline AesNI_ErrorCode aesni_get_error_code(const AesNI_ErrorDetails* err_details) +/** + * \brief Extracts an error code from error details. + * + * \param[in] err_details The error details structure. Must not be `NULL`. + * \return The error code stored in the error details. + */ +static __inline AesNI_StatusCode aesni_get_error_code( + const AesNI_ErrorDetails* err_details) { return err_details->ec; } -size_t aesni_format_error(const AesNI_ErrorDetails*, char*, size_t); +/** + * \brief Formats a pretty error message, including error parameters. + * + * \param[in] err_details The pointer to error details. Must not be `NULL`. + * \param[out] dest The pointer to the destination string buffer. + * \param[in] dest_size The size of the destination buffer, in bytes. + * \return If `dest` is NULL, the number of bytes required to store the full + * error message, and the number of characters written (excluding the + * terminating '\0' character) otherwise. + */ +size_t aesni_format_error( + const AesNI_ErrorDetails* err_details, + char* dest, + size_t dest_size); -void aesni_make_error_success(AesNI_ErrorDetails*); -void aesni_make_error_null_argument(AesNI_ErrorDetails*, const char* arg_name); -void aesni_make_error_invalid_pkcs7_padding(AesNI_ErrorDetails*); +/** + * \brief Initializes error details structure. + * + * \param[out] err_details The error details structure to fill. + */ +AesNI_StatusCode aesni_make_error_success( + AesNI_ErrorDetails* err_details); + +/** + * \brief Builds error details from a `NULL` argument error. + * + * \param[out] err_details The error details structure to fill. + * \param[in] arg_name The `NULL` argument name. Must not be `NULL`. + */ +AesNI_StatusCode aesni_make_error_null_argument( + AesNI_ErrorDetails* err_details, + const char* arg_name); + +/** + * \brief Builds error details from an invalid PKCS7 padding error. + * + * \param[out] err_details The error details structure to fill. + */ +AesNI_StatusCode aesni_make_error_invalid_pkcs7_padding( + AesNI_ErrorDetails* err_details); #ifdef __cplusplus } #endif + +/** + * \} + */ -- cgit v1.2.3