Ejemplo n.º 1
0
/*
 *   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;
}
Ejemplo n.º 2
0
/*
 *   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;
}