! . */
| 9251 | |
| 9252 | /*! . */ |
| 9253 | int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometry, unsigned int direction, void *data, char *name) { |
| 9254 | /* Associate a virtual file with a data object for either reading or writing. |
| 9255 | * Family and geometry specifies the nature of the data to be read or written. |
| 9256 | * Direction is either GMT_IN or GMT_OUT and determines if we read or write. |
| 9257 | * Reading: data must point to a data container we wish to read from via a module. |
| 9258 | * Writing: data is either an existing output data container that the user created |
| 9259 | * beforehand or it is NULL and we create an expanding output resource. |
| 9260 | * name is the name given to the virtual file and is returned. */ |
| 9261 | int object_ID = GMT_NOTSET, item_s = 0; |
| 9262 | unsigned int item, orig_family, actual_family = 0, via_type = 0, messenger = 0, module_input, the_mode = GMT_IS_DUPLICATE; |
| 9263 | struct GMTAPI_DATA_OBJECT *S_obj = NULL; |
| 9264 | struct GMTAPI_CTRL *API = NULL; |
| 9265 | if (V_API == NULL) return_error (V_API, GMT_NOT_A_SESSION); |
| 9266 | module_input = (family & GMT_VIA_MODULE_INPUT); /* Are we registering a resource that is a module input? */ |
| 9267 | family -= module_input; |
| 9268 | if (direction & GMT_IS_REFERENCE) { /* Treat this memory as read-only */ |
| 9269 | direction -= GMT_IS_REFERENCE; |
| 9270 | the_mode = GMT_IS_REFERENCE; |
| 9271 | } |
| 9272 | else if (direction & GMT_IS_DUPLICATE) /* This is the default - just remove the mode flag */ |
| 9273 | direction -= GMT_IS_DUPLICATE; |
| 9274 | if (!(direction == GMT_IN || direction == GMT_OUT)) return GMT_NOT_A_VALID_DIRECTION; |
| 9275 | if (direction == GMT_IN && data == NULL) return GMT_PTR_IS_NULL; |
| 9276 | if (name == NULL) return_error (V_API, GMT_PTR_IS_NULL); |
| 9277 | orig_family = family; /* In case we will call GMT_Create_Data later */ |
| 9278 | actual_family = gmtapi_separate_families (&family); /* In case via have a VIA situation */ |
| 9279 | if (geometry >= GMT_VIA_CHAR) { |
| 9280 | via_type = (geometry / 100); /* via_type is 1 higher than GMT_CHAR */ |
| 9281 | geometry %= 100; |
| 9282 | } |
| 9283 | if (direction == GMT_IN && !gmtapi_valid_input_family (family)) return GMT_NOT_A_VALID_FAMILY; |
| 9284 | if (direction == GMT_OUT && !gmtapi_valid_output_family (family)) return GMT_NOT_A_VALID_FAMILY; |
| 9285 | if (via_type && data && !gmtapi_valid_type (via_type-1)) return GMT_NOT_A_VALID_TYPE; /* via type only valid if not passing any data but want vector or matrix */ |
| 9286 | if (actual_family != family && !gmtapi_valid_via_family (actual_family)) return GMT_NOT_A_VALID_FAMILY; |
| 9287 | API = gmtapi_get_api_ptr (V_API); |
| 9288 | |
| 9289 | if (data) { /* Data container provided, see if registered */ |
| 9290 | for (item = 0; object_ID == GMT_NOTSET && item < API->n_objects; item++) { /* Loop over all objects */ |
| 9291 | if (!API->object[item]) continue; /* Skip freed objects */ |
| 9292 | if (API->object[item]->resource == data) object_ID = API->object[item]->ID; /* Found a matching data pointer */ |
| 9293 | } |
| 9294 | if (object_ID != GMT_NOTSET && (item_s = gmtapi_get_item (API, family, data)) == GMT_NOTSET) { /* Not found in list */ |
| 9295 | return_error (API, GMT_OBJECT_NOT_FOUND); /* Could not find that item in the array despite finding its ID? */ |
| 9296 | } |
| 9297 | S_obj = API->object[item_s]; /* Short-hand for later */ |
| 9298 | if (!(S_obj->family == family && S_obj->actual_family == actual_family)) |
| 9299 | return GMT_NOT_A_VALID_FAMILY; |
| 9300 | } |
| 9301 | if (direction == GMT_IN) { /* Set things up for reading */ |
| 9302 | /* See if this one is known to us already */ |
| 9303 | if (object_ID == GMT_NOTSET) { /* Register data as a new object for reading [GMT_IN] and reset its status to unread */ |
| 9304 | if ((object_ID = GMT_Register_IO (API, family, the_mode|GMT_IO_RESET, geometry, GMT_IN, NULL, data)) == GMT_NOTSET) |
| 9305 | return (API->error); |
| 9306 | if ((item_s = gmtapi_get_item (API, family, data)) == GMT_NOTSET) { /* Not found in list */ |
| 9307 | return_error (API, GMT_OBJECT_NOT_FOUND); /* Could not find that item in the array despite finding its ID? */ |
| 9308 | } |
| 9309 | S_obj = API->object[item_s]; /* Short-hand for later */ |
| 9310 | } |