Mark3 Realtime Kernel
memutil.cpp
Go to the documentation of this file.
1 /*===========================================================================
2  _____ _____ _____ _____
3  ___| _|__ __|_ |__ __|__ |__ __| __ |__ ______
4 | \ / | || \ || | || |/ / ||___ |
5 | \/ | || \ || \ || \ ||___ |
6 |__/\__/|__|_||__|\__\ __||__|\__\ __||__|\__\ __||______|
7  |_____| |_____| |_____| |_____|
8 
9 --[Mark3 Realtime Platform]--------------------------------------------------
10 
11 Copyright (c) 2012 - 2019 m0slevin, all rights reserved.
12 See license.txt for more information
13 ===========================================================================*/
21 #include "kerneltypes.h"
22 #include "mark3cfg.h"
23 #include "memutil.h"
24 #include "kerneldebug.h"
25 
26 namespace Mark3
27 {
28 
29 //---------------------------------------------------------------------------
30 void MemUtil::DecimalToString(uint8_t u8Data_, char* szText_)
31 {
32  uint8_t u8Tmp = u8Data_;
33  uint8_t u8Max;
34 
35  KERNEL_ASSERT(szText_);
36 
37  // Find max index to print...
38  if (u8Data_ >= 100) {
39  u8Max = 3;
40  } else if (u8Data_ >= 10) {
41  u8Max = 2;
42  } else {
43  u8Max = 1;
44  }
45 
46  szText_[u8Max] = 0;
47  while ((u8Max--) != 0u) {
48  szText_[u8Max] = '0' + (u8Tmp % 10);
49  u8Tmp /= 10;
50  }
51 }
52 
53 //---------------------------------------------------------------------------
54 void MemUtil::DecimalToString(uint16_t u16Data_, char* szText_)
55 {
56  uint16_t u16Tmp = u16Data_;
57  uint16_t u16Max = 1;
58  uint16_t u16Compare = 10;
59 
60  KERNEL_ASSERT(szText_);
61 
62  while (u16Data_ >= u16Compare && u16Max < 5) {
63  u16Compare *= 10;
64  u16Max++;
65  }
66 
67  szText_[u16Max] = 0;
68  while ((u16Max--) != 0u) {
69  szText_[u16Max] = '0' + (u16Tmp % 10);
70  u16Tmp /= 10;
71  }
72 }
73 
74 //---------------------------------------------------------------------------
75 void MemUtil::DecimalToString(uint32_t u32Data_, char* szText_)
76 {
77  uint32_t u32Tmp = u32Data_;
78  uint32_t u32Max = 1;
79  uint32_t u32Compare = 10;
80 
81  KERNEL_ASSERT(szText_);
82 
83  while (u32Data_ >= u32Compare && u32Max < 12) {
84  u32Compare *= 10;
85  u32Max++;
86  }
87 
88  szText_[u32Max] = 0;
89  while ((u32Max--) != 0u) {
90  szText_[u32Max] = '0' + (u32Tmp % 10);
91  u32Tmp /= 10;
92  }
93 }
94 
95 //---------------------------------------------------------------------------
96 void MemUtil::DecimalToString(uint64_t u64Data_, char* szText_)
97 {
98  uint64_t u64Tmp = u64Data_;
99  uint64_t u64Max = 1;
100  uint64_t u64Compare = 10;
101 
102  KERNEL_ASSERT(szText_);
103 
104  while (u64Data_ >= u64Compare && u64Max < 21) {
105  u64Compare *= 10;
106  u64Max++;
107  }
108 
109  szText_[u64Max] = 0;
110  while ((u64Max--) != 0u) {
111  szText_[u64Max] = '0' + (u64Tmp % 10);
112  u64Tmp /= 10;
113  }
114 }
115 
116 //---------------------------------------------------------------------------
117 // Basic checksum routines
118 uint8_t MemUtil::Checksum8(const void* pvSrc_, uint16_t u16Len_)
119 {
120  uint8_t u8Ret = 0;
121  uint8_t* pcData = (uint8_t*)pvSrc_;
122 
123  KERNEL_ASSERT(pvSrc_);
124 
125  // 8-bit CRC, computed byte at a time
126  while ((u16Len_--) != 0u) { u8Ret += *pcData++; }
127  return u8Ret;
128 }
129 
130 //---------------------------------------------------------------------------
131 uint16_t MemUtil::Checksum16(const void* pvSrc_, uint16_t u16Len_)
132 {
133  uint16_t u16Ret = 0;
134  uint8_t* pcData = (uint8_t*)pvSrc_;
135 
136  KERNEL_ASSERT(pvSrc_);
137 
138  // 16-bit CRC, computed byte at a time
139  while ((u16Len_--) != 0u) { u16Ret += *pcData++; }
140  return u16Ret;
141 }
142 
143 //---------------------------------------------------------------------------
144 // Basic string routines
145 uint16_t MemUtil::StringLength(const char* szStr_)
146 {
147  uint8_t* pcData = (uint8_t*)szStr_;
148  uint16_t u16Len = 0;
149 
150  KERNEL_ASSERT(szStr_);
151 
152  while (*pcData++ != 0u) { u16Len++; }
153  return u16Len;
154 }
155 
156 //---------------------------------------------------------------------------
157 bool MemUtil::CompareStrings(const char* szStr1_, const char* szStr2_)
158 {
159  char* szTmp1 = (char*)szStr1_;
160  char* szTmp2 = (char*)szStr2_;
161 
162  KERNEL_ASSERT(szStr1_);
163  KERNEL_ASSERT(szStr2_);
164 
165  while ((*szTmp1 != 0) && (*szTmp2 != 0)) {
166  if (*szTmp1++ != *szTmp2++) {
167  return false;
168  }
169  }
170 
171  // Both terminate at the same length
172  return ((*szTmp1) == 0) && ((*szTmp2) == 0);
173 }
174 
175 //---------------------------------------------------------------------------
176 bool MemUtil::CompareStrings(const char* szStr1_, const char* szStr2_, uint16_t u16Length_)
177 {
178  char* szTmp1 = (char*)szStr1_;
179  char* szTmp2 = (char*)szStr2_;
180 
181  while (((*szTmp1 != 0) && (*szTmp2 != 0)) && (u16Length_ != 0u)) {
182  if (*szTmp1++ != *szTmp2++) {
183  return false;
184  }
185  u16Length_--;
186  }
187 
188  // Both terminate at the same length
189  return (((*szTmp1) == 0) && ((*szTmp2) == 0)) || (u16Length_ == 0u);
190 }
191 
192 //---------------------------------------------------------------------------
193 void MemUtil::CopyMemory(void* pvDst_, const void* pvSrc_, uint16_t u16Len_)
194 {
195  char* szDst = (char*)pvDst_;
196  char* szSrc = (char*)pvSrc_;
197 
198  KERNEL_ASSERT(pvDst_);
199  KERNEL_ASSERT(pvSrc_);
200 
201  // Run through the strings verifying that each character matches
202  // and the lengths are the same.
203  while ((u16Len_--) != 0u) { *szDst++ = *szSrc++; }
204 }
205 
206 //---------------------------------------------------------------------------
207 void MemUtil::CopyString(char* szDst_, const char* szSrc_)
208 {
209  char* szDst = (char*)szDst_;
210  char* szSrc = (char*)szSrc_;
211 
212  KERNEL_ASSERT(szDst_);
213  KERNEL_ASSERT(szSrc_);
214 
215  // Run through the strings verifying that each character matches
216  // and the lengths are the same.
217  while (*szSrc != 0) { *szDst++ = *szSrc++; }
218 }
219 
220 //---------------------------------------------------------------------------
221 int16_t MemUtil::StringSearch(const char* szBuffer_, const char* szPattern_)
222 {
223  auto* szTmpPat = szPattern_;
224  int16_t i16Idx = 0;
225  int16_t i16Start;
226  KERNEL_ASSERT(szBuffer_);
227  KERNEL_ASSERT(szPattern_);
228 
229  // Run through the big buffer looking for a match of the pattern
230  while (szBuffer_[i16Idx] != 0) {
231  // Reload the pattern
232  i16Start = i16Idx;
233  szTmpPat = (char*)szPattern_;
234  while ((*szTmpPat != 0) && (szBuffer_[i16Idx] != 0)) {
235  if (*szTmpPat != szBuffer_[i16Idx]) {
236  break;
237  }
238  szTmpPat++;
239  i16Idx++;
240  }
241  // Made it to the end of the pattern, it's a match.
242  if (*szTmpPat == '\0') {
243  return i16Start;
244  }
245  i16Idx++;
246  }
247 
248  return -1;
249 }
250 
251 //---------------------------------------------------------------------------
252 bool MemUtil::CompareMemory(const void* pvMem1_, const void* pvMem2_, uint16_t u16Len_)
253 {
254  auto* szTmp1 = static_cast<const char*>(pvMem1_);
255  auto* szTmp2 = static_cast<const char*>(pvMem2_);
256 
257  KERNEL_ASSERT(pvMem1_);
258  KERNEL_ASSERT(pvMem2_);
259 
260  // Run through the strings verifying that each character matches
261  // and the lengths are the same.
262  while ((u16Len_--) != 0u) {
263  if (*szTmp1++ != *szTmp2++) {
264  return false;
265  }
266  }
267  return true;
268 }
269 
270 //---------------------------------------------------------------------------
271 void MemUtil::SetMemory(void* pvDst_, uint8_t u8Val_, uint16_t u16Len_)
272 {
273  auto* szDst = static_cast<char*>(pvDst_);
274 
275  KERNEL_ASSERT(pvDst_);
276 
277  while ((u16Len_--) != 0u) { *szDst++ = u8Val_; }
278 }
279 
280 //---------------------------------------------------------------------------
281 uint8_t MemUtil::Tokenize(const char* szBuffer_, Token_t* pastTokens_, uint8_t u8MaxTokens_)
282 {
283  auto u8CurrArg = uint8_t{0};
284  auto u8LastArg = uint8_t{0};
285  auto i = uint8_t{0};
286 
287  auto bEscape = false;
288 
289  KERNEL_ASSERT(szBuffer_);
290  KERNEL_ASSERT(pastTokens_);
291 
292  while (szBuffer_[i] != 0) {
293  //-- Handle unescaped quotes
294  if (szBuffer_[i] == '\"') {
295  bEscape = !bEscape;
296  i++;
297  continue;
298  }
299 
300  //-- Handle all escaped chars - by ignoring them
301  if (szBuffer_[i] == '\\') {
302  i++;
303  if (szBuffer_[i] != 0) {
304  i++;
305  }
306  continue;
307  }
308 
309  //-- Process chars based on current escape characters
310  if (bEscape) {
311  // Everything within the quote is treated as literal, but escaped chars are still treated the same
312  i++;
313  continue;
314  }
315 
316  //-- Non-escaped case
317  if (szBuffer_[i] != ' ') {
318  i++;
319  continue;
320  }
321 
322  pastTokens_[u8CurrArg].pcToken = &(szBuffer_[u8LastArg]);
323  pastTokens_[u8CurrArg].u8Len = i - u8LastArg;
324  u8CurrArg++;
325  if (u8CurrArg >= u8MaxTokens_) {
326  return u8MaxTokens_;
327  }
328 
329  i++;
330  while (szBuffer_[i] == ' ') { i++; }
331 
332  u8LastArg = i;
333  }
334  if ((i != 0u) && (szBuffer_[i] == 0) && ((i - u8LastArg) != 0)) {
335  pastTokens_[u8CurrArg].pcToken = &(szBuffer_[u8LastArg]);
336  pastTokens_[u8CurrArg].u8Len = i - u8LastArg;
337  u8CurrArg++;
338  }
339  return u8CurrArg;
340 }
341 } // namespace Mark3
static void CopyMemory(void *pvDst_, const void *pvSrc_, uint16_t u16Len_)
CopyMemory.
Definition: memutil.cpp:193
Utility class containing memory, string, and conversion routines.
static void CopyString(char *szDst_, const char *szSrc_)
CopyString.
Definition: memutil.cpp:207
Basic data type primatives used throughout the OS.
static int16_t StringSearch(const char *szBuffer_, const char *szPattern_)
StringSearch.
Definition: memutil.cpp:221
static bool CompareStrings(const char *szStr1_, const char *szStr2_)
CompareStrings.
Definition: memutil.cpp:157
static bool CompareMemory(const void *pvMem1_, const void *pvMem2_, uint16_t u16Len_)
CompareMemory.
Definition: memutil.cpp:252
static void DecimalToString(uint8_t u8Data_, char *szText_)
DecimalToString.
Definition: memutil.cpp:30
#define KERNEL_ASSERT(x)
Definition: kerneldebug.h:36
static uint8_t Tokenize(const char *szBuffer_, Token_t *pastTokens_, uint8_t u8MaxTokens_)
Tokenize Function to tokenize a string based on a space delimeter. This is a non-destructive function...
Definition: memutil.cpp:281
Definition: atomic.cpp:23
Mark3 Kernel Configuration This file is used to configure the kernel for your specific application in...
Macros and functions used for assertions, kernel traces, etc.
Token descriptor struct format.
Definition: memutil.h:32
const char * pcToken
Pointer to the beginning of the token string.
Definition: memutil.h:33
static uint8_t Checksum8(const void *pvSrc_, uint16_t u16Len_)
Checksum8.
Definition: memutil.cpp:118
static uint16_t Checksum16(const void *pvSrc_, uint16_t u16Len_)
Checksum16.
Definition: memutil.cpp:131
static void SetMemory(void *pvDst_, uint8_t u8Val_, uint16_t u16Len_)
SetMemory.
Definition: memutil.cpp:271
static uint16_t StringLength(const char *szStr_)
StringLength.
Definition: memutil.cpp:145
uint8_t u8Len
Length of the token (in bytes)
Definition: memutil.h:34