Changeset 820ab55c in mainline
- Timestamp:
- 2010-09-26T16:59:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 70ce016
- Parents:
- 4edd39fc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/adt/generic_field.h
r4edd39fc r820ab55c 43 43 #include <unistd.h> 44 44 45 /** Internal magic value for a field consistency check. 46 */ 45 /** Internal magic value for a field consistency check. */ 47 46 #define GENERIC_FIELD_MAGIC_VALUE 0x55667788 48 47 49 48 /** Generic type field declaration. 50 * @param[in] name Name of the field. 51 * @param[in] type Inner object type. 49 * 50 * @param[in] name Name of the field. 51 * @param[in] type Inner object type. 52 52 */ 53 #define GENERIC_FIELD_DECLARE(name, type) \ 54 \ 55 typedef struct name name##_t; \ 56 typedef name##_t * name##_ref; \ 57 \ 58 struct name{ \ 59 int size; \ 60 int next; \ 61 type ** items; \ 62 int magic; \ 63 }; \ 64 \ 65 int name##_add(name##_ref field, type * value); \ 66 int name##_count(name##_ref field); \ 67 void name##_destroy(name##_ref field); \ 68 void name##_exclude_index(name##_ref field, int index); \ 69 type ** name##_get_field(name##_ref field); \ 70 type * name##_get_index(name##_ref field, int index); \ 71 int name##_initialize(name##_ref field); \ 72 int name##_is_valid(name##_ref field); 53 #define GENERIC_FIELD_DECLARE(name, type) \ 54 typedef struct name name##_t; \ 55 typedef name##_t *name##_ref; \ 56 \ 57 struct name { \ 58 int size; \ 59 int next; \ 60 type **items; \ 61 int magic; \ 62 }; \ 63 \ 64 int name##_add(name##_ref, type *); \ 65 int name##_count(name##_ref); \ 66 void name##_destroy(name##_ref); \ 67 void name##_exclude_index(name##_ref, int); \ 68 type **name##_get_field(name##_ref); \ 69 type *name##_get_index(name##_ref, int); \ 70 int name##_initialize(name##_ref); \ 71 int name##_is_valid(name##_ref); 73 72 74 73 /** Generic type field implementation. 75 * Should follow declaration with the same parameters. 76 * @param[in] name Name of the field. 77 * @param[in] type Inner object type. 74 * 75 * Should follow declaration with the same parameters. 76 * 77 * @param[in] name Name of the field. 78 * @param[in] type Inner object type. 78 79 */ 79 #define GENERIC_FIELD_IMPLEMENT(name, type) \ 80 \ 81 int name##_add(name##_ref field, type * value){ \ 82 if(name##_is_valid(field)){ \ 83 if(field->next == (field->size - 1)){ \ 84 type ** tmp; \ 85 \ 86 tmp = (type **) realloc(field->items, sizeof(type *) * 2 * field->size); \ 87 if(! tmp){ \ 88 return ENOMEM; \ 89 } \ 90 field->size *= 2; \ 91 field->items = tmp; \ 92 } \ 93 field->items[field->next] = value; \ 94 ++ field->next; \ 95 field->items[field->next] = NULL; \ 96 return field->next - 1; \ 97 } \ 98 return EINVAL; \ 99 } \ 100 \ 101 int name##_count(name##_ref field){ \ 102 return name##_is_valid(field) ? field->next : -1; \ 103 } \ 104 \ 105 void name##_destroy(name##_ref field){ \ 106 if(name##_is_valid(field)){ \ 107 int index; \ 108 \ 109 field->magic = 0; \ 110 for(index = 0; index < field->next; ++ index){ \ 111 if(field->items[index]){ \ 112 free(field->items[index]); \ 113 } \ 114 } \ 115 free(field->items); \ 116 } \ 117 } \ 118 \ 119 void name##_exclude_index(name##_ref field, int index){ \ 120 if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){ \ 121 free(field->items[index]); \ 122 field->items[index] = NULL; \ 123 } \ 124 } \ 125 \ 126 type * name##_get_index(name##_ref field, int index){ \ 127 if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){ \ 128 return field->items[index]; \ 129 } \ 130 return NULL; \ 131 } \ 132 \ 133 type ** name##_get_field(name##_ref field){ \ 134 return name##_is_valid(field) ? field->items : NULL; \ 135 } \ 136 \ 137 int name##_initialize(name##_ref field){ \ 138 if(! field){ \ 139 return EINVAL; \ 140 } \ 141 field->size = 2; \ 142 field->next = 0; \ 143 field->items = (type **) malloc(sizeof(type *) * field->size); \ 144 if(! field->items){ \ 145 return ENOMEM; \ 146 } \ 147 field->items[field->next] = NULL; \ 148 field->magic = GENERIC_FIELD_MAGIC_VALUE; \ 149 return EOK; \ 150 } \ 151 \ 152 int name##_is_valid(name##_ref field){ \ 153 return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \ 154 } 80 #define GENERIC_FIELD_IMPLEMENT(name, type) \ 81 int name##_add(name##_ref field, type *value) \ 82 { \ 83 if (name##_is_valid(field)) { \ 84 if (field->next == (field->size - 1)) { \ 85 type **tmp; \ 86 tmp = (type **) realloc(field->items, \ 87 sizeof(type *) * 2 * field->size); \ 88 if (!tmp) \ 89 return ENOMEM; \ 90 field->size *= 2; \ 91 field->items = tmp; \ 92 } \ 93 field->items[field->next] = value; \ 94 ++field->next; \ 95 field->items[field->next] = NULL; \ 96 return field->next - 1; \ 97 } \ 98 return EINVAL; \ 99 } \ 100 \ 101 int name##_count(name##_ref field) \ 102 { \ 103 return name##_is_valid(field) ? field->next : -1; \ 104 } \ 105 \ 106 void name##_destroy(name##_ref field) \ 107 { \ 108 if (name##_is_valid(field)) { \ 109 int index; \ 110 field->magic = 0; \ 111 for (index = 0; index < field->next; ++ index) { \ 112 if (field->items[index]) \ 113 free(field->items[index]); \ 114 } \ 115 free(field->items); \ 116 } \ 117 } \ 118 \ 119 void name##_exclude_index(name##_ref field, int index) \ 120 { \ 121 if (name##_is_valid(field) && (index >= 0) && \ 122 (index < field->next) && (field->items[index])) { \ 123 free(field->items[index]); \ 124 field->items[index] = NULL; \ 125 } \ 126 } \ 127 \ 128 type *name##_get_index(name##_ref field, int index) \ 129 { \ 130 if (name##_is_valid(field) && (index >= 0) && \ 131 (index < field->next) && (field->items[index])) \ 132 return field->items[index]; \ 133 return NULL; \ 134 } \ 135 \ 136 type **name##_get_field(name##_ref field) \ 137 { \ 138 return name##_is_valid(field) ? field->items : NULL; \ 139 } \ 140 \ 141 int name##_initialize(name##_ref field) \ 142 { \ 143 if (!field) \ 144 return EINVAL; \ 145 field->size = 2; \ 146 field->next = 0; \ 147 field->items = (type **) malloc(sizeof(type *) * field->size); \ 148 if (!field->items) \ 149 return ENOMEM; \ 150 field->items[field->next] = NULL; \ 151 field->magic = GENERIC_FIELD_MAGIC_VALUE; \ 152 return EOK; \ 153 } \ 154 \ 155 int name##_is_valid(name##_ref field) \ 156 { \ 157 return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \ 158 } 155 159 156 160 #endif … … 158 162 /** @} 159 163 */ 160
Note:
See TracChangeset
for help on using the changeset viewer.