- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / oscam-string.c
blobe67879c90c8b0e9f275a378c80893c1e8844a62b
1 #include "globals.h"
2 #include "oscam-string.h"
4 /* This function encapsulates malloc. It automatically adds an error message
5 to the log if it failed and calls cs_exit(quiterror) if quiterror > -1.
6 result will be automatically filled with the new memory position or NULL
7 on failure. */
8 bool cs_malloc(void *result, size_t size)
10 void **tmp = result;
11 *tmp = malloc(size);
13 if(*tmp == NULL)
15 fprintf(stderr, "%s: ERROR: Can't allocate %zu bytes!", __func__, size);
17 else
19 memset(*tmp, 0, size);
21 return !!*tmp;
24 /* This function encapsulates realloc. It automatically adds an error message
25 to the log if it failed and calls cs_exit(quiterror) if quiterror > -1.
26 result will be automatically filled with the new memory position or NULL
27 on failure. If a failure occured, the existing memory in result will
28 be freed. */
29 bool cs_realloc(void *result, size_t size)
31 void **tmp = result, **tmp2 = result;
32 *tmp = realloc(*tmp, size);
34 if(*tmp == NULL)
36 fprintf(stderr, "%s: ERROR: Can't allocate %zu bytes!", __func__, size);
37 NULLFREE(*tmp2);
39 return !!*tmp;
42 /* strlen is wrongly used in oscam. Calling strlen directly
43 * e.g. strlen(somechar) can cause segmentation fault if pointer to somechar is NULL!
44 * This one looks better?
46 size_t cs_strlen(const char *c)
48 if (c == NULL)
50 return 0;
52 else
54 if (c[0] == '\0')
56 return 0;
58 else
60 return strlen(c);
65 /* Allocates a new empty string and copies str into it. You need to free() the result. */
66 char *cs_strdup(const char *str)
68 char *newstr;
69 if(!str)
70 { return NULL; }
72 if(cs_malloc(&newstr, cs_strlen(str) + 1))
74 cs_strncpy(newstr, str, cs_strlen(str) + 1);
75 return newstr;
77 return NULL;
80 /* Ordinary strncpy does not terminate the string if the source is exactly
81 as long or longer as the specified size. This can raise security issues.
82 This function is a replacement which makes sure that a \0 is always added.
83 num should be the real size of char array (do not subtract -1). */
84 void cs_strncpy(char *destination, const char *source, size_t num)
86 if(!source)
88 destination[0] = '\0';
89 return;
92 uint32_t l, size = cs_strlen(source);
93 if(size > num - 1)
94 { l = num - 1; }
95 else
96 { l = size; }
98 memcpy(destination, source, l);
99 destination[l] = '\0';
102 bool cs_strncat(char *destination, char *source, size_t destination_size)
104 uint32_t dest_sz = 0;
105 uint32_t source_sz = 0;
107 if (!destination_size)
109 cs_log("ERROR, destination_size 0!");
110 return false;
113 if (destination)
115 dest_sz += cs_strlen(destination);
117 else
119 cs_log("ERROR, destination pointer NULL!");
120 return false;
123 if (source)
125 source_sz += cs_strlen(source);
127 else
129 cs_log("ERROR, source pointer NULL!");
130 return false;
133 if ((dest_sz + source_sz) == 0)
135 cs_log("ERROR, booth destination and source with zero size!");
136 return false;
139 if ((dest_sz + source_sz) < destination_size)
141 if (dest_sz)
143 void *dest = (void *)destination;
144 memcpy(destination, dest, dest_sz);
147 if (source_sz)
148 memcpy(destination + dest_sz, source, source_sz);
150 destination[dest_sz + source_sz] = '\0';
152 else
154 cs_log("ERROR, buffer overflow!");
155 return false;
158 return true;
161 /* Converts the string txt to it's lower case representation. */
162 char *strtolower(char *txt)
164 char *p;
165 for(p = txt; *p; p++)
167 if(isupper((uint8_t)*p))
168 { *p = tolower((uint8_t) * p); }
170 return txt;
173 /* Converts the string txt to it's upper case representation. */
174 char *strtoupper(char *txt)
176 char *p;
177 for(p = txt; *p; p++)
179 if(islower((uint8_t)*p))
180 { *p = toupper((uint8_t)*p); }
182 return txt;
185 char *trim(char *txt)
187 int32_t l;
188 char *p1, *p2;
190 if(*txt == ' ')
192 for(p1 = p2 = txt; (*p1 == ' ') || (*p1 == '\t') || (*p1 == '\n') || (*p1 == '\r'); p1++)
193 { ; }
195 while(*p1)
196 { *p2++ = *p1++; }
198 *p2 = '\0';
201 l = cs_strlen(txt);
202 if(l > 0)
204 for(p1 = txt + l - 1; l > 0 && ((*p1 == ' ') || (*p1 == '\t') || (*p1 == '\n') || (*p1 == '\r')); *p1-- = '\0', l--)
205 { ; }
207 return txt;
210 char *trim2(char *txt)
212 int32_t i, n;
214 for(i = n = 0; i < (int32_t)cs_strlen(txt); i++)
216 if(txt[i] == ' ' || txt[i] == '\t') continue;
217 if(txt[i] == '#') {break;}
218 txt[n] = txt[i];
219 n++;
221 txt[n] = '\0';
223 return txt;
226 char *remove_white_chars(char *txt)
228 char *p1 = txt, *p2 = txt;
230 if(NULL != p1)
232 while('\0' != *p1)
234 if((' ' != *p1) && ('\t' != *p1) && ('\n' != *p1) && ('\r' != *p1))
236 *p2++ = *p1;
238 p1++;
240 *p2 = '\0';
242 return txt;
245 bool streq(const char *s1, const char *s2)
247 if(!s1 && s2) { return 0; }
248 if(s1 && !s2) { return 0; }
249 if(!s1 && !s2) { return 1; }
250 return strcmp(s1, s2) == 0;
253 char *cs_hexdump(int32_t m, const uint8_t *buf, int32_t n, char *target, int32_t len)
255 int32_t i = 0;
256 if(target == NULL || buf == NULL)
258 return NULL;
260 target[0] = '\0';
261 m = m ? 3 : 2;
263 if(m * n >= len)
265 n = (len / m) - 1;
268 while(i < n)
270 snprintf(target + (m * i), len - (m * i), "%02X%s", *buf++, m > 2 ? " " : "");
271 i++;
273 return target;
277 * For using gethexval we must check if char c is within range othervise gethexval return
278 * negative value so we must ensure we not shift left those negative value! So before
279 * using gethexval function you need to check char c with function gethexval_within_range to
280 * ensure char c is within accepted range!
282 bool gethexval_within_range(char c)
284 if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
286 return true;
288 return false;
291 int32_t gethexval(char c)
293 if(c >= '0' && c <= '9') { return c - '0'; }
294 if(c >= 'A' && c <= 'F') { return c - 'A' + 10; }
295 if(c >= 'a' && c <= 'f') { return c - 'a' + 10; }
296 return -1;
299 int32_t cs_atob(uint8_t *buf, char *asc, int32_t n)
301 int32_t i, rc;
302 if(buf == NULL || asc == NULL)
304 return -1;
306 for(i = 0; i < n; i++)
308 if(!gethexval_within_range(asc[i << 1]) || !gethexval_within_range(asc[(i << 1) + 1]))
310 return -1;
312 rc = (gethexval(asc[i << 1]) << 4) | gethexval(asc[(i << 1) + 1]);
313 if(rc & 0x100)
315 return -1;
317 buf[i] = rc;
319 return n;
322 uint32_t cs_atoi(char *asc, int32_t l, int32_t val_on_err)
324 int32_t i, n = 0;
325 uint32_t rc = 0;
326 if(asc == NULL)
328 errno = EINVAL;
329 rc = val_on_err ? 0xFFFFFFFF : 0;
330 return rc;
332 for(i = ((l - 1) << 1), errno = 0; i >= 0 && n < 4; i -= 2)
334 if(!gethexval_within_range(asc[i]) || !gethexval_within_range(asc[i + 1]))
336 errno = EINVAL;
337 rc = val_on_err ? 0xFFFFFFFF : 0;
338 break;
340 int32_t b = (gethexval(asc[i]) << 4) | gethexval(asc[i + 1]);
341 if(b < 0)
343 errno = EINVAL;
344 rc = val_on_err ? 0xFFFFFFFF : 0;
345 break;
347 rc |= b << (n << 3);
348 n++;
350 return rc;
353 int32_t byte_atob(char *asc)
355 int32_t rc = (-1);
356 if(asc == NULL)
358 return rc;
360 if(cs_strlen(trim(asc)) != 2)
362 rc = -1;
364 else
366 if(!gethexval_within_range(asc[0]) || !gethexval_within_range(asc[1]))
368 return rc;
370 else
372 rc = (gethexval(asc[0]) << 4) | gethexval(asc[1]);
373 if(rc & 0x100)
375 rc = -1;
379 return rc;
382 int32_t word_atob(char *asc)
384 int32_t rc = (-1);
386 if(asc == NULL)
388 return rc;
391 if(cs_strlen(trim(asc)) != 4)
393 rc = -1;
395 else
397 if(!gethexval_within_range(asc[0]) || !gethexval_within_range(asc[1]) || !gethexval_within_range(asc[2]) || !gethexval_within_range(asc[3]))
399 return rc;
401 else
403 rc = gethexval(asc[0]) << 12 | gethexval(asc[1]) << 8 | gethexval(asc[2]) << 4 | gethexval(asc[3]);
404 if(rc & 0x10000)
406 rc = -1;
410 return rc;
414 * dynamic word_atob
415 * converts an 1-6 digit asc hexstring
417 int32_t dyn_word_atob(char *asc)
419 int32_t rc = (-1);
420 int32_t i, len;
422 if(asc == NULL)
424 return rc;
426 len = cs_strlen(trim(asc));
427 if(len <= 6 && len > 0)
429 for(i = 0, rc = 0; i < len; i++)
431 if(!gethexval_within_range(asc[i]))
433 return -1;
435 rc = rc << 4 | gethexval(asc[i]);
437 if(rc & 0x1000000)
439 rc = -1;
442 return rc;
445 int32_t key_atob_l(char *asc, uint8_t *bin, int32_t l)
447 int32_t i, n1, n2, rc;
449 if(asc == NULL || bin == NULL)
451 return -1;
453 for(i = rc = 0; i < l; i += 2)
455 if(!gethexval_within_range(asc[i]) || !gethexval_within_range(asc[i + 1]))
457 rc = -1;
459 else
461 n1 = gethexval(asc[i]);
462 n2 = gethexval(asc[i + 1]);
463 bin[i >> 1] = (n1 << 4) + (n2 & 0xff);
466 return rc;
469 uint32_t b2i(int32_t n, const uint8_t *b)
471 if(b == NULL)
473 return 0;
475 switch(n)
477 case 1:
478 return b[0];
479 case 2:
480 return (b[0] << 8) | b[1];
482 case 3:
483 return (b[0] << 16) | (b[1] << 8) | b[2];
485 case 4:
486 return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) & 0xffffffffL;
488 default:
489 cs_log("Error in b2i, n=%i", n);
491 return 0;
494 uint64_t b2ll(int32_t n, const uint8_t *b)
496 int32_t i;
497 uint64_t k = 0;
498 if(b == NULL)
500 return k;
502 for(i = 0; i < n; k += b[i++])
504 k <<= 8;
506 return k;
509 uint8_t *i2b_buf(int32_t n, uint32_t i, uint8_t *b)
511 switch(n)
513 case 2:
514 b[0] = (i >> 8) & 0xff;
515 b[1] = (i) & 0xff;
516 break;
518 case 3:
519 b[0] = (i >> 16) & 0xff;
520 b[1] = (i >> 8) & 0xff;
521 b[2] = (i) & 0xff;
522 break;
524 case 4:
525 b[0] = (i >> 24) & 0xff;
526 b[1] = (i >> 16) & 0xff;
527 b[2] = (i >> 8) & 0xff;
528 b[3] = (i) & 0xff;
529 break;
531 return b;
534 uint8_t *ull2b_buf(uint64_t i, uint8_t *b)
536 b[0] = (i >> 56) & 0xff;
537 b[1] = (i >> 48) & 0xff;
538 b[2] = (i >> 40) & 0xff;
539 b[3] = (i >> 32) & 0xff;
540 b[4] = (i >> 24) & 0xff;
541 b[5] = (i >> 16) & 0xff;
542 b[6] = (i >> 8) & 0xff;
543 b[7] = (i) & 0xff;
544 return b;
547 uint32_t a2i(char *asc, int32_t bytes)
549 int32_t i, n;
550 uint32_t rc;
551 if(asc == NULL)
553 errno = EINVAL;
554 return 0x1f1f1f;
556 for(rc = i = 0, n = cs_strlen(trim(asc)) - 1; i < abs(bytes) << 1; n--, i++)
558 if(n >= 0)
560 int32_t rcl;
561 if(!gethexval_within_range(asc[n]))
563 errno = EINVAL;
564 return 0x1f1f1f;
566 else
568 rcl = gethexval(asc[n]);
569 rc |= rcl << (i << 2);
572 else
574 if(bytes < 0)
576 rc |= 0xf << (i << 2);
580 errno = 0;
581 return rc;
584 int32_t boundary(int32_t exp, int32_t n)
586 return (((n - 1) >> exp) + 1) << exp;
589 /* Checks whether an array has at least one non-zero byte.
590 length specifies the maximum length to check for. */
591 int32_t array_has_nonzero_byte(uint8_t *value, int32_t length)
593 if(!value)
595 return 0;
598 int32_t i;
599 for(i = 0; i < length; i++)
601 if(value[i] > 0)
603 return 1;
606 return 0;
609 #define RAND_POOL_SIZE 64
611 // The last bytes are used to init random seed
612 static uint8_t rand_pool[RAND_POOL_SIZE + sizeof(uint32_t)];
614 void get_random_bytes_init(void)
616 srand(time(NULL));
617 int fd = open("/dev/urandom", O_RDONLY);
619 if(fd < 0)
621 fd = open("/dev/random", O_RDONLY);
622 if(fd < 0)
624 return;
628 if(read(fd, rand_pool, RAND_POOL_SIZE + sizeof(uint32_t)) > -1)
630 uint32_t pool_seed = b2i(4, rand_pool + RAND_POOL_SIZE);
631 srand(pool_seed);
633 close(fd);
636 void get_random_bytes(uint8_t *dst, uint32_t dst_len)
638 static uint32_t rand_pool_pos; // *MUST* be static
639 uint32_t i;
641 for(i = 0; i < dst_len; i++)
643 rand_pool_pos++; // Races are welcome...
644 dst[i] = rand() ^ rand_pool[rand_pool_pos % RAND_POOL_SIZE];
648 static uint32_t crc_table[256] =
650 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
651 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
652 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
653 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
654 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
655 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
656 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
657 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
658 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
659 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
660 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
661 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
662 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
663 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
664 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
665 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
666 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
667 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
668 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
669 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
670 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
671 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
672 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
673 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
674 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
675 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
676 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
677 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
678 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
679 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
680 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
681 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
682 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
683 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
684 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
685 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
686 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
687 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
688 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
689 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
690 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
691 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
692 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
693 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
694 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
695 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
696 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
697 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
698 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
699 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
700 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
701 0x2d02ef8dL
705 * crc32 -- compute the CRC-32 of a data stream
706 * Copyright (C) 1995-1996 Mark Adler
707 * For conditions of distribution and use, see copyright notice in zlib.h
709 #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
710 #define DO2(buf) DO1(buf); DO1(buf);
711 #define DO4(buf) DO2(buf); DO2(buf);
712 #define DO8(buf) DO4(buf); DO4(buf);
714 uint32_t crc32(uint32_t crc, const uint8_t *buf, uint32_t len)
716 if(!buf)
718 return 0L;
720 crc = crc ^ 0xffffffffL;
721 while(len >= 8)
723 DO8(buf);
724 len -= 8;
726 if(len)
730 DO1(buf);
732 while(--len);
734 return crc ^ 0xffffffffL;
737 static uint16_t ccitt_crc_table [256] =
739 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5,
740 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
741 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
742 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
743 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c,
744 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
745 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b,
746 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
747 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
748 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
749 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5,
750 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
751 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969,
752 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
753 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
754 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
755 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03,
756 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
757 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6,
758 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
759 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
760 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
761 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1,
762 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
763 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c,
764 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
765 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
766 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
767 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447,
768 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
769 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2,
770 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
771 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
772 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
773 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
774 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
775 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0,
776 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
777 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
778 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
779 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba,
780 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
781 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
784 uint16_t ccitt_crc(uint8_t *data, size_t length, uint16_t seed, uint16_t final)
786 size_t count;
787 uint32_t crc = seed;
788 uint32_t temp;
790 for (count = 0; count < length; ++count)
792 temp = (*data++ ^ (crc >> 8)) & 0xff;
793 crc = ccitt_crc_table[temp] ^ (crc << 8);
795 return (uint16_t)(crc ^ final);
798 static const uint32_t ccitt32_crc_table[256] =
800 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
801 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
802 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
803 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
804 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
805 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
806 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
807 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
808 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
809 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
810 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
811 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
812 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
813 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
814 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
815 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
816 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
817 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
818 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
819 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
820 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
821 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
822 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
823 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
824 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
825 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
826 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
827 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
828 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
829 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
830 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
831 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
834 uint32_t ccitt32_crc(uint8_t *data, size_t len)
836 uint32_t crc = 0xffffffff;
837 while(len--)
839 crc = ((crc << 8) & 0xffffff00) ^ ccitt32_crc_table[((crc >> 24) & 0xff) ^ *data++];
841 return(crc);
844 // https://en.wikipedia.org/wiki/Jenkins_hash_function
845 uint32_t jhash(const char *key, size_t len)
847 uint32_t hash, i;
848 for(hash = i = 0; i < len; i++)
850 hash += key[i];
851 hash += (hash << 10);
852 hash ^= (hash >> 6);
854 hash += (hash << 3);
855 hash ^= (hash >> 11);
856 hash += (hash << 15);
857 return hash;
860 /* Converts a char to it's hex representation. See char_to_hex on how to use it. */
861 char to_hex(char code)
863 static const char hex[] = "0123456789abcdef";
864 return hex[(int)code & 15];
867 /* Converts a char array to a char array with hex values (needed for example for md5).
868 Note that result needs to be at least (p_array_len * 2) + 1 large. */
869 void char_to_hex(const uint8_t *p_array, uint32_t p_array_len, uint8_t *result)
871 result[p_array_len * 2] = '\0';
872 const uint8_t *p_end = p_array + p_array_len;
873 uint32_t pos = 0;
874 const uint8_t *p;
876 for(p = p_array; p != p_end; p++, pos += 2)
878 result[pos] = to_hex(*p >> 4);
879 result[pos + 1] = to_hex(*p & 15);
883 static inline uint8_t to_uchar(char ch)
885 return ch;
888 void base64_encode(const char *in, size_t inlen, char *out, size_t outlen)
890 static const char b64str[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
891 while(inlen && outlen)
893 *out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f];
894 if(!--outlen) { break; }
895 *out++ = b64str[((to_uchar(in[0]) << 4) + (--inlen ? to_uchar(in[1]) >> 4 : 0)) & 0x3f];
896 if(!--outlen) { break; }
897 *out++ = (inlen ? b64str[((to_uchar(in[1]) << 2) + (--inlen ? to_uchar(in[2]) >> 6 : 0)) & 0x3f] : '=');
898 if(!--outlen) { break; }
899 *out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '=';
900 if(!--outlen) { break; }
901 if(inlen) { inlen--; }
902 if(inlen) { in += 3; }
903 if(outlen) { *out = '\0'; }
907 size_t b64encode(const char *in, size_t inlen, char **out)
909 size_t outlen = 1 + BASE64_LENGTH(inlen);
910 if(inlen > outlen)
912 *out = NULL;
913 return 0;
915 if(!cs_malloc(out, outlen))
917 return -1;
919 base64_encode(in, inlen, *out, outlen);
920 return outlen - 1;
923 static int8_t b64decoder[256];
925 /* Prepares the base64 decoding array */
926 void b64prepare(void)
928 const uint8_t alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
929 int32_t i;
931 for(i = sizeof(b64decoder) - 1; i >= 0; --i)
933 b64decoder[i] = -1;
936 for(i = sizeof(alphabet) - 1; i >= 0; --i)
938 b64decoder[alphabet[i]] = i;
942 /* Decodes a base64-encoded string. The given array will be used directly for output and is thus modified! */
943 int32_t b64decode(uint8_t *result)
945 int32_t i, len = cs_strlen((char *)result), j = 0, bits = 0, char_count = 0;
947 if(!b64decoder[0])
949 b64prepare();
952 for(i = 0; i < len; ++i)
954 if(result[i] == '=') { break; }
955 int8_t tmp = b64decoder[result[i]];
956 if(tmp == -1) { continue; }
957 bits += tmp;
958 ++char_count;
959 if(char_count == 4)
961 result[j++] = bits >> 16;
962 result[j++] = (bits >> 8) & 0xff;
963 result[j++] = bits & 0xff;
964 bits = 0;
965 char_count = 0;
967 else
969 bits <<= 6;
972 if(i == len)
974 if(char_count)
976 result[j] = '\0';
977 return 0;
980 else
982 switch(char_count)
984 case 1:
985 result[j] = '\0';
986 return 0;
987 case 2:
988 result[j++] = bits >> 10;
989 result[j] = '\0';
990 break;
991 case 3:
992 result[j++] = bits >> 16;
993 result[j++] = (bits >> 8) & 0xff;
994 result[j] = '\0';
995 break;
998 return j;
1002 #ifdef READ_SDT_CHARSETS
1004 // ISO_6937 function taken from VLC
1005 /*****************************************************************************
1006 * Local conversion routine from ISO_6937 to UTF-8 charset. Support for this
1007 * is still missing in libiconv, hence multiple operating systems lack it.
1008 * The conversion table adds Euro sign (0xA4) as per ETSI EN 300 468 Annex A
1009 *****************************************************************************/
1011 static const uint16_t iso_6937_to_ucs4[128] =
1013 /* 0x80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
1014 /* 0x88 */ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
1015 /* 0x90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
1016 /* 0x98 */ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
1017 /* 0xa0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0000, 0x00a7,
1018 /* 0xa8 */ 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193,
1019 /* 0xb0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7,
1020 /* 0xb8 */ 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
1021 /* 0xc0 */ 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1022 /* 0xc8 */ 0xffff, 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff,
1023 /* 0xd0 */ 0x2014, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6,
1024 /* 0xd8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e,
1025 /* 0xe0 */ 0x2126, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x013f,
1026 /* 0xe8 */ 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149,
1027 /* 0xf0 */ 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140,
1028 /* 0xf8 */ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad
1031 /* The outer array range runs from 0xc1 to 0xcf, the inner range from 0x40
1032 to 0x7f. */
1033 static const uint16_t iso_6937_to_ucs4_comb[15][64] =
1035 /* 0xc1 */
1037 /* 0x40 */ 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0x00c8, 0x0000, 0x0000,
1038 /* 0x48 */ 0x0000, 0x00cc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d2,
1039 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d9, 0x0000, 0x0000,
1040 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1041 /* 0x60 */ 0x0000, 0x00e0, 0x0000, 0x0000, 0x0000, 0x00e8, 0x0000, 0x0000,
1042 /* 0x68 */ 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f2,
1043 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f9, 0x0000, 0x0000,
1044 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1046 /* 0xc2 */
1048 /* 0x40 */ 0x0000, 0x00c1, 0x0000, 0x0106, 0x0000, 0x00c9, 0x0000, 0x0000,
1049 /* 0x48 */ 0x0000, 0x00cd, 0x0000, 0x0000, 0x0139, 0x0000, 0x0143, 0x00d3,
1050 /* 0x50 */ 0x0000, 0x0000, 0x0154, 0x015a, 0x0000, 0x00da, 0x0000, 0x0000,
1051 /* 0x58 */ 0x0000, 0x00dd, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1052 /* 0x60 */ 0x0000, 0x00e1, 0x0000, 0x0107, 0x0000, 0x00e9, 0x0000, 0x0000,
1053 /* 0x68 */ 0x0000, 0x00ed, 0x0000, 0x0000, 0x013a, 0x0000, 0x0144, 0x00f3,
1054 /* 0x70 */ 0x0000, 0x0000, 0x0155, 0x015b, 0x0000, 0x00fa, 0x0000, 0x0000,
1055 /* 0x78 */ 0x0000, 0x00fd, 0x017a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1057 /* 0xc3 */
1059 /* 0x40 */ 0x0000, 0x00c2, 0x0000, 0x0108, 0x0000, 0x00ca, 0x0000, 0x011c,
1060 /* 0x48 */ 0x0124, 0x00ce, 0x0134, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d4,
1061 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x015c, 0x0000, 0x00db, 0x0000, 0x0174,
1062 /* 0x58 */ 0x0000, 0x0176, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1063 /* 0x60 */ 0x0000, 0x00e2, 0x0000, 0x0109, 0x0000, 0x00ea, 0x0000, 0x011d,
1064 /* 0x68 */ 0x0125, 0x00ee, 0x0135, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f4,
1065 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x00fb, 0x0000, 0x0175,
1066 /* 0x78 */ 0x0000, 0x0177, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1068 /* 0xc4 */
1070 /* 0x40 */ 0x0000, 0x00c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1071 /* 0x48 */ 0x0000, 0x0128, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d1, 0x00d5,
1072 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0168, 0x0000, 0x0000,
1073 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1074 /* 0x60 */ 0x0000, 0x00e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1075 /* 0x68 */ 0x0000, 0x0129, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f1, 0x00f5,
1076 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0169, 0x0000, 0x0000,
1077 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1079 /* 0xc5 */
1081 /* 0x40 */ 0x0000, 0x0100, 0x0000, 0x0000, 0x0000, 0x0112, 0x0000, 0x0000,
1082 /* 0x48 */ 0x0000, 0x012a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014c,
1083 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016a, 0x0000, 0x0000,
1084 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1085 /* 0x60 */ 0x0000, 0x0101, 0x0000, 0x0000, 0x0000, 0x0113, 0x0000, 0x0000,
1086 /* 0x68 */ 0x0000, 0x012b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014d,
1087 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0x0000, 0x0000,
1088 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1090 /* 0xc6 */
1092 /* 0x40 */ 0x0000, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011e,
1093 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1094 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x0000, 0x0000,
1095 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1096 /* 0x60 */ 0x0000, 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011f,
1097 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1098 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x0000, 0x0000,
1099 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1101 /* 0xc7 */
1103 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010a, 0x0000, 0x0116, 0x0000, 0x0120,
1104 /* 0x48 */ 0x0000, 0x0130, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1105 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1106 /* 0x58 */ 0x0000, 0x0000, 0x017b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1107 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010b, 0x0000, 0x0117, 0x0000, 0x0121,
1108 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1109 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1110 /* 0x78 */ 0x0000, 0x0000, 0x017c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1112 /* 0xc8 */
1114 /* 0x40 */ 0x0000, 0x00c4, 0x0000, 0x0000, 0x0000, 0x00cb, 0x0000, 0x0000,
1115 /* 0x48 */ 0x0000, 0x00cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d6,
1116 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00dc, 0x0000, 0x0000,
1117 /* 0x58 */ 0x0000, 0x0178, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1118 /* 0x60 */ 0x0000, 0x00e4, 0x0000, 0x0000, 0x0000, 0x00eb, 0x0000, 0x0000,
1119 /* 0x68 */ 0x0000, 0x00ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f6,
1120 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fc, 0x0000, 0x0000,
1121 /* 0x78 */ 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1123 /* 0xc9 */
1125 0x0000,
1127 /* 0xca */
1129 /* 0x40 */ 0x0000, 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1130 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1131 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x0000,
1132 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1133 /* 0x60 */ 0x0000, 0x00e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1134 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1135 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016f, 0x0000, 0x0000,
1136 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1138 /* 0xcb */
1140 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x00c7, 0x0000, 0x0000, 0x0000, 0x0122,
1141 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0136, 0x013b, 0x0000, 0x0145, 0x0000,
1142 /* 0x50 */ 0x0000, 0x0000, 0x0156, 0x015e, 0x0162, 0x0000, 0x0000, 0x0000,
1143 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1144 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x00e7, 0x0000, 0x0000, 0x0000, 0x0123,
1145 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0137, 0x013c, 0x0000, 0x0146, 0x0000,
1146 /* 0x70 */ 0x0000, 0x0000, 0x0157, 0x015f, 0x0163, 0x0000, 0x0000, 0x0000,
1147 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1149 /* 0xcc */
1151 0x0000,
1153 /* 0xcd */
1155 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1156 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150,
1157 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0170, 0x0000, 0x0000,
1158 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1159 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1160 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0151,
1161 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0171, 0x0000, 0x0000,
1162 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1164 /* 0xce */
1166 /* 0x40 */ 0x0000, 0x0104, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x0000,
1167 /* 0x48 */ 0x0000, 0x012e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1168 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0172, 0x0000, 0x0000,
1169 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1170 /* 0x60 */ 0x0000, 0x0105, 0x0000, 0x0000, 0x0000, 0x0119, 0x0000, 0x0000,
1171 /* 0x68 */ 0x0000, 0x012f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1172 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0173, 0x0000, 0x0000,
1173 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1175 /* 0xcf */
1177 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010c, 0x010e, 0x011a, 0x0000, 0x0000,
1178 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013d, 0x0000, 0x0147, 0x0000,
1179 /* 0x50 */ 0x0000, 0x0000, 0x0158, 0x0160, 0x0164, 0x0000, 0x0000, 0x0000,
1180 /* 0x58 */ 0x0000, 0x0000, 0x017d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1181 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010d, 0x010f, 0x011b, 0x0000, 0x0000,
1182 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013e, 0x0000, 0x0148, 0x0000,
1183 /* 0x70 */ 0x0000, 0x0000, 0x0159, 0x0161, 0x0165, 0x0000, 0x0000, 0x0000,
1184 /* 0x78 */ 0x0000, 0x0000, 0x017e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1188 size_t ISO6937toUTF8(const uint8_t **inbuf, size_t *inbytesleft, uint8_t **outbuf, size_t *outbytesleft)
1190 if(!inbuf || !(*inbuf))
1192 return (size_t)(0); /* Reset state requested */
1195 const uint8_t *iptr = *inbuf;
1196 const uint8_t *iend = iptr + *inbytesleft;
1197 uint8_t *optr = *outbuf;
1198 uint8_t *oend = optr + *outbytesleft;
1199 uint16_t ch;
1200 int err = 0;
1202 while (iptr < iend)
1204 if(*iptr < 0x80)
1206 if(optr >= oend)
1208 err = E2BIG;
1209 break; /* No space in outbuf */
1211 *optr++ = *iptr++;
1212 continue;
1215 if (optr + 2 >= oend)
1217 err = E2BIG;
1218 break; /* No space in outbuf for multibyte char */
1220 ch = iso_6937_to_ucs4[*iptr - 0x80];
1222 if(ch == 0xffff)
1224 /* Composed character */
1225 if (iptr + 1 >= iend)
1227 err = EINVAL;
1228 break; /* No next character */
1230 if (iptr[1] < 0x40 || iptr[1] >= 0x80 || !(ch = iso_6937_to_ucs4_comb[iptr[0] - 0xc1][iptr[1] - 0x40]))
1232 err = EILSEQ;
1233 break; /* Illegal combination */
1235 iptr += 2;
1237 else
1239 if (!ch)
1241 err = EILSEQ;
1242 break;
1244 iptr++;
1247 if (ch < 0x800)
1249 optr[1] = 0x80 | (ch & 0x3f);
1250 optr[0] = 0xc0 | (ch >> 6);
1251 optr +=2;
1253 else
1255 optr[2] = 0x80 | (ch & 0x3f);
1256 ch >>= 6;
1257 optr[1] = 0x80 | (ch & 0x3f);
1258 optr[0] = 0xe0 | (ch >> 6);
1259 optr += 3;
1263 *inbuf = iptr;
1264 *outbuf = optr;
1265 *inbytesleft = iend - iptr;
1266 *outbytesleft = oend - optr;
1267 if(err)
1269 errno = err;
1270 return (size_t)(-1);
1272 return (size_t)(0);
1275 #include "oscam-string-isotables.h"
1277 static const uint16_t *get_iso8859_table(int8_t iso_table_number)
1279 if(iso_table_number > 1 && iso_table_number < 17 && iso_table_number != 12)
1281 if(iso_table_number < 12)
1283 return iso_8859_to_unicode[iso_table_number - 2];
1285 else
1287 return iso_8859_to_unicode[iso_table_number - 3];
1290 else
1292 return NULL;
1296 size_t ISO8859toUTF8(int8_t iso_table_number, const uint8_t **inbuf, size_t *inbytesleft, uint8_t **outbuf, size_t *outbytesleft)
1298 if(!inbuf || !(*inbuf))
1300 return (size_t)(0); /* Reset state requested */
1303 const uint8_t *iptr = *inbuf;
1304 const uint8_t *iend = iptr + *inbytesleft;
1305 uint8_t *optr = *outbuf;
1306 uint8_t *oend = optr + *outbytesleft;
1307 uint16_t ch;
1308 int err = 0;
1309 const uint16_t *iso_table = NULL;
1311 if( iso_table_number != 1 )
1313 iso_table = get_iso8859_table(iso_table_number);
1314 if ( iso_table == NULL )
1316 errno = EINVAL;
1317 return (size_t)(-1);
1321 while (iptr < iend)
1323 if(*iptr < 0x80)
1325 if(optr >= oend)
1327 err = E2BIG;
1328 break; /* No space in outbuf */
1330 *optr++ = *iptr++;
1331 continue;
1334 if( iso_table_number == 1 || *iptr < 0xA1 )
1336 ch = *iptr;
1338 else
1340 ch = iso_table[*iptr - 0xA1];
1342 iptr++;
1344 if (ch < 0x80)
1346 if (optr >= oend)
1348 err = E2BIG;
1349 break; /* No space in outbuf for char */
1351 optr[0] = ch & 0xff;
1352 optr += 1;
1354 else if (ch < 0x800)
1356 if (optr + 1 >= oend)
1358 err = E2BIG;
1359 break; /* No space in outbuf for multibyte char */
1361 optr[1] = 0x80 | (ch & 0x3f);
1362 optr[0] = 0xc0 | (ch >> 6);
1363 optr += 2;
1365 else
1367 if (optr + 2 >= oend)
1369 err = E2BIG;
1370 break; /* No space in outbuf for multibyte char */
1372 optr[2] = 0x80 | (ch & 0x3f);
1373 ch >>= 6;
1374 optr[1] = 0x80 | (ch & 0x3f);
1375 optr[0] = 0xe0 | (ch >> 6);
1376 optr += 3;
1379 *inbuf = iptr;
1380 *outbuf = optr;
1381 *inbytesleft = iend - iptr;
1382 *outbytesleft = oend - optr;
1384 if(err)
1386 errno = err;
1387 return (size_t)(-1);
1389 return (size_t)(0);
1392 #endif
1394 size_t UnicodetoUTF8(const uint8_t **inbuf, size_t *inbytesleft, uint8_t **outbuf, size_t *outbytesleft)
1396 if(!inbuf || !(*inbuf))
1398 return (size_t)(0); /* Reset state requested */
1401 const uint8_t *iptr = *inbuf;
1402 const uint8_t *iend = iptr + *inbytesleft;
1403 uint8_t*optr = *outbuf;
1404 uint8_t *oend = optr + *outbytesleft;
1405 uint16_t ch;
1406 int err = 0;
1408 while (iptr + 1 < iend)
1410 ch = (iptr[0] << 8) | iptr[1];
1411 iptr += 2;
1413 if (ch < 0x80)
1415 if (optr >= oend)
1417 err = E2BIG;
1418 break; /* No space in outbuf for char */
1420 optr[0] = ch & 0xff;
1421 optr += 1;
1423 else if (ch < 0x800)
1425 if (optr + 1 >= oend)
1427 err = E2BIG;
1428 break; /* No space in outbuf for multibyte char */
1430 optr[1] = 0x80 | (ch & 0x3f);
1431 optr[0] = 0xc0 | (ch >> 6);
1432 optr += 2;
1434 else
1436 if (optr + 2 >= oend)
1438 err = E2BIG;
1439 break; /* No space in outbuf for multibyte char */
1441 optr[2] = 0x80 | (ch & 0x3f);
1442 ch >>= 6;
1443 optr[1] = 0x80 | (ch & 0x3f);
1444 optr[0] = 0xe0 | (ch >> 6);
1445 optr += 3;
1449 *inbuf = iptr;
1450 *outbuf = optr;
1451 *inbytesleft = iend - iptr;
1452 *outbytesleft = oend - optr;
1454 if(err)
1456 errno = err;
1457 return (size_t)(-1);
1459 return (size_t)(0);