📄 gbx_value.c
字号:
/*************************************************************************** value.c Datatype management routines. Conversions between each Gambas datatype, and conversions between Gambas datatypes and native datatypes. (c) 2000-2004 Beno� Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#include "gb_common.h"#include "gb_common_case.h"#include <float.h>#include <math.h>#include "gbx_math.h"#include "gbx_type.h"#include "gbx_array.h"#include "gbx_string.h"#include "gbx_number.h"#include "gbx_object.h"#include "gbx_variant.h"#include "gbx_date.h"#include "gbx_exec.h"#include "gbx_local.h"#include "gb_common_buffer.h"#include "gbx_value.h"PUBLIC void VALUE_default(VALUE *value, TYPE type){ static void *jump[16] = { &&__VOID, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__FLOAT, &&__DATE, &&__STRING, &&__STRING, &&__VARIANT, &&__ARRAY, &&__STRUCT, &&__FUNCTION, &&__CLASS, &&__NULL }; value->type = type; if (TYPE_is_object(type)) goto __OBJECT; else goto *jump[type];__BOOLEAN:__BYTE:__SHORT:__INTEGER: value->_integer.value = 0; return;__FLOAT: value->_float.value = 0; return;__STRING: value->_string.addr = NULL; value->_string.start = 0; value->_string.len = 0; return;__VARIANT: value->_variant.vtype = T_NULL; return;__DATE: value->_date.date = 0; value->_date.time = 0; return;__VOID: return;__OBJECT: value->_object.class = (CLASS *)type; value->_object.object = NULL; return;__LONG:__ARRAY:__STRUCT:__FUNCTION:__CLASS:__NULL: ERROR_panic("VALUE_default: Unknown default type");}PUBLIC void VALUE_convert(VALUE *value, TYPE type){ static void *jump[16][16] = { /* void b c h i l f d cs s v array struct func class n */ /* void */ { &&__OK, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, &&__NR, }, /* b */ { &&__N, &&__OK, &&__b2c, &&__b2h, &&__TYPE, &&__N, &&__b2f, &&__N, &&__b2s, &&__b2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* c */ { &&__N, &&__c2b, &&__OK, &&__c2h, &&__TYPE, &&__N, &&__c2f, &&__c2d, &&__c2s, &&__c2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* h */ { &&__N, &&__h2b, &&__h2c, &&__OK, &&__TYPE, &&__N, &&__h2f, &&__h2d, &&__h2s, &&__h2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* i */ { &&__N, &&__i2b, &&__i2c, &&__i2h, &&__OK, &&__N, &&__i2f, &&__i2d, &&__i2s, &&__i2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* l */ { &&__N, &&__N, &&__N, &&__N, &&__N, &&__OK, &&__N, &&__N, &&__N, &&__N, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* f */ { &&__N, &&__f2b, &&__f2c, &&__f2h, &&__f2i, &&__N, &&__OK, &&__f2d, &&__f2s, &&__f2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* d */ { &&__N, &&__N, &&__d2c, &&__d2h, &&__d2i, &&__N, &&__d2f, &&__OK, &&__d2s, &&__d2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* cs */ { &&__N, &&__s2b, &&__s2c, &&__s2h, &&__s2i, &&__N, &&__s2f, &&__s2d, &&__OK, &&__OK, &&__s2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* s */ { &&__N, &&__s2b, &&__s2c, &&__s2h, &&__s2i, &&__N, &&__s2f, &&__s2d, &&__OK, &&__OK, &&__s2v, &&__N, &&__N, &&__N, &&__N, &&__N, }, /* v */ { &&__N, &&__v2, &&__v2, &&__v2, &&__v2, &&__N, &&__v2, &&__v2, &&__v2, &&__v2, &&__OK, &&__N, &&__N, &&__N, &&__N, &&__v2, }, /* array */ { &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__OK, &&__N, &&__N, &&__N, &&__N, }, /* struct */ { &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__OK, &&__N, &&__N, &&__N, }, /* func */ { &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__OK, &&__N, &&__N, }, /* class */ { &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__OK, &&__N, }, /* null */ { &&__N, &&__n2b, &&__N, &&__N, &&__N, &&__N, &&__N, &&__N, &&__n2s, &&__n2s, &&__2v, &&__N, &&__N, &&__N, &&__N, &&__OK, }, }; long len; char *addr; long index; CLASS *class; boolean test;__CONV: if ((type | value->type) >> 4) goto __OBJECT; else goto *jump[value->type][type];__c2b:__h2b:__i2b: value->_integer.value = (value->_integer.value != 0) ? -1 : 0; goto __TYPE;__f2b: value->_integer.value = (value->_float.value != 0) ? -1 : 0; goto __TYPE;__b2c:__h2c:__i2c: value->_integer.value = (unsigned char)value->_integer.value; goto __TYPE;__f2c: value->_integer.value = (unsigned char)value->_float.value; goto __TYPE;__b2h:__c2h:__i2h: value->_integer.value = (short)value->_integer.value; goto __TYPE;__f2h: value->_integer.value = (short)value->_float.value; goto __TYPE;__f2i: value->_integer.value = (long)value->_float.value; goto __TYPE;__b2f:__c2f:__h2f:__i2f: value->_float.value = value->_integer.value; goto __TYPE;__c2d:__h2d:__i2d: value->_date.date = Max(0, value->_integer.value); value->_date.time = 0; goto __TYPE;__f2d: index = (long)fix(value->_float.value); value->_date.time = (long)((value->_float.value - index) * 86400000.0 + 0.5); value->_date.date = index; goto __TYPE;__d2c:__d2h:__d2i: value->_integer.value = value->_date.date; value->type = T_INTEGER; goto *jump[T_INTEGER][type];__d2f: value->_float.value = (double)value->_date.date + (double)value->_date.time / 86400000.0; goto __TYPE;__b2s: if (value->_boolean.value) STRING_char_value(value, 'T'); else STRING_void_value(value); return;__c2s:__h2s:__i2s: len = sprintf(COMMON_buffer, "%ld", value->_integer.value); STRING_new_temp_value(value, COMMON_buffer, len); BORROW(value); return;__f2s: LOCAL_format_number(value->_float.value, LF_GENERAL_NUMBER, NULL, 0, &addr, &len, FALSE); STRING_new_temp_value(value, addr, len); BORROW(value); return;__d2s: len = DATE_to_string(COMMON_buffer, value); STRING_new_temp_value(value, COMMON_buffer, len); BORROW(value); return;__s2b: addr = value->_string.addr; value->_integer.value = ((addr != NULL) && (value->_string.len != 0)) ? -1 : 0; if (value->type == T_STRING) STRING_unref(&addr); goto __TYPE;__s2c:__s2h:__s2i: addr = value->type == T_STRING ? value->_string.addr : NULL; if (NUMBER_from_string(NB_READ_INTEGER, value->_string.addr + value->_string.start, value->_string.len, value)) goto __N; STRING_unref(&addr); goto *jump[T_INTEGER][type];__s2f: addr = value->type == T_STRING ? value->_string.addr : NULL; if (NUMBER_from_string(NB_READ_FLOAT, value->_string.addr + value->_string.start, value->_string.len, value)) goto __N; STRING_unref(&addr); return;__s2d: addr = value->type == T_STRING ? value->_string.addr : NULL; if (DATE_from_string(value->_string.addr + value->_string.start, value->_string.len, value, FALSE)) goto __N; STRING_unref(&addr); return;__n2b: value->_integer.value = 0; goto __TYPE;__n2s: STRING_void_value(value); return;__v2: /* ATTENTION ! VALUE_read sert normalement �lire un stockage en m�oire. On le d�ourne ici pour convertir le variant. Mais si le variant contient un T_STRING, � doit rester un T_STRING ! */ index = value->_variant.vtype; if (index != T_NULL) VALUE_read(value, &value->_variant.value, value->_variant.vtype); value->type = index; goto __CONV;__s2v: STRING_copy_from_value_temp(&addr, value); if (addr != value->_string.addr) { STRING_ref(addr); if (value->type == T_STRING) STRING_unref(&value->_string.addr); } *((char **)value->_variant.value) = addr; value->_variant.vtype = T_STRING; goto __TYPE;__2v: /* VALUE_put ne fonctionne pas avec T_STRING ! */ if (value->type != T_NULL) VALUE_put(value, &value->_variant.value, value->type); value->_variant.vtype = value->type; goto __TYPE;__OBJECT: if (!TYPE_is_object(type)) { if (type == T_BOOLEAN) { test = (value->_object.object != NULL); OBJECT_UNREF(&value->_object.object, "VALUE_convert"); value->_boolean.value = test ? -1 : 0; goto __TYPE; } if (type == T_VARIANT) goto __2v; goto __N; } if (!TYPE_is_object(value->type)) { if (value->type == T_NULL) { OBJECT_null(value, (CLASS *)type); /* marche aussi pour type = T_OBJECT */ goto __TYPE; } if (value->type == T_VARIANT) goto __v2; if (value->type == T_CLASS) { class = value->_class.class; CLASS_load(class); if (class->auto_create) value->_object.object = CLASS_auto_create(class, 0); else value->_object.object = class; OBJECT_REF(value->_object.object, "VALUE_convert"); value->type = T_OBJECT; /* on continue... */ } else goto __N; } if (value->type == T_OBJECT) { if (value->_object.object == NULL) goto __TYPE; class = OBJECT_class(value->_object.object); /* on continue */ } else class = value->_object.class; if (CLASS_is_virtual(class)) THROW(E_VIRTUAL); if (type == T_OBJECT) goto __TYPE;__RETRY: if ((class == (CLASS *)type) || CLASS_inherits(class, (CLASS *)type)) goto __TYPE; if (value->type != T_OBJECT && value->_object.object) { class = OBJECT_class(value->_object.object); value->type = T_OBJECT; goto __RETRY; } THROW(E_TYPE, TYPE_get_name(type), TYPE_get_name((TYPE)class));__TYPE: value->type = type;__OK: return;__N: THROW(E_TYPE, TYPE_get_name(type), TYPE_get_name(value->type));__NR: THROW(E_NRETURN);}PUBLIC void VALUE_write(VALUE *value, void *addr, TYPE type){ static void *jump[16] = { &&__VOID, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__FLOAT, &&__DATE, &&__STRING, &&__STRING, &&__VARIANT, &&__ARRAY, &&__STRUCT, &&__FUNCTION, &&__CLASS, &&__NULL }; char *str;__CONV: if (TYPE_is_object(type)) goto __OBJECT; else goto *jump[type];__BOOLEAN: VALUE_conv(value, type); *((unsigned char *)addr) = (value->_boolean.value != 0 ? 1 : 0); return;__BYTE: VALUE_conv(value, type); *((unsigned char *)addr) = (unsigned char)(value->_byte.value); return;__SHORT: VALUE_conv(value, type); *((short *)addr) = (short)(value->_short.value); return;__INTEGER: VALUE_conv(value, type); *((long *)addr) = value->_integer.value; return;__FLOAT: VALUE_conv(value, type); *((double *)addr) = value->_float.value; return;__DATE: VALUE_conv(value, type); ((long *)addr)[0] = value->_date.date; ((long *)addr)[1] = value->_date.time; return;__STRING: /* Il faut faire l'affectation en deux temps au cas o value->_string.addr == *addr ! */ VALUE_conv(value, type); STRING_copy_from_value_temp(&str, value); STRING_ref(str); STRING_unref((char **)addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -