mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Improve str.h and str.c
Move alloca_tohex() from serval.h into str.h so it can be used stand-alone. Rename str_to_ll_scaled() to str_to_int64_scaled(). Add str_to_uint64_scaled() and scale_factor(). Add a few more URI parsing functions. Move some functions out of str.c and into str.h as inline functions.
This commit is contained in:
parent
1fbf7001d1
commit
494a766b9e
@ -86,7 +86,7 @@ static int overlay_interface_type(char *s)
|
||||
if (!strcasecmp(s,"wifi")) return OVERLAY_INTERFACE_WIFI;
|
||||
if (!strcasecmp(s,"other")) return OVERLAY_INTERFACE_UNKNOWN;
|
||||
if (!strcasecmp(s,"catear")) return OVERLAY_INTERFACE_PACKETRADIO;
|
||||
return WHY("Invalid interface type -- consider using 'wifi','ethernet' or 'other'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int overlay_interface_arg(char *arg)
|
||||
@ -1290,7 +1290,7 @@ parse_quantity(char *q)
|
||||
if (strlen(q) >= 80)
|
||||
return WHY("quantity string >=80 characters");
|
||||
long long result;
|
||||
if (str_to_ll_scaled(q, 10, &result, NULL))
|
||||
if (str_to_int64_scaled(q, 10, &result, NULL))
|
||||
return result;
|
||||
return WHYF("Illegal quantity: %s", alloca_str_toprint(q));
|
||||
}
|
||||
|
1
serval.h
1
serval.h
@ -466,7 +466,6 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
int overlay_frame_process(struct overlay_interface *interface, struct overlay_frame *f);
|
||||
int overlay_frame_resolve_addresses(struct overlay_frame *f);
|
||||
|
||||
#define alloca_tohex(buf,len) tohex((char *)alloca((len)*2+1), (buf), (len))
|
||||
#define alloca_tohex_sid(sid) alloca_tohex((sid), SID_SIZE)
|
||||
#define alloca_tohex_sas(sas) alloca_tohex((sas), SAS_SIZE)
|
||||
|
||||
|
75
str.c
75
str.c
@ -28,7 +28,7 @@
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
char hexdigit[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
const char hexdigit[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
|
||||
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes)
|
||||
{
|
||||
@ -163,24 +163,50 @@ char *str_str(char *haystack, const char *needle, int haystack_len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int str_to_ll_scaled(const char *str, int base, long long *result, const char **afterp)
|
||||
uint64_t scale_factor(const char *str, const char **afterp)
|
||||
{
|
||||
uint64_t factor = 1;
|
||||
switch (str[0]) {
|
||||
case 'k': ++str; factor = 1000LL; break;
|
||||
case 'K': ++str; factor = 1024LL; break;
|
||||
case 'm': ++str; factor = 1000LL * 1000LL; break;
|
||||
case 'M': ++str; factor = 1024LL * 1024LL; break;
|
||||
case 'g': ++str; factor = 1000LL * 1000LL * 1000LL; break;
|
||||
case 'G': ++str; factor = 1024LL * 1024LL * 1024LL; break;
|
||||
}
|
||||
if (afterp)
|
||||
*afterp = str;
|
||||
else if (*str)
|
||||
factor = 0;
|
||||
return factor;
|
||||
}
|
||||
|
||||
int str_to_int64_scaled(const char *str, int base, int64_t *result, const char **afterp)
|
||||
{
|
||||
if (!(isdigit(*str) || *str == '-' || *str == '+'))
|
||||
return 0;
|
||||
char *end;
|
||||
long long value = strtoll(str, &end, base);
|
||||
const char *end = str;
|
||||
long long value = strtoll(str, (char**)&end, base);
|
||||
if (end == str)
|
||||
return 0;
|
||||
switch (*end) {
|
||||
case '\0': break;
|
||||
case 'k': value *= 1000LL; ++end; break;
|
||||
case 'K': value *= 1024LL; ++end; break;
|
||||
case 'm': value *= 1000LL * 1000LL; ++end; break;
|
||||
case 'M': value *= 1024LL * 1024LL; ++end; break;
|
||||
case 'g': value *= 1000LL * 1000LL * 1000LL; ++end; break;
|
||||
case 'G': value *= 1024LL * 1024LL * 1024LL; ++end; break;
|
||||
default: return 0;
|
||||
}
|
||||
value *= scale_factor(end, &end);
|
||||
if (afterp)
|
||||
*afterp = end;
|
||||
else if (*end)
|
||||
return 0;
|
||||
*result = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int str_to_uint64_scaled(const char *str, int base, uint64_t *result, const char **afterp)
|
||||
{
|
||||
if (!isdigit(*str))
|
||||
return 0;
|
||||
const char *end = str;
|
||||
unsigned long long value = strtoull(str, (char**)&end, base);
|
||||
if (end == str)
|
||||
return 0;
|
||||
value *= scale_factor(end, &end);
|
||||
if (afterp)
|
||||
*afterp = end;
|
||||
else if (*end)
|
||||
@ -265,27 +291,6 @@ size_t str_fromprint(unsigned char *dst, const char *src)
|
||||
return dst - odst;
|
||||
}
|
||||
|
||||
int is_uri_char_scheme(char c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c) || c == '+' || c == '-' || c == '.';
|
||||
}
|
||||
|
||||
int is_uri_char_unreserved(char c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c) || c == '-' || c == '.' || c == '_' || c == '~';
|
||||
}
|
||||
|
||||
int is_uri_char_reserved(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case ':': case '/': case '?': case '#': case '[': case ']': case '@':
|
||||
case '!': case '$': case '&': case '\'': case '(': case ')':
|
||||
case '*': case '+': case ',': case ';': case '=':
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return true if the string resembles a URI.
|
||||
* Based on RFC-3986 generic syntax, assuming nothing about the hierarchical part.
|
||||
*
|
||||
|
44
str.h
44
str.h
@ -21,6 +21,7 @@
|
||||
#define __STR_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@ -58,13 +59,15 @@ __STR_INLINE int is_xstring(const char *text, int len)
|
||||
return *text == '\0';
|
||||
}
|
||||
|
||||
extern char hexdigit[16];
|
||||
extern const char hexdigit[16];
|
||||
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes);
|
||||
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t nbinary);
|
||||
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t nbinary);
|
||||
int is_all_matching(const unsigned char *ptr, size_t len, unsigned char value);
|
||||
char *str_toupper_inplace(char *s);
|
||||
|
||||
#define alloca_tohex(buf,len) tohex((char *)alloca((len)*2+1), (buf), (len))
|
||||
|
||||
__STR_INLINE int hexvalue(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
@ -136,7 +139,9 @@ char *str_str(char *haystack, const char *needle, int haystack_len);
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int str_to_ll_scaled(const char *str, int base, long long *result, const char **afterp);
|
||||
int str_to_int64_scaled(const char *str, int base, int64_t *result, const char **afterp);
|
||||
int str_to_uint64_scaled(const char *str, int base, uint64_t *result, const char **afterp);
|
||||
uint64_t scale_factor(const char *str, const char **afterp);
|
||||
|
||||
/* Return true if the string resembles a nul-terminated URI.
|
||||
* Based on RFC-3986 generic syntax, assuming nothing about the hierarchical part.
|
||||
@ -147,6 +152,41 @@ int str_to_ll_scaled(const char *str, int base, long long *result, const char **
|
||||
*/
|
||||
int str_is_uri(const char *uri);
|
||||
|
||||
__STR_INLINE int is_uri_char_scheme(char c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c) || c == '+' || c == '-' || c == '.';
|
||||
}
|
||||
|
||||
__STR_INLINE int is_uri_char_unreserved(char c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c) || c == '-' || c == '.' || c == '_' || c == '~';
|
||||
}
|
||||
|
||||
__STR_INLINE int is_uri_char_reserved(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case ':': case '/': case '?': case '#': case '[': case ']': case '@':
|
||||
case '!': case '$': case '&': case '\'': case '(': case ')':
|
||||
case '*': case '+': case ',': case ';': case '=':
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return true if the string resembles a URI scheme without the terminating colon.
|
||||
* Based on RFC-3986 generic syntax.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
__STR_INLINE int str_is_uri_scheme(const char *scheme)
|
||||
{
|
||||
if (!isalpha(*scheme++))
|
||||
return 0;
|
||||
while (is_uri_char_scheme(*scheme))
|
||||
++scheme;
|
||||
return *scheme == '\0';
|
||||
}
|
||||
|
||||
/* Pick apart a URI into its basic parts.
|
||||
*
|
||||
* uri := scheme ":" hierarchical [ "?" query ] [ "#" fragment ]
|
||||
|
@ -49,13 +49,13 @@ static inline char stripe(int i)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
argv0 = argv[0];
|
||||
long long size = 0;
|
||||
uint64_t size = 0;
|
||||
const char *label = "";
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
const char *arg = argv[i];
|
||||
if (str_startswith(arg, "--size=", &arg)) {
|
||||
if (!str_to_ll_scaled(arg, 10, &size, NULL) || size < 0)
|
||||
if (!str_to_uint64_scaled(arg, 10, &size, NULL) || size < 0)
|
||||
fatal("illegal --size= argument: %s", arg);
|
||||
}
|
||||
else if (str_startswith(arg, "--label=", &arg))
|
||||
@ -63,7 +63,7 @@ int main(int argc, char **argv)
|
||||
else
|
||||
fatal("unrecognised argument: %s", arg);
|
||||
}
|
||||
long long offset = 0;
|
||||
uint64_t offset = 0;
|
||||
char buf[127];
|
||||
for (i = 0; i != sizeof buf; ++i)
|
||||
buf[i] = stripe(i);
|
||||
|
Loading…
x
Reference in New Issue
Block a user