audk/BaseTools/ImageTool/DynamicBuffer.c

220 lines
4.5 KiB
C

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <Base.h>
#include <Library/BaseOverflowLib.h>
#include "ImageTool.h"
#include "DynamicBuffer.h"
#ifndef IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH
#define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000
#endif // IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH
void
ImageToolBufferInit (
image_tool_dynamic_buffer *Buffer
)
{
memset (Buffer, 0, sizeof (*Buffer));
}
static
uint32_t
ImageToolBufferExpand (
image_tool_dynamic_buffer *Buffer,
uint32_t Size
)
{
bool Overflow;
uint32_t NewAllocatedSize;
uint8_t *NewMemory;
uint32_t Offset;
assert (Buffer->DataSize <= Buffer->AllocatedSize);
assert (IS_ALIGNED (Buffer->AllocatedSize, IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH));
if (Buffer->AllocatedSize - Buffer->DataSize < Size) {
Overflow = BaseOverflowAlignUpU32 (
Size,
IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH,
&NewAllocatedSize
);
if (Overflow) {
DEBUG_RAISE ();
return MAX_UINT32;
}
Overflow = BaseOverflowAddU32 (
NewAllocatedSize,
Buffer->AllocatedSize,
&NewAllocatedSize
);
if (Overflow) {
DEBUG_RAISE ();
return MAX_UINT32;
}
NewMemory = AllocatePool (NewAllocatedSize);
if (NewMemory == NULL) {
DEBUG_RAISE ();
return MAX_UINT32;
}
if (Buffer->Memory != NULL) {
memmove (NewMemory, Buffer->Memory, Buffer->DataSize);
FreePool (Buffer->Memory);
}
memset (
NewMemory + Buffer->DataSize,
0,
NewAllocatedSize - Buffer->DataSize
);
Buffer->Memory = NewMemory;
Buffer->AllocatedSize = NewAllocatedSize;
}
Offset = Buffer->DataSize;
Buffer->DataSize += Size;
return Offset;
}
void
ImageToolBufferRead (
void *Data,
uint32_t Size,
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
)
{
assert (Offset + Size > Offset);
assert (Offset + Size <= Buffer->DataSize);
memmove (Data, &Buffer->Memory[Offset], Size);
}
void
ImageToolBufferWrite (
image_tool_dynamic_buffer *Buffer,
uint32_t Offset,
const void *Data,
uint32_t Size
)
{
assert (Offset + Size > Offset);
assert (Offset + Size <= Buffer->DataSize);
memmove (&Buffer->Memory[Offset], Data, Size);
}
uint32_t
ImageToolBufferAppend (
image_tool_dynamic_buffer *Buffer,
const void *Data,
uint32_t Size
)
{
uint32_t Offset;
Offset = ImageToolBufferExpand (Buffer, Size);
if (Offset != MAX_UINT32) {
memmove (&Buffer->Memory[Offset], Data, Size);
}
return Offset;
}
uint32_t
ImageToolBufferAppendReserve (
image_tool_dynamic_buffer *Buffer,
uint32_t Size
)
{
uint32_t Offset;
Offset = ImageToolBufferExpand (Buffer, Size);
if (Offset != MAX_UINT32) {
memset (&Buffer->Memory[Offset], 0, Size);
}
return Offset;
}
uint32_t
ImageToolBufferAppendReserveAlign (
image_tool_dynamic_buffer *Buffer,
uint32_t Alignment
)
{
assert (IS_POW2 (Alignment));
return ImageToolBufferAppendReserve (
Buffer,
ALIGN_VALUE_ADDEND (ImageToolBufferGetSize (Buffer), Alignment)
);
}
void *
ImageToolBufferGetPointer (
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
)
{
assert (Offset < Buffer->DataSize);
return &Buffer->Memory[Offset];
}
uint32_t
ImageToolBufferGetSize (
const image_tool_dynamic_buffer *Buffer
)
{
return Buffer->DataSize;
}
void *
ImageToolBufferDump (
uint32_t *Size,
image_tool_dynamic_buffer *Buffer
)
{
void *Data;
uint32_t DataSize;
// LCOV_EXCL_START
if (Buffer->Memory == NULL) {
return NULL;
}
// LCOV_EXCL_STOP
DataSize = ImageToolBufferGetSize (Buffer);
Data = AllocateCopyPool (DataSize, Buffer->Memory);
if (Data == NULL) {
return NULL;
}
*Size = DataSize;
return Data;
}
void
ImageToolBufferFree (
image_tool_dynamic_buffer *Buffer
)
{
if (Buffer->Memory != NULL) {
FreePool (Buffer->Memory);
}
ImageToolBufferInit (Buffer);
}