X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=device-src%2Fproperty.c;h=275cc8088bf0871a2324945466e9fae6b2db9467;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=3980a3f6c2326b5f3e84a6b02a95ab6c3d0db38f;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/device-src/property.c b/device-src/property.c index 3980a3f..275cc80 100644 --- a/device-src/property.c +++ b/device-src/property.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 as @@ -14,13 +14,18 @@ * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120 - * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com + * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300 + * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com */ #include "amanda.h" #include "property.h" +#include "glib-util.h" + +/***** + * Property-specific Types, etc. + */ static const GEnumValue _concurrency_paradigm_values[] = { { CONCURRENCY_PARADIGM_EXCLUSIVE, @@ -93,7 +98,7 @@ GType media_access_mode_get_type (void) { /* Copy function for GBoxed QualifiedSize. */ static gpointer qualified_size_copy(gpointer source) { - gpointer rval = malloc(sizeof(QualifiedSize)); + gpointer rval = g_new(QualifiedSize, 1); memcpy(rval, source, sizeof(QualifiedSize)); return rval; } @@ -108,122 +113,98 @@ GType qualified_size_get_type (void) { return type; } -static const GFlagsValue _feature_support_flags_values[] = { - { FEATURE_STATUS_ENABLED, - "FEATURE_STATUS_ENABLED", - "enabled" }, - { FEATURE_STATUS_DISABLED, - "FEATURE_STATUS_DISABLED", - "disabled" }, - { FEATURE_SURETY_BAD, - "FEATURE_SURETY_BAD", - "bad" }, - { FEATURE_SURETY_GOOD, - "FEATURE_SURETY_GOOD", - "good" }, - { FEATURE_SOURCE_DEFAULT, - "FEATURE_SOURCE_DEFAULT", - "default" }, - { FEATURE_SOURCE_DETECTED, - "FEATURE_SOURCE_DETECTED", - "detected" }, - { FEATURE_SOURCE_USER, - "FEATURE_SOURCE_USER", - "user"}, - { 0, NULL, NULL } -}; +/****** + * Property registration and lookup + */ -GType feature_support_get_type (void) { - static GType type = 0; - if (G_UNLIKELY(type == 0)) { - type = g_flags_register_static ("FeatureSupportFlags", - _feature_support_flags_values); - } - return type; -} +static GPtrArray *device_property_bases = NULL; +static GHashTable *device_property_bases_by_name = NULL; -gboolean feature_support_flags_is_valid(FeatureSupportFlags f) { - int status = 0, surety = 0, source = 0; - - if (f & FEATURE_STATUS_ENABLED) - status ++; - if (f & FEATURE_STATUS_DISABLED) - status ++; - if (f & FEATURE_SURETY_BAD) - surety ++; - if (f & FEATURE_SURETY_GOOD) - surety ++; - if (f & FEATURE_SOURCE_DEFAULT) - source ++; - if (f & FEATURE_SOURCE_DETECTED) - source ++; - if (f & FEATURE_SOURCE_USER) - source ++; - - return (!(f & ~FEATURE_SUPPORT_FLAGS_MASK) && - status == 1 && surety == 1 && source == 1); +DevicePropertyBase* device_property_get_by_id(DevicePropertyId id) { + if (!device_property_bases || id >= device_property_bases->len) + return NULL; + + return g_ptr_array_index(device_property_bases, id); } -static GSList* device_property_base_list = NULL; +DevicePropertyBase* device_property_get_by_name(const char *name) { + gpointer rv; -const DevicePropertyBase* device_property_get_by_id(DevicePropertyId id) { - GSList *iter; + if (!device_property_bases_by_name) + return NULL; - iter = device_property_base_list; - while (iter != NULL) { - DevicePropertyBase* rval = (DevicePropertyBase*)(iter->data); - if (rval->ID == id) { - return rval; - } - iter = g_slist_next(iter); - } + rv = g_hash_table_lookup(device_property_bases_by_name, name); + if (rv) + return (DevicePropertyBase *)rv; return NULL; } -const DevicePropertyBase* device_property_get_by_name(const char *name) { - GSList *iter = device_property_base_list; +#define toupper_and_underscore(c) (((c)=='-')? '_' : g_ascii_toupper((c))) +static guint +device_property_hash( + gconstpointer key) +{ + /* modified version of glib's hash function, copyright + * GLib Team and others 1997-2000. */ + const char *p = key; + guint h = toupper_and_underscore(*p); + + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + toupper_and_underscore(*p); + + return h; +} - g_return_val_if_fail(name != NULL, NULL); +static gboolean +device_property_equal( + gconstpointer v1, + gconstpointer v2) +{ + const char *s1 = v1, *s2 = v2; - while (iter != NULL) { - DevicePropertyBase* rval = (DevicePropertyBase*)(iter->data); - if (strcasecmp(rval->name, name) == 0) { - return rval; - } - iter = g_slist_next(iter); + while (*s1 && *s2) { + if (toupper_and_underscore(*s1) != toupper_and_underscore(*s2)) + return FALSE; + s1++, s2++; } + if (*s1 || *s2) + return FALSE; - return NULL; + return TRUE; } -DevicePropertyId device_property_register(DevicePropertyBase* base) { - static guint id = 0; - g_assert(base != NULL); - g_assert(base->ID == -1); - g_assert(base->name != NULL); - g_assert(base->description != NULL); - - base->ID = id++; - - device_property_base_list = g_slist_prepend(device_property_base_list, - base); - return id; -} +void +device_property_fill_and_register(DevicePropertyBase *base, + GType type, const char * name, const char * desc) { + + /* create the hash table and array if necessary */ + if (!device_property_bases) { + device_property_bases = g_ptr_array_new(); + device_property_bases_by_name = g_hash_table_new(device_property_hash, device_property_equal); + } -/* Does the same thing, but fills in a new DevicePropertyBase. */ -static void -device_property_fill_and_register(DevicePropertyBase * base, - GType type, - const char * name, - const char * desc) { + /* check for a duplicate */ + if (device_property_get_by_name(name)) { + g_critical("A property named '%s' already exists!", name); + } + + /* allocate space for this DPB and fill it in */ + base->ID = device_property_bases->len; base->type = type; - base->name = name; - base->description = desc; - base->ID = -1; - device_property_register(base); + base->name = name; /* no strdup -- it's statically allocated */ + base->description = desc; /* ditto */ + + /* add it to the array and hash table; note that its array index and its + * ID are the same. */ + g_ptr_array_add(device_property_bases, base); + g_hash_table_insert(device_property_bases_by_name, (gpointer)name, (gpointer)base); } +/****** + * Initialization + */ void device_property_init(void) { device_property_fill_and_register(&device_property_concurrency, @@ -241,13 +222,16 @@ void device_property_init(void) { "averaged for some (currently undefined) period of time)"); device_property_fill_and_register(&device_property_block_size, G_TYPE_INT, "block_size", - "Device blocking factor in bytes."); + "Block size to use while writing."); device_property_fill_and_register(&device_property_min_block_size, G_TYPE_UINT, "min_block_size", "Minimum supported blocking factor."); device_property_fill_and_register(&device_property_max_block_size, G_TYPE_UINT, "max_block_size", "Maximum supported blocking factor."); + device_property_fill_and_register(&device_property_read_buffer_size, + G_TYPE_UINT, "read_buffer_size", + "Minimum size of a read for this device (maximum expected block size)"); device_property_fill_and_register(&device_property_appendable, G_TYPE_BOOLEAN, "appendable", "Does device support appending to previously-written media?"); @@ -267,43 +251,6 @@ void device_property_init(void) { device_property_fill_and_register(&device_property_max_volume_usage, G_TYPE_UINT64, "max_volume_usage", "Artificial limit to data written to volume."); - device_property_fill_and_register(&device_property_fsf, - FEATURE_SUPPORT_FLAGS_TYPE, "fsf", - "Does this drive support the MTFSF command?"); - device_property_fill_and_register(&device_property_bsf, - FEATURE_SUPPORT_FLAGS_TYPE, "bsf", - "Does this drive support the MTBSF command?" ); - device_property_fill_and_register(&device_property_fsr, - FEATURE_SUPPORT_FLAGS_TYPE, "fsr", - "Does this drive support the MTFSR command?"); - device_property_fill_and_register(&device_property_bsr, - FEATURE_SUPPORT_FLAGS_TYPE, "bsr", - "Does this drive support the MTBSR command?"); - /* FIXME: Is this feature even useful? */ - device_property_fill_and_register(&device_property_eom, - FEATURE_SUPPORT_FLAGS_TYPE, "eom", - "Does this drive support the MTEOM command?"); - device_property_fill_and_register(&device_property_bsf_after_eom, - FEATURE_SUPPORT_FLAGS_TYPE, - "bsf_after_eom", - "Does this drive require an MTBSF after MTEOM in order to append?" ); - device_property_fill_and_register(&device_property_final_filemarks, - G_TYPE_UINT, "final_filemarks", - "How many filemarks to write after the last tape file?" ); - device_property_fill_and_register(&device_property_read_buffer_size, - G_TYPE_UINT, "read_buffer_size", - "What buffer size should be used for reading?"); - device_property_fill_and_register(&device_property_s3_secret_key, - G_TYPE_STRING, "s3_secret_key", - "Secret access key to authenticate with Amazon S3"); - device_property_fill_and_register(&device_property_s3_access_key, - G_TYPE_STRING, "s3_access_key", - "Access key ID to authenticate with Amazon S3"); -#ifdef WANT_DEVPAY - device_property_fill_and_register(&device_property_s3_user_token, - G_TYPE_STRING, "s3_user_token", - "User token for authentication Amazon devpay requests"); -#endif device_property_fill_and_register(&device_property_verbose, G_TYPE_BOOLEAN, "verbose", "Should the device produce verbose output?"); @@ -316,21 +263,11 @@ DevicePropertyBase device_property_compression_rate; DevicePropertyBase device_property_block_size; DevicePropertyBase device_property_min_block_size; DevicePropertyBase device_property_max_block_size; +DevicePropertyBase device_property_read_buffer_size; DevicePropertyBase device_property_appendable; DevicePropertyBase device_property_canonical_name; DevicePropertyBase device_property_medium_access_type; DevicePropertyBase device_property_partial_deletion; DevicePropertyBase device_property_free_space; DevicePropertyBase device_property_max_volume_usage; -DevicePropertyBase device_property_fsf; -DevicePropertyBase device_property_bsf; -DevicePropertyBase device_property_fsr; -DevicePropertyBase device_property_bsr; -DevicePropertyBase device_property_eom; -DevicePropertyBase device_property_bsf_after_eom; -DevicePropertyBase device_property_final_filemarks; -DevicePropertyBase device_property_read_buffer_size; -DevicePropertyBase device_property_s3_access_key; -DevicePropertyBase device_property_s3_secret_key; -DevicePropertyBase device_property_s3_user_token; DevicePropertyBase device_property_verbose;