295 lines
7.9 KiB
C

/** @file
Copyright (C) 2021, Mike Beaton. All rights reserved.<BR>
SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef OC_FLEX_ARRAY_LIB_H
#define OC_FLEX_ARRAY_LIB_H
#if !defined (OC_TRACE_FLEX)
#define OC_TRACE_FLEX DEBUG_VERBOSE
#endif
#include <Uefi.h>
#include <Library/OcStringLib.h>
#include <Protocol/ApplePlatformInfoDatabase.h>
/**
Forward declaration of OC_FLEX_ARRAY structure.
**/
typedef struct OC_FLEX_ARRAY_ OC_FLEX_ARRAY;
/**
Free any allocated memory pointed to by flex array item.
@param[in] Item Item to free.
**/
typedef
VOID
(*OC_FLEX_ARRAY_FREE_ITEM) (
IN VOID *Item
);
/**
Utility method to free memory pointed to by flex array
item when the item is a single pointer, or when the only
allocated memory is pointed to by a pointer which is the
first element.
@param[in] Item Flex array item to free.
**/
VOID
OcFlexArrayFreePointerItem (
IN VOID *Item
);
/**
Initialize flex array.
@param[in] ItemSize Size of each item in the array.
@param[in] FreeItem Method to free one item, called once per item by
OcFlexArrayFree; may be NULL if there is nothing
pointed to by pool items which needs freeing.
@retval Non-NULL Flex array was created.
@retval NULL Out of memory.
**/
OC_FLEX_ARRAY *
OcFlexArrayInit (
IN CONST UINTN ItemSize,
IN CONST OC_FLEX_ARRAY_FREE_ITEM FreeItem OPTIONAL
);
/**
Add new item to flex array, resizing if necessary. New item memory is zeroed.
@param[in,out] FlexArray Flex array to modify.
@retval Non-NULL Address of item created.
@retval NULL Out of memory, in which case FlexArray->Items will be set
to NULL, but FlexArray itself will still be allocated.
**/
VOID *
OcFlexArrayAddItem (
IN OUT OC_FLEX_ARRAY *FlexArray
);
/**
Insert new item at position in flex array, resizing array if necessary. New item memory is zeroed.
@param[in,out] FlexArray Flex array to modify.
@param[in] InsertIndex Index at which to insert; must be less than or equal to current item count.
@retval Non-NULL Address of item created.
@retval NULL Out of memory, in which case FlexArray->Items will be set
to NULL, but FlexArray itself will still be allocated.
**/
VOID *
OcFlexArrayInsertItem (
IN OUT OC_FLEX_ARRAY *FlexArray,
IN CONST UINTN InsertIndex
);
/**
Return item at index in array.
@param[in,out] FlexArray Flex array to access.
@param[in,out] Index Index of item to return.
@retval Non-NULL Item.
@retval NULL Out-of-range item requested. This also ASSERTs.
**/
VOID *
OcFlexArrayItemAt (
IN CONST OC_FLEX_ARRAY *FlexArray,
IN CONST UINTN Index
);
/**
Free flex array.
@param[in,out] FlexArray Flex array to free.
**/
VOID
OcFlexArrayFree (
IN OUT OC_FLEX_ARRAY **FlexArray
);
/**
Discard last item on flex array, optionally calling item free method.
@param[in,out] FlexArray Flex array to modify.
@param[in] FreeItem Whether to call item free method.
**/
VOID
OcFlexArrayDiscardItem (
IN OUT OC_FLEX_ARRAY *FlexArray,
IN CONST BOOLEAN FreeItem
);
/**
Free dynamic container object, but do not free and
pass back out allocated items with item count.
@param[in,out] FlexArray Flex array to free.
@param[in,out] Items Pool allocated flex array item list.
@param[in,out] Count Item list count.
**/
VOID
OcFlexArrayFreeContainer (
IN OUT OC_FLEX_ARRAY **FlexArray,
IN OUT VOID **Items,
IN OUT UINTN *Count
);
/*
Flex array.
*/
struct OC_FLEX_ARRAY_ {
//
// Allocated array.
//
VOID *Items;
//
// Item size.
//
UINTN ItemSize;
//
// Current used count.
//
UINTN Count;
//
// Current allocated count.
//
UINTN AllocatedCount;
//
// Optional method to free memory pointed to from item.
//
OC_FLEX_ARRAY_FREE_ITEM FreeItem;
};
/*
Forward declaration of OC_ASCII_STRING_BUFFER structure.
*/
typedef struct OC_ASCII_STRING_BUFFER_ OC_ASCII_STRING_BUFFER;
/**
Initialize string buffer.
@retval Non-NULL Buffer was created.
@retval NULL Out of memory.
**/
OC_ASCII_STRING_BUFFER *
OcAsciiStringBufferInit (
VOID
);
/**
Append new string to buffer, resizing if necessary.
@param[in,out] StringBuffer Buffer to modify.
@param[in] AppendString String to append. If NULL, nothing will be modified.
@retval EFI_SUCCESS String was appended.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_UNSUPPORTED Internal error.
**/
EFI_STATUS
OcAsciiStringBufferAppend (
IN OUT OC_ASCII_STRING_BUFFER *Buffer,
IN CONST CHAR8 *AppendString OPTIONAL
);
/**
Append new substring to buffer, resizing if necessary.
@param[in,out] StringBuffer Buffer to modify.
@param[in] AppendString String to append. If NULL, nothing will be modified.
@param[in] Length Maxiumum length of substring to use. 0 means use 0 characters.
Use MAX_UINTN for all chars. Ignored if AppendString is NULL.
@retval EFI_SUCCESS String was appended.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_UNSUPPORTED Internal error.
**/
EFI_STATUS
OcAsciiStringBufferAppendN (
IN OUT OC_ASCII_STRING_BUFFER *Buffer,
IN CONST CHAR8 *AppendString, OPTIONAL
IN CONST UINTN Length
);
/**
Safely print to string buffer.
@param[in,out] StringBuffer Buffer to modify.
@param[in] FormatString A Null-terminated ASCII format string.
@param[in] ... Variable argument list whose contents are accessed based on the
format string specified by FormatString.
@retval EFI_SUCCESS When data was printed to string buffer.
@retval EFI_OUT_OF_RESOURCES Out of memory increasing string buffer sufficiently to print to.
**/
EFI_STATUS
EFIAPI
OcAsciiStringBufferSPrint (
IN OUT OC_ASCII_STRING_BUFFER *Buffer,
IN CONST CHAR8 *FormatString,
...
);
/**
Free string buffer memory and return pointer to pool allocated resultant string.
Note that if no data was ever appended to the string then the return value
will be NULL, not a zero length string.
@param[in,out] StringBuffer StringBuffer to free.
@retval Non-NULL Pointer to pool allocated accumulated string.
@retval NULL No data was ever added to the string.
**/
CHAR8 *
OcAsciiStringBufferFreeContainer (
IN OUT OC_ASCII_STRING_BUFFER **StringBuffer
);
/**
Free string buffer memory; free and discard any allocated resultant string.
@param[in,out] StringBuffer StringBuffer to free.
@retval Non-NULL Pointer to pool allocated accumulated string.
@retval NULL No data was ever added to the string.
**/
VOID
OcAsciiStringBufferFree (
IN OUT OC_ASCII_STRING_BUFFER **StringBuffer
);
/*
String buffer.
*/
struct OC_ASCII_STRING_BUFFER_ {
CHAR8 *String;
UINTN StringLength;
UINTN BufferSize;
};
/**
Split string by delimiter.
@param[in] String A Null-terminated string.
@param[in] Delim Delimiter to search in String.
@param[in] StringFormat Are option names and values Unicode or ASCII?
@return A flex array containing splitted string.
**/
OC_FLEX_ARRAY *
OcStringSplit (
IN CONST VOID *String,
IN CONST CHAR16 Delim,
IN CONST OC_STRING_FORMAT StringFormat
);
#endif // OC_FLEX_ARRAY_LIB_H