📄 gbx_c_array.c
字号:
/*************************************************************************** CArray.c The Array native classes. (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.***************************************************************************/#define __GBX_C_ARRAY_C#include "gb_common.h"#include "gb_error.h"#include "gb_array.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_c_file.h"#include "gbx_c_array.h"PRIVATE void *get_data(CARRAY *_object, long i){ if ((i < 0) || (i >= ARRAY_count(THIS->data))) { GB_Error((char *)E_BOUND); return NULL; } return (void *)((char *)(THIS->data) + i * TYPE_sizeof_memory(THIS->type));}PRIVATE void release_one(CARRAY *_object, long i){ switch(THIS->type) { case T_STRING: STRING_unref(&(((char **)(THIS->data))[i])); break; case T_OBJECT: OBJECT_unref(&(((void **)(THIS->data))[i])); break; case T_VARIANT: VARIANT_free(&(((VARIANT *)(THIS->data))[i])); break; default: break; }}PRIVATE 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]); break; case T_VARIANT: for (i = start; i < end; i++) VARIANT_free(&((VARIANT *)(THIS->data))[i]); break; default: break; }}PRIVATE 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]); break; case T_VARIANT: for (i = start; i < end; i++) VARIANT_keep(&((VARIANT *)(THIS->data))[i]); break; default: break; }}PRIVATE void clear(CARRAY *_object){ release(THIS, 0, -1); ARRAY_delete(&THIS->data); ARRAY_create_with_size(&THIS->data, TYPE_sizeof_memory(THIS->type), 8);}PRIVATE void *insert(CARRAY *_object, long index){ return ARRAY_insert(&THIS->data, index);}/*PUBLIC CARRAY *CARRAY_create(CLASS *klass){ void *object; OBJECT_new(&object, CLASS_Array, NULL, NULL); OBJECT_UNREF_KEEP(&object, "CARRAY_create"); return (CARRAY *)object;}*/PUBLIC void CARRAY_split(CARRAY *_object, const char *str, const char *sep, const char *esc){ char c; const char *p; long len; const char *elt; bool escape; if (sep == NULL || *sep == 0) sep = ","; if (esc == NULL) esc = ""; clear(THIS); p = str; escape = FALSE; for(;;) { c = *str; if (p == str && c != 0 && index(esc, c)) { escape = TRUE; goto _NEXT; } if (escape) { if (c != 0 && index(esc, c) == NULL) goto _NEXT; else c = *(++str); } if (c != 0 && index(sep, c) == NULL) goto _NEXT; if (escape) { len = str - p - 2; if (len > 0) { /*str[-1] = 0;*/ elt = p + 1; } } else { len = str - p; if (len > 0) { /**str = 0;*/ elt = p; } } if (len <= 0) { ARRAY_add_void(&THIS->data); } else { STRING_new((char **)ARRAY_add(&THIS->data), elt, len); } if (c == 0) break; p = str + 1; escape = FALSE; _NEXT: str++; }}BEGIN_METHOD(CARRAY_new, GB_INTEGER size) TYPE type; CLASS *klass; long size; long inc; klass = OBJECT_class(THIS); if (klass == CLASS_IntegerArray) type = T_INTEGER; else if (klass == CLASS_ShortArray) type = T_SHORT; else if (klass == CLASS_ByteArray) type = T_BYTE; 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_ObjectArray) type = T_OBJECT; else type = T_VARIANT; THIS->type = type; 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);END_METHODBEGIN_METHOD_VOID(CARRAY_free) release(THIS, 0, -1); ARRAY_delete(&THIS->data);END_METHODBEGIN_METHOD_VOID(CARRAY_clear) clear(THIS);END_METHODBEGIN_PROPERTY(CARRAY_count) GB_ReturnInt(ARRAY_count(THIS->data));END_PROPERTYBEGIN_PROPERTY(CARRAY_max) GB_ReturnInt(ARRAY_count(THIS->data) - 1);END_PROPERTYBEGIN_METHOD(CARRAY_remove, GB_INTEGER index; GB_INTEGER count) long index = VARG(index); long count = VARGOPT(count, 1); /* do it after 1.0 if (index < 0) index = ARRAY_count(THIS->data) - index;*/ if ((index < 0) || (index >= ARRAY_count(THIS->data))) { GB_Error((char *)E_ARG); return; } if (count < 0) count = ARRAY_count(THIS->data) - index; release(THIS, index, index + count); ARRAY_remove_many(&THIS->data, index, count);END_METHODBEGIN_METHOD(CARRAY_resize, GB_INTEGER size) long size = VARG(size); long count = ARRAY_count(THIS->data); 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_METHODPRIVATE void add(CARRAY *_object, GB_VALUE *value, long index){ void *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 *)ARG(value), VARGOPT(index, -1)); \ \END_METHOD \\BEGIN_METHOD(CARRAY_##_type##_push, GB_##_gtype value) \\ add(THIS, (GB_VALUE *)ARG(value), -1); \ \END_METHODIMPLEMENT_add(integer, INTEGER)/*IMPLEMENT_add(short, INTEGER)IMPLEMENT_add(byte, INTEGER)*/IMPLEMENT_add(float, FLOAT)IMPLEMENT_add(date, DATE)IMPLEMENT_add(string, STRING)IMPLEMENT_add(object, OBJECT)IMPLEMENT_add(variant, VARIANT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -