forked from Embroidermodder/libembroidery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emb-utility.c
449 lines (396 loc) · 9.98 KB
/
emb-utility.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
#if ARDUINO
/*TODO: arduino embTime includes */
#else
#include <time.h>
#endif
static char binaryReadByte(EmbFile* file)
{
return (char)embFile_getc(file);
}
static int binaryReadBytes(EmbFile* file, unsigned char* destination, int count)
{
return (int)embFile_read((char*)destination, 1, count, file);
}
static short binaryReadInt16(EmbFile* file)
{
char a[2];
embFile_read(a, 1, 2, file);
return EMB_GET_SHORT(a);
}
static int binaryReadInt32(EmbFile* file)
{
char a[4];
embFile_read(a, 1, 4, file);
return EMB_GET_INT(a);
}
static unsigned char binaryReadUInt8(EmbFile* file)
{
return (unsigned char)embFile_getc(file);
}
static unsigned short binaryReadUInt16(EmbFile* file)
{
char a[2];
embFile_read(a, 1, 2, file);
return EMB_GET_SHORT(a);
}
static unsigned int binaryReadUInt32(EmbFile* file)
{
char a[4];
embFile_read(a, 1, 4, file);
return EMB_GET_INT(a);
}
/* Big endian version */
static short binaryReadInt16BE(EmbFile* file)
{
char a[2];
embFile_read(a, 1, 2, file);
return EMB_GET_SHORT_BE(a);
}
/* Big endian version */
static unsigned short binaryReadUInt16BE(EmbFile* file)
{
char a[2];
embFile_read(a, 1, 2, file);
return EMB_GET_SHORT_BE(a);
}
/* Big endian version */
static int binaryReadInt32BE(EmbFile* file)
{
char a[4];
embFile_read(a, 1, 4, file);
return EMB_GET_INT_BE(a);
}
/* Big endian version */
static unsigned int binaryReadUInt32BE(EmbFile* file)
{
char a[4];
embFile_read(a, 1, 4, file);
return EMB_GET_INT_BE(a);
}
static void binaryReadString(EmbFile* file, char* buffer, int maxLength)
{
int i = 0;
while (i < maxLength) {
buffer[i] = (char)embFile_getc(file);
if (buffer[i] == '\0')
break;
i++;
}
}
static void binaryReadUnicodeString(EmbFile* file, char* buffer, const int stringLength)
{
int i = 0;
for (i = 0; i < stringLength * 2; i++) {
char input = (char)embFile_getc(file);
if (input != 0) {
buffer[i] = input;
}
}
}
static float binaryReadFloat(EmbFile* file)
{
union {
float f32;
unsigned int u32;
} float_int_u;
float_int_u.u32 = binaryReadInt32(file);
return float_int_u.f32;
}
static void binaryWriteByte(EmbFile* file, unsigned char data)
{
embFile_putc(data, file);
}
static void binaryWriteBytes(EmbFile* file, const char* data, int size)
{
embFile_write((char*)data, 1, size, file);
}
static void binaryWriteShort(EmbFile* file, short data)
{
char a[2];
EMB_WRITE_SHORT(a, data);
embFile_write(a, 1, 2, file);
}
static void binaryWriteShortBE(EmbFile* file, short data)
{
char a[2];
EMB_WRITE_SHORT_BE(a, data);
embFile_write(a, 1, 2, file);
}
static void binaryWriteUShort(EmbFile* file, unsigned short data)
{
char a[2];
EMB_WRITE_SHORT(a, data);
embFile_write(a, 1, 2, file);
}
static void binaryWriteUShortBE(EmbFile* file, unsigned short data)
{
char a[2];
EMB_WRITE_SHORT_BE(a, data);
embFile_write(a, 1, 2, file);
}
static void binaryWriteInt(EmbFile* file, int data)
{
char a[4];
EMB_WRITE_INT(a, data);
embFile_write(a, 1, 4, file);
}
static void binaryWriteIntBE(EmbFile* file, int data)
{
char a[4];
EMB_WRITE_INT_BE(a, data);
embFile_write(a, 1, 4, file);
}
static void binaryWriteUInt(EmbFile* file, unsigned int data)
{
char a[4];
EMB_WRITE_INT(a, data);
embFile_write(a, 1, 4, file);
}
static void binaryWriteUIntBE(EmbFile* file, unsigned int data)
{
char a[4];
EMB_WRITE_INT_BE(a, data);
embFile_write(a, 1, 4, file);
}
static void binaryWriteFloat(EmbFile* file, float data)
{
union {
float f32;
unsigned int u32;
} float_int_u;
float_int_u.f32 = data;
binaryWriteUInt(file, float_int_u.u32);
}
/*! Rounds a double (\a src) and returns it as an \c int. */
static int roundDouble(double src)
{
if (src < 0.0)
return (int)ceil(src - 0.5);
return (int)floor(src + 0.5);
}
/*! Removes all characters from the left end of the string
* (\a str) that match (\a junk), moving right until a mismatch occurs. */
static char* lTrim(char* str, char junk)
{
while (*str == junk) {
str++;
}
return str;
}
/*! Duplicates the string (\a src) and returns it. It is created on the heap.
* The caller is responsible for freeing the allocated memory. */
static char* emb_strdup(char* src)
{
char* dest = 0;
if (!src) {
embLog("ERROR: helpers-misc.c emb_strdup(), src argument is null\n");
return 0;
}
dest = (char*)malloc(strlen(src) + 1);
if (!dest) {
embLog("ERROR: helpers-misc.c emb_strdup(), cannot allocate memory\n");
} else {
strcpy(dest, src);
}
return dest;
}
static void embTime_initNow(EmbTime* t)
{
#if ARDUINO
/*TODO: arduino embTime_initNow */
#else
time_t rawtime;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
t->year = timeinfo->tm_year;
t->month = timeinfo->tm_mon;
t->day = timeinfo->tm_mday;
t->hour = timeinfo->tm_hour;
t->minute = timeinfo->tm_min;
t->second = timeinfo->tm_sec;
#endif /* ARDUINO */
}
static EmbTime embTime_time(EmbTime* t)
{
#if ARDUINO
/*TODO: arduino embTime_time */
#else
int divideByZero = 0;
divideByZero = divideByZero / divideByZero;
/*TODO: wrap time() from time.h and verify it works consistently */
#endif /* ARDUINO */
return *t;
}
/* Converts a 6 digit hex string (I.E. "00FF00") into an
* EmbColor and returns it. */
EmbColor embColor_fromHexStr(char* val)
{
int i;
EmbColor color;
for (i = 0; i < 6; i++) {
if (val[i] >= 'A' && val[i] <= 'F') {
val[i] = '9' + val[i] - 'A' + 1;
}
val[i] -= '0';
}
color.r = val[0] * 16 + val[1];
color.g = val[2] * 16 + val[3];
color.b = val[4] * 16 + val[5];
return color;
}
/* Replacing the %d in *printf functionality.
*/
static void embPointerToArray(char* buffer, void* pointer, int maxDigits)
{
unsigned int i, value;
value = (unsigned long int)pointer;
for (i = 0; i < maxDigits - 1; i++) {
buffer[i] = ' ';
}
buffer[maxDigits - 1] = 0;
for (; i >= 0; i--) {
buffer[i] = (value % 16) - '0';
if (buffer[i] > '9')
buffer[i] += 'A' - '9';
value /= 16;
if (value == 0)
break;
}
buffer += i;
}
/* Replacing the %d in *printf functionality.
*
* Accounts for the sign of the
*/
static void embIntToArray(char* buffer, int number, int maxDigits)
{
int i, j, sign;
unsigned int unumber;
sign = 0;
unumber = number;
if (number < 0.0) {
unumber = -number;
sign = 1;
}
for (i = 0; i < maxDigits - 2; i++) {
buffer[i] = ' ';
}
buffer[maxDigits - 1] = 0;
for (i = maxDigits - 2; i >= 0; i--) {
printf("%s %d %d\n", buffer, i, unumber);
buffer[i] = (char)(unumber % 10) + '0';
unumber = unumber / 10;
if (unumber == 0)
break;
}
if (sign) {
buffer[i] = '-';
}
/* left shift to the front of the buffer so the buffer doesn't change
* size in later use
*/
for (j = 0; j < maxDigits - i; j++) {
buffer[j] = buffer[i + j];
}
}
static void writeInt(EmbFile* file, int n, int m)
{
char buffer[30];
embIntToArray(buffer, n, m);
embFile_print(file, buffer);
}
/* Replacing the %f in *printf functionality.
*/
static void embFloatToArray(char* buffer, float number, float tolerence, int before, int after)
{
int i, maxDigits, j;
float t;
float afterPos[] = { 1.0e-1, 1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6, 1.0e-7, 1.0e-8 };
float beforePos[] = { 1.0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8 };
maxDigits = before + after + 1;
for (i = 0; i < maxDigits - 1; i++) {
buffer[i] = ' ';
}
buffer[maxDigits - 1] = 0;
for (i = before - 1; i >= 0; i--) {
t = 0.0;
for (j = 0; j < 9; j++) {
t += beforePos[i];
printf("%s %d %d %f %f\n", buffer, i, j, t, number);
if ((number - tolerence > t) && (t + beforePos[i] > number + tolerence)) {
buffer[before - 1 - i] = j + '1';
number -= (j + 1) * beforePos[i];
break;
}
}
}
buffer[before] = '.';
for (i = 0; i < after; i++) {
t = 0.0;
for (j = 0; j < 9; j++) {
t += afterPos[i];
printf("%s %d %d %f %f\n", buffer, i, j, t, number);
if ((number - tolerence > t) && (t + afterPos[i] > number + tolerence)) {
buffer[before + 1 + i] = j + '1';
number -= (j + 1) * afterPos[i];
break;
}
}
}
buffer[before + 1 + after] = 0;
lTrim(buffer, ' ');
}
/* puts() abstraction. Uses Serial.print() on ARDUINO */
static void embLog(const char* str)
{
/* testing embedded mode on Linux */
/* #if ARDUINO
inoLog_serial(str);
inoLog_serial("\n");
#else */
puts(str);
/* #endif ARDUINO */
}
/* Wrapper functions around Keith Pomakis' HashTable Library */
static EmbHash* embHash_create(void)
{
return HashTableCreate(1);
}
static void embHash_free(EmbHash* hash)
{
HashTableDestroy(hash);
hash = 0;
}
static int embHash_contains(const EmbHash* hash, const void* key)
{
return HashTableContainsKey(hash, key);
}
static int embHash_insert(EmbHash* hash, const void* key, void* value)
{
return HashTablePut(hash, key, value);
}
static void* embHash_value(const EmbHash* hash, const void* key)
{
return HashTableGet(hash, key);
}
static void embHash_remove(EmbHash* hash, const void* key)
{
HashTableRemove(hash, key);
}
static void embHash_clear(EmbHash* hash)
{
HashTableRemoveAll(hash);
}
static int embHash_empty(const EmbHash* hash)
{
return HashTableIsEmpty(hash);
}
static long embHash_count(const EmbHash* hash)
{
return HashTableSize(hash);
}
static void embHash_rehash(EmbHash* hash, long numOfBuckets)
{
HashTableRehash(hash, numOfBuckets);
}