/*--------------------------------------------------------------------------- | Facility : libnform | Function : static TypeArgument *GenericArgument( | const FIELDTYPE* typ, | int (*argiterator)(void**), | int* err) | | Description : The iterator callback must browse through all fieldtype | parameters that have an argument associated with the | type. The iterator returns 1 if the operation to get | the next element was successfull, 0 otherwise. If the | iterator could move to the next argument, it fills | the void* pointer representing the argument into the | location provided as argument to the iterator. | The err reference is used to keep track of errors. | | Return Values : Pointer to argument structure +--------------------------------------------------------------------------*/ static TypeArgument * GenericArgument(const FIELDTYPE *typ, int (*argiterator) (void **), int *err) { TypeArgument *res = (TypeArgument *)0; if (typ != 0 && (typ->status & _HAS_ARGS) != 0 && err != 0 && argiterator != 0) { if (typ->status & _LINKED_TYPE) { /* Composite fieldtypes keep track internally of their own memory */ TypeArgument *p = typeMalloc(TypeArgument, 1); if (p) { p->left = GenericArgument(typ->left, argiterator, err); p->right = GenericArgument(typ->right, argiterator, err); return p; } else *err += 1; } else { assert(typ->genericarg != (void *)0); if (typ->genericarg == 0) *err += 1; else { void *argp; int valid = argiterator(&argp); if (valid == 0 || argp == 0 || !(res = (TypeArgument *)typ->genericarg(argp))) { *err += 1; } } } } return res; }
_nc_set_generic_fieldtype(FIELD *field, FIELDTYPE *ftyp, int (*argiterator) (void **)) { int code = E_SYSTEM_ERROR; int err = 0; if (field) { if (field && field->type) _nc_Free_Type(field); field->type = ftyp; if (ftyp) { if (argiterator) { /* The precondition is that the iterator is reset */ field->arg = (void *)GenericArgument(field->type, argiterator, &err); if (err) { _nc_Free_Argument(field->type, (TypeArgument *)(field->arg)); field->type = (FIELDTYPE *)0; field->arg = (void *)0; } else { code = E_OK; if (field->type) field->type->ref++; } } } else { field->arg = (void *)0; code = E_OK; } } return code; }
void ListReader::Initialize(TypeReaderManager* typeReaderManager) { // When specializing the generic List<T> reader, look up how to read our specific element type T. elementReader = typeReaderManager->GetByTargetType(GenericArgument(0)); }
void DictionaryReader::Initialize(TypeReaderManager* typeReaderManager) { // When specializing the generic Dictionary<K, V> reader, look up how to read our specific types K and V. keyReader = typeReaderManager->GetByTargetType(GenericArgument(0)); valueReader = typeReaderManager->GetByTargetType(GenericArgument(1)); }
void NullableReader::Initialize(TypeReaderManager* typeReaderManager) { // When specializing the generic Nullable<T> reader, look up how to read our specific value type T. valueReader = typeReaderManager->GetByTargetType(GenericArgument(0)); }