Design Pattern Examples
Overview of object-oriented design patterns
Adapter_FrontEndClass.cpp
Go to the documentation of this file.
1
5
6#include <Adapter_BackEnd.h>
7
8#include "helpers/formatstring.h"
9
11
12namespace // Anonymous namespace
13{
19 const char* _GetErrorMessage(DDR_ErrorCode errorCode)
20 {
21 const char* message = "";
22
23 switch (errorCode)
24 {
26 message = "Operation succeeded";
27 break;
28
30 message = "Memory block is already open and cannot be opened again";
31 break;
32
34 message = "Memory block is closed and cannot be accessed";
35 break;
36
38 message = "The given name is not a recognized memory block name";
39 break;
40
42 message = "The handle argument does not correspond to a valid open memory block";
43 break;
44
46 message = "The given offset is out of bounds";
47 break;
48
50 message = "The block name pointer or return handle pointer argument is NULL";
51 break;
52
53 default:
54 message = "Unrecognized error code.";
55 break;
56 }
57
58 return message;
59 }
60
70 std::string _ConstructErrorMessage(DDR_ErrorCode errorCode, const char* operation)
71 {
72 std::string msg = _GetErrorMessage(errorCode);
73 return Helpers::formatstring("%s: %s", operation, msg.c_str());
74 }
75
76} // end anonymous namespace
77
78
79//#############################################################################
80//#############################################################################
81//#############################################################################
82
83
85{
87 // DataReaderWriter::_GetBlockNameForBlockNumber method
90 {
91 const char* blockName = NULL;
92
93 switch (blockNumber)
94 {
95 case Memory_Block_0:
96 blockName = BLOCK_NAME_0;
97 break;
98
99 case Memory_Block_1:
100 blockName = BLOCK_NAME_1;
101 break;
102
103 case Memory_Block_2:
104 blockName = BLOCK_NAME_2;
105 break;
106
107 default:
108 break;
109 }
110
111 return blockName;
112 }
113
114
116 // Constructor
119 : _initialized(false)
120 , _dataHandle(0)
121 {
122 const char* blockName = _GetBlockNameForBlockNumber(blockNumber);
123 if (blockName != NULL)
124 {
125 DDR_ErrorCode errorCode = DDR_OpenMemoryBlock(blockName, &_dataHandle);
126 if (errorCode == DDR_ErrorCode_Success)
127 {
128 int memorySizeInChunks = 0;
129 errorCode = DDR_GetMemorySize(_dataHandle, &memorySizeInChunks);
130 if (errorCode != DDR_ErrorCode_Success)
131 {
132 std::string msg =
133 _ConstructErrorMessage(errorCode,
134 "Memory block not opened so cannot retrieve memory block size");
135 throw new DataReaderWriterInitException(msg);
136 }
137 _memoryBlockByteSize = static_cast<uint32_t>(memorySizeInChunks) * sizeof(uint32_t);
138 _initialized = true;
139 }
140 else
141 {
142 std::string msg =
143 _ConstructErrorMessage(errorCode, "Initializing data reader/writer");
144 throw new DataReaderWriterInitException(msg);
145 }
146 }
147 }
148
150 // Destructor
153 {
154 if (_initialized)
155 {
157 }
158 }
159
160
162 // DataReaderWriter::GetMemoryBlockByteSize
165 {
167 }
168
170 // DataReaderWriter::Read method
172 ByteArray DataReaderWriter::Read(int byteOffset, uint32_t maxBytes)
173 {
174 if (!_initialized)
175 {
177 "Data reader/writer is not initialized. Unable to read.");
178 }
179
180 ByteArray data(maxBytes);
181
182 if (maxBytes > 0)
183 {
184 int chunkOffset = byteOffset / (sizeof(uint32_t));
185 uint32_t value = 0;
186 uint32_t bufferIndex = 0;
188 errorCode = DDR_GetDataChunk(_dataHandle, chunkOffset, &value);
189 if (errorCode == DDR_ErrorCode_Success)
190 {
191 int byteOffsetInChunk = byteOffset % (sizeof(uint32_t));
192 while (bufferIndex < maxBytes)
193 {
194 data[bufferIndex] = value & 0xff;
195 bufferIndex++;
196 value >>= 8;
197 byteOffsetInChunk++;
198 if (byteOffsetInChunk == sizeof(uint32_t))
199 {
200 chunkOffset++;
201 if (chunkOffset >= DDR_MAX_OFFSET)
202 {
203 break;
204 }
205 byteOffsetInChunk = 0;
206 errorCode = DDR_GetDataChunk(_dataHandle, chunkOffset, &value);
207 if (errorCode != DDR_ErrorCode_Success)
208 {
209 std::string msg = _ConstructErrorMessage(errorCode, "Reading memory");
210 throw new DataReaderWriterException(msg);
211 }
212 }
213 }
214 if (errorCode == DDR_ErrorCode_Success)
215 {
216 if (bufferIndex > 0) {
217 if (static_cast<uint32_t>(bufferIndex) > maxBytes) {
218 data.resize(bufferIndex);
219 }
220 }
221 }
222 }
223 else
224 {
225 std::string msg = _ConstructErrorMessage(errorCode, "Reading memory");
226 throw new DataReaderWriterException(msg);
227 }
228 }
229
230 return data;
231 }
232
234 // DataReaderWriter::Write method
236 void DataReaderWriter::Write(int byteOffset, const ByteArray& data, uint32_t maxBytes)
237 {
238 if (!_initialized)
239 {
241 "Data reader/writer is not initialized. Unable to write.");
242 }
243 if (maxBytes > 0)
244 {
246 int chunkOffset = byteOffset / sizeof(uint32_t);
247 uint32_t value = 0;
248 int byteOffsetInChunk = byteOffset % sizeof(uint32_t);
249 uint32_t bufferIndex = 0;
250 uint32_t byteMask = 0xff << (byteOffsetInChunk * 8);
251 if (byteOffsetInChunk != 0)
252 {
253 errorCode = DDR_GetDataChunk(_dataHandle, chunkOffset, &value);
254 }
255 if (errorCode == DDR_ErrorCode_Success)
256 {
257 while (bufferIndex < maxBytes)
258 {
259 value &= ~byteMask;
260 value |= ((uint32_t)data[bufferIndex]) << (byteOffsetInChunk * 8);
261 bufferIndex++;
262 byteMask <<= 8;
263 byteOffsetInChunk++;
264 if (byteOffsetInChunk == sizeof(uint32_t))
265 {
266 errorCode = DDR_SetDataChunk(_dataHandle, chunkOffset, value);
267 if (errorCode == DDR_ErrorCode_Success)
268 {
269 byteMask = 0xff;
270 byteOffsetInChunk = 0;
271 chunkOffset++;
272 if (chunkOffset >= DDR_MAX_OFFSET)
273 {
274 break;
275 }
276 errorCode = DDR_GetDataChunk(_dataHandle, chunkOffset, &value);
277 if (errorCode != DDR_ErrorCode_Success)
278 {
279 break;
280 }
281 }
282 else
283 {
284 std::string msg = _ConstructErrorMessage(errorCode, "Writing memory");
285 throw new DataReaderWriterException(msg);
286 }
287 }
288 }
289 if (errorCode == DDR_ErrorCode_Success)
290 {
291 if (byteOffsetInChunk != 0)
292 {
293 errorCode = DDR_SetDataChunk(_dataHandle, chunkOffset, value);
294 }
295 }
296 if (errorCode != DDR_ErrorCode_Success)
297 {
298 std::string msg = _ConstructErrorMessage(errorCode, "Writing memory");
299 throw new DataReaderWriterException(msg);
300 }
301 }
302 else
303 {
304 std::string msg = _ConstructErrorMessage(errorCode, "Reading memory in preparation to writing memory");
305 throw new DataReaderWriterException(msg);
306 }
307 }
308 }
309
311 // DataReaderWriter::BufferToString method
314 uint32_t maxBytes, int indent)
315 {
316 std::string output;
317 std::string indentSpaces(indent, ' ');
318
319 if (maxBytes != 0)
320 {
321 size_t byteCount = maxBytes;
322 if (byteCount > data.size())
323 {
324 byteCount = data.size();
325 }
326 uint32_t bytesPerRow = 32;
327 for (uint32_t row = 0; row < maxBytes; row += bytesPerRow)
328 {
329 output += Helpers::formatstring("%s%04x --", indentSpaces.c_str(), row);
330 for (uint32_t col = 0;
331 col < bytesPerRow && (row + col) < maxBytes;
332 ++col)
333 {
334 if (col > 0)
335 {
336 output += " ";
337 }
338 size_t dataIndex = static_cast<size_t>(row) + col;
339 output += Helpers::formatstring("%02x", data[dataIndex]);
340 }
341 output += "\n";
342 }
343 }
344 return output;
345 }
346
347} // end namespace
const char * BLOCK_NAME_0
Name of the first block.
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...
const char * BLOCK_NAME_2
Name of the third block.
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.
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.
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.
Declaration of the DataReaderWriter class used in the Adapter Pattern.
static const char * _GetErrorMessage(DDR_ErrorCode errorCode)
Convert the given error code to a string message.
Represents an error that occurred when reading or writing data in the Data reader/writer.
uint32_t GetMemoryBlockByteSize()
Retrieve the size of the currently opened memory block in bytes.
std::string BufferToString(const ByteArray &data, uint32_t maxBytes, int indent)
Convert the specified data up to the specified number of bytes into a string by performing a "hex dum...
void Write(int byteOffset, const ByteArray &data, uint32_t maxBytes)
Write a specified number of bytes.
const char * _GetBlockNameForBlockNumber(DataReaderWriter::MemoryBlockNumber blockNumber)
Given a block number, retrieve the corresponding block name.
ByteArray Read(int byteOffset, uint32_t maxBytes)
Read a specified number of bytes.
MemoryBlockNumber
Represents the memory blocks that can be accessed. Hides how memory blocks are actually identified.
DataReaderWriter(MemoryBlockNumber blockNumber)
Constructor.
Represents an error that occurred during initialization or shut down of the Data reader/writer.
The namespace containing all Design Pattern Examples implemented in C++.
std::vector< uint8_t > ByteArray
std::string formatstring(const char *fmt,...)
Use the given string and arguments to return a buffer containing the formatted string....