📄 gbx_c_collection.c
字号:
/*************************************************************************** CCollection.c The Collection native class. (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_COLLECTION_C#include "gb_common.h"#include "gb_error.h"#include "gbx_variant.h"#include "gambas.h"#include "gbx_api.h"#include "gbx_class.h"#include "gbx_object.h"#include "gbx_c_collection.h"static void collection_free(CCOLLECTION *col){ VARIANT *value; HASH_ENUM iter; CLEAR(&iter); for(;;) { value = HASH_TABLE_next(col->hash_table, &iter); if (value == NULL) break; VARIANT_free(value); } HASH_TABLE_delete(&col->hash_table);}static void *collection_get_key(CCOLLECTION *col, const char *key, long len){ return HASH_TABLE_lookup(col->hash_table, key, len);}static void *collection_add_key(CCOLLECTION *col, const char *key, long len){ if (len < 0) len = strlen(key); return HASH_TABLE_insert(col->hash_table, key, len);}static void collection_remove_key(CCOLLECTION *col, const char *key, long len){ void *value; if (len < 0) len = strlen(key); value = HASH_TABLE_lookup(col->hash_table, key, len); if (value == NULL) return; VARIANT_free(value); HASH_TABLE_remove(col->hash_table, key, len);}BEGIN_METHOD(CCOLLECTION_new, GB_INTEGER mode) int mode = MISSING(mode) ? 0 : VARG(mode); HASH_TABLE_create(&THIS->hash_table, TYPE_sizeof(T_VARIANT), mode); THIS->last = NULL;END_METHODBEGIN_METHOD_VOID(CCOLLECTION_free) collection_free(THIS);END_METHODBEGIN_PROPERTY(collection_count) GB_ReturnInt(HASH_TABLE_size(THIS->hash_table));END_PROPERTYBEGIN_PROPERTY(collection_key) char *key; long len; if (HASH_TABLE_get_last_key(THIS->hash_table, &key, &len)) GB_ReturnNull(); else GB_ReturnNewString(key, len);END_PROPERTYBEGIN_METHOD(collection_add, GB_VARIANT value; GB_STRING key) void *data; data = collection_add_key(THIS, STRING(key), LENGTH(key)); GB_StoreVariant(ARG(value), data);END_METHODBEGIN_METHOD(collection_exist, GB_STRING key) /*if (LENGTH(key) == 0) GB_ReturnBoolean(FALSE); else*/ GB_ReturnBoolean(collection_get_key(THIS, STRING(key), LENGTH(key)) != NULL);END_METHODBEGIN_METHOD(collection_remove, GB_STRING key) collection_remove_key(THIS, STRING(key), LENGTH(key));END_METHODBEGIN_METHOD_VOID(collection_clear) int mode = THIS->hash_table->mode; collection_free(THIS); HASH_TABLE_create(&THIS->hash_table, TYPE_sizeof(T_VARIANT), mode);END_METHOD#if 0BEGIN_METHOD_VOID(collection_first) HASH_ENUM *iter = (HASH_ENUM *)GB_GetEnum(); iter->index = (-1); iter->node = NULL;END_METHOD#endifBEGIN_METHOD_VOID(collection_next) void *value; HASH_TABLE *hash_table = OBJECT(CCOLLECTION)->hash_table; HASH_ENUM *iter = (HASH_ENUM *)GB_GetEnum(); value = HASH_TABLE_next(hash_table, iter); if (value == NULL) GB_StopEnum(); else GB_ReturnPtr(T_VARIANT, value);END_METHOD/*BEGIN_METHOD(collection_copy, CCOLLECTION *copy) CCOLLECTION *copy = PARAM(copy); HASH_TABLE *hash_table = THIS->hash_table; CCOL_ENUM enum_state; void *value; collection_clear(THIS, NULL); enum_state.i = -1; enum_state.node = NULL; for(;;) { value = HASH_TABLE_next(hash_table, &enum_state->i, &enum_state->node); if (value == NULL) break; GB_ReturnPtr(OBJECT(CCOLLECTION)->type, value); data = collection_add_key(THIS, PARAM(key).addr, PARAM(key).len); GB_Store(T_VARIANT, &PARAM(value), data);END_METHOD*/BEGIN_METHOD(collection_get, GB_STRING key) void *data; data = collection_get_key(THIS, STRING(key), LENGTH(key)); if (data == NULL) GB_ReturnNull(); else GB_ReturnPtr(T_VARIANT, data);END_METHODBEGIN_METHOD(collection_put, GB_VARIANT value; GB_STRING key) void *data; if (VARIANT_is_null((VARIANT *)&VARG(value))) collection_remove_key(THIS, STRING(key), LENGTH(key)); else { data = collection_add_key(THIS, STRING(key), LENGTH(key)); GB_StoreVariant(ARG(value), data); }END_METHODPUBLIC GB_DESC NATIVE_Collection[] ={ GB_DECLARE("Collection", sizeof(CCOLLECTION)), GB_METHOD("_new", NULL, CCOLLECTION_new, "[(Mode)i]"), GB_METHOD("_free", NULL, CCOLLECTION_free, NULL), GB_PROPERTY_READ("Count", "i", collection_count), GB_PROPERTY_READ("Length", "i", collection_count), GB_PROPERTY_READ("Key", "s", collection_key), GB_METHOD("Add", NULL, collection_add, "(Value)v(Key)s"), GB_METHOD("Exist", "b", collection_exist, "(Key)s"), GB_METHOD("Remove", NULL, collection_remove, "(Key)s"), GB_METHOD("Clear", NULL, collection_clear, NULL), /*GB_METHOD("_first", NULL, collection_first, NULL),*/ GB_METHOD("_next", "v", collection_next, NULL), GB_METHOD("_get", "v", collection_get, "(Key)s"), GB_METHOD("_put", NULL, collection_put, "(Value)v(Key)s"), GB_END_DECLARE};PUBLIC void GB_CollectionNew(GB_COLLECTION *col, int mode){ GB_INTEGER param; param.type = GB_T_INTEGER; param.value = mode; OBJECT_create_native((void **)col, CLASS_Collection, (VALUE *)¶m);}PUBLIC long GB_CollectionCount(GB_COLLECTION col){ return HASH_TABLE_size(((CCOLLECTION *)col)->hash_table);}PUBLIC void GB_CollectionSet(GB_COLLECTION col, const char *key, long len, GB_VARIANT *value){ VARIANT *data; if (VARIANT_is_null((VARIANT *)&value->value)) collection_remove_key((CCOLLECTION *)col, key, len); else { data = (VARIANT *)collection_add_key((CCOLLECTION *)col, key, len); GB_StoreVariant(value, data); }}PUBLIC int GB_CollectionGet(GB_COLLECTION col, const char *key, long len, GB_VARIANT *value){ void *val; val = collection_get_key((CCOLLECTION *)col, key, len); if (val) { value->type = GB_T_VARIANT; *((VARIANT *)&value->value) = *((VARIANT *)val); return FALSE; } else { value->type = GB_T_NULL; return TRUE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -