/* generic.h: */

#ifndef _GENERIC_H_
#define _GENERIC_H_

typedef unsigned long t_ulong;
typedef unsigned short t_ushort;
typedef unsigned char t_uchar;
typedef int t_bool;

typedef enum protocol {
  PRO_UNKNOWN,
  PRO_ISO,
  PRO_HIGH_SIERRA,
  PRO_ROCK,
  PRO_HFS
} t_protocol;

typedef struct VOLUME {
  CDROM		 *cd;			/* Pointer to CDROM structure	*/
  t_protocol	 protocol;		/* Protocol used		*/
  struct handler *handler;		/* Pointer to handler struct	*/
  void		 *vol_info;		/* Depends on protocol		*/
  size_t	 vol_info_size;		/* Size of vol_info structure	*/
} VOLUME;

typedef struct CDROM_OBJ {
  t_bool		directory_f;	/* TRUE iff object is a directory     */
  t_bool		symlink_f;	/* TRUE iff object is a symbolic link */
  struct handler *handler;		/* Pointer to handler struct	*/
  unsigned long		pos;		/* Current position (for read & seek) */
  void			*obj_info;	/* Depends on protocol		      */
} CDROM_OBJ;

typedef struct CDROM_INFO {
  t_bool		directory_f;	/* TRUE if object is a directory     */
  t_bool		symlink_f;	/* TRUE if object is a symbolic link */
  int			name_length;	/* length of file name		     */
  char			name[256];	/* file name			     */
  unsigned long		date;		/* creation date		     */
  unsigned long		file_length;	/* length of file		     */
  void			*suppl_info;	/* supplementary information	     */
} CDROM_INFO;

/* Codes: M=mandatory,
 *        O=optional (may be NULL)
 */

typedef struct handler {
  /*M*/ void	  (*close_vol_info)(VOLUME *);
  /*M*/ CDROM_OBJ *(*open_top_level_directory)(VOLUME *);
  /*M*/ CDROM_OBJ *(*open_obj_in_directory)(VOLUME *,CDROM_OBJ *, char *);
  /*M*/ CDROM_OBJ *(*find_parent)(VOLUME *,CDROM_OBJ *);
  /*M*/ void	  (*close_obj)(CDROM_OBJ *);
  /*M*/ int	  (*read_from_file)(VOLUME *,CDROM_OBJ *, char *, int);
  /*M*/ LONG	  (*cdrom_info)(VOLUME *,CDROM_OBJ *, CDROM_INFO *);
  /*M*/ LONG	  (*examine_next)(VOLUME *,CDROM_OBJ *, CDROM_INFO *, unsigned long *);
  /*M*/ void	  *(*clone_obj_info)(void *);
  /*M*/ t_bool	  (*is_top_level_obj)(VOLUME *,CDROM_OBJ *);
  /*M*/ t_bool	  (*same_objects)(CDROM_OBJ *, CDROM_OBJ *);
  /*O*/	t_ulong	  (*creation_date)(VOLUME *);
  /*M*/ t_ulong   (*volume_size)(VOLUME *);
  /*M*/ t_ulong   (*volume_free)(VOLUME *);
  /*M*/ void      (*volume_id)(VOLUME *, char *, int);
  /*M*/ t_ulong	  (*location)(VOLUME *,CDROM_OBJ *);
  /*M*/ t_ulong	  (*file_length)(CDROM_OBJ *);
  /*M*/ t_ulong   (*block_size)(VOLUME *);
} t_handler;

#define ISOERR_NO_PVD           3       /* prim volume descr not found  */
#define ISOERR_ILLEGAL_NAME     ERROR_INVALID_COMPONENT_NAME       /* illegal path name            */
#define ISOERR_NO_SUCH_RECORD   5       /* no such record in path table */
#define ISOERR_NOT_FOUND        ERROR_OBJECT_NOT_FOUND       /* file not found               */
#define ISOERR_BAD_ARGUMENTS    8       /* bad arguments                */
#define ISOERR_IS_SYMLINK       ERROR_IS_SOFT_LINK       /* cannot open symbolic links   */
#define ISOERR_INTERNAL        10       /* reason unknown               */



VOLUME *Open_Volume (CDROM *p_cdrom, t_bool lowercase);
void Close_Volume (VOLUME *p_volume);

CDROM_OBJ *Open_Top_Level_Directory (VOLUME *p_volume);
CDROM_OBJ *Open_Object (VOLUME *p_volume,CDROM_OBJ *p_current_dir, char *p_path_name);
void Close_Object (CDROM_OBJ *p_object);

int Read_From_File (VOLUME *p_volume,CDROM_OBJ *p_file, char *p_buffer, int p_buffer_length);

LONG CDROM_Info (VOLUME *p_volume,CDROM_OBJ *p_obj, CDROM_INFO *p_info);
LONG Examine_Next (VOLUME *p_volume,CDROM_OBJ *p_dir, CDROM_INFO *p_info, unsigned long *p_offset);

CDROM_OBJ *Clone_Object (CDROM_OBJ *p_object);
CDROM_OBJ *Find_Parent (VOLUME *p_volume,CDROM_OBJ *p_object);

t_bool Is_Top_Level_Object (VOLUME *p_volume,CDROM_OBJ *p_object);

LONG Seek_Position (CDROM_OBJ *p_object, long p_offset, int p_mode);

t_bool Same_Objects (CDROM_OBJ *p_object1, CDROM_OBJ *p_object2);
t_ulong Volume_Creation_Date (VOLUME *p_volume);
t_ulong Volume_Size (VOLUME *p_volume);
t_ulong Volume_Free (VOLUME *p_volume);
t_ulong Block_Size (VOLUME *p_volume);
void Volume_ID (VOLUME *p_volume, char *p_buffer, int p_buf_length);
t_ulong Location (VOLUME *p_volume,CDROM_OBJ *p_object);
int Full_Path_Name (VOLUME *p_volume,CDROM_OBJ *p_obj, char *p_buf, int p_buf_length);


#endif /* _GENERIC_H_ */
