Process Hacker
circbuf_i.h
Go to the documentation of this file.
1 #ifdef T
2 
3 #include <templ.h>
4 
5 VOID T___(PhInitializeCircularBuffer, T)(
6  _Out_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
7  _In_ ULONG Size
8  )
9 {
10 #ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
11  Buffer->Size = PhRoundUpToPowerOfTwo(Size);
12  Buffer->SizeMinusOne = Buffer->Size - 1;
13 #else
14  Buffer->Size = Size;
15 #endif
16 
17  Buffer->Count = 0;
18  Buffer->Index = 0;
19  Buffer->Data = PhAllocate(sizeof(T) * Buffer->Size);
20 }
21 
22 VOID T___(PhDeleteCircularBuffer, T)(
23  _Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer
24  )
25 {
26  PhFree(Buffer->Data);
27 }
28 
29 VOID T___(PhResizeCircularBuffer, T)(
30  _Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
31  _In_ ULONG NewSize
32  )
33 {
34  T *newData;
35  ULONG tailSize;
36  ULONG headSize;
37 
38 #ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
39  NewSize = PhRoundUpToPowerOfTwo(NewSize);
40 #endif
41 
42  // If we're not actually resizing it, return.
43  if (NewSize == Buffer->Size)
44  return;
45 
46  newData = PhAllocate(sizeof(T) * NewSize);
47  tailSize = (ULONG)(Buffer->Size - Buffer->Index);
48  headSize = Buffer->Count - tailSize;
49 
50  if (NewSize > Buffer->Size)
51  {
52  // Copy the tail, then the head.
53  memcpy(newData, &Buffer->Data[Buffer->Index], sizeof(T) * tailSize);
54  memcpy(&newData[tailSize], Buffer->Data, sizeof(T) * headSize);
55  Buffer->Index = 0;
56  }
57  else
58  {
59  if (tailSize >= NewSize)
60  {
61  // Copy only a part of the tail.
62  memcpy(newData, &Buffer->Data[Buffer->Index], sizeof(T) * NewSize);
63  Buffer->Index = 0;
64  }
65  else
66  {
67  // Copy the tail, then only part of the head.
68  memcpy(newData, &Buffer->Data[Buffer->Index], sizeof(T) * tailSize);
69  memcpy(&newData[tailSize], Buffer->Data, sizeof(T) * (NewSize - tailSize));
70  Buffer->Index = 0;
71  }
72 
73  // Since we're making the circular buffer smaller, limit the count.
74  if (Buffer->Count > NewSize)
75  Buffer->Count = NewSize;
76  }
77 
78  Buffer->Data = newData;
79  Buffer->Size = NewSize;
80 #ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
81  Buffer->SizeMinusOne = NewSize - 1;
82 #endif
83 }
84 
85 VOID T___(PhClearCircularBuffer, T)(
86  _Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer
87  )
88 {
89  Buffer->Count = 0;
90  Buffer->Index = 0;
91 }
92 
93 VOID T___(PhCopyCircularBuffer, T)(
94  _Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
95  _Out_writes_(Count) T *Destination,
96  _In_ ULONG Count
97  )
98 {
99  ULONG tailSize;
100  ULONG headSize;
101 
102  tailSize = (ULONG)(Buffer->Size - Buffer->Index);
103  headSize = Buffer->Count - tailSize;
104 
105  if (Count > Buffer->Count)
106  Count = Buffer->Count;
107 
108  if (tailSize >= Count)
109  {
110  // Copy only a part of the tail.
111  memcpy(Destination, &Buffer->Data[Buffer->Index], sizeof(T) * Count);
112  }
113  else
114  {
115  // Copy the tail, then only part of the head.
116  memcpy(Destination, &Buffer->Data[Buffer->Index], sizeof(T) * tailSize);
117  memcpy(&Destination[tailSize], Buffer->Data, sizeof(T) * (Count - tailSize));
118  }
119 }
120 
121 #endif