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)
15 InitializeCircularBuffer(
16 IN PCIRCULAR_BUFFER pBuffer
,
19 TRACE_(SERIAL
, "InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer
, BufferSize
);
21 pBuffer
->Buffer
= (PUCHAR
)ExAllocatePoolWithTag(NonPagedPool
, BufferSize
* sizeof(UCHAR
), SERIAL_TAG
);
23 return STATUS_INSUFFICIENT_RESOURCES
;
24 pBuffer
->Length
= BufferSize
;
25 pBuffer
->ReadPosition
= pBuffer
->WritePosition
= 0;
26 return STATUS_SUCCESS
;
31 IN PCIRCULAR_BUFFER pBuffer
)
33 TRACE_(SERIAL
, "FreeCircularBuffer(pBuffer %p)\n", pBuffer
);
35 if (pBuffer
->Buffer
!= NULL
)
36 ExFreePoolWithTag(pBuffer
->Buffer
, SERIAL_TAG
);
37 return STATUS_SUCCESS
;
41 IsCircularBufferEmpty(
42 IN PCIRCULAR_BUFFER pBuffer
)
44 TRACE_(SERIAL
, "IsCircularBufferEmpty(pBuffer %p)\n", pBuffer
);
46 return (pBuffer
->ReadPosition
== pBuffer
->WritePosition
);
50 GetNumberOfElementsInCircularBuffer(
51 IN PCIRCULAR_BUFFER pBuffer
)
53 TRACE_(SERIAL
, "GetNumberOfElementsInCircularBuffer(pBuffer %p)\n", pBuffer
);
55 return (pBuffer
->WritePosition
+ pBuffer
->Length
- pBuffer
->ReadPosition
) % pBuffer
->Length
;
59 PushCircularBufferEntry(
60 IN PCIRCULAR_BUFFER pBuffer
,
64 TRACE_(SERIAL
, "PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer
, Entry
);
66 ASSERT(pBuffer
->Length
);
67 NextPosition
= (pBuffer
->WritePosition
+ 1) % pBuffer
->Length
;
68 if (NextPosition
== pBuffer
->ReadPosition
)
69 return STATUS_BUFFER_TOO_SMALL
;
70 pBuffer
->Buffer
[pBuffer
->WritePosition
] = Entry
;
71 pBuffer
->WritePosition
= NextPosition
;
72 return STATUS_SUCCESS
;
76 PopCircularBufferEntry(
77 IN PCIRCULAR_BUFFER pBuffer
,
80 TRACE_(SERIAL
, "PopCircularBufferEntry(pBuffer %p)\n", pBuffer
);
82 ASSERT(pBuffer
->Length
);
83 if (IsCircularBufferEmpty(pBuffer
))
84 return STATUS_ARRAY_BOUNDS_EXCEEDED
;
85 *Entry
= pBuffer
->Buffer
[pBuffer
->ReadPosition
];
86 pBuffer
->ReadPosition
= (pBuffer
->ReadPosition
+ 1) % pBuffer
->Length
;
87 return STATUS_SUCCESS
;
91 IncreaseCircularBufferSize(
92 IN PCIRCULAR_BUFFER pBuffer
,
93 IN ULONG NewBufferSize
)
97 TRACE_(SERIAL
, "IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer
, NewBufferSize
);
99 ASSERT(pBuffer
->Length
);
100 if (pBuffer
->Length
> NewBufferSize
)
101 return STATUS_INVALID_PARAMETER
;
102 else if (pBuffer
->Length
== NewBufferSize
)
103 return STATUS_SUCCESS
;
105 NewBuffer
= (PUCHAR
)ExAllocatePoolWithTag(NonPagedPool
, NewBufferSize
* sizeof(UCHAR
), SERIAL_TAG
);
107 return STATUS_INSUFFICIENT_RESOURCES
;
108 RtlCopyMemory(NewBuffer
, pBuffer
->Buffer
, pBuffer
->Length
* sizeof(UCHAR
));
109 ExFreePoolWithTag(pBuffer
->Buffer
, SERIAL_TAG
);
110 pBuffer
->Buffer
= NewBuffer
;
111 pBuffer
->Length
= NewBufferSize
;
112 return STATUS_SUCCESS
;