nkeynes@1097 | 1 | /**
|
nkeynes@1097 | 2 | * $Id$
|
nkeynes@1097 | 3 | *
|
nkeynes@1097 | 4 | * low-level 'block device' for input to cdrom discs.
|
nkeynes@1097 | 5 | *
|
nkeynes@1097 | 6 | * Copyright (c) 2009 Nathan Keynes.
|
nkeynes@1097 | 7 | *
|
nkeynes@1097 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@1097 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@1097 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@1097 | 11 | * (at your option) any later version.
|
nkeynes@1097 | 12 | *
|
nkeynes@1097 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@1097 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@1097 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@1097 | 16 | * GNU General Public License for more details.
|
nkeynes@1097 | 17 | */
|
nkeynes@1097 | 18 |
|
nkeynes@1097 | 19 | #ifndef cdrom_sector_H
|
nkeynes@1097 | 20 | #define cdrom_sector_H 1
|
nkeynes@1097 | 21 |
|
nkeynes@1097 | 22 | #include <stdio.h>
|
nkeynes@1097 | 23 | #include <glib/gtypes.h>
|
nkeynes@1097 | 24 | #include "drivers/cdrom/defs.h"
|
nkeynes@1097 | 25 |
|
nkeynes@1097 | 26 | #ifdef __cplusplus
|
nkeynes@1097 | 27 | extern "C" {
|
nkeynes@1097 | 28 | #endif
|
nkeynes@1097 | 29 |
|
nkeynes@1097 | 30 | /******************************** Sector Source ******************************/
|
nkeynes@1097 | 31 | #define SECTOR_SOURCE_TAG 0x42444556
|
nkeynes@1097 | 32 | typedef struct sector_source *sector_source_t;
|
nkeynes@1097 | 33 | typedef enum {
|
nkeynes@1097 | 34 | NULL_SECTOR_SOURCE,
|
nkeynes@1097 | 35 | FILE_SECTOR_SOURCE,
|
nkeynes@1107 | 36 | MEM_SECTOR_SOURCE,
|
nkeynes@1097 | 37 | DISC_SECTOR_SOURCE,
|
nkeynes@1097 | 38 | TRACK_SECTOR_SOURCE
|
nkeynes@1097 | 39 | } sector_source_type_t;
|
nkeynes@1097 | 40 |
|
nkeynes@1097 | 41 | typedef cdrom_error_t (*sector_source_read_fn_t)(sector_source_t, cdrom_lba_t, cdrom_count_t, unsigned char *outbuf);
|
nkeynes@1097 | 42 | typedef cdrom_error_t (*sector_source_read_sectors_fn_t)(sector_source_t, cdrom_lba_t, cdrom_count_t, cdrom_read_mode_t mode,
|
nkeynes@1097 | 43 | unsigned char *outbuf, size_t *length);
|
nkeynes@1097 | 44 | typedef void (*sector_source_destroy_fn_t)(sector_source_t);
|
nkeynes@1097 | 45 |
|
nkeynes@1097 | 46 | /**
|
nkeynes@1097 | 47 | * A 'sector source' is a read-only random-access data source that supports
|
nkeynes@1097 | 48 | * reads of arbitrary blocks within their capacity. A block device has a
|
nkeynes@1097 | 49 | * defined mode, block size, and block count.
|
nkeynes@1097 | 50 | *
|
nkeynes@1097 | 51 | * Source are ref-counted, and automatically destroyed when the reference
|
nkeynes@1097 | 52 | * count reaches 0.
|
nkeynes@1097 | 53 | */
|
nkeynes@1097 | 54 | struct sector_source {
|
nkeynes@1097 | 55 | uint32_t tag; /* sector source tag */
|
nkeynes@1097 | 56 | uint32_t ref_count; /* Reference count. Initialized to 0 */
|
nkeynes@1097 | 57 | sector_source_type_t type;
|
nkeynes@1097 | 58 |
|
nkeynes@1097 | 59 | sector_mode_t mode; /* Implies sector size. */
|
nkeynes@1107 | 60 | cdrom_count_t size; /* Block count */
|
nkeynes@1097 | 61 |
|
nkeynes@1097 | 62 | /**
|
nkeynes@1097 | 63 | * Read blocks from the device using the native block size.
|
nkeynes@1097 | 64 | * @param buf Buffer to receive the blocks
|
nkeynes@1097 | 65 | * @param block First block to transfer (numbered from 0)
|
nkeynes@1097 | 66 | * @param block_count number of blocks to transfer.
|
nkeynes@1097 | 67 | * @return 0 on success, otherwise an error code.
|
nkeynes@1097 | 68 | */
|
nkeynes@1097 | 69 | sector_source_read_fn_t read_blocks;
|
nkeynes@1097 | 70 |
|
nkeynes@1097 | 71 | /**
|
nkeynes@1097 | 72 | * Read sectors from the device using the specified read mode, performing any
|
nkeynes@1097 | 73 | * necessary conversions.
|
nkeynes@1097 | 74 | */
|
nkeynes@1097 | 75 | sector_source_read_sectors_fn_t read_sectors;
|
nkeynes@1097 | 76 |
|
nkeynes@1097 | 77 | /**
|
nkeynes@1097 | 78 | * Release all resources and memory used by the device (note should never
|
nkeynes@1097 | 79 | * be called directly
|
nkeynes@1097 | 80 | */
|
nkeynes@1097 | 81 | sector_source_destroy_fn_t destroy;
|
nkeynes@1097 | 82 |
|
nkeynes@1097 | 83 | };
|
nkeynes@1097 | 84 |
|
nkeynes@1097 | 85 | /**
|
nkeynes@1097 | 86 | * Block device that always returns zeros.
|
nkeynes@1097 | 87 | */
|
nkeynes@1097 | 88 | sector_source_t null_sector_source_new( sector_mode_t mode, cdrom_count_t size );
|
nkeynes@1097 | 89 |
|
nkeynes@1097 | 90 | #define FILE_SECTOR_FULL_FILE ((cdrom_count_t)-1)
|
nkeynes@1097 | 91 |
|
nkeynes@1097 | 92 | /**
|
nkeynes@1097 | 93 | * File reader. Last block is 0-padded.
|
nkeynes@1097 | 94 | */
|
nkeynes@1097 | 95 | sector_source_t file_sector_source_new_filename( const gchar *filename, sector_mode_t mode,
|
nkeynes@1097 | 96 | uint32_t offset, cdrom_count_t sector_count );
|
nkeynes@1097 | 97 | sector_source_t file_sector_source_new( FILE *f, sector_mode_t mode, uint32_t offset, cdrom_count_t sector_count,
|
nkeynes@1097 | 98 | gboolean closeOnDestroy );
|
nkeynes@1097 | 99 | sector_source_t file_sector_source_new_full( FILE *f, sector_mode_t mode, gboolean closeOnDestroy );
|
nkeynes@1097 | 100 |
|
nkeynes@1097 | 101 | /**
|
nkeynes@1107 | 102 | * Temp-file creator - initially empty. Creates a file in the system temp dir,
|
nkeynes@1107 | 103 | * unlinked on destruction or program exit.
|
nkeynes@1107 | 104 | */
|
nkeynes@1107 | 105 | sector_source_t tmpfile_sector_source_new( sector_mode_t mode );
|
nkeynes@1107 | 106 |
|
nkeynes@1107 | 107 | /**
|
nkeynes@1097 | 108 | * Construct a file source that shares its file descriptor with another
|
nkeynes@1097 | 109 | * file source.
|
nkeynes@1097 | 110 | */
|
nkeynes@1097 | 111 | sector_source_t file_sector_source_new_source( sector_source_t ref, sector_mode_t mode, uint32_t offset,
|
nkeynes@1097 | 112 | cdrom_count_t sector_count );
|
nkeynes@1097 | 113 |
|
nkeynes@1097 | 114 | /**
|
nkeynes@1097 | 115 | * Change the value of the source's closeOnDestroy flag
|
nkeynes@1097 | 116 | */
|
nkeynes@1097 | 117 | void file_sector_source_set_close_on_destroy( sector_source_t ref, gboolean closeOnDestroy );
|
nkeynes@1097 | 118 |
|
nkeynes@1097 | 119 | /**
|
nkeynes@1097 | 120 | * Retrieve the source's underlying FILE
|
nkeynes@1097 | 121 | */
|
nkeynes@1097 | 122 | FILE *file_sector_source_get_file( sector_source_t ref );
|
nkeynes@1097 | 123 |
|
nkeynes@1097 | 124 | /**
|
nkeynes@1097 | 125 | * Retrieve the source's underlying file descriptor
|
nkeynes@1097 | 126 | */
|
nkeynes@1097 | 127 | int file_sector_source_get_fd( sector_source_t ref );
|
nkeynes@1097 | 128 |
|
nkeynes@1107 | 129 | /** Construct a memory source with the given mode and size */
|
nkeynes@1107 | 130 | sector_source_t mem_sector_source_new( sector_mode_t mode, cdrom_count_t size );
|
nkeynes@1107 | 131 |
|
nkeynes@1107 | 132 | /**
|
nkeynes@1107 | 133 | * Construct a memory source using the supplied buffer for data.
|
nkeynes@1107 | 134 | * @param buffer The buffer to read from, which must be at least size * sector_size in length
|
nkeynes@1107 | 135 | * @param mode The sector mode of the data in the buffer, which cannot be SECTOR_UNKNOWN
|
nkeynes@1107 | 136 | * @param size Number of sectors in the buffer
|
nkeynes@1107 | 137 | * @param freeOnDestroy If true, the source owns the buffer and will release it when the
|
nkeynes@1107 | 138 | * source is destroyed.
|
nkeynes@1107 | 139 | */
|
nkeynes@1107 | 140 | sector_source_t mem_sector_source_new_buffer( unsigned char *buffer, sector_mode_t mode, cdrom_count_t size,
|
nkeynes@1107 | 141 | gboolean freeOnDestroy );
|
nkeynes@1107 | 142 |
|
nkeynes@1107 | 143 | /**
|
nkeynes@1107 | 144 | * Retrieve the underlying buffer for a memory source
|
nkeynes@1107 | 145 | */
|
nkeynes@1107 | 146 | unsigned char *mem_sector_source_get_buffer( sector_source_t source );
|
nkeynes@1107 | 147 |
|
nkeynes@1097 | 148 | /**
|
nkeynes@1097 | 149 | * Increment the reference count for a block device.
|
nkeynes@1097 | 150 | */
|
nkeynes@1097 | 151 | void sector_source_ref( sector_source_t device );
|
nkeynes@1097 | 152 |
|
nkeynes@1097 | 153 | /**
|
nkeynes@1097 | 154 | * Unreference a block device. If decremented to 0, the device will be
|
nkeynes@1097 | 155 | * destroyed.
|
nkeynes@1097 | 156 | */
|
nkeynes@1097 | 157 | void sector_source_unref( sector_source_t device );
|
nkeynes@1097 | 158 |
|
nkeynes@1097 | 159 | /**
|
nkeynes@1097 | 160 | * Release an unbound block device. If the ref count is 0, the device is
|
nkeynes@1097 | 161 | * destroyed. Otherwise the function has no effect.
|
nkeynes@1097 | 162 | */
|
nkeynes@1097 | 163 | void sector_source_release( sector_source_t device );
|
nkeynes@1097 | 164 |
|
nkeynes@1097 | 165 | cdrom_error_t sector_source_read( sector_source_t device, cdrom_lba_t lba, cdrom_count_t block_count, unsigned char *buf );
|
nkeynes@1097 | 166 |
|
nkeynes@1097 | 167 | cdrom_error_t sector_source_read_sectors( sector_source_t device, cdrom_lba_t lba, cdrom_count_t block_count,
|
nkeynes@1097 | 168 | cdrom_read_mode_t mode, unsigned char *buf, size_t *length );
|
nkeynes@1097 | 169 |
|
nkeynes@1097 | 170 | /***** Internals for sector source implementations *****/
|
nkeynes@1097 | 171 |
|
nkeynes@1097 | 172 | /**
|
nkeynes@1097 | 173 | * Initialize a new (pre-allocated) sector source
|
nkeynes@1097 | 174 | */
|
nkeynes@1097 | 175 | sector_source_t sector_source_init( sector_source_t device, sector_source_type_t type, sector_mode_t mode, cdrom_count_t size,
|
nkeynes@1097 | 176 | sector_source_read_fn_t readfn, sector_source_destroy_fn_t destroyfn );
|
nkeynes@1097 | 177 |
|
nkeynes@1097 | 178 | /**
|
nkeynes@1097 | 179 | * Default sector source destructor method
|
nkeynes@1097 | 180 | */
|
nkeynes@1097 | 181 | void default_sector_source_destroy( sector_source_t device );
|
nkeynes@1097 | 182 |
|
nkeynes@1097 | 183 |
|
nkeynes@1097 | 184 | /**
|
nkeynes@1097 | 185 | * Extract the necessary fields from a single raw sector for the given read mode.
|
nkeynes@1097 | 186 | * @param raw_sector input raw 2352 byte sector
|
nkeynes@1097 | 187 | * @param mode sector mode and field specification flags
|
nkeynes@1097 | 188 | * @param buf output buffer for sector data
|
nkeynes@1097 | 189 | * @param length output length of sector written to buf
|
nkeynes@1097 | 190 | * @return CDROM_ERROR_OK on success, otherwise an appropriate error code.
|
nkeynes@1097 | 191 | */
|
nkeynes@1097 | 192 | cdrom_error_t sector_extract_from_raw( unsigned char *raw_sector, cdrom_read_mode_t mode, unsigned char *buf, size_t *length );
|
nkeynes@1097 | 193 |
|
nkeynes@1097 | 194 | /**
|
nkeynes@1097 | 195 | * Test if the given pointer is a valid sector source
|
nkeynes@1097 | 196 | */
|
nkeynes@1097 | 197 | #define IS_SECTOR_SOURCE(dev) ((dev) != NULL && ((sector_source_t)(dev))->tag == SECTOR_SOURCE_TAG)
|
nkeynes@1097 | 198 |
|
nkeynes@1097 | 199 | /**
|
nkeynes@1097 | 200 | * Test if the given pointer is a valid sector source of the given type
|
nkeynes@1097 | 201 | */
|
nkeynes@1097 | 202 | #define IS_SECTOR_SOURCE_TYPE(dev,id) (IS_SECTOR_SOURCE(dev) && ((sector_source_t)(dev))->type == id)
|
nkeynes@1097 | 203 |
|
nkeynes@1097 | 204 |
|
nkeynes@1097 | 205 |
|
nkeynes@1097 | 206 | #ifdef __cplusplus
|
nkeynes@1097 | 207 | }
|
nkeynes@1097 | 208 | #endif
|
nkeynes@1097 | 209 |
|
nkeynes@1097 | 210 | #endif /* !cdrom_sector_H */
|