Harlequin RIP SDK

Implementation of the file system device type. More...

#include "skinkit.h"
#include "devutils.h"
#include "ripthread.h"
#include "file.h"
#include "paths.h"
#include "mem.h"
#include "sync.h"
#include "skindevs.h"
#include "hqmemcpy.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "swdevice.h"
#include "swoften.h"

Data Structures

struct  FileDeviceState
 Structure to hold device-specific state. More...
 

Typedefs

typedef struct FileDeviceState FileDeviceState
 Structure to hold device-specific state.
 

Functions

FileDeviceStatedevstate (DEVICELIST *dev)
 Extract private state from devicelist.
 
static HqBool initialiseDeviceState (DEVICELIST *dev)
 Initialise a FileDeviceState object. More...
 
static void uninitialiseDeviceState (FileDeviceState *pDeviceState)
 Uninitialise a FileDeviceState object.
 
static int32 fs_device_init (DEVICELIST *dev)
 File system device initialisation. More...
 
static int32 fs_ioerror (DEVICELIST *dev)
 
static int32 fs_spare (void)
 
static DEVICE_FILEDESCRIPTOR fs_open_file (DEVICELIST *dev, uint8 *filename, int32 openflags)
 The file_open call for the file system device type.
 
static int32 fs_read_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, uint8 *buff, int32 len)
 The read_file routine for the file system device type. More...
 
static int32 fs_write_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, uint8 *buff, int32 len)
 The write_file routine for the file system device type. More...
 
static int32 fs_close_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor)
 The close_file routine for the file system device type. More...
 
static int32 fs_seek_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, Hq32x2 *destination, int32 flags)
 The seek_file routine for the file system device type.
 
static int32 fs_bytes_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, Hq32x2 *bytes, int32 reason)
 The bytes_file routine for the file system device type. More...
 
static int32 fs_status_file (DEVICELIST *dev, uint8 *filename, STAT *statbuff)
 The status_file routine for the file system device type.
 
static void * fs_start_file_list (DEVICELIST *dev, uint8 *pattern)
 
  • fs_start_file_list

 
static int32 fs_next_file (DEVICELIST *dev, void **handle, uint8 *pattern, FILEENTRY *entry)
 fs_next_file
 
static int32 fs_end_file_list (DEVICELIST *dev, void *handle)
 fs_end_file_list
 
static int32 fs_rename_file (DEVICELIST *dev, uint8 *file1, uint8 *file2)
 The rename_file routine for the file system device type.
 
static int32 fs_delete_file (DEVICELIST *dev, uint8 *filename)
 The delete_file routine for the file system device type.
 
static int32 fs_set_param (DEVICELIST *dev, DEVICEPARAM *param)
 The set_param routine for the file system device type. More...
 
static int32 fs_get_param (DEVICELIST *dev, DEVICEPARAM *param)
 The get_param routine for the file system device type. More...
 
static int32 fs_status_device (DEVICELIST *dev, DEVSTAT *devstat)
 The status_device routine for the file system device type. More...
 
static int32 fs_device_dismount (DEVICELIST *dev)
 The device_dismount routine for the file system device type.
 
static int32 fs_ioctl (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, int32 opcode, intptr_t arg)
 The ioctl routine for the file system device type.
 

Variables

static int32 fs_param_count = 0
 The start_param routine for the file system device type. More...
 
DEVICETYPE Fs_Device_Type
 The device type structure for the file system devices. More...
 

Detailed Description

Implementation of the file system device type.

Implementation of the file system device type.

The device type interface is described in DEVICE interface.

This is a largely complete, though simple, implementation.

The most complex part is the implementation of the filenameforall operator through the three relevant functions in the device.

This is the device type which is assigned the device type number 0; see SDK devices and the DEVICE interface for a discussion of device type numbers.

A system which does not have a disk is still required to support a device type 0. However, the semantics would be different: it would only need to be readable, and supply known named files, such as SW/Sys/ExtraDevices (which is essential) and built-in fonts. It could provide the byte stream for the read calls straight out of memory (ROM perhaps) rather than accessing a disk.

The operation of this implementation of the device type is that each device of this type represents a portion of the file system, e.g., on a PC the devices might be used to represent drives (%C%, %D%, ...) and on a Macintosh they represent volumes. There will always be a device %os% created implictly by the core rip, and this will usually be a restricted part of the file system: Harlequin's own products have a directory called "SW" by default which is what %os% refers to. Such a directory is supplied with the Core RIP library, including example system files, many of which may be used unchanged.

This implementation uses one device parameter, /Prefix. This identifies where on the filing system the PostScript device is to refer to. This is a string representing a native pathname on the target file system. When PostScript refers to a file called "%p%aa/bb/cc", we map this to a name in the file system. This implementation does this by prefixing the name passed to the open call ("aa/bb/cc") with the prefix for the device (which is assumed to terminate with a '/'). The prefix is stored in the private data field of the devicelist structure for each device.

