mirror of
https://github.com/reactos/reactos.git
synced 2024-06-27 00:11:35 +00:00
114 lines
3.1 KiB
C
114 lines
3.1 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: Serial port driver
|
|
* FILE: drivers/dd/serial/circularbuffer.c
|
|
* PURPOSE: Operations on a circular buffer
|
|
*
|
|
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
|
*/
|
|
|
|
#include "serial.h"
|
|
|
|
#include <debug.h>
|
|
|
|
NTSTATUS
|
|
InitializeCircularBuffer(
|
|
IN PCIRCULAR_BUFFER pBuffer,
|
|
IN ULONG BufferSize)
|
|
{
|
|
TRACE_(SERIAL, "InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize);
|
|
ASSERT(pBuffer);
|
|
pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);
|
|
if (!pBuffer->Buffer)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
pBuffer->Length = BufferSize;
|
|
pBuffer->ReadPosition = pBuffer->WritePosition = 0;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
FreeCircularBuffer(
|
|
IN PCIRCULAR_BUFFER pBuffer)
|
|
{
|
|
TRACE_(SERIAL, "FreeCircularBuffer(pBuffer %p)\n", pBuffer);
|
|
ASSERT(pBuffer);
|
|
if (pBuffer->Buffer != NULL)
|
|
ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
BOOLEAN
|
|
IsCircularBufferEmpty(
|
|
IN PCIRCULAR_BUFFER pBuffer)
|
|
{
|
|
TRACE_(SERIAL, "IsCircularBufferEmpty(pBuffer %p)\n", pBuffer);
|
|
ASSERT(pBuffer);
|
|
return (pBuffer->ReadPosition == pBuffer->WritePosition);
|
|
}
|
|
|
|
ULONG
|
|
GetNumberOfElementsInCircularBuffer(
|
|
IN PCIRCULAR_BUFFER pBuffer)
|
|
{
|
|
TRACE_(SERIAL, "GetNumberOfElementsInCircularBuffer(pBuffer %p)\n", pBuffer);
|
|
ASSERT(pBuffer);
|
|
return (pBuffer->WritePosition + pBuffer->Length - pBuffer->ReadPosition) % pBuffer->Length;
|
|
}
|
|
|
|
NTSTATUS
|
|
PushCircularBufferEntry(
|
|
IN PCIRCULAR_BUFFER pBuffer,
|
|
IN UCHAR Entry)
|
|
{
|
|
ULONG NextPosition;
|
|
TRACE_(SERIAL, "PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry);
|
|
ASSERT(pBuffer);
|
|
ASSERT(pBuffer->Length);
|
|
NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length;
|
|
if (NextPosition == pBuffer->ReadPosition)
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
pBuffer->Buffer[pBuffer->WritePosition] = Entry;
|
|
pBuffer->WritePosition = NextPosition;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
PopCircularBufferEntry(
|
|
IN PCIRCULAR_BUFFER pBuffer,
|
|
OUT PUCHAR Entry)
|
|
{
|
|
TRACE_(SERIAL, "PopCircularBufferEntry(pBuffer %p)\n", pBuffer);
|
|
ASSERT(pBuffer);
|
|
ASSERT(pBuffer->Length);
|
|
if (IsCircularBufferEmpty(pBuffer))
|
|
return STATUS_ARRAY_BOUNDS_EXCEEDED;
|
|
*Entry = pBuffer->Buffer[pBuffer->ReadPosition];
|
|
pBuffer->ReadPosition = (pBuffer->ReadPosition + 1) % pBuffer->Length;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
IncreaseCircularBufferSize(
|
|
IN PCIRCULAR_BUFFER pBuffer,
|
|
IN ULONG NewBufferSize)
|
|
{
|
|
PUCHAR NewBuffer;
|
|
|
|
TRACE_(SERIAL, "IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize);
|
|
ASSERT(pBuffer);
|
|
ASSERT(pBuffer->Length);
|
|
if (pBuffer->Length > NewBufferSize)
|
|
return STATUS_INVALID_PARAMETER;
|
|
else if (pBuffer->Length == NewBufferSize)
|
|
return STATUS_SUCCESS;
|
|
|
|
NewBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, NewBufferSize * sizeof(UCHAR), SERIAL_TAG);
|
|
if (!NewBuffer)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
RtlCopyMemory(NewBuffer, pBuffer->Buffer, pBuffer->Length * sizeof(UCHAR));
|
|
ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
|
|
pBuffer->Buffer = NewBuffer;
|
|
pBuffer->Length = NewBufferSize;
|
|
return STATUS_SUCCESS;
|
|
}
|