util.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * Copyright (C) 2007-2010 Michael Buesch <m@bues.ch>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include "util.h"
  15. #include "razer_private.h"
  16. #include <unistd.h>
  17. #include <errno.h>
  18. #include <ctype.h>
  19. #include <stdarg.h>
  20. void razer_free(void *ptr, size_t size)
  21. {
  22. if (ptr) {
  23. memset(ptr, 0, size);
  24. free(ptr);
  25. }
  26. }
  27. char * razer_strsplit(char *str, char sep)
  28. {
  29. char c;
  30. if (!str)
  31. return NULL;
  32. for (c = *str; c != '\0' && c != sep; c = *str)
  33. str++;
  34. if (c == sep) {
  35. *str = '\0';
  36. return str + 1;
  37. }
  38. return NULL;
  39. }
  40. int razer_split_tuple(const char *str, char sep,
  41. size_t elems_max_len, ...)
  42. {
  43. char *elem;
  44. va_list ap;
  45. int err = 0;
  46. if (!elems_max_len)
  47. return -EINVAL;
  48. if (strlen(str) >= elems_max_len)
  49. return -EINVAL;
  50. va_start(ap, elems_max_len);
  51. while (1) {
  52. elem = va_arg(ap, char *);
  53. if (!elem)
  54. break;
  55. elem[0] = '\0';
  56. if (!str) {
  57. err = -ENODATA;
  58. continue;
  59. }
  60. razer_strlcpy(elem, str, elems_max_len);
  61. str = razer_strsplit(elem, sep);
  62. }
  63. va_end(ap);
  64. return err;
  65. }
  66. int razer_string_to_int(const char *string, int *i)
  67. {
  68. char *tailptr;
  69. long retval;
  70. retval = strtol(string, &tailptr, 0);
  71. if (tailptr == string || tailptr[0] != '\0')
  72. return -EINVAL;
  73. *i = retval;
  74. return 0;
  75. }
  76. int razer_string_to_bool(const char *string, bool *b)
  77. {
  78. int i;
  79. if (strcasecmp(string, "yes") == 0 ||
  80. strcasecmp(string, "true") == 0 ||
  81. strcasecmp(string, "on") == 0) {
  82. *b = 1;
  83. return 0;
  84. }
  85. if (strcasecmp(string, "no") == 0 ||
  86. strcasecmp(string, "false") == 0 ||
  87. strcasecmp(string, "off") == 0) {
  88. *b = 0;
  89. return 0;
  90. }
  91. if (!razer_string_to_int(string, &i)) {
  92. *b = !!i;
  93. return 0;
  94. }
  95. return -EINVAL;
  96. }
  97. int razer_string_to_mode(const char *string, enum razer_led_mode *mode)
  98. {
  99. if (strcasecmp(string, "static") == 0) {
  100. *mode = RAZER_LED_MODE_STATIC;
  101. return 0;
  102. }
  103. if (strcasecmp(string, "spectrum") == 0) {
  104. *mode = RAZER_LED_MODE_SPECTRUM;
  105. return 0;
  106. }
  107. if (strcasecmp(string, "breathing") == 0) {
  108. *mode = RAZER_LED_MODE_BREATHING;
  109. return 0;
  110. }
  111. return -EINVAL;
  112. }
  113. int razer_string_to_color(const char *string, struct razer_rgb_color *color)
  114. {
  115. uint32_t temp = (uint32_t)strtol(string, NULL, 16);
  116. color->r = (uint8_t)((temp >> 16) & 0xFF);
  117. color->g = (uint8_t)((temp >> 8) & 0xFF);
  118. color->b = (uint8_t)(temp & 0xFF);
  119. color->valid = 1;
  120. return 0;
  121. }
  122. char * razer_string_strip(char *str)
  123. {
  124. char *start = str;
  125. size_t len;
  126. if (!str)
  127. return NULL;
  128. while (*start != '\0' && isspace(*start))
  129. start++;
  130. len = strlen(start);
  131. while (len && isspace(start[len - 1])) {
  132. start[len - 1] = '\0';
  133. len--;
  134. }
  135. return start;
  136. }
  137. void razer_strlcpy(char *dst, const char *src, size_t dst_size)
  138. {
  139. size_t len;
  140. if (!dst_size)
  141. return;
  142. len = strlen(src);
  143. if (len >= dst_size)
  144. len = dst_size - 1;
  145. memcpy(dst, src, len);
  146. dst[len] = 0;
  147. }
  148. void razer_timeval_add_msec(struct timeval *tv, unsigned int msec)
  149. {
  150. unsigned int seconds, usec;
  151. seconds = msec / 1000;
  152. msec = msec % 1000;
  153. usec = msec * 1000;
  154. tv->tv_usec += usec;
  155. while (tv->tv_usec >= 1000000) {
  156. tv->tv_sec++;
  157. tv->tv_usec -= 1000000;
  158. }
  159. tv->tv_sec += seconds;
  160. }
  161. /* Returns true, if a is after b. */
  162. bool razer_timeval_after(const struct timeval *a, const struct timeval *b)
  163. {
  164. if (a->tv_sec > b->tv_sec)
  165. return 1;
  166. if ((a->tv_sec == b->tv_sec) && (a->tv_usec > b->tv_usec))
  167. return 1;
  168. return 0;
  169. }
  170. /* Return a-b in milliseconds */
  171. int razer_timeval_msec_diff(const struct timeval *a, const struct timeval *b)
  172. {
  173. int64_t usec_a, usec_b, usec_diff;
  174. usec_a = (int64_t)a->tv_sec * 1000000;
  175. usec_a += (int64_t)a->tv_usec;
  176. usec_b = (int64_t)b->tv_sec * 1000000;
  177. usec_b += (int64_t)b->tv_usec;
  178. usec_diff = usec_a - usec_b;
  179. return usec_diff / 1000;
  180. }
  181. void razer_msleep(unsigned int msecs)
  182. {
  183. int err;
  184. struct timespec time;
  185. time.tv_sec = 0;
  186. while (msecs >= 1000) {
  187. time.tv_sec++;
  188. msecs -= 1000;
  189. }
  190. time.tv_nsec = msecs;
  191. time.tv_nsec *= 1000000;
  192. do {
  193. err = nanosleep(&time, &time);
  194. } while (err && errno == EINTR);
  195. if (err) {
  196. razer_error("nanosleep() failed with: %s\n",
  197. strerror(errno));
  198. }
  199. }
  200. le16_t razer_xor16_checksum(const void *_buffer, size_t size)
  201. {
  202. const uint8_t *buffer = _buffer;
  203. uint16_t sum = 0;
  204. size_t i;
  205. for (i = 0; i < size; i += 2) {
  206. sum ^= buffer[i];
  207. if (i < size - 1)
  208. sum ^= ((uint16_t)(buffer[i + 1])) << 8;
  209. }
  210. return cpu_to_le16(sum);
  211. }
  212. be16_t razer_xor16_checksum_be(const void *_buffer, size_t size)
  213. {
  214. return (be16_t)bswap_16((uint16_t)razer_xor16_checksum(_buffer, size));
  215. }
  216. uint8_t razer_xor8_checksum(const void *_buffer, size_t size)
  217. {
  218. const uint8_t *buffer = _buffer;
  219. uint8_t sum = 0;
  220. size_t i;
  221. for (i = 0; i < size; i++)
  222. sum ^= buffer[i];
  223. return sum;
  224. }
  225. static char razer_char_to_ascii(char c)
  226. {
  227. if (c >= 32 && c <= 126)
  228. return c;
  229. return '.';
  230. }
  231. void razer_dump(const char *prefix, const void *_buf, size_t size)
  232. {
  233. const unsigned char *buf = _buf;
  234. size_t i;
  235. char ascii[17] = { 0, };
  236. unsigned int ascii_idx = 0;
  237. for (i = 0; i < size; i++) {
  238. if (i % 16 == 0) {
  239. if (i != 0) {
  240. printf(" |%s|\n", ascii);
  241. memset(ascii, 0, sizeof(ascii));
  242. ascii_idx = 0;
  243. }
  244. printf("%s-[%04X]: ", prefix, (unsigned int)i);
  245. }
  246. printf("%02X%s", buf[i], (i % 2) ? " " : "");
  247. ascii[ascii_idx++] = razer_char_to_ascii(buf[i]);
  248. }
  249. if (ascii[0]) {
  250. for (; i % 16; i++)
  251. printf((i % 2) ? " " : " ");
  252. printf(" |%s|", ascii);
  253. }
  254. printf("\n\n");
  255. }
  256. void razer_ascii_to_utf16(razer_utf16_t *dest, size_t dest_max_chars,
  257. const char *src)
  258. {
  259. size_t count = 0;
  260. if (!dest_max_chars)
  261. return;
  262. /* FIXME: This code is wrong.
  263. * But it works for most strings in the current setup.
  264. * So it probably won't blow up too often.
  265. */
  266. while (count < dest_max_chars - 1) {
  267. if (!*src)
  268. break;
  269. *dest++ = *src++;
  270. count++;
  271. }
  272. *dest = 0;
  273. }
  274. int razer_utf16_cpy(razer_utf16_t *dest, const razer_utf16_t *src,
  275. size_t max_chars)
  276. {
  277. size_t i;
  278. for (i = 0; i < max_chars; i++, dest++, src++) {
  279. *dest = *src;
  280. if (!(*src))
  281. return 0;
  282. }
  283. return -ENOSPC;
  284. }
  285. size_t razer_utf16_strlen(const razer_utf16_t *str)
  286. {
  287. size_t count = 0;
  288. while (*str) {
  289. str++;
  290. count++;
  291. }
  292. return count;
  293. }