monero/external/net_skeleton/modules/util.c

167 lines
4.8 KiB
C

/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#include "net_skeleton.h"
#include "util.h"
const char *ns_skip(const char *s, const char *end,
const char *delims, struct ns_str *v) {
v->p = s;
while (s < end && strchr(delims, * (unsigned char *) s) == NULL) s++;
v->len = s - v->p;
while (s < end && strchr(delims, * (unsigned char *) s) != NULL) s++;
return s;
}
static int lowercase(const char *s) {
return tolower(* (const unsigned char *) s);
}
int ns_ncasecmp(const char *s1, const char *s2, size_t len) {
int diff = 0;
if (len > 0)
do {
diff = lowercase(s1++) - lowercase(s2++);
} while (diff == 0 && s1[-1] != '\0' && --len > 0);
return diff;
}
int ns_vcasecmp(const struct ns_str *str2, const char *str1) {
size_t n1 = strlen(str1), n2 = str2->len;
return n1 == n2 ? ns_ncasecmp(str1, str2->p, n1) : n1 > n2 ? 1 : -1;
}
int ns_vcmp(const struct ns_str *str2, const char *str1) {
size_t n1 = strlen(str1), n2 = str2->len;
return n1 == n2 ? memcmp(str1, str2->p, n2) : n1 > n2 ? 1 : -1;
}
#ifdef _WIN32
static void to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
char buf[MAX_PATH_SIZE * 2], buf2[MAX_PATH_SIZE * 2], *p;
strncpy(buf, path, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
/* Trim trailing slashes. Leave backslash for paths like "X:\" */
p = buf + strlen(buf) - 1;
while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
/*
* Convert to Unicode and back. If doubly-converted string does not
* match the original, something is fishy, reject.
*/
memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
NULL, NULL);
if (strcmp(buf, buf2) != 0) {
wbuf[0] = L'\0';
}
}
#endif /* _WIN32 */
int ns_stat(const char *path, ns_stat_t *st) {
#ifdef _WIN32
wchar_t wpath[MAX_PATH_SIZE];
to_wchar(path, wpath, ARRAY_SIZE(wpath));
DBG(("[%ls] -> %d", wpath, _wstati64(wpath, st)));
return _wstati64(wpath, st);
#else
return stat(path, st);
#endif
}
FILE *ns_fopen(const char *path, const char *mode) {
#ifdef _WIN32
wchar_t wpath[MAX_PATH_SIZE], wmode[10];
to_wchar(path, wpath, ARRAY_SIZE(wpath));
to_wchar(mode, wmode, ARRAY_SIZE(wmode));
return _wfopen(wpath, wmode);
#else
return fopen(path, mode);
#endif
}
int ns_open(const char *path, int flag, int mode) {
#ifdef _WIN32
wchar_t wpath[MAX_PATH_SIZE];
to_wchar(path, wpath, ARRAY_SIZE(wpath));
return _wopen(wpath, flag, mode);
#else
return open(path, flag, mode);
#endif
}
void ns_base64_encode(const unsigned char *src, int src_len, char *dst) {
static const char *b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i, j, a, b, c;
for (i = j = 0; i < src_len; i += 3) {
a = src[i];
b = i + 1 >= src_len ? 0 : src[i + 1];
c = i + 2 >= src_len ? 0 : src[i + 2];
dst[j++] = b64[a >> 2];
dst[j++] = b64[((a & 3) << 4) | (b >> 4)];
if (i + 1 < src_len) {
dst[j++] = b64[(b & 15) << 2 | (c >> 6)];
}
if (i + 2 < src_len) {
dst[j++] = b64[c & 63];
}
}
while (j % 4 != 0) {
dst[j++] = '=';
}
dst[j++] = '\0';
}
/* Convert one byte of encoded base64 input stream to 6-bit chunk */
static unsigned char from_b64(unsigned char ch) {
/* Inverse lookup map */
static const unsigned char tab[128] = {
255, 255, 255, 255, 255, 255, 255, 255, /* 0 */
255, 255, 255, 255, 255, 255, 255, 255, /* 8 */
255, 255, 255, 255, 255, 255, 255, 255, /* 16 */
255, 255, 255, 255, 255, 255, 255, 255, /* 24 */
255, 255, 255, 255, 255, 255, 255, 255, /* 32 */
255, 255, 255, 62, 255, 255, 255, 63, /* 40 */
52, 53, 54, 55, 56, 57, 58, 59, /* 48 */
60, 61, 255, 255, 255, 200, 255, 255, /* 56 '=' is 200, on index 61 */
255, 0, 1, 2, 3, 4, 5, 6, /* 64 */
7, 8, 9, 10, 11, 12, 13, 14, /* 72 */
15, 16, 17, 18, 19, 20, 21, 22, /* 80 */
23, 24, 25, 255, 255, 255, 255, 255, /* 88 */
255, 26, 27, 28, 29, 30, 31, 32, /* 96 */
33, 34, 35, 36, 37, 38, 39, 40, /* 104 */
41, 42, 43, 44, 45, 46, 47, 48, /* 112 */
49, 50, 51, 255, 255, 255, 255, 255, /* 120 */
};
return tab[ch & 127];
}
void ns_base64_decode(const unsigned char *s, int len, char *dst) {
unsigned char a, b, c, d;
while (len >= 4 &&
(a = from_b64(s[0])) != 255 &&
(b = from_b64(s[1])) != 255 &&
(c = from_b64(s[2])) != 255 &&
(d = from_b64(s[3])) != 255) {
if (a == 200 || b == 200) break; /* '=' can't be there */
*dst++ = a << 2 | b >> 4;
if (c == 200) break;
*dst++ = b << 4 | c >> 2;
if (d == 200) break;
*dst++ = c << 6 | d;
s += 4;
len -=4;
}
*dst = 0;
}