agileRTOS (zrtos)  Version 0.8.0 (ghostbuster)
mem.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 ykat UG (haftungsbeschraenkt) - All Rights Reserved
3  *
4  * Permission for non-commercial use is hereby granted,
5  * free of charge, without warranty of any kind.
6  */
7 #ifndef ZRTOS_MEM_H
8 #define ZRTOS_MEM_H
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 
14 #include <zrtos/types.h>
15 #include <zrtos/cast.h>
16 
17 
18 /**
19  * Swap \p len bytes of \p dest and \p src inplace.
20  *
21  * @param[in] dest destination
22  * @param[in] src source
23  * @param[in] len byte length to swap
24  *
25  * @return Nothing
26  */
27 void zrtos_mem__swap(void *dest, void *src, size_t len){
28  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
29  uint8_t *tmp_src = ZRTOS_CAST(uint8_t*,src);
30  while(len--){
31  ZRTOS_TYPES__SWAP_PTR_CONTENTS(tmp_src,tmp_dest);
32  tmp_src++;
33  tmp_dest++;
34  }
35 }
36 
38  void *ptr
39  ,size_t offest_dest
40  ,size_t offset_src
41  ,size_t len
42 ){
44  zrtos_types__ptr_add(ptr,offest_dest)
45  ,zrtos_types__ptr_add(ptr,offset_src)
46  ,len
47  );
48 }
49 
51  void *ptr
52  ,size_t length
53  ,size_t buffer_length
54 ){
55  size_t d = length;
56  size_t n = buffer_length;
57  size_t i = d;
58  size_t j = n - d;
59  while(i != j){
60  if(i < j){
61  //A is shorter
62  zrtos_mem__swap_ex(ptr, d - i, d + j - i, i);
63  j -= i;
64  }else{
65  //B is shorter
66  zrtos_mem__swap_ex(ptr, d - i, d, j);
67  i -= j;
68  }
69  }
70  //Finally, block swap A and B
71  zrtos_mem__swap_ex(ptr, d - i, d, i);
72 }
73 
74 #ifdef ZRTOS__USE_MEMMOVE
75 # define zrtos_mem__move_right_overlapping memmove
76 # define zrtos_mem__move_left_overlapping memmove
77 #else
79  void *dest
80  ,void *src
81  ,size_t length
82 ){
83  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
84  uint8_t *tmp_src = ZRTOS_CAST(uint8_t*,src);
85  tmp_dest += --length;
86  tmp_src += length++;
87  while(length--){
88  *tmp_dest-- = *tmp_src--;
89  }
90 }
91 
93  void *dest
94  ,void *src
95  ,size_t length
96 ){
97  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
98  uint8_t *tmp_src = ZRTOS_CAST(uint8_t*,src);
99  while(length--){
100  *tmp_dest++ = *tmp_src++;
101  }
102 }
103 #endif
104 
106  void *dest
107  ,void *src
108  ,size_t length
109 ){
110  zrtos_mem__move_left_overlapping(dest,src,length);
111 }
112 
113 int zrtos_mem__cmp(void *str1, void *str2, size_t count){
114  uint8_t *s1 = ZRTOS_CAST(uint8_t*,str1);
115  uint8_t *s2 = ZRTOS_CAST(uint8_t*,str2);
116 
117  while(count-- > 0){
118  if(*s1++ != *s2++){
119  return s1[-1] < s2[-1] ? -1 : 1;
120  }
121  }
122 
123  return 0;
124 }
125 
126 void zrtos_mem__reverse(void *dest,size_t len){
127  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
128  uint8_t *tmp_src = tmp_dest + len;
129  len>>=1;
130  while(len--){
131  --tmp_src;
132  ZRTOS_TYPES__SWAP_PTR_CONTENTS(tmp_dest,tmp_src);
133  tmp_dest++;
134  }
135 }
136 
137 void zrtos_mem__set(void *dest,uint8_t value,size_t len){
138  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
139  while(len--){
140  *tmp_dest++ = value;
141  }
142 }
143 
144 void zrtos_mem__zero(void *dest,size_t len){
145  zrtos_mem__set(dest,0,len);
146 }
147 
148 void *zrtos_mem__search(const void *key, const void *base, size_t /* nmemb */ high,
149  size_t size, int (*compar)(const void *, const void *))
150 {
151  register char *p;
152  size_t low;
153  size_t mid;
154  int r;
155 
156  if (size > 0) { /* TODO: change this to an assert?? */
157  low = 0;
158  while (low < high) {
159  mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
160  p = ((char *)base) + mid * size; /* Could overflow here... */
161  r = (*compar)(key, p); /* but that's an application problem! */
162  if (r > 0) {
163  low = mid + 1;
164  } else if (r < 0) {
165  high = mid;
166  } else {
167  return p;
168  }
169  }
170  }
171  return NULL;
172 }
173 
174 void zrtos_mem__sort(void *base,
175  size_t nel,
176  size_t width,
177  int (*comp)(const void *, const void *))
178 {
179  size_t wnel, gap, wgap, i, j, k;
180  char *a, *b, tmp;
181 
182  wnel = width * nel;
183  for (gap = 0; ++gap < nel;){
184  gap *= 3;
185  }
186  while ((gap /= 3) != 0) {
187  wgap = width * gap;
188  for (i = wgap; i < wnel; i += width) {
189  for (j = i - wgap; ;j -= wgap) {
190  a = j + (char *)base;
191  b = a + wgap;
192  if ((*comp)(a, b) <= 0){
193  break;
194  }
195  k = width;
196  do {
197  tmp = *a;
198  *a++ = *b;
199  *b++ = tmp;
200  } while (--k);
201  if (j < wgap){
202  break;
203  }
204  }
205  }
206  }
207 }
208 
209 size_t zrtos_mem__from_hex(void *dest,char *src,size_t len){
210  uint8_t *tmp_dest = ZRTOS_CAST(uint8_t*,dest);
211  while(len--){
212  uint8_t h = (*src++) - '0';
213  uint8_t l = (*src++) - '0';
214 
215  if(h > 9){
216  h -= 'A' - '9';
217  }
218  if(l > 9){
219  l -= 'A' - '9';
220  }
221 
222  *tmp_dest++ = (h << 4) | l;
223  }
224  return zrtos_types__ptr_get_byte_distance(tmp_dest,dest);
225 }
226 
227 
228 #ifdef __cplusplus
229 }
230 #endif
231 #endif
#define ZRTOS_CAST(type, value)
Definition: cast.h:18
void zrtos_mem__sort(void *base, size_t nel, size_t width, int(*comp)(const void *, const void *))
Definition: mem.h:174
size_t zrtos_mem__from_hex(void *dest, char *src, size_t len)
Definition: mem.h:209
void zrtos_mem__zero(void *dest, size_t len)
Definition: mem.h:144
void zrtos_mem__left_rotate(void *ptr, size_t length, size_t buffer_length)
Definition: mem.h:50
void zrtos_mem__move_right_overlapping(void *dest, void *src, size_t length)
Definition: mem.h:78
void zrtos_mem__swap(void *dest, void *src, size_t len)
Swap len bytes of dest and src inplace.
Definition: mem.h:27
void zrtos_mem__reverse(void *dest, size_t len)
Definition: mem.h:126
void zrtos_mem__set(void *dest, uint8_t value, size_t len)
Definition: mem.h:137
void zrtos_mem__cpy(void *dest, void *src, size_t length)
Definition: mem.h:105
void * zrtos_types__ptr_add(void *ptr, size_t byte_len)
Definition: types.h:35
size_t zrtos_types__ptr_get_byte_distance(void *bigger, void *smaller)
Definition: types.h:43
void * zrtos_mem__search(const void *key, const void *base, size_t high, size_t size, int(*compar)(const void *, const void *))
Definition: mem.h:148
#define ZRTOS_TYPES__SWAP_PTR_CONTENTS(a, b)
Definition: types.h:156
int zrtos_mem__cmp(void *str1, void *str2, size_t count)
Definition: mem.h:113
void zrtos_mem__swap_ex(void *ptr, size_t offest_dest, size_t offset_src, size_t len)
Definition: mem.h:37
static uint8_t
Definition: mcp2515.h:159
void zrtos_mem__move_left_overlapping(void *dest, void *src, size_t length)
Definition: mem.h:92