2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Serial port driver
4 * FILE: drivers/dd/serial/circularbuffer.c
5 * PURPOSE: Operations on a circular buffer
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
13 InitializeCircularBuffer(
14 IN PCIRCULAR_BUFFER pBuffer
,
17 TRACE_(SERIAL
, "InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer
, BufferSize
);
19 pBuffer
->Buffer
= (PUCHAR
)ExAllocatePoolWithTag(NonPagedPool
, BufferSize
* sizeof(UCHAR
), SERIAL_TAG
);
21 return STATUS_INSUFFICIENT_RESOURCES
;
22 pBuffer
->Length
= BufferSize
;
23 pBuffer
->ReadPosition
= pBuffer
->WritePosition
= 0;
24 return STATUS_SUCCESS
;
29 IN PCIRCULAR_BUFFER pBuffer
)
31 TRACE_(SERIAL
, "FreeCircularBuffer(pBuffer %p)\n", pBuffer
);
33 if (pBuffer
->Buffer
!= NULL
)
34 ExFreePoolWithTag(pBuffer
->Buffer
, SERIAL_TAG
);
35 return STATUS_SUCCESS
;
39 IsCircularBufferEmpty(
40 IN PCIRCULAR_BUFFER pBuffer
)
42 TRACE_(SERIAL
, "IsCircularBufferEmpty(pBuffer %p)\n", pBuffer
);
44 return (pBuffer
->ReadPosition
== pBuffer
->WritePosition
);
48 GetNumberOfElementsInCircularBuffer(
49 IN PCIRCULAR_BUFFER pBuffer
)
51 TRACE_(SERIAL
, "GetNumberOfElementsInCircularBuffer(pBuffer %p)\n", pBuffer
);
53 return (pBuffer
->WritePosition
+ pBuffer
->Length
- pBuffer
->ReadPosition
) % pBuffer
->Length
;
57 PushCircularBufferEntry(
58 IN PCIRCULAR_BUFFER pBuffer
,
62 TRACE_(SERIAL
, "PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer
, Entry
);
64 ASSERT(pBuffer
->Length
);
65 NextPosition
= (pBuffer
->WritePosition
+ 1) % pBuffer
->Length
;
66 if (NextPosition
== pBuffer
->ReadPosition
)
67 return STATUS_BUFFER_TOO_SMALL
;
68 pBuffer
->Buffer
[pBuffer
->WritePosition
] = Entry
;
69 pBuffer
->WritePosition
= NextPosition
;
70 return STATUS_SUCCESS
;
74 PopCircularBufferEntry(
75 IN PCIRCULAR_BUFFER pBuffer
,
78 TRACE_(SERIAL
, "PopCircularBufferEntry(pBuffer %p)\n", pBuffer
);
80 ASSERT(pBuffer
->Length
);
81 if (IsCircularBufferEmpty(pBuffer
))
82 return STATUS_ARRAY_BOUNDS_EXCEEDED
;
83 *Entry
= pBuffer
->Buffer
[pBuffer
->ReadPosition
];
84 pBuffer
->ReadPosition
= (pBuffer
->ReadPosition
+ 1) % pBuffer
->Length
;
85 return STATUS_SUCCESS
;
89 IncreaseCircularBufferSize(
90 IN PCIRCULAR_BUFFER pBuffer
,
91 IN ULONG NewBufferSize
)
95 TRACE_(SERIAL
, "IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer
, NewBufferSize
);
97 ASSERT(pBuffer
->Length
);
98 if (pBuffer
->Length
> NewBufferSize
)
99 return STATUS_INVALID_PARAMETER
;
100 else if (pBuffer
->Length
== NewBufferSize
)
101 return STATUS_SUCCESS
;
103 NewBuffer
= (PUCHAR
)ExAllocatePoolWithTag(NonPagedPool
, NewBufferSize
* sizeof(UCHAR
), SERIAL_TAG
);
105 return STATUS_INSUFFICIENT_RESOURCES
;
106 RtlCopyMemory(NewBuffer
, pBuffer
->Buffer
, pBuffer
->Length
* sizeof(UCHAR
));
107 ExFreePoolWithTag(pBuffer
->Buffer
, SERIAL_TAG
);
108 pBuffer
->Buffer
= NewBuffer
;
109 pBuffer
->Length
= NewBufferSize
;
110 return STATUS_SUCCESS
;