/*************************************************************************** gbx_c_array.c The Array native classes. (c) 2000-2007 Benoit Minisini 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. ***************************************************************************/ #define __GBX_C_ARRAY_C #include "gbx_info.h" #ifndef GBX_INFO #include "gb_common.h" #include "gb_error.h" #include "gb_array.h" #include "gb_limit.h" #include "gbx_class.h" #include "gbx_exec.h" #include "gbx_date.h" #include "gbx_variant.h" #include "gbx_compare.h" #include "gbx_class.h" #include "gbx_object.h" #include "gbx_api.h" #include "gbx_print.h" #include "gbx_c_file.h" #include "gbx_c_array.h" static bool check_not_multi(CARRAY *_object) { if (THIS->dim) { GB_Error("Array is multi-dimensional"); return TRUE; } else return FALSE; } static int get_dim(CARRAY *_object) { int d; if (!THIS->dim) return 1; else { for(d = 0;; d++) { if (THIS->dim[d] < 0) return (d + 1); } } } static int get_bound(CARRAY *_object, int d) { if (!THIS->dim) return ARRAY_count(THIS); else { d = THIS->dim[d]; if (d < 0) d = (-d); return d; } } static void *get_data(CARRAY *_object, int index) { if ((index < 0) || (index >= ARRAY_count(THIS->data))) { GB_Error((char *)E_BOUND); return NULL; } return (void *)((char *)(THIS->data) + index * TYPE_sizeof_memory(THIS->type)); } static void *get_data_multi(CARRAY *_object, GB_INTEGER *arg, int nparam) { int index; //fprintf(stderr, "get_data_multi: nparam = %d\n", nparam); if (THIS->dim) { int max; int i; int d; bool stop = FALSE; index = 0; nparam--; for (i = 0;; i++) { if (i > nparam) break; max = THIS->dim[i]; if (max < 0) { max = (-max); stop = TRUE; } VALUE_conv((VALUE *)&arg[i], GB_T_INTEGER); d = arg[i].value; if (d < 0 || d >= max) { GB_Error((char *)E_BOUND); return NULL; } index *= max; index += d; if (stop) break; } if (i != nparam) { GB_Error((char *)E_NDIM); return NULL; } } else { if (nparam != 1) { GB_Error((char *)E_NDIM); return NULL; } index = arg->value; if ((index < 0) || (index >= ARRAY_count(THIS->data))) { GB_Error((char *)E_BOUND); return NULL; } } return (void *)((char *)(THIS->data) + index * TYPE_sizeof_memory(THIS->type)); } static void release_one(CARRAY *_object, int i) { switch(THIS->type) { case T_STRING: STRING_unref(&(((char **)(THIS->data))[i])); break; case T_OBJECT: OBJECT_UNREF(((void **)(THIS->data))[i], "release_one"); break; case T_VARIANT: VARIANT_free(&(((VARIANT *)(THIS->data))[i])); break; default: break; } } static void release(CARRAY *_object, int start, int end) { int i; if (end < 0) end = ARRAY_count(THIS->data); switch(THIS->type) { case T_STRING: for (i = start; i < end; i++) STRING_unref(&((char **)(THIS->data))[i]); break; case T_OBJECT: for (i = start; i < end; i++) OBJECT_UNREF(((void **)(THIS->data))[i], "release"); break; case T_VARIANT: for (i = start; i < end; i++) VARIANT_free(&((VARIANT *)(THIS->data))[i]); break; default: break; } } static void borrow(CARRAY *_object, int start, int end) { int i; if (end < 0) end = ARRAY_count(THIS->data); switch(THIS->type) { case T_STRING: for (i = start; i < end; i++) STRING_ref(((char **)(THIS->data))[i]); break; case T_OBJECT: for (i = start; i < end; i++) OBJECT_REF(((void **)(THIS->data))[i], "borrow"); break; case T_VARIANT: for (i = start; i < end; i++) VARIANT_keep(&((VARIANT *)(THIS->data))[i]); break; default: break; } } static void clear(CARRAY *_object) { release(THIS, 0, -1); if (THIS->dim) { memset(THIS->data, 0, TYPE_sizeof_memory(THIS->type) * ARRAY_count(THIS->data)); } else { ARRAY_delete(&THIS->data); ARRAY_create_with_size(&THIS->data, TYPE_sizeof_memory(THIS->type), 8); } } static void *insert(CARRAY *_object, int index) { return ARRAY_insert(&THIS->data, index); } void CARRAY_get_value(CARRAY *_object, int index, VALUE *value) { VALUE_read(value, get_data(THIS, index), THIS->type); } BEGIN_METHOD(CARRAY_new, GB_INTEGER size) TYPE type; CLASS *klass; int size; int inc; GB_INTEGER *sizes = ARG(size); int nsize = GB_NParam() + 1; int i; klass = OBJECT_class(THIS); if (klass == CLASS_IntegerArray) type = T_INTEGER; else if (klass == CLASS_ShortArray) type = T_SHORT; else if (klass == CLASS_BooleanArray) type = T_BOOLEAN; else if (klass == CLASS_ByteArray) type = T_BYTE; else if (klass == CLASS_LongArray) type = T_LONG; else if (klass == CLASS_SingleArray) type = T_SINGLE; else if (klass == CLASS_FloatArray) type = T_FLOAT; else if (klass == CLASS_DateArray) type = T_DATE; else if (klass == CLASS_StringArray) type = T_STRING; else if (klass == CLASS_VariantArray) type = T_VARIANT; else if (klass == CLASS_ObjectArray) type = T_OBJECT; else if (klass == CLASS_PointerArray) type = T_POINTER; else { GB_Error("Bad array type"); return; } //printf("CARRAY_new: type = %d nsize = %d\n", type, nsize); THIS->type = type; if (nsize <= 1) { size = VARGOPT(size, 0); if (size < 0) size = 0; inc = (size / 8) & ~7; if (inc < 8) inc = 8; ARRAY_create_with_size(&THIS->data, TYPE_sizeof_memory(type), inc); if (size > 0) ARRAY_add_many_void(&THIS->data, size); } else { if (nsize > MAX_ARRAY_DIM) { GB_Error("Too many dimensions"); return; } size = 1; for (i = 0; i < nsize; i++) { VALUE_conv((VALUE *)&sizes[i], T_INTEGER); if (sizes[i].value < 1) { GB_Error("Bad dimension"); return; } size *= sizes[i].value; } ALLOC_ZERO(&THIS->dim, nsize * sizeof(int), "CARRAY_new"); for (i = 0; i < nsize; i++) THIS->dim[i] = sizes[i].value; THIS->dim[nsize - 1] = (-THIS->dim[nsize - 1]); ARRAY_create_with_size(&THIS->data, TYPE_sizeof_memory(type), 8); ARRAY_add_many_void(&THIS->data, size); } END_METHOD BEGIN_PROPERTY(CARRAY_type) GB_ReturnInteger(THIS->type); END_PROPERTY BEGIN_METHOD_VOID(CARRAY_free) release(THIS, 0, -1); ARRAY_delete(&THIS->data); if (THIS->dim) FREE(&THIS->dim, "CARRAY_free"); END_METHOD BEGIN_METHOD_VOID(CARRAY_clear) clear(THIS); END_METHOD BEGIN_PROPERTY(CARRAY_data) GB_ReturnPointer(THIS->data); END_PROPERTY BEGIN_PROPERTY(CARRAY_count) GB_ReturnInt(ARRAY_count(THIS->data)); END_PROPERTY BEGIN_PROPERTY(CARRAY_max) GB_ReturnInt(ARRAY_count(THIS->data) - 1); END_PROPERTY static bool copy_remove(CARRAY *_object, int start, int length, bool copy, bool remove) { CARRAY *array; int count = ARRAY_count(THIS->data); void *data; int i, nsize; if (check_not_multi(THIS) && (start != 0 || length != -1)) return TRUE; if (start < 0) { GB_Error((char *)E_BOUND); return TRUE; } if (start >= count) length = 0; if (length == -1) length = count - start; if (length < 0 || (start + length) > count) { GB_Error((char *)E_BOUND); return TRUE; } if (copy) { GB_ArrayNew((GB_ARRAY *)POINTER(&array), THIS->type, 0); if (length > 0) { data = ARRAY_insert_many(&array->data, 0, length); memmove(data, get_data(THIS, start), length * TYPE_sizeof_memory(THIS->type)); borrow(array, 0, -1); } if (THIS->dim) { nsize = get_dim(THIS); ALLOC_ZERO(&array->dim, nsize * sizeof(int), "copy_remove"); for (i = 0; i < nsize; i++) array->dim[i] = THIS->dim[i]; } } if (remove) { release(THIS, start, start + length); ARRAY_remove_many(&THIS->data, start, length); } if (copy) GB_ReturnObject(array); return FALSE; } BEGIN_METHOD(CARRAY_remove, GB_INTEGER index; GB_INTEGER length) copy_remove(THIS, VARG(index), VARGOPT(length, 1), FALSE, TRUE); END_METHOD BEGIN_METHOD(CARRAY_copy, GB_INTEGER start; GB_INTEGER length) int start, length; if (MISSING(start) && MISSING(length)) { start = 0; length = -1; } else { start = VARGOPT(start, 0); length = VARGOPT(length, 1); } copy_remove(THIS, start, length, TRUE, FALSE); END_METHOD BEGIN_METHOD(CARRAY_extract, GB_INTEGER start; GB_INTEGER length) copy_remove(THIS, VARG(start), VARGOPT(length, 1), TRUE, TRUE); END_METHOD BEGIN_METHOD(CARRAY_resize, GB_INTEGER size) int size = VARG(size); int count = ARRAY_count(THIS->data); if (check_not_multi(THIS)) return; if (size > count) { ARRAY_add_many_void(&THIS->data, size - count); } else if ((size < count) && (size >= 0)) { release(THIS, size, -1); ARRAY_remove_many(&THIS->data, size, count - size); } END_METHOD static void add(CARRAY *_object, GB_VALUE *value, int index) { void *data; if (check_not_multi(THIS)) return; data = insert(THIS, index); /*GB_Conv(value, THIS->type);*/ GB_Store(THIS->type, value, data); } #define IMPLEMENT_add(_type, _gtype) \ BEGIN_METHOD(CARRAY_##_type##_add, GB_##_gtype value; GB_INTEGER index) \ \ add(THIS, (GB_VALUE *)(void *)ARG(value), VARGOPT(index, -1)); \ \ END_METHOD \ \ BEGIN_METHOD(CARRAY_##_type##_push, GB_##_gtype value) \ \ add(THIS, (GB_VALUE *)(void *)ARG(value), -1); \ \ END_METHOD IMPLEMENT_add(integer, INTEGER) IMPLEMENT_add(long, LONG) IMPLEMENT_add(float, FLOAT) IMPLEMENT_add(date, DATE) IMPLEMENT_add(string, STRING) IMPLEMENT_add(object, OBJECT) IMPLEMENT_add(variant, VARIANT) #define IMPLEMENT_put(_type, _gtype) \ BEGIN_METHOD(CARRAY_##_type##_put, GB_##_gtype value; GB_INTEGER index) \ \ void *data = get_data_multi(THIS, ARG(index), GB_NParam() + 1); \ if (!data) return; \ GB_Store(GB_T_##_gtype, (GB_VALUE *)(void *)ARG(value), data); \ \ END_METHOD #define IMPLEMENT_put2(_type, _gtype, _gstore) \ BEGIN_METHOD(CARRAY_##_type##_put, GB_##_gtype value; GB_INTEGER index) \ \ void *data = get_data_multi(THIS, ARG(index), GB_NParam() + 1); \ if (!data) return; \ GB_Store(GB_T_##_gstore, (GB_VALUE *)(void *)ARG(value), data); \ \ END_METHOD IMPLEMENT_put(integer, INTEGER) IMPLEMENT_put2(short, INTEGER, SHORT) IMPLEMENT_put2(byte, INTEGER, BYTE) IMPLEMENT_put2(boolean, INTEGER, BOOLEAN) IMPLEMENT_put(long, LONG) IMPLEMENT_put(float, FLOAT) IMPLEMENT_put2(single, FLOAT, SINGLE) IMPLEMENT_put(date, DATE) IMPLEMENT_put(string, STRING) IMPLEMENT_put(object, OBJECT) IMPLEMENT_put(variant, VARIANT) BEGIN_METHOD(CARRAY_fill, GB_VALUE value; GB_INTEGER start; GB_INTEGER length) int count = ARRAY_count(THIS->data); int start = VARGOPT(start, 0); int length = VARGOPT(length, count); int i; void *data; int size; if ((start + length) > count) length = count - start; VALUE_conv((VALUE *)ARG(value), THIS->type); data = get_data(THIS, start); size = TYPE_sizeof_memory(THIS->type); for (i = 0; i < length; i++) { GB_Store(THIS->type, (GB_VALUE *)ARG(value), data); data += size; } END_METHOD BEGIN_METHOD(CARRAY_insert, GB_OBJECT array; GB_INTEGER pos) int pos = VARGOPT(pos, -1); CARRAY *array = (CARRAY *)VARG(array); int count; void *data; if (GB_CheckObject(array)) return; if (check_not_multi(THIS)) { GB_ReturnNull(); return; } count = ARRAY_count(array->data); if (count > 0) { if (pos < 0) pos = ARRAY_count(THIS->data); data = ARRAY_insert_many(&THIS->data, pos, count); borrow(array, 0, -1); memmove(data, array->data, count * TYPE_sizeof_memory(THIS->type)); } GB_ReturnObject(THIS); END_METHOD BEGIN_METHOD_VOID(CARRAY_pop) int index = ARRAY_count(THIS->data) - 1; if (check_not_multi(THIS)) return; if (index < 0) { GB_Error((char *)E_ARG); return; } GB_ReturnPtr(THIS->type, get_data(THIS, index)); BORROW(&TEMP); release_one(THIS, index); ARRAY_remove(&THIS->data, index); UNBORROW(&TEMP); END_METHOD BEGIN_METHOD(CARRAY_get, GB_INTEGER index) void *data = get_data_multi(THIS, ARG(index), GB_NParam() + 1); if (data) GB_ReturnPtr(THIS->type, data); END_METHOD BEGIN_METHOD_VOID(CARRAY_next) int *index = (int *)GB_GetEnum(); if (*index >= ARRAY_count(THIS->data)) GB_StopEnum(); else { GB_ReturnPtr(THIS->type, get_data(THIS, *index)); (*index)++; } END_METHOD BEGIN_METHOD(CARRAY_sort, GB_INTEGER mode) COMPARE_FUNC compare; int mode = VARGOPT(mode, 0); void *data = THIS->data; if (ARRAY_count(data) > 1) { compare = COMPARE_get(THIS->type, mode); qsort(data, ARRAY_count(data), TYPE_sizeof_memory(THIS->type), compare); } GB_ReturnObject(THIS); END_METHOD static int find(CARRAY *_object, int mode, void *value) { COMPARE_FUNC compare = COMPARE_get(THIS->type, mode); int i; for (i = 0; i < ARRAY_count(THIS->data); i++) { if ((*compare)(value, get_data(THIS, i)) == 0) return i; } return (-1); } #define IMPLEMENT_find(_type, _gtype) \ BEGIN_METHOD(CARRAY_##_type##_find, _gtype value) \ \ GB_ReturnInt(find(THIS, 0, &VARG(value))); \ \ END_METHOD \ BEGIN_METHOD(CARRAY_##_type##_exist, _gtype value) \ \ GB_ReturnBoolean(find(THIS, 0, &VARG(value)) >= 0); \ \ END_METHOD IMPLEMENT_find(integer, GB_INTEGER) /*IMPLEMENT_find(short, GB_INTEGER) IMPLEMENT_find(byte, GB_INTEGER)*/ IMPLEMENT_find(long, GB_LONG) IMPLEMENT_find(float, GB_FLOAT) IMPLEMENT_find(date, GB_DATE) IMPLEMENT_find(object, GB_OBJECT) BEGIN_METHOD(CARRAY_string_find, GB_STRING value; GB_INTEGER mode) char *str = GB_ToZeroString(ARG(value)); GB_ReturnInteger(find(THIS, VARGOPT(mode, 0), &str)); END_METHOD BEGIN_METHOD(CARRAY_string_exist, GB_STRING value; GB_INTEGER mode) char *str = GB_ToZeroString(ARG(value)); GB_ReturnInteger(find(THIS, VARGOPT(mode, 0), &str) >= 0); END_METHOD BEGIN_METHOD(CARRAY_string_join, GB_STRING sep; GB_STRING esc) char *sep = ","; int lsep = 1; char *esc = ""; int lesc = 0; char escl, escr; char *res = NULL; int i; char **data = (char **)THIS->data; char *p, *p2; int l; if (!MISSING(sep)) { sep = STRING(sep); lsep = LENGTH(sep); } if (!MISSING(esc)) { esc = STRING(esc); lesc = LENGTH(esc); if (lesc == 1) escl = escr = esc[0]; else if (lesc >= 2) { escl = esc[0]; escr = esc[1]; } } for (i = 0; i < ARRAY_count(data); i++) { p = data[i]; l = STRING_length(data[i]); if (i) STRING_add(&res, sep, lsep); if (lesc) { STRING_add(&res, &escl, 1); if (l) { for(;;) { p2 = index(p, escr); if (p2) { STRING_add(&res, p, p2 - p + 1); STRING_add(&res, &escr, 1); p = p2 + 1; } else { STRING_add(&res, p, l + data[i] - p); break; } } } STRING_add(&res, &escr, 1); } else if (l) STRING_add(&res, p, l); } if (res) { STRING_extend_end(&res); GB_ReturnString(res); } else GB_ReturnNull(); END_METHOD BEGIN_METHOD_VOID(CARRAY_reverse) size_t size; int count; char *buffer[16]; char *pi, *pj; count = ARRAY_count(THIS->data); if (count <= 1) return; size = TYPE_sizeof_memory(THIS->type); pi = get_data(THIS, 0); pj = get_data(THIS, count - 1); do { memcpy(buffer, pi, size); memcpy(pi, pj, size); memcpy(pj, buffer, size); pi += size; pj -= size; } while (pi < pj); END_METHOD BEGIN_METHOD(CARRAY_read, GB_OBJECT file; GB_INTEGER start; GB_INTEGER length) int count = ARRAY_count(THIS->data); int start = VARGOPT(start, 0); int length = VARGOPT(length, count); if ((start + length) > count) length = count - start; STREAM_read(CSTREAM_stream(VARG(file)), get_data(THIS, start), length * TYPE_sizeof_memory(THIS->type)); END_METHOD BEGIN_METHOD(CARRAY_write, GB_OBJECT file; GB_INTEGER start; GB_INTEGER length) int count = ARRAY_count(THIS->data); int start = VARGOPT(start, 0); int length = VARGOPT(length, count); if ((start + length) > count) length = count - start; STREAM_write(CSTREAM_stream(VARG(file)), get_data(THIS, start), length * TYPE_sizeof_memory(THIS->type)); END_METHOD BEGIN_PROPERTY(CARRAY_dim) GB_ReturnInteger(get_dim(THIS)); END_PROPERTY BEGIN_METHOD(CARRAY_bounds_get, GB_INTEGER index) int dim = get_dim(THIS); int index = VARG(index); if (index < 0 || index >= dim) { GB_Error((char *)E_BOUND); return; } GB_ReturnInteger(get_bound(THIS, index)); END_PROPERTY BEGIN_METHOD_VOID(CARRAY_print) int dim[MAX_ARRAY_DIM] = { 0 }; char *data = THIS->data; int ndim = get_dim(THIS); int i, j; if (ARRAY_count(THIS) == 0) { GB_PrintString("[]", 2); return; } for (i = 0; i < ndim; i++) GB_PrintString("[", 1); for(;;) { GB_PrintData(THIS->type, data); for (i = 0; i < ndim; i++) { dim[i]++; if (dim[i] < get_bound(THIS, i)) break; dim[i] = 0; } for (j = 0; j < i; j++) GB_PrintString("]", 1); if (i == ndim) break; for (j = 0; j < i; j++) GB_PrintString("[", 1); if (i == 0) GB_PrintString(",", 1); data += TYPE_sizeof_memory(THIS->type); } END_METHOD #endif /* #ifndef GBX_INFO */ GB_DESC NATIVE_ArrayBounds[] = { GB_DECLARE(".Array.Bounds", sizeof(CARRAY)), GB_NOT_CREATABLE(), GB_METHOD("_get", "i", CARRAY_bounds_get, "(Dimension)i"), GB_END_DECLARE }; GB_DESC NATIVE_Array[] = { GB_DECLARE("Array", sizeof(CARRAY)), GB_NOT_CREATABLE(), GB_METHOD("_free", NULL, CARRAY_free, NULL), GB_PROPERTY_READ("Type", "i", CARRAY_type), GB_PROPERTY_READ("Count", "i", CARRAY_count), GB_PROPERTY_READ("Max", "i", CARRAY_max), GB_PROPERTY_READ("Length", "i", CARRAY_count), GB_PROPERTY_READ("Dim", "i", CARRAY_dim), GB_PROPERTY_READ("Data", "p", CARRAY_data), GB_PROPERTY_SELF("Bounds", ".Array.Bounds"), GB_METHOD("Remove", NULL, CARRAY_remove, "(Index)i[(Length)i]"), GB_METHOD("Clear", NULL, CARRAY_clear, NULL), GB_METHOD("Resize", NULL, CARRAY_resize, "(Size)i"), GB_METHOD("Reverse", NULL, CARRAY_reverse, NULL), GB_METHOD("_print", NULL, CARRAY_print, NULL), //GB_METHOD("FromString", "i", CARRAY_from_string, "(String)s[(Separator)s(Escape)s]"), //GB_METHOD("Sort", NULL, CARRAY_sort, "[(Compare)i]"), //GB_METHOD("Find", "i", CARRAY_find, "(Value)s[(Compare)i]"), GB_END_DECLARE }; GB_DESC NATIVE_BooleanArray[] = { GB_DECLARE("Boolean[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_integer_add, "(Value)b[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_integer_push, "(Value)b"), GB_METHOD("_put", NULL, CARRAY_boolean_put, "(Value)b(Index)i."), GB_METHOD("Find", "i", CARRAY_integer_find, "(Value)b"), GB_METHOD("Exist", "b", CARRAY_integer_exist, "(Value)b"), GB_METHOD("Pop", "b", CARRAY_pop, NULL), GB_METHOD("_get", "b", CARRAY_get, "(Index)i."), GB_METHOD("_next", "b", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Boolean[]", CARRAY_insert, "(Array)Boolean[];[(Pos)i]"), GB_METHOD("Copy", "Boolean[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Boolean[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Boolean[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Boolean[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)b[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_ByteArray[] = { GB_DECLARE("Byte[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_integer_add, "(Value)c[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_integer_push, "(Value)c"), GB_METHOD("_put", NULL, CARRAY_byte_put, "(Value)c(Index)i."), GB_METHOD("Find", "i", CARRAY_integer_find, "(Value)c"), GB_METHOD("Exist", "b", CARRAY_integer_exist, "(Value)c"), GB_METHOD("Pop", "c", CARRAY_pop, NULL), GB_METHOD("_get", "c", CARRAY_get, "(Index)i."), GB_METHOD("_next", "c", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Byte[]", CARRAY_insert, "(Array)Byte[];[(Pos)i]"), GB_METHOD("Copy", "Byte[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Byte[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Byte[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Byte[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)c[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_ShortArray[] = { GB_DECLARE("Short[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_integer_add, "(Value)h[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_integer_push, "(Value)h"), GB_METHOD("_put", NULL, CARRAY_short_put, "(Value)h(Index)i."), GB_METHOD("Find", "i", CARRAY_integer_find, "(Value)h"), GB_METHOD("Exist", "b", CARRAY_integer_exist, "(Value)h"), GB_METHOD("Pop", "h", CARRAY_pop, NULL), GB_METHOD("_get", "h", CARRAY_get, "(Index)i."), GB_METHOD("_next", "h", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Short[]", CARRAY_insert, "(Array)Short[];[(Pos)i]"), GB_METHOD("Copy", "Short[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Short[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Short[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Short[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)h[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_IntegerArray[] = { GB_DECLARE("Integer[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_integer_add, "(Value)i[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_integer_push, "(Value)i"), GB_METHOD("_put", NULL, CARRAY_integer_put, "(Value)i(Index)i."), GB_METHOD("Find", "i", CARRAY_integer_find, "(Value)i"), GB_METHOD("Exist", "b", CARRAY_integer_exist, "(Value)i"), GB_METHOD("Pop", "i", CARRAY_pop, NULL), GB_METHOD("_get", "i", CARRAY_get, "(Index)i."), GB_METHOD("_next", "i", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Integer[]", CARRAY_insert, "(Array)Integer[];[(Pos)i]"), GB_METHOD("Copy", "Integer[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Integer[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Integer[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Integer[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)i[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_LongArray[] = { GB_DECLARE("Long[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_long_add, "(Value)l[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_long_push, "(Value)l"), GB_METHOD("_put", NULL, CARRAY_long_put, "(Value)l(Index)i."), GB_METHOD("Find", "i", CARRAY_long_find, "(Value)l"), GB_METHOD("Exist", "b", CARRAY_long_exist, "(Value)l"), GB_METHOD("Pop", "l", CARRAY_pop, NULL), GB_METHOD("_get", "l", CARRAY_get, "(Index)i."), GB_METHOD("_next", "l", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Long[]", CARRAY_insert, "(Array)Long[];[(Pos)i]"), GB_METHOD("Copy", "Long[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Long[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Long[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Long[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)l[(Start)i(Length)i]"), GB_END_DECLARE }; #ifdef OS_64BITS #define CARRAY_pointer_add CARRAY_long_add #define CARRAY_pointer_push CARRAY_long_push #define CARRAY_pointer_put CARRAY_long_put #define CARRAY_pointer_find CARRAY_long_find #define CARRAY_pointer_exist CARRAY_long_exist #else #define CARRAY_pointer_add CARRAY_integer_add #define CARRAY_pointer_push CARRAY_integer_push #define CARRAY_pointer_put CARRAY_integer_put #define CARRAY_pointer_find CARRAY_integer_find #define CARRAY_pointer_exist CARRAY_integer_exist #endif GB_DESC NATIVE_PointerArray[] = { GB_DECLARE("Pointer[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_long_add, "(Value)p[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_long_push, "(Value)p"), GB_METHOD("_put", NULL, CARRAY_long_put, "(Value)p(Index)i."), GB_METHOD("Find", "i", CARRAY_long_find, "(Value)p"), GB_METHOD("Exist", "b", CARRAY_long_exist, "(Value)p"), GB_METHOD("Pop", "p", CARRAY_pop, NULL), GB_METHOD("_get", "p", CARRAY_get, "(Index)i."), GB_METHOD("_next", "p", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Pointer[]", CARRAY_insert, "(Array)Pointer[];[(Pos)i]"), GB_METHOD("Copy", "Pointer[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Pointer[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Pointer[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Pointer[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)p[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_StringArray[] = { GB_DECLARE("String[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_string_add, "(Value)s[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_string_push, "(Value)s"), GB_METHOD("_put", NULL, CARRAY_string_put, "(Value)s(Index)i."), GB_METHOD("Find", "i", CARRAY_string_find, "(Value)s[(Mode)i]"), GB_METHOD("Exist", "b", CARRAY_string_exist, "(Value)s[(Mode)i]"), GB_METHOD("Pop", "s", CARRAY_pop, NULL), GB_METHOD("_get", "s", CARRAY_get, "(Index)i."), GB_METHOD("_next", "s", CARRAY_next, NULL), GB_METHOD("Insert", "String[]", CARRAY_insert, "(Array)String[];[(Pos)i]"), GB_METHOD("Join", "s", CARRAY_string_join, "[(Separator)s(Escape)s]"), GB_METHOD("Copy", "String[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "String[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "String[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "String[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)s[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_FloatArray[] = { GB_DECLARE("Float[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_float_add, "(Value)f[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_float_push, "(Value)f"), GB_METHOD("_put", NULL, CARRAY_float_put, "(Value)f(Index)i."), GB_METHOD("Find", "i", CARRAY_float_find, "(Value)f"), GB_METHOD("Exist", "b", CARRAY_float_exist, "(Value)f"), GB_METHOD("Pop", "f", CARRAY_pop, NULL), GB_METHOD("_get", "f", CARRAY_get, "(Index)i."), GB_METHOD("_next", "f", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Float[]", CARRAY_insert, "(Array)Float[];[(Pos)i]"), GB_METHOD("Copy", "Float[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Float[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Float[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Float[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)f[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_SingleArray[] = { GB_DECLARE("Single[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_float_add, "(Value)g[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_float_push, "(Value)g"), GB_METHOD("_put", NULL, CARRAY_single_put, "(Value)g(Index)i."), GB_METHOD("Find", "i", CARRAY_float_find, "(Value)g"), GB_METHOD("Exist", "b", CARRAY_float_exist, "(Value)g"), GB_METHOD("Pop", "g", CARRAY_pop, NULL), GB_METHOD("_get", "g", CARRAY_get, "(Index)i."), GB_METHOD("_next", "g", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Single[]", CARRAY_insert, "(Array)Single[];[(Pos)i]"), GB_METHOD("Copy", "Single[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Single[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Single[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Single[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)g[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_DateArray[] = { GB_DECLARE("Date[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_date_add, "(Value)d[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_date_push, "(Value)d"), GB_METHOD("_put", NULL, CARRAY_date_put, "(Value)d(Index)i."), GB_METHOD("Find", "i", CARRAY_date_find, "(Value)d"), GB_METHOD("Exist", "b", CARRAY_date_exist, "(Value)d"), GB_METHOD("Pop", "d", CARRAY_pop, NULL), GB_METHOD("_get", "d", CARRAY_get, "(Index)i."), GB_METHOD("_next", "d", CARRAY_next, NULL), GB_METHOD("Read", NULL, CARRAY_read, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Write", NULL, CARRAY_write, "(Stream)Stream;[(Start)i(Length)i]"), GB_METHOD("Insert", "Date[]", CARRAY_insert, "(Array)Date[];[(Pos)i]"), GB_METHOD("Copy", "Date[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Date[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Date[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Sort", "Date[]", CARRAY_sort, "[(Mode)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)d[(Start)i(Length)i]"), GB_END_DECLARE }; GB_DESC NATIVE_ObjectArray[] = { GB_DECLARE("Object[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_object_add, "(Value)o[(Index)i.]"), GB_METHOD("Push", NULL, CARRAY_object_push, "(Value)o"), GB_METHOD("_put", NULL, CARRAY_object_put, "(Value)o(Index)i."), GB_METHOD("Find", "i", CARRAY_object_find, "(Value)o"), GB_METHOD("Exist", "b", CARRAY_object_exist, "(Value)o"), GB_METHOD("Pop", "o", CARRAY_pop, NULL), GB_METHOD("_get", "o", CARRAY_get, "(Index)i."), GB_METHOD("_next", "o", CARRAY_next, NULL), GB_METHOD("Insert", "Object[]", CARRAY_insert, "(Array)Object[];[(Pos)i]"), GB_METHOD("Copy", "Object[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Object[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Object[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)o[(Start)i(Length)i]"), GB_METHOD("Sort", "Object[]", CARRAY_sort, "[(Mode)i]"), GB_END_DECLARE }; #if 0 #ifndef GBX_INFO GB_DESC NATIVE_TemplateArray[ARRAY_TEMPLATE_NDESC] = { GB_DECLARE("*[]", sizeof(CARRAY)), GB_INHERITS("Object[]"), //GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_object_add, "(Value)*;[(Index)i.]"), GB_METHOD("Push", NULL, CARRAY_object_push, "(Value)*;"), GB_METHOD("_put", NULL, CARRAY_object_put, "(Value)*;(Index)i."), GB_METHOD("Find", "i", CARRAY_object_find, "(Value)*;"), GB_METHOD("Pop", "*", CARRAY_pop, NULL), GB_METHOD("_get", "*", CARRAY_get, "(Index)i."), GB_METHOD("_next", "*", CARRAY_next, NULL), GB_METHOD("Insert", "*", CARRAY_insert, "(Array)*[];[(Pos)i]"), GB_METHOD("Copy", "*[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "*[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "*[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)*[(Start)i(Length)i]"), //GB_METHOD("Sort", "Object[]", CARRAY_sort, "[(Mode)i]"), GB_END_DECLARE }; #endif #endif GB_DESC NATIVE_VariantArray[] = { GB_DECLARE("Variant[]", sizeof(CARRAY)), GB_INHERITS("Array"), GB_METHOD("_new", NULL, CARRAY_new, "[(Size)i.]"), GB_METHOD("Add", NULL, CARRAY_variant_add, "(Value)v[(Index)i]"), GB_METHOD("Push", NULL, CARRAY_variant_push, "(Value)v"), GB_METHOD("_put", NULL, CARRAY_variant_put, "(Value)v(Index)i."), GB_METHOD("Pop", "v", CARRAY_pop, NULL), GB_METHOD("_get", "v", CARRAY_get, "(Index)i."), GB_METHOD("_next", "v", CARRAY_next, NULL), GB_METHOD("Insert", "Variant[]", CARRAY_insert, "(Array)Variant[];[(Pos)i]"), GB_METHOD("Copy", "Variant[]", CARRAY_copy, "[(Start)i(Length)i]"), GB_METHOD("Extract", "Variant[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Delete", "Variant[]", CARRAY_extract, "(Start)i[(Length)i]"), GB_METHOD("Fill", NULL, CARRAY_fill, "(Value)v[(Start)i(Length)i]"), GB_END_DECLARE }; #ifndef GBX_INFO static CARRAY *_array; static bool _novoid; static char *_entry; static const char *_ptr; static int _lptr; static void add_char(const char *p) { //fprintf(stderr, "add_char: %p %c\n", p, p ? *p : 0); if (p && p == (_ptr + _lptr)) { _lptr++; return; } if (_lptr) { //fprintf(stderr, "STRING_add: '%.*s'\n", _lptr, _ptr); STRING_add(&_entry, _ptr, _lptr); } _ptr = p; _lptr = p ? 1 : 0; } static void add_entry() { add_char(NULL); if (!_entry) { if (!_novoid) ARRAY_add_void(&_array->data); } else { *((char **)ARRAY_add(&_array->data)) = _entry; _entry = NULL; } //fprintf(stderr, "** add_entry\n"); } void CARRAY_split(CARRAY *_object, const char *str, int lstr, const char *sep, const char *esc, bool no_void) { int i; char c; bool escape; char escl, escr; if (sep == NULL || *sep == 0) sep = ","; if (esc == NULL || *esc == 0) escl = escr = 0; else { escl = *esc++; if (*esc) escr = *esc; else escr = escl; } clear(THIS); _array = _object; _entry = NULL; _novoid = no_void; _ptr = NULL; _lptr = 0; escape = FALSE; for (i = 0; i < lstr; i++) { c = *str; if (escape) { if (c != escr) add_char(str); else if ((i < (lstr - 1)) && str[1] == escr) { add_char(str); str++; i++; } else escape = FALSE; } else if (c == escl) { escape = TRUE; } else if (index(sep, c)) { add_entry(); } else add_char(str); str++; } add_entry(); _array = NULL; } /* Gambas API */ void GB_ArrayNew(GB_ARRAY *array, uint type, int size) { CLASS *class; int np; if (size > 0) { GB_Push(1, GB_T_INTEGER, size); np = 1; } else { np = 0; } switch(type) { case GB_T_BOOLEAN: class = CLASS_BooleanArray; break; case GB_T_BYTE: class = CLASS_ByteArray; break; case GB_T_SHORT: class = CLASS_ShortArray; break; case GB_T_INTEGER: class = CLASS_IntegerArray; break; case GB_T_LONG: class = CLASS_LongArray; break; case GB_T_SINGLE: class = CLASS_SingleArray; break; case GB_T_FLOAT: class = CLASS_FloatArray; break; case GB_T_STRING: class = CLASS_StringArray; break; case GB_T_DATE: class = CLASS_DateArray; break; case GB_T_OBJECT: class = CLASS_ObjectArray; break; case GB_T_POINTER: class = CLASS_PointerArray; break; default: class = CLASS_VariantArray; break; } OBJECT_create((void **)array, class, NULL, NULL, np); } int GB_ArrayCount(GB_ARRAY array) { return ARRAY_count(((CARRAY *)array)->data); } void *GB_ArrayAdd(GB_ARRAY array) { return insert((CARRAY *)array, -1); } void *GB_ArrayGet(GB_ARRAY array, int index) { return get_data((CARRAY *)array, index); } #endif