There is nothing special about the / in the PostScript name, but we map it to the platform's directory separator. This has two consequences: because the semantics of the name "aa/bb/cc" are those of a flat file system, when a request is made to open the file for writing, if we are to use the same name, we must create any directories in the path in order to open the file. The mapping also means that we ignore the difference between files called "aa/bb/cc/" and "aa/bb/cc". These are both valid PostScript names and should refer to different files, but are mapped to the same file in this implementation. To be strictly correct this should be handled by some more sophisticated name mapping.

Some names will causes failures, e.g., names with an embedded colon on Windows. To overcome this some name mapping mechanism would need to be implemented.

The /Prefix is obtained by the setdevparams PostScript operator, so a useful piece of PostScript (to go in SW/Sys/ExtraDevices, for example) would be:

statusdict begin
(%%cd%) dup devmount pop
<<
  /Password 0
  /DeviceType 0
  /Prefix (./)
  /Enable true
>> setdevparams
end

(devmount is not listed in the PostScript Language Reference Manual, but is found in all PostScript rips with file systems).

However, there is no PostScript associated with mounting the %os% device: it needs to exist in order for SW/Sys/ExtraDevices to be executed. This implementation assumes its prefix is always SW/ (i.e., a directory called SW in the current working directory). More general solutions include obtaining this from an environment variable, configuration file or command line option.

Though almost complete more general consideration might be given to the following:

Function Documentation

◆ fs_bytes_file()

static int32 fs_bytes_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor,
Hq32x2 bytes,
int32  reason 
)
static

The bytes_file routine for the file system device type.

reason SW_BYTES_AVAIL_REL - immediately available after current pos reason SW_BYTES_TOTAL_ABS - total extent of file in bytes

◆ fs_close_file()

static int32 fs_close_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor 
)
static

The close_file routine for the file system device type.

The abort call also invokes this function, because an abnormal close is the same as a normal close for the file system device type.

◆ fs_device_init()

static int32 fs_device_init ( DEVICELIST dev)
static

File system device initialisation.

This is called for each device (note: not device type) when its type number is assigned by a call to setdevparams.

◆ fs_get_param()

static int32 fs_get_param ( DEVICELIST dev,
DEVICEPARAM param 
)
static

The get_param routine for the file system device type.

This routine serves two purposes: when the parameter name is NULL, it is to return the next device parameter - fs_param_count keeps track of how far through the list we are, though in this case there is only one - otherwise it should return the one called for by the name.

◆ fs_ioerror()

static int32 fs_ioerror ( DEVICELIST dev)
static

A device type function stub that raises an IOerror.

◆ fs_read_file()

static int32 fs_read_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor,
uint8 buff,
int32  len 
)
static

The read_file routine for the file system device type.

Read from file described by 'descriptor' which is on the device 'dev' into the buffer 'buff'.

For abnormally large buffers (only when the device requests such sizes by the appropriate device type call), reading from the file system in chunks might be required, with SwOften calls between each.

◆ fs_set_param()

static int32 fs_set_param ( DEVICELIST dev,
DEVICEPARAM param 
)
static

The set_param routine for the file system device type.

The only parameter that this implementation recognises is /Prefix, which must be a string, and it is used to define the prefix which is tacked on to the beginning of any filename requested by Harlequin RIP.

◆ fs_spare()

static int32 fs_spare ( void  )
static

Stub routine for spare device type slot.

◆ fs_status_device()

static int32 fs_status_device ( DEVICELIST dev,
DEVSTAT *  devstat 
)
static

The status_device routine for the file system device type.

This is in contrast to status_file: it returns information about a device of this device type, rather than a file open on the device. The comprehensive implementation of this routine is likely to be complex. The example here simply gives no useful information.

◆ fs_write_file()

static int32 fs_write_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor,
uint8 buff,
int32  len 
)
static

The write_file routine for the file system device type.

Write to the file described by 'descriptor' which is on the device 'dev' from the buffer 'buff'.

The comment for reading regarding SwOften also applies here.

◆ initialiseDeviceState()

static HqBool initialiseDeviceState ( DEVICELIST dev)
static

Initialise a FileDeviceState object.

pDeviceState should point to preallocated memory.

Variable Documentation

◆ Fs_Device_Type

DEVICETYPE Fs_Device_Type

The device type structure for the file system devices.

Points to note: (a) of the function pointers included in this structure, only the tickle function should be a NULL pointer. The rest must be filled in with stub routines which at least set the last error flag appropriately. (b) the device is "relative" (it can support named files, unlike, for example, a serial line). This means that when an attempt is made to open a named file in PostScript unqualified by a device, devices of this type will each receive open requests until one does not report an "undefined" error. See SDK DG 10.7.2. (c) the device is "writable": this means that devices of this type will be considered when trying to open a file for writing from PostScript.

◆ fs_param_count

int32 fs_param_count = 0
static

The start_param routine for the file system device type.

The routine is called as part of the currentdevparams operator; the individual parameters are returned one at a time by subsequent calls to the get_param function. fs_param_count is used to maintain the state between calls to get_param.

Also return the number of parameters recognized by this implementation of the file system device type.