Conversion functions
This commit is contained in:
@@ -1,6 +1,47 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "malunal/strview.h"
|
||||
|
||||
#define STRVIEW_NUMBUF_SIZE 64
|
||||
|
||||
static
|
||||
malunal_cstr_t
|
||||
describe(malunal_int32_t code) {
|
||||
switch (code) {
|
||||
case STRVIEW_ERROR_NULL_INPUT:
|
||||
return "String view input was null.";
|
||||
case STRVIEW_ERROR_OUT_OF_RANGE:
|
||||
return "Conversion of string view to value was out of range.";
|
||||
case STRVIEW_ERROR_UNCONSUMED:
|
||||
return "String view was not consumed fully during conversion.";
|
||||
}
|
||||
|
||||
return "Unknown strview error";
|
||||
}
|
||||
|
||||
const error_domain_t ERROR_DOMAIN_STRVIEW_T = {
|
||||
.describe = &describe,
|
||||
.name = "malunal.strview.error"
|
||||
};
|
||||
|
||||
static malunal_size_t
|
||||
strview__copy_to_buffer(
|
||||
strview_iptr_t self,
|
||||
malunal_char_t buffer[STRVIEW_NUMBUF_SIZE]
|
||||
) {
|
||||
malunal_size_t length = strview_length(self);
|
||||
malunal_size_t copied =
|
||||
length >= STRVIEW_NUMBUF_SIZE - 1
|
||||
? STRVIEW_NUMBUF_SIZE - 1
|
||||
: length;
|
||||
|
||||
if (copied > 0)
|
||||
memcpy(buffer, self->beg, copied);
|
||||
buffer[copied] = '\0';
|
||||
return copied;
|
||||
}
|
||||
|
||||
|
||||
strview_t
|
||||
strview(
|
||||
@@ -178,3 +219,97 @@ strview_contains(
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
error_t
|
||||
strview_to_int64(
|
||||
strview_iptr_t self,
|
||||
malunal_int64_t* out
|
||||
) {
|
||||
if (self == null) {
|
||||
if (out != null)
|
||||
*out = 0;
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_NULL_INPUT
|
||||
};
|
||||
}
|
||||
|
||||
malunal_char_t buffer[STRVIEW_NUMBUF_SIZE];
|
||||
malunal_size_t copied = strview__copy_to_buffer(self, buffer);
|
||||
if (copied == 0) {
|
||||
if (out != null)
|
||||
*out = 0;
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_UNCONSUMED
|
||||
};
|
||||
}
|
||||
|
||||
malunal_str_t endptr;
|
||||
malunal_int64_t value;
|
||||
|
||||
errno = 0;
|
||||
value = strtoll(buffer, &endptr, 10);
|
||||
if (out != null)
|
||||
*out = value;
|
||||
|
||||
if (errno == ERANGE)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_OUT_OF_RANGE
|
||||
};
|
||||
|
||||
return endptr != buffer + copied
|
||||
? (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_UNCONSUMED
|
||||
}
|
||||
: NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
strview_to_double(
|
||||
strview_iptr_t self,
|
||||
malunal_double_t* out
|
||||
) {
|
||||
if (self == null) {
|
||||
if (out != null)
|
||||
*out = 0.0;
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_NULL_INPUT
|
||||
};
|
||||
}
|
||||
|
||||
malunal_char_t buffer[STRVIEW_NUMBUF_SIZE];
|
||||
malunal_size_t copied = strview__copy_to_buffer(self, buffer);
|
||||
if (copied == 0) {
|
||||
if (out != null)
|
||||
*out = 0.0;
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_UNCONSUMED
|
||||
};
|
||||
}
|
||||
|
||||
malunal_str_t endptr;
|
||||
malunal_double_t value;
|
||||
|
||||
errno = 0;
|
||||
value = strtod(buffer, &endptr);
|
||||
if (out != null)
|
||||
*out = value;
|
||||
|
||||
if (errno == ERANGE)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_OUT_OF_RANGE
|
||||
};
|
||||
|
||||
return endptr != buffer + copied
|
||||
? (error_t) {
|
||||
.domain = &ERROR_DOMAIN_STRVIEW_T,
|
||||
.code = STRVIEW_ERROR_UNCONSUMED
|
||||
}
|
||||
: NO_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user