Design Pattern Examples
Overview of object-oriented design patterns
Adapter_BackEnd.c
Go to the documentation of this file.
1
5#include "pch.h"
6
7#include "Adapter_BackEnd.h"
8
9#define BLOCK_0_NAME "gorp"
10#define BLOCK_1_NAME "baba"
11#define BLOCK_2_NAME "yaga"
12
16
20#define MAX_DATA_SIZE 32
21
25typedef struct
26{
30 const char* name;
31
36 bool locked;
37
42 uint32_t data[MAX_DATA_SIZE];
44
51 { BLOCK_0_NAME, false, { 0 } },
52 { BLOCK_1_NAME, false, { 0 } },
53 { BLOCK_2_NAME, false, { 0 } }
54};
55
56
58
65static int _FindBlock(const char* blockName)
66{
67 int foundIndex = -1;
68
69 for (size_t index = 0; index < memory_block_count; index++)
70 {
71 if (strcmp(memory_blocks[index].name, blockName) == 0)
72 {
73 foundIndex = (int)index;
74 break;
75 }
76 }
77 return foundIndex;
78}
79
89static bool _ConvertHandleToBlockIndex(int dataHandle, int* memoryIndex)
90{
91 bool isValidHandle = false;
92
93 if (memoryIndex != NULL)
94 {
95 int index = dataHandle;
96 if (index >= 0 && index < (int)memory_block_count)
97 {
98 *memoryIndex = index;
99 isValidHandle = true;
100 }
101 }
102
103 return isValidHandle;
104}
105
106
113static bool _IsValidOffset(int chunkOffset)
114{
115 return chunkOffset >= 0 && chunkOffset < DDR_MAX_OFFSET;
116}
117
119// DDR_OpenMemoryBlock()
121DDR_ErrorCode DDR_OpenMemoryBlock(const char* blockName, int* dataHandle)
122{
124
125 if (blockName != NULL && dataHandle != NULL)
126 {
127 *dataHandle = DDR_INVALID_HANDLE;
129 int foundBlockIndex = _FindBlock(blockName);
130 if (foundBlockIndex != -1)
131 {
133 if (!memory_blocks[foundBlockIndex].locked)
134 {
135 memory_blocks[foundBlockIndex].locked = true;
136 // Note: We are using the index as the handle
137 *dataHandle = foundBlockIndex;
138 errorCode = DDR_ErrorCode_Success;
139 memset(memory_blocks[foundBlockIndex].data, 0xff, sizeof(memory_blocks[foundBlockIndex].data));
140 }
141 }
142 }
143
144 return errorCode;
145}
146
148// DDR_CloseMemoryBlock()
151{
153
154 int memoryIndex = -1;
155 if (_ConvertHandleToBlockIndex(dataHandle, &memoryIndex))
156 {
158 if (memory_blocks[memoryIndex].locked)
159 {
160 memory_blocks[memoryIndex].locked = false;
161 errorCode = DDR_ErrorCode_Success;
162 }
163 }
164
165 return errorCode;
166}
167
169// DDR_GetMemorySize()
171DDR_ErrorCode DDR_GetMemorySize(int dataHandle, int* memorySizeInChunks)
172{
174 if (memorySizeInChunks != NULL)
175 {
177 int memoryIndex = -1;
178 if (_ConvertHandleToBlockIndex(dataHandle, &memoryIndex))
179 {
180 *memorySizeInChunks = MAX_DATA_SIZE;
181 errorCode = DDR_ErrorCode_Success;
182 }
183 }
184
185 return errorCode;
186}
187
189// DDR_GetDataChunk()
191DDR_ErrorCode DDR_GetDataChunk(int dataHandle, int chunkOffset, uint32_t* value)
192{
194
195 if (value != NULL)
196 {
197 int memoryIndex = -1;
198 if (_ConvertHandleToBlockIndex(dataHandle, &memoryIndex))
199 {
201 if (memory_blocks[memoryIndex].locked)
202 {
204 if (_IsValidOffset(chunkOffset))
205 {
206 *value = memory_blocks[memoryIndex].data[chunkOffset];
207 errorCode = DDR_ErrorCode_Success;
208 }
209 }
210 }
211 }
212
213 return errorCode;
214}
215
217// DDR_SetDataChunk()
219DDR_ErrorCode DDR_SetDataChunk(int dataHandle, int chunkOffset, uint32_t value)
220{
222 int memoryIndex = -1;
223 if (_ConvertHandleToBlockIndex(dataHandle, &memoryIndex))
224 {
226 if (memory_blocks[memoryIndex].locked)
227 {
229 if (_IsValidOffset(chunkOffset))
230 {
231 memory_blocks[memoryIndex].data[chunkOffset] = value;
232 errorCode = DDR_ErrorCode_Success;
233 }
234 }
235 }
236
237 return errorCode;
238}
const char * BLOCK_NAME_0
Name of the first block.
#define BLOCK_2_NAME
static size_t memory_block_count
DDR_ErrorCode DDR_SetDataChunk(int dataHandle, int chunkOffset, uint32_t value)
Writes a single 32-bit value to the given offset in the memory block indicated by the specified handl...
static MemoryBlock memory_blocks[]
Predefined set of memory blocks that can be accessed by name. Data for each memory block is stored as...
static bool _ConvertHandleToBlockIndex(int dataHandle, int *memoryIndex)
Convert the given data handle to an index into the memory blocks.
const char * BLOCK_NAME_2
Name of the third block.
#define BLOCK_0_NAME
DDR_ErrorCode DDR_GetDataChunk(int dataHandle, int chunkOffset, uint32_t *value)
Read a single 32-bit value at the given offset in the memory block indicated by the specified handle.
static bool _IsValidOffset(int chunkOffset)
Determine if the given offset is valid.
#define MAX_DATA_SIZE
Maximum number of 32-bit chunks in a single memory block.
static int _FindBlock(const char *blockName)
Retrieve the index of the requested memory block.
DDR_ErrorCode DDR_OpenMemoryBlock(const char *blockName, int *dataHandle)
Open access to a memory block for exclusive use, given the name of the memory block.
#define BLOCK_1_NAME
DDR_ErrorCode DDR_CloseMemoryBlock(int dataHandle)
Close access to a previously opened memory block, thus releasing it for others to open.
const char * BLOCK_NAME_1
Name of the second block.
DDR_ErrorCode DDR_GetMemorySize(int dataHandle, int *memorySizeInChunks)
Retrieve the number of chunks in the memory block indicated by the handle to the successfully opened ...
Declaration of the "low-level" memory block read/write functions that are provided in a separate DLL ...
DDR_ErrorCode
Represents the possible errors that can be returned from the memory block access functions.
@ DDR_ErrorCode_Block_Not_Opened
Memory block is closed and cannot be accessed.
@ DDR_ErrorCode_Block_Already_Opened
Memory block is already open and cannot be opened again.
@ DDR_ErrorCode_Null_Argument
The block name pointer or return handle pointer argument is NULL.
@ DDR_ErrorCode_Invalid_Block_Name
The given name is not a recognized memory block name.
@ DDR_ErrorCode_Invalid_Handle
The handle argument does not correspond to a valid open memory block.
@ DDR_ErrorCode_Success
Operation succeeded.
@ DDR_ErrorCode_Invalid_Offset
The given offset is out of bounds.
@ DDR_MAX_OFFSET
All offsets must from 0 to 1 less than this value.
@ DDR_INVALID_HANDLE
Value indicating the handle is invalid.
#define _countof(w)
Header for precompiled headers. Used only on Windows.
Represents a single memory block.
bool locked
True if a caller has acquired this memory block for exclusive access; otherwise, false,...
uint32_t data[MAX_DATA_SIZE]
Data held in this memory block, stored as 32-bit values. Least significant byte is first byte of each...
const char * name
Name of a memory block so it can be addressed individually.