/* * Open a network file */ CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc, int mode, os_filetype_t typ, const char *mime_type) { vm_val_t filespec; /* check for a TadsObject implementing getFilename */ if (G_predef->filespec_getFilename != VM_INVALID_PROP && val->typ == VM_OBJ && CVmObjTads::is_tadsobj_obj(vmg_ val->val.obj)) { /* call getFilename - the return value is the file spec */ G_interpreter->get_prop( vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc); /* the result is the real file spec */ filespec = *G_interpreter->get_r0(); } else { /* it's not a TadsObject, so it must directly have the file name */ filespec = *val; } /* check the argument type */ CVmNetFile *nf = 0; if (filespec.typ == VM_OBJ && CVmObjTemporaryFile::is_tmpfil_obj(vmg_ filespec.val.obj)) { /* temporary file object - get the object, properly cast */ CVmObjTemporaryFile *tmp = (CVmObjTemporaryFile *)vm_objp( vmg_ filespec.val.obj); /* if the temporary file object is invalid, it's an error */ if (tmp->get_fname() == 0) err_throw(VMERR_CREATE_FILE); /* create the local file descriptor for the temp file path */ nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ); /* mark it as a temp file */ nf->is_temp = TRUE; } else { /* anything else has to be a string */ char fname[OSFNMAX]; CVmBif::get_str_val_fname(vmg_ fname, sizeof(fname), CVmBif::get_str_val(vmg_ &filespec)); /* * if it's a local file, and it has a relative path, explicitly * apply the image file path as the default working directory */ if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_)) { /* build the full, absolute name based on the image file path */ char fname_abs[OSFNMAX]; os_build_full_path(fname_abs, sizeof(fname_abs), G_image_loader->get_path(), fname); /* replace the relative path with the new absolute path */ lib_strcpy(fname, sizeof(fname), fname_abs); } /* create the regular network file descriptor */ nf = open(vmg_ fname, 0, mode, typ, mime_type); } /* if they gave us an object as our file spec, remember it */ if (nf != 0 && val->typ == VM_OBJ) nf->filespec = val->val.obj; /* return the network file descriptor */ return nf; }
/* * Open a network file */ CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc, int mode, os_filetype_t typ, const char *mime_type) { vm_val_t filespec; /* check for a TadsObject implementing getFilename */ if (G_predef->filespec_getFilename != VM_INVALID_PROP && vm_val_cast_ok(CVmObjTads, val)) { /* call getFilename - the return value is the file spec */ G_interpreter->get_prop( vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc); /* the result is the real file spec */ filespec = *G_interpreter->get_r0(); } else { /* it's not a TadsObject, so it must directly have the file name */ filespec = *val; } /* check the file spec argument type */ CVmNetFile *nf = 0; CVmObjTemporaryFile *tmp = 0; CVmObjFileName *ofn = 0; if ((tmp = vm_val_cast(CVmObjTemporaryFile, &filespec)) != 0) { /* if the temporary file object is invalid, it's an error */ if (tmp->get_fname() == 0) err_throw(VMERR_CREATE_FILE); /* create the local file descriptor for the temp file path */ nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ); /* mark it as a temp file */ nf->is_temp = TRUE; } else if (filespec.is_numeric(vmg0_) || ((ofn = vm_val_cast(CVmObjFileName, &filespec)) != 0 && ofn->is_special_file())) { /* * It's a special file ID, either as an integer or as a FileName * wrapping a special file int. Get the value. */ int32_t sfid = (ofn != 0 ? ofn->get_sfid() : filespec.num_to_int(vmg0_)); /* resolve the file system path for the given special file ID */ char fname[OSFNMAX] = { '\0' }; if (!CVmObjFile::sfid_to_path(vmg_ fname, sizeof(fname), sfid)) err_throw(VMERR_BAD_VAL_BIF); /* create the special file descriptor */ nf = open(vmg_ fname, sfid, mode, typ, mime_type); } else { /* anything else has to be a string */ char fname[OSFNMAX]; CVmBif::get_fname_val(vmg_ fname, sizeof(fname), &filespec); /* * if it's a local file, and it has a relative path, explicitly * apply the image file path as the default working directory */ if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_)) { /* build the full, absolute name based on the file base path */ char fnabs[OSFNMAX]; os_build_full_path(fnabs, sizeof(fnabs), G_file_path, fname); /* replace the relative path with the new absolute path */ lib_strcpy(fname, sizeof(fname), fnabs); } /* create the regular network file descriptor */ nf = open(vmg_ fname, 0, mode, typ, mime_type); } /* if they gave us an object as our file spec, remember it */ if (nf != 0 && val->typ == VM_OBJ) nf->filespec = val->val.obj; /* return the network file descriptor */ return nf; }