xref: /reactos/sdk/lib/dnslib/flatbuf.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS DNS Shared Library
4  * FILE:        lib/dnslib/flatbuf.c
5  * PURPOSE:     Functions for managing the Flat Buffer Implementation (FLATBUF)
6  */
7 
8 /* INCLUDES ******************************************************************/
9 #include "precomp.h"
10 
11 /* DATA **********************************************************************/
12 
13 /* FUNCTIONS *****************************************************************/
14 
15 VOID
16 WINAPI
FlatBuf_Init(IN PFLATBUFF FlatBuffer,IN PVOID Buffer,IN SIZE_T Size)17 FlatBuf_Init(IN PFLATBUFF FlatBuffer,
18              IN PVOID Buffer,
19              IN SIZE_T Size)
20 {
21     /* Set up the Flat Buffer start, current and ending position */
22     FlatBuffer->Buffer = Buffer;
23     FlatBuffer->BufferPos = (ULONG_PTR)Buffer;
24     FlatBuffer->BufferEnd = (PVOID)(FlatBuffer->BufferPos + Size);
25 
26     /* Setup the current size and the available size */
27     FlatBuffer->BufferSize = FlatBuffer->BufferFreeSize = Size;
28 }
29 
30 PVOID
31 WINAPI
FlatBuf_Arg_Reserve(IN OUT PULONG_PTR Position,IN OUT PSIZE_T FreeSize,IN SIZE_T Size,IN ULONG Align)32 FlatBuf_Arg_Reserve(IN OUT PULONG_PTR Position,
33                     IN OUT PSIZE_T FreeSize,
34                     IN SIZE_T Size,
35                     IN ULONG Align)
36 {
37     ULONG_PTR NewPosition, OldPosition = *Position;
38     SIZE_T NewFreeSize = *FreeSize;
39 
40     /* Start by aligning our position */
41     if (Align) OldPosition += (Align - 1) & ~Align;
42 
43     /* Update it */
44     NewPosition = OldPosition + Size;
45 
46     /* Update Free Size */
47     NewFreeSize += (OldPosition - NewPosition);
48 
49     /* Save new values */
50     *Position = NewPosition;
51     *FreeSize = NewFreeSize;
52 
53     /* Check if we're out of space or not */
54     if (NewFreeSize > 0) return (PVOID)OldPosition;
55     return NULL;
56 }
57 
58 PVOID
59 WINAPI
FlatBuf_Arg_CopyMemory(IN OUT PULONG_PTR Position,IN OUT PSIZE_T FreeSize,IN PVOID Buffer,IN SIZE_T Size,IN ULONG Align)60 FlatBuf_Arg_CopyMemory(IN OUT PULONG_PTR Position,
61                        IN OUT PSIZE_T FreeSize,
62                        IN PVOID Buffer,
63                        IN SIZE_T Size,
64                        IN ULONG Align)
65 {
66     PVOID Destination;
67 
68     /* First reserve the memory */
69     Destination = FlatBuf_Arg_Reserve(Position, FreeSize, Size, Align);
70     if (Destination)
71     {
72         /* We have space, do the copy */
73         RtlCopyMemory(Destination, Buffer, Size);
74     }
75 
76     /* Return the pointer to the data */
77     return Destination;
78 }
79 
80 PVOID
81 WINAPI
FlatBuf_Arg_WriteString(IN OUT PULONG_PTR Position,IN OUT PSIZE_T FreeSize,IN PVOID String,IN BOOLEAN IsUnicode)82 FlatBuf_Arg_WriteString(IN OUT PULONG_PTR Position,
83                         IN OUT PSIZE_T FreeSize,
84                         IN PVOID String,
85                         IN BOOLEAN IsUnicode)
86 {
87     PVOID Destination;
88     SIZE_T StringLength;
89     ULONG Align;
90 
91     /* Calculate the string length */
92     if (IsUnicode)
93     {
94         /* Get the length in bytes and use WCHAR alignment */
95         StringLength = (wcslen((LPWSTR)String) + 1) * sizeof(WCHAR);
96         Align = sizeof(WCHAR);
97     }
98     else
99     {
100         /* Get the length in bytes and use CHAR alignment */
101         StringLength = strlen((LPSTR)String) + 1;
102         Align = sizeof(CHAR);
103     }
104 
105     /* Now reserve the memory */
106     Destination = FlatBuf_Arg_Reserve(Position, FreeSize, StringLength, Align);
107     if (Destination)
108     {
109         /* We have space, do the copy */
110         RtlCopyMemory(Destination, String, StringLength);
111     }
112 
113     /* Return the pointer to the data */
114     return Destination;
115 }
116 
117