fx: add wstr and wchar value types
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef CSTR_H_
|
||||||
|
#define CSTR_H_
|
||||||
|
|
||||||
|
#include <fx/status.h>
|
||||||
|
#include <fx/value.h>
|
||||||
|
|
||||||
|
extern fx_status cstr_to_char(const char *in, fx_wchar *out);
|
||||||
|
|
||||||
|
extern fx_status cstr_to_bool(const char *in, bool *out);
|
||||||
|
extern fx_status cstr_to_i16(const char *in, i16 *out);
|
||||||
|
extern fx_status cstr_to_u16(const char *in, u16 *out);
|
||||||
|
extern fx_status cstr_to_i32(const char *in, i32 *out);
|
||||||
|
extern fx_status cstr_to_u32(const char *in, u32 *out);
|
||||||
|
extern fx_status cstr_to_i64(const char *in, i64 *out);
|
||||||
|
extern fx_status cstr_to_u64(const char *in, u64 *out);
|
||||||
|
extern fx_status cstr_to_iptr(const char *in, iptr *out);
|
||||||
|
extern fx_status cstr_to_uptr(const char *in, uptr *out);
|
||||||
|
|
||||||
|
extern fx_status cstr_to_sbyte(const char *in, sbyte *out);
|
||||||
|
extern fx_status cstr_to_byte(const char *in, byte *out);
|
||||||
|
extern fx_status cstr_to_short(const char *in, short *out);
|
||||||
|
extern fx_status cstr_to_ushort(const char *in, unsigned short *out);
|
||||||
|
extern fx_status cstr_to_int(const char *in, int *out);
|
||||||
|
extern fx_status cstr_to_uint(const char *in, unsigned int *out);
|
||||||
|
extern fx_status cstr_to_long(const char *in, long *out);
|
||||||
|
extern fx_status cstr_to_ulong(const char *in, unsigned long *out);
|
||||||
|
extern fx_status cstr_to_longlong(const char *in, long long *out);
|
||||||
|
extern fx_status cstr_to_ulonglong(const char *in, unsigned long long *out);
|
||||||
|
extern fx_status cstr_to_size(const char *in, size_t *out);
|
||||||
|
|
||||||
|
extern fx_status cstr_to_float(const char *in, float *out);
|
||||||
|
extern fx_status cstr_to_double(const char *in, double *out);
|
||||||
|
extern fx_status cstr_to_cstr(const char *in, const char **out);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef FX_WSTR_H_
|
||||||
|
#define FX_WSTR_H_
|
||||||
|
|
||||||
|
#include <fx/encoding.h>
|
||||||
|
#include <fx/macros.h>
|
||||||
|
|
||||||
|
FX_DECLS_BEGIN;
|
||||||
|
|
||||||
|
#define FX_TYPE_WCHAR (fx_wchar_get_type())
|
||||||
|
#define FX_TYPE_WSTR (fx_wstr_get_type())
|
||||||
|
|
||||||
|
typedef struct _fx_wchar_class fx_wchar_class;
|
||||||
|
typedef struct _fx_wstr_class fx_wstr_class;
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_wchar)
|
||||||
|
FX_TYPE_CLASS_DECLARATION_END(fx_wchar)
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_wstr)
|
||||||
|
FX_TYPE_CLASS_DECLARATION_END(fx_wstr)
|
||||||
|
|
||||||
|
FX_API fx_type_id fx_wchar_get_type(void);
|
||||||
|
FX_API fx_type_id fx_wstr_get_type(void);
|
||||||
|
|
||||||
|
FX_API int fx_wstrcmp(const fx_wchar *a, const fx_wchar *b);
|
||||||
|
FX_API int fx_wastrcmp(const char *a, const fx_wchar *b);
|
||||||
|
FX_API fx_wchar *fx_wstrdup(const fx_wchar *s);
|
||||||
|
FX_API size_t fx_wstrlen(const fx_wchar *s);
|
||||||
|
FX_API size_t fx_wstrcspn(const fx_wchar *dest, const fx_wchar *src);
|
||||||
|
|
||||||
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
#endif
|
||||||
+257
@@ -0,0 +1,257 @@
|
|||||||
|
#include <ctype.h>
|
||||||
|
#include <fx/comparable.h>
|
||||||
|
#include <fx/convertible.h>
|
||||||
|
#include <fx/hash.h>
|
||||||
|
#include <fx/operable.h>
|
||||||
|
#include <fx/stream.h>
|
||||||
|
#include <fx/value-type.h>
|
||||||
|
#include <fx/value.h>
|
||||||
|
#include <fx/wstr.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
static fx_status to_string(
|
||||||
|
const fx_value *v,
|
||||||
|
fx_stream *out,
|
||||||
|
const char *format)
|
||||||
|
{
|
||||||
|
const fx_wchar s[] = {v->v_wchar, 0};
|
||||||
|
return fx_stream_write_wstr(out, s, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static i32 compare(const fx_value *left, const fx_value *right)
|
||||||
|
{
|
||||||
|
fx_wchar s;
|
||||||
|
if (!FX_OK(fx_value_get_wchar(right, &s))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memcmp(&left->v_wchar, &s, sizeof s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fx_status hash(const fx_value *v, uint64_t *out_hash)
|
||||||
|
{
|
||||||
|
*out_hash = v->v_wchar;
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_char(fx_wchar in, fx_wchar *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_bool(fx_wchar in, bool *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_i16(fx_wchar in, i16 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_u16(fx_wchar in, u16 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_i32(fx_wchar in, i32 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_u32(fx_wchar in, u32 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_i64(fx_wchar in, i64 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_u64(fx_wchar in, u64 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_iptr(fx_wchar in, iptr *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_uptr(fx_wchar in, uptr *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_sbyte(fx_wchar in, sbyte *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_byte(fx_wchar in, byte *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_short(fx_wchar in, short *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_ushort(fx_wchar in, unsigned short *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_int(fx_wchar in, int *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_uint(fx_wchar in, unsigned int *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_long(fx_wchar in, long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_ulong(fx_wchar in, unsigned long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_longlong(fx_wchar in, long long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_ulonglong(fx_wchar in, unsigned long long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_size(fx_wchar in, size_t *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_float(fx_wchar in, float *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_double(fx_wchar in, double *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wchar_to_wchar(fx_wchar in, fx_wchar *out)
|
||||||
|
{
|
||||||
|
*out = in;
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WCHAR_CONVERTER(fx_type, c_type) \
|
||||||
|
static fx_status to_##fx_type(const fx_value *in, c_type *out) \
|
||||||
|
{ \
|
||||||
|
fx_wchar s = FX_WCHAR_INVALID; \
|
||||||
|
fx_value_get_wchar(in, &s); \
|
||||||
|
return wchar_to_##fx_type(s, out); \
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR_CONVERTER(bool, bool)
|
||||||
|
WCHAR_CONVERTER(i16, i16)
|
||||||
|
WCHAR_CONVERTER(u16, u16)
|
||||||
|
WCHAR_CONVERTER(i32, i32)
|
||||||
|
WCHAR_CONVERTER(u32, u32)
|
||||||
|
WCHAR_CONVERTER(i64, i64)
|
||||||
|
WCHAR_CONVERTER(u64, u64)
|
||||||
|
WCHAR_CONVERTER(iptr, iptr)
|
||||||
|
WCHAR_CONVERTER(uptr, uptr)
|
||||||
|
WCHAR_CONVERTER(sbyte, sbyte)
|
||||||
|
WCHAR_CONVERTER(byte, byte)
|
||||||
|
WCHAR_CONVERTER(short, short)
|
||||||
|
WCHAR_CONVERTER(ushort, unsigned short)
|
||||||
|
WCHAR_CONVERTER(int, int)
|
||||||
|
WCHAR_CONVERTER(uint, unsigned int)
|
||||||
|
WCHAR_CONVERTER(long, long)
|
||||||
|
WCHAR_CONVERTER(ulong, unsigned long)
|
||||||
|
WCHAR_CONVERTER(longlong, long long)
|
||||||
|
WCHAR_CONVERTER(ulonglong, unsigned long long)
|
||||||
|
WCHAR_CONVERTER(size, size_t)
|
||||||
|
WCHAR_CONVERTER(float, float)
|
||||||
|
WCHAR_CONVERTER(double, double)
|
||||||
|
|
||||||
|
static fx_status add(const fx_value *l, const fx_value *r, fx_value *out)
|
||||||
|
{
|
||||||
|
fx_wchar left = l->v_wchar;
|
||||||
|
fx_wchar right = r->v_wchar;
|
||||||
|
fx_string *result = fx_string_create();
|
||||||
|
if (!result) {
|
||||||
|
return FX_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_string_append_wc(result, left);
|
||||||
|
fx_string_append_wc(result, right);
|
||||||
|
*out = FX_VALUE_OBJECT(result);
|
||||||
|
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_BEGIN(fx_wchar)
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||||
|
FX_INTERFACE_ENTRY(to_string) = to_string;
|
||||||
|
FX_INTERFACE_ENTRY(hash) = hash;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_operable, FX_TYPE_OPERABLE)
|
||||||
|
FX_INTERFACE_ENTRY(op_add) = add;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_operable, FX_TYPE_OPERABLE)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_comparable, FX_TYPE_COMPARABLE)
|
||||||
|
FX_INTERFACE_ENTRY(c_compare) = compare;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_comparable, FX_TYPE_COMPARABLE)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_convertible, FX_TYPE_CONVERTIBLE)
|
||||||
|
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_i16) = to_i16;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u16) = to_u16;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u32) = to_u32;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_i64) = to_i64;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u64) = to_u64;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_iptr) = to_iptr;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_uptr) = to_uptr;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_sbyte) = to_sbyte;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_byte) = to_byte;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_short) = to_short;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ushort) = to_ushort;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_int) = to_int;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_uint) = to_uint;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_long) = to_long;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ulong) = to_ulong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_longlong) = to_longlong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ulonglong) = to_ulonglong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_size) = to_size;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_float) = to_float;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_double) = to_double;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_convertible, FX_TYPE_CONVERTIBLE)
|
||||||
|
FX_TYPE_CLASS_END(fx_wchar)
|
||||||
|
|
||||||
|
FX_TYPE_DEFINITION_BEGIN(fx_wchar)
|
||||||
|
__FX_VALUE_TYPE_ID(WCHAR);
|
||||||
|
FX_TYPE_EXTENDS(FX_TYPE_VALUE_TYPE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_CONVERTIBLE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_OPERABLE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_COMPARABLE);
|
||||||
|
FX_TYPE_NAME("fx.wchar");
|
||||||
|
FX_TYPE_CLASS(fx_wchar_class);
|
||||||
|
FX_TYPE_INSTANCE_PRIVATE(char *);
|
||||||
|
FX_TYPE_DEFINITION_END(fx_wchar)
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
#include <ctype.h>
|
||||||
|
#include <fx/comparable.h>
|
||||||
|
#include <fx/convertible.h>
|
||||||
|
#include <fx/hash.h>
|
||||||
|
#include <fx/operable.h>
|
||||||
|
#include <fx/stream.h>
|
||||||
|
#include <fx/value-type.h>
|
||||||
|
#include <fx/value.h>
|
||||||
|
#include <fx/wstr.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
static fx_status to_string(
|
||||||
|
const fx_value *v,
|
||||||
|
fx_stream *out,
|
||||||
|
const char *format)
|
||||||
|
{
|
||||||
|
return fx_stream_write_fmt(out, NULL, "%s", v->v_wstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static i32 compare(const fx_value *left, const fx_value *right)
|
||||||
|
{
|
||||||
|
const fx_wchar *s;
|
||||||
|
if (!FX_OK(fx_value_get_wstr(right, &s))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fx_wstrcmp(left->v_wstr, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fx_status hash(const fx_value *v, uint64_t *out_hash)
|
||||||
|
{
|
||||||
|
*out_hash = fx_hash_wstr(v->v_wstr);
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_char(const fx_wchar *in, fx_wchar *out)
|
||||||
|
{
|
||||||
|
if (in[0] == '\0' || in[1] == '\0') {
|
||||||
|
*out = in[0];
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FX_ERR_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_bool(const fx_wchar *in, bool *out)
|
||||||
|
{
|
||||||
|
if (!fx_wstrcmp(in, L"1") || !fx_wstrcmp(in, L"true")
|
||||||
|
|| fx_wstrcmp(in, L"True")) {
|
||||||
|
*out = true;
|
||||||
|
return FX_SUCCESS;
|
||||||
|
} else if (
|
||||||
|
!fx_wstrcmp(in, L"0") || !fx_wstrcmp(in, L"false")
|
||||||
|
|| fx_wstrcmp(in, L"False")) {
|
||||||
|
*out = false;
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FX_ERR_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_i16(const fx_wchar *in, i16 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_u16(const fx_wchar *in, u16 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_i32(const fx_wchar *in, i32 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_u32(const fx_wchar *in, u32 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_i64(const fx_wchar *in, i64 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_u64(const fx_wchar *in, u64 *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_iptr(const fx_wchar *in, iptr *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_uptr(const fx_wchar *in, uptr *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_sbyte(const fx_wchar *in, sbyte *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_byte(const fx_wchar *in, byte *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_short(const fx_wchar *in, short *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_ushort(const fx_wchar *in, unsigned short *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_int(const fx_wchar *in, int *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_uint(const fx_wchar *in, unsigned int *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_long(const fx_wchar *in, long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_ulong(const fx_wchar *in, unsigned long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_longlong(const fx_wchar *in, long long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_ulonglong(const fx_wchar *in, unsigned long long *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_size(const fx_wchar *in, size_t *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_float(const fx_wchar *in, float *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_double(const fx_wchar *in, double *out)
|
||||||
|
{
|
||||||
|
return FX_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_status wstr_to_wstr(const fx_wchar *in, const fx_wchar **out)
|
||||||
|
{
|
||||||
|
*out = in;
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WSTR_CONVERTER(fx_type, c_type) \
|
||||||
|
static fx_status to_##fx_type(const fx_value *in, c_type *out) \
|
||||||
|
{ \
|
||||||
|
const fx_wchar *s = NULL; \
|
||||||
|
fx_value_get_wstr(in, &s); \
|
||||||
|
return wstr_to_##fx_type(s, out); \
|
||||||
|
}
|
||||||
|
|
||||||
|
WSTR_CONVERTER(bool, bool)
|
||||||
|
WSTR_CONVERTER(i16, i16)
|
||||||
|
WSTR_CONVERTER(u16, u16)
|
||||||
|
WSTR_CONVERTER(i32, i32)
|
||||||
|
WSTR_CONVERTER(u32, u32)
|
||||||
|
WSTR_CONVERTER(i64, i64)
|
||||||
|
WSTR_CONVERTER(u64, u64)
|
||||||
|
WSTR_CONVERTER(iptr, iptr)
|
||||||
|
WSTR_CONVERTER(uptr, uptr)
|
||||||
|
WSTR_CONVERTER(sbyte, sbyte)
|
||||||
|
WSTR_CONVERTER(byte, byte)
|
||||||
|
WSTR_CONVERTER(short, short)
|
||||||
|
WSTR_CONVERTER(ushort, unsigned short)
|
||||||
|
WSTR_CONVERTER(int, int)
|
||||||
|
WSTR_CONVERTER(uint, unsigned int)
|
||||||
|
WSTR_CONVERTER(long, long)
|
||||||
|
WSTR_CONVERTER(ulong, unsigned long)
|
||||||
|
WSTR_CONVERTER(longlong, long long)
|
||||||
|
WSTR_CONVERTER(ulonglong, unsigned long long)
|
||||||
|
WSTR_CONVERTER(size, size_t)
|
||||||
|
WSTR_CONVERTER(float, float)
|
||||||
|
WSTR_CONVERTER(double, double)
|
||||||
|
WSTR_CONVERTER(wstr, const fx_wchar *)
|
||||||
|
|
||||||
|
static fx_status add(const fx_value *l, const fx_value *r, fx_value *out)
|
||||||
|
{
|
||||||
|
const fx_wchar *left = l->v_wstr;
|
||||||
|
const fx_wchar *right = r->v_wstr;
|
||||||
|
fx_string *result = fx_string_create();
|
||||||
|
if (!result) {
|
||||||
|
return FX_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_string_append_wstr(result, left);
|
||||||
|
fx_string_append_wstr(result, right);
|
||||||
|
*out = FX_VALUE_OBJECT(result);
|
||||||
|
|
||||||
|
return FX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_BEGIN(fx_wstr)
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||||
|
FX_INTERFACE_ENTRY(to_string) = to_string;
|
||||||
|
FX_INTERFACE_ENTRY(hash) = hash;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_operable, FX_TYPE_OPERABLE)
|
||||||
|
FX_INTERFACE_ENTRY(op_add) = add;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_operable, FX_TYPE_OPERABLE)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_comparable, FX_TYPE_COMPARABLE)
|
||||||
|
FX_INTERFACE_ENTRY(c_compare) = compare;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_comparable, FX_TYPE_COMPARABLE)
|
||||||
|
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_convertible, FX_TYPE_CONVERTIBLE)
|
||||||
|
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_bool) = to_bool;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_i16) = to_i16;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u16) = to_u16;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u32) = to_u32;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_i64) = to_i64;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_u64) = to_u64;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_iptr) = to_iptr;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_uptr) = to_uptr;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_sbyte) = to_sbyte;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_byte) = to_byte;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_short) = to_short;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ushort) = to_ushort;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_int) = to_int;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_uint) = to_uint;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_long) = to_long;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ulong) = to_ulong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_longlong) = to_longlong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_ulonglong) = to_ulonglong;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_size) = to_size;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_float) = to_float;
|
||||||
|
FX_INTERFACE_ENTRY(c_to_double) = to_double;
|
||||||
|
FX_TYPE_VTABLE_INTERFACE_END(fx_convertible, FX_TYPE_CONVERTIBLE)
|
||||||
|
FX_TYPE_CLASS_END(fx_wstr)
|
||||||
|
|
||||||
|
FX_TYPE_DEFINITION_BEGIN(fx_wstr)
|
||||||
|
__FX_VALUE_TYPE_ID(WSTR);
|
||||||
|
FX_TYPE_EXTENDS(FX_TYPE_VALUE_TYPE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_CONVERTIBLE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_OPERABLE);
|
||||||
|
FX_TYPE_IMPLEMENTS(FX_TYPE_COMPARABLE);
|
||||||
|
FX_TYPE_NAME("fx.wstr");
|
||||||
|
FX_TYPE_CLASS(fx_wstr_class);
|
||||||
|
FX_TYPE_INSTANCE_PRIVATE(char *);
|
||||||
|
FX_TYPE_DEFINITION_END(fx_wstr)
|
||||||
|
|
||||||
|
/*** MISC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
int fx_wstrcmp(const fx_wchar *a, const fx_wchar *b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; a[i] == b[i]; i++)
|
||||||
|
if (a[i] == '\0')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return a[i] - b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int fx_wastrcmp(const char *a, const fx_wchar *b)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
fx_wchar ch_a = fx_wchar_utf8_codepoint_decode(a);
|
||||||
|
fx_wchar ch_b = *b;
|
||||||
|
|
||||||
|
if (!ch_a && !ch_b) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch_a != ch_b) {
|
||||||
|
return ch_a - ch_b;
|
||||||
|
}
|
||||||
|
|
||||||
|
a += fx_wchar_utf8_codepoint_stride(a);
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_wchar *fx_wstrdup(const fx_wchar *s)
|
||||||
|
{
|
||||||
|
size_t len = fx_wstrlen(s);
|
||||||
|
fx_wchar *buf = calloc(len + 1, sizeof(fx_wchar));
|
||||||
|
if (!buf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, s, len * sizeof(fx_wchar));
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fx_wstrlen(const fx_wchar *s)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
for (len = 0; s[len] != 0; len++)
|
||||||
|
;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fx_wstrcspn(const fx_wchar *dest, const fx_wchar *src)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
for (i = 0; dest[i]; i++) {
|
||||||
|
for (size_t ii = 0; src[ii]; ii++) {
|
||||||
|
if (dest[i] == src[ii]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user