util.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * libsfn/util.c
  3. *
  4. * Copyright (C) 2020 bzt (bztsrc@gitlab)
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies
  11. * of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. * DEALINGS IN THE SOFTWARE.
  25. *
  26. * @brief Utility functions
  27. *
  28. */
  29. #include <stdlib.h>
  30. #include <ssfn.h>
  31. /**
  32. * Convert hex string to binary number. Use this lightning fast implementation
  33. * instead of the unbeliveably crap, slower than a pregnant snail sscanf...
  34. */
  35. unsigned int gethex(char *ptr, int len)
  36. {
  37. unsigned int ret = 0;
  38. for(;len--;ptr++) {
  39. if(*ptr>='0' && *ptr<='9') { ret <<= 4; ret += (unsigned int)(*ptr-'0'); }
  40. else if(*ptr >= 'a' && *ptr <= 'f') { ret <<= 4; ret += (unsigned int)(*ptr-'a'+10); }
  41. else if(*ptr >= 'A' && *ptr <= 'F') { ret <<= 4; ret += (unsigned int)(*ptr-'A'+10); }
  42. else break;
  43. }
  44. return ret;
  45. }
  46. /**
  47. * Turn a decimal or hex string into binary number
  48. */
  49. unsigned int getnum(char *s)
  50. {
  51. if(!s || !*s) return 0;
  52. if(*s=='\'') { s++; return ssfn_utf8(&s); }
  53. if((*s=='0' && s[1]=='x') || (*s=='U' && s[1]=='+')) return gethex(s+2,8);
  54. return atoi(s);
  55. }
  56. /**
  57. * Read wasm integer (LEB128)
  58. */
  59. unsigned char *getleb(unsigned char *bytes, unsigned int *value)
  60. {
  61. unsigned int ret = 0, shift = 0, b;
  62. if(!bytes) return NULL;
  63. do {
  64. b = *bytes++;
  65. ret |= ((b & 0x7f) << shift);
  66. shift += 7;
  67. } while(shift < 32 && (b & 0x80));
  68. if(value) *value = ret;
  69. return bytes;
  70. }
  71. /**
  72. * Encode run-length bytes
  73. */
  74. unsigned char *rle_enc(unsigned char *inbuff, int inlen, int *outlen)
  75. {
  76. int i, k, l, o;
  77. unsigned char *outbuff;
  78. if(!inbuff || inlen < 1 || !outlen) return NULL;
  79. /* allocate memory for the worst case scenario */
  80. outbuff = (unsigned char *)realloc(NULL, 2 * inlen + 1);
  81. if(!outbuff) return NULL;
  82. k = o = 0; outbuff[o++] = 0;
  83. for(i = 0; i < inlen; i++) {
  84. for(l = 1; l < 128 && i + l < inlen && inbuff[i] == inbuff[i + l]; l++);
  85. if(l > 1) {
  86. l--; if(outbuff[k]) { outbuff[k]--; outbuff[o++] = 0x80 | l; } else outbuff[k] = 0x80 | l;
  87. outbuff[o++] = inbuff[i]; k = o; outbuff[o++] = 0; i += l; continue;
  88. }
  89. outbuff[k]++; outbuff[o++] = inbuff[i];
  90. if(outbuff[k] > 127) { outbuff[k]--; k = o; outbuff[o++] = 0; }
  91. }
  92. if(!(outbuff[k] & 0x80)) { if(outbuff[k]) outbuff[k]--; else o--; }
  93. *outlen = o;
  94. outbuff = (unsigned char *)realloc(outbuff, o);
  95. return outbuff;
  96. }
  97. /**
  98. * Decode run-length encoded bytes
  99. */
  100. unsigned char *rle_dec(unsigned char *inbuff, int inlen, int *outlen)
  101. {
  102. int l, o = 0, s = 0;
  103. unsigned char *end = inbuff + inlen, *outbuff = NULL;
  104. if(!inbuff || inlen < 2 || !outlen) return NULL;
  105. if(*outlen) {
  106. s = *outlen;
  107. outbuff = (unsigned char*)realloc(outbuff, s);
  108. if(!outbuff) return NULL;
  109. }
  110. while(inbuff < end) {
  111. l = ((*inbuff++) & 0x7F) + 1;
  112. /* if we don't know the required buffer size in advance, allocate memory in 4k blocks */
  113. if(o + l + 1 > s) {
  114. s += 4096;
  115. outbuff = (unsigned char*)realloc(outbuff, s);
  116. if(!outbuff) return NULL;
  117. }
  118. if(inbuff[-1] & 0x80) {
  119. while(l--) outbuff[o++] = *inbuff;
  120. inbuff++;
  121. } else while(l--) outbuff[o++] = *inbuff++;
  122. }
  123. *outlen = o;
  124. outbuff = (unsigned char *)realloc(outbuff, o);
  125. return outbuff;
  126. }
  127. /**
  128. * Check if a row is background color only
  129. */
  130. int isempty(int len, unsigned char *data)
  131. {
  132. int i;
  133. if(!data || len < 1) return 1;
  134. for(i = 0; i < len; i++)
  135. if(data[i] != 0xFF) return 0;
  136. return 1;
  137. }
  138. /**
  139. * RFC4648 base64 decoder
  140. */
  141. int base64_decode(char *s, unsigned char *out)
  142. {
  143. unsigned char *ret = out;
  144. int b = 0, c = 0, d;
  145. while(*s && *s != '=' && *s != '<' && *s != '>' && *s != '\"') {
  146. while(*s && (*s == ' ' || *s == '\r' || *s == '\n')) s++;
  147. if(!*s) break;
  148. if(*s >= 'A' && *s <= 'Z') d = *s - 'A'; else
  149. if(*s >= 'a' && *s <= 'z') d = *s - 'a' + 26; else
  150. if(*s >= '0' && *s <= '9') d = *s - '0' + 52; else
  151. if(*s == '+' || *s == '-' || *s == '.') d = 62; else
  152. if(*s == '/' || *s == '_') d = 63; else break;
  153. b += d; c++; s++;
  154. if(c == 4) {
  155. *out++ = (b >> 16);
  156. *out++ = ((b >> 8) & 0xff);
  157. *out++ = (b & 0xff);
  158. b = c = 0;
  159. } else {
  160. b <<= 6;
  161. }
  162. }
  163. switch(c) {
  164. case 1: break;
  165. case 2: *out++ = (b >> 10); break;
  166. case 3: *out++ = (b >> 16); *out++ = ((b >> 8) & 0xff); break;
  167. }
  168. *out = 0;
  169. return (int)(out - ret);
  170. }