• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 /**************************************************************************************************
3  * IOWOW library
4  *
5  * MIT License
6  *
7  * Copyright (c) 2012-2020 Softmotions Ltd <info@softmotions.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  *  copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  *************************************************************************************************/
27 
28 
29 #include "iwcfg.h"
30 #include "iwutils.h"
31 #include "iwlog.h"
32 #include <limits.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <stdint.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include "mt19937ar.h"
40 
41 #define IWU_RAND_MAX 0xffffffff
42 
iwu_init(void)43 iwrc iwu_init(void) {
44   init_mt19937ar();
45   return 0;
46 }
47 
iwu_rand_seed(uint32_t seed)48 void iwu_rand_seed(uint32_t seed) {
49   init_genrand(seed);
50 }
51 
iwu_rand_u32(void)52 uint32_t iwu_rand_u32(void) {
53   return genrand_int32();
54 }
55 
iwu_rand_dnorm(double_t avg,double_t sd)56 double_t iwu_rand_dnorm(double_t avg, double_t sd) {
57   assert(sd >= 0.0);
58   return sqrt(-2.0 * log((genrand_int31() / (double_t) INT_MAX))) *
59          cos(2 * 3.141592653589793 * (genrand_int31() / (double_t) INT_MAX)) * sd + avg;
60 }
61 
iwu_rand_range(uint32_t range)62 uint32_t iwu_rand_range(uint32_t range) {
63   return genrand_int32() % range;
64 }
65 
iwu_rand_inorm(int range)66 uint32_t iwu_rand_inorm(int range) {
67   int num = (int) iwu_rand_dnorm(range >> 1, (double_t) range / 10.0);
68   return (num < 0 || num >= range) ? 0 : num;
69 }
70 
iwlog2_32(uint32_t val)71 int iwlog2_32(uint32_t val) {
72   static const int tab32[32] = {
73     0,  9,  1, 10, 13, 21,  2, 29,
74     11, 14, 16, 18, 22, 25,  3, 30,
75     8, 12, 20, 28, 15, 17, 24,  7,
76     19, 27, 23,  6, 26,  5,  4, 31
77   };
78   val |= val >> 1;
79   val |= val >> 2;
80   val |= val >> 4;
81   val |= val >> 8;
82   val |= val >> 16;
83   return tab32[(val * 0x07C4ACDD) >> 27];
84 }
85 
iwlog2_64(uint64_t val)86 int iwlog2_64(uint64_t val) {
87   static const int table[64] = {
88     0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
89     51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
90     57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
91     45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63
92   };
93   val |= val >> 1;
94   val |= val >> 2;
95   val |= val >> 4;
96   val |= val >> 8;
97   val |= val >> 16;
98   val |= val >> 32;
99   return table[(val * 0x03f6eaf2cd271461) >> 58];
100 }
101 
iwu_crc32(const uint8_t * buf,int len,uint32_t init)102 uint32_t iwu_crc32(const uint8_t *buf, int len, uint32_t init) {
103 
104   static const unsigned int crc32_table[] = {
105     0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
106     0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
107     0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
108     0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
109     0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
110     0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
111     0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
112     0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
113     0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
114     0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
115     0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
116     0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
117     0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
118     0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
119     0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
120     0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
121     0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
122     0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
123     0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
124     0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
125     0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
126     0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
127     0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
128     0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
129     0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
130     0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
131     0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
132     0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
133     0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
134     0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
135     0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
136     0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
137     0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
138     0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
139     0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
140     0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
141     0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
142     0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
143     0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
144     0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
145     0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
146     0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
147     0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
148     0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
149     0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
150     0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
151     0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
152     0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
153     0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
154     0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
155     0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
156     0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
157     0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
158     0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
159     0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
160     0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
161     0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
162     0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
163     0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
164     0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
165     0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
166     0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
167     0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
168     0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
169   };
170 
171   uint32_t crc = init;
172   while (len--) {
173     crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
174     buf++;
175   }
176   return crc;
177 }
178 
iwu_replace_char(char * data,char sch,char rch)179 char *iwu_replace_char(char *data, char sch, char rch) {
180   for (int i = 0; data[i]; ++i) {
181     if (data[i] == sch) {
182       data[i] = rch;
183     }
184   }
185   return data;
186 }
187 
iwu_cmp_files(FILE * f1,FILE * f2,bool verbose)188 int iwu_cmp_files(FILE *f1, FILE *f2, bool verbose) {
189   if (!f1 && !f2) {
190     return 0;
191   }
192   if (!f1) {
193     return -1;
194   }
195   if (!f2) {
196     return 1;
197   }
198   fseek(f1, 0, SEEK_SET);
199   fseek(f2, 0, SEEK_SET);
200   int c1 = getc(f1);
201   int c2 = getc(f2);
202   int pos = 0, line = 1;
203   while (c1 != EOF && c2 != EOF) {
204     pos++;
205     if (c1 == '\n' && c2 == '\n') {
206       line++;
207       pos = 0;
208     } else if (c1 != c2) {
209       if (verbose) {
210         fprintf(stderr, "\nDiff at: %d:%d\n", line, pos);
211       }
212       return (c1 - c2);
213     }
214     c1 = getc(f1);
215     c2 = getc(f2);
216   }
217   if ((c1 - c2) && verbose) { // -V793
218     fprintf(stderr, "\nDiff at: %d:%d\n", line, pos);
219   }
220   return (c1 - c2);
221 }
222 
iwu_file_read_as_buf(const char * path)223 char *iwu_file_read_as_buf(const char *path) {
224   struct stat st;
225   if (stat(path, &st) == -1) {
226     return 0;
227   }
228   int fd = open(path, O_RDONLY);
229   if (fd == -1) return 0;
230 
231   char *data = malloc(st.st_size + 1);
232   if (!data) {
233     close(fd);
234     return 0;
235   }
236   if (st.st_size != read(fd, data, st.st_size)) {
237     close(fd);
238     return 0;
239   }
240   close(fd);
241   data[st.st_size] = '\0';
242   return data;
243 }
244 
iwu_x31_u32_hash(const char * s)245 uint32_t iwu_x31_u32_hash(const char *s) {
246   uint32_t h = (uint32_t) * s;
247   if (h) {
248     for (++s; *s; ++s) {
249       h = (h << 5) - h + (uint32_t) * s;
250     }
251   }
252   return h;
253 }
254 
iwu_replace(IWXSTR ** result,const char * data,int datalen,const char * keys[],int keysz,iwu_replace_mapper mapper,void * mapper_op)255 iwrc iwu_replace(IWXSTR **result,
256                  const char *data,
257                  int datalen,
258                  const char *keys[],
259                  int keysz,
260                  iwu_replace_mapper mapper,
261                  void *mapper_op) {
262 
263   if (!result || !data || !keys || !mapper) {
264     return IW_ERROR_INVALID_ARGS;
265   }
266 
267   iwrc rc = 0;
268   if (datalen < 1 || keysz < 1) {
269     *result = iwxstr_new2(datalen < 1 ? 1 : datalen);
270     if (datalen > 0) {
271       rc = iwxstr_cat(*result, data, datalen);
272     }
273     return rc;
274   }
275 
276   const char *start = data;
277   const char *ptr = start;
278 
279   IWXSTR *bbuf = 0;
280   IWXSTR *inter = 0;
281   bbuf = iwxstr_new2(datalen);
282   RCA(bbuf, finish);
283   inter = iwxstr_new2(datalen);
284   RCA(inter, finish);
285 
286   for (int i = 0; i < keysz; ++i) {
287     iwxstr_clear(bbuf);
288     const char *key = keys[i];
289     size_t klen = strlen(key);
290     while (true) {
291       const char *p = strstr(ptr, key);
292       if (!p) {
293         if (ptr != start) {
294           rc = iwxstr_cat(bbuf, ptr, datalen - (ptr - start));
295           RCGO(rc, finish);
296         }
297         break;
298       }
299       iwxstr_cat(bbuf, ptr, p - ptr);
300       const char *repl = mapper(key, mapper_op);
301       rc = iwxstr_cat2(bbuf, repl ? repl : key);
302       RCGO(rc, finish);
303       ptr = p + klen;
304       if (ptr - start >= datalen) {
305         break;
306       }
307     }
308     if (ptr != start) {
309       iwxstr_clear(inter);
310       rc = iwxstr_cat(inter, iwxstr_ptr(bbuf), iwxstr_size(bbuf));
311       RCGO(rc, finish);
312       ptr = iwxstr_ptr(inter);
313       start = ptr;
314       datalen = iwxstr_size(inter);
315     }
316   }
317 
318 finish:
319   if (bbuf) {
320     iwxstr_destroy(bbuf);
321   }
322   if (!rc && start == data) {
323     rc = iwxstr_cat(inter, data, datalen);
324   }
325   if (rc) {
326     if (inter) {
327       iwxstr_destroy(inter);
328     }
329   } else {
330     *result = inter;
331   }
332   return rc;
333 }
334