libcdio  2.1.0
About: GNU libcdio is a library for CD-ROM and CD image access.
  Fossies Dox: libcdio-2.1.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

read.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2005, 2008, 2011, 2012 Rocky Bernstein <rocky@gnu.org>
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
21 
22 
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 # define __CDIO_CONFIG_H__ 1
26 #endif
27 
28 #ifdef HAVE_STDBOOL_H
29 # include <stdbool.h>
30 #endif
31 
32 #include <cdio/cdio.h>
33 #include <cdio/logging.h>
34 #include "cdio_private.h"
35 #include "cdio_assert.h"
36 
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
40 
41 #define check_read_parms(p_cdio, p_buf, i_lsn) \
42  if (!p_cdio) return DRIVER_OP_UNINIT; \
43  if (!p_buf || CDIO_INVALID_LSN == i_lsn) \
44  return DRIVER_OP_ERROR;
45 
46 #define check_lsn(i_lsn) \
47  check_read_parms(p_cdio, p_buf, i_lsn); \
48  { \
49  lsn_t end_lsn = \
50  cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK); \
51  if ( i_lsn > end_lsn ) { \
52  cdio_info("Trying to access past end of disk lsn: %ld, end lsn: %ld", \
53  (long int) i_lsn, (long int) end_lsn); \
54  return DRIVER_OP_ERROR; \
55  } \
56  }
57 
58 #define check_lsn_blocks(i_lsn, i_blocks) \
59  check_read_parms(p_cdio, p_buf, i_lsn); \
60  { \
61  lsn_t end_lsn = \
62  cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK); \
63  if ( i_lsn > end_lsn ) { \
64  cdio_info("Trying to access past end of disk lsn: %ld, end lsn: %ld", \
65  (long int) i_lsn, (long int) end_lsn); \
66  return DRIVER_OP_ERROR; \
67  } \
68  /* Care is used in the expression below to be correct with */ \
69  /* respect to unsigned integers. */ \
70  if ( i_lsn + i_blocks > end_lsn + 1 ) { \
71  cdio_info("Request truncated to end disk; lsn: %ld, end lsn: %ld", \
72  (long int) i_lsn, (long int) end_lsn); \
73  i_blocks = end_lsn - i_lsn + 1; \
74  } \
75  }
76 
82 off_t
83 cdio_lseek (const CdIo_t *p_cdio, off_t offset, int whence)
84 {
85  if (!p_cdio) return DRIVER_OP_UNINIT;
86 
87  if (p_cdio->op.lseek)
88  return (p_cdio->op.lseek) (p_cdio->env, offset, whence);
89  return DRIVER_OP_UNSUPPORTED;
90 }
91 
104 ssize_t
105 cdio_read (const CdIo_t *p_cdio, void *p_buf, size_t i_size)
106 {
107  if (!p_cdio) return DRIVER_OP_UNINIT;
108 
109  if (p_cdio->op.read)
110  return (p_cdio->op.read) (p_cdio->env, p_buf, i_size);
111  return DRIVER_OP_UNSUPPORTED;
112 }
113 
119 cdio_read_audio_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn)
120 {
121  check_lsn(i_lsn);
122  if (p_cdio->op.read_audio_sectors)
123  return p_cdio->op.read_audio_sectors (p_cdio->env, p_buf, i_lsn, 1);
124  return DRIVER_OP_UNSUPPORTED;
125 }
126 
132 cdio_read_audio_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
133  uint32_t i_blocks)
134 {
135  check_lsn_blocks(i_lsn, i_blocks);
136 
137  if (0 == i_blocks) return DRIVER_OP_SUCCESS;
138 
139  if (p_cdio->op.read_audio_sectors) {
140  cdio_debug("Reading audio sector(s) lsn %u for %d blocks",
141  i_lsn, i_blocks);
142  return (p_cdio->op.read_audio_sectors) (p_cdio->env, p_buf, i_lsn,
143  i_blocks);
144  }
145  return DRIVER_OP_UNSUPPORTED;
146 }
147 
153 cdio_read_data_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
154  uint16_t i_blocksize, uint32_t i_blocks)
155 {
156  check_lsn(i_lsn);
157 
158  if (0 == i_blocks) return DRIVER_OP_SUCCESS;
159 
160  if (p_cdio->op.read_data_sectors) {
161  cdio_debug("Reading data sector(s) lsn, %u blocksize %d, for %d blocks",
162  i_lsn, i_blocksize, i_blocks);
163  return p_cdio->op.read_data_sectors (p_cdio->env, p_buf, i_lsn,
164  i_blocksize, i_blocks);
165  }
166  return DRIVER_OP_UNSUPPORTED;
167 }
168 
169 
170 #ifndef SEEK_SET
171 #define SEEK_SET 0
172 #endif
173 
179 cdio_read_mode1_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
180  bool b_form2)
181 {
182  uint32_t size = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE ;
183 
184  check_lsn(i_lsn);
185  if (p_cdio->op.read_mode1_sector) {
186  cdio_debug("Reading mode 1 secto lsn %u", i_lsn);
187  return p_cdio->op.read_mode1_sector(p_cdio->env, p_buf, i_lsn, b_form2);
188  } else if (p_cdio->op.lseek && p_cdio->op.read) {
189  char buf[M2RAW_SECTOR_SIZE] = { 0, };
190  if (0 > cdio_lseek(p_cdio, CDIO_CD_FRAMESIZE*i_lsn, SEEK_SET))
191  return -1;
192  if (0 > cdio_read(p_cdio, buf, CDIO_CD_FRAMESIZE))
193  return -1;
194  memcpy (p_buf, buf, size);
195  return DRIVER_OP_SUCCESS;
196  }
197 
198  return DRIVER_OP_UNSUPPORTED;
199 }
200 
212 cdio_read_mode1_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
213  bool b_form2, uint32_t i_blocks)
214 {
215  check_lsn_blocks(i_lsn, i_blocks);
216 
217  if (0 == i_blocks) return DRIVER_OP_SUCCESS;
218 
219  if (p_cdio->op.read_mode1_sectors)
220  return (p_cdio->op.read_mode1_sectors) (p_cdio->env, p_buf, i_lsn, b_form2,
221  i_blocks);
222  return DRIVER_OP_UNSUPPORTED;
223 }
224 
235 cdio_read_mode2_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
236  bool b_form2)
237 {
238  check_lsn(i_lsn);
239  if (p_cdio->op.read_mode2_sector)
240  return p_cdio->op.read_mode2_sector (p_cdio->env, p_buf, i_lsn, b_form2);
241 
242  /* fallback */
243  if (p_cdio->op.read_mode2_sectors != NULL)
244  return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, b_form2, 1);
245  return DRIVER_OP_UNSUPPORTED;
246 }
247 
259 cdio_read_mode2_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
260  bool b_form2, uint32_t i_blocks)
261 {
262  check_lsn_blocks(i_lsn, i_blocks);
263 
264  if (0 == i_blocks) return DRIVER_OP_SUCCESS;
265 
266  if (p_cdio->op.read_mode2_sectors)
267  return (p_cdio->op.read_mode2_sectors) (p_cdio->env, p_buf, i_lsn,
268  b_form2, i_blocks);
269  return DRIVER_OP_UNSUPPORTED;
270 
271 }
272 
273 
278 cdio_read_sector(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
279  cdio_read_mode_t read_mode)
280 {
281  return cdio_read_sectors(p_cdio, p_buf, i_lsn, read_mode, 1);
282 }
283 
314 cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
315  cdio_read_mode_t read_mode, uint32_t i_blocks)
316 {
317  switch(read_mode) {
319  return cdio_read_audio_sectors (p_cdio, p_buf, i_lsn, i_blocks);
320  case CDIO_READ_MODE_M1F1:
321  return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
322  case CDIO_READ_MODE_M1F2:
323  return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, true, i_blocks);
324  case CDIO_READ_MODE_M2F1:
325  return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
326  case CDIO_READ_MODE_M2F2:
327  return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, true, i_blocks);
328  }
329  /* Can't happen. Just to shut up gcc. */
330  return DRIVER_OP_ERROR;
331 }
332 
333 /*
334  * Local variables:
335  * c-file-style: "gnu"
336  * tab-width: 8
337  * indent-tabs-mode: nil
338  * End:
339  */
SEEK_SET
#define SEEK_SET
Definition: read.c:171
cdio_funcs_t::lseek
off_t(* lseek)(void *p_env, off_t offset, int whence)
Definition: cdio_private.h:360
CDIO_READ_MODE_AUDIO
Definition: read.h:35
cdio_read_data_sectors
driver_return_code_t cdio_read_data_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: read.c:153
cdio_read_mode1_sectors
driver_return_code_t cdio_read_mode1_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2, uint32_t i_blocks)
Definition: read.c:212
cdio.h
The top-level header for libcdio: the CD Input and Control library. Applications include this for any...
cdio_funcs_t::read_mode2_sectors
int(* read_mode2_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2, unsigned int i_blocks)
Definition: cdio_private.h:410
lsn_t
int32_t lsn_t
Definition: types.h:266
driver_return_code_t
driver_return_code_t
Definition: device.h:205
CDIO_READ_MODE_M1F2
Definition: read.h:37
cdio_read_mode1_sector
driver_return_code_t cdio_read_mode1_sector(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2)
Definition: read.c:179
cdio_lseek
off_t cdio_lseek(const CdIo_t *p_cdio, off_t offset, int whence)
Definition: read.c:83
DRIVER_OP_UNSUPPORTED
Definition: device.h:212
_CdIo
Definition: cdio_private.h:472
cdio_private.h
cdio_debug
void void cdio_debug(const char format[],...) GNUC_PRINTF(1
cdio_funcs_t::read_mode1_sector
int(* read_mode1_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2)
Definition: cdio_private.h:418
_CdIo::env
void * env
Definition: cdio_private.h:476
cdio_read_audio_sectors
driver_return_code_t cdio_read_audio_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, uint32_t i_blocks)
Definition: read.c:132
cdio_funcs_t::read_mode2_sector
int(* read_mode2_sector)(void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2)
Definition: cdio_private.h:402
NULL
#define NULL
Definition: types.h:184
cdio_read_sectors
driver_return_code_t cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, cdio_read_mode_t read_mode, uint32_t i_blocks)
Definition: read.c:314
cdio_funcs_t::read_audio_sectors
int(* read_audio_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, unsigned int i_blocks)
Definition: cdio_private.h:373
CDIO_READ_MODE_M2F1
Definition: read.h:38
CDIO_READ_MODE_M2F2
Definition: read.h:39
cdio_read_sector
driver_return_code_t cdio_read_sector(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, cdio_read_mode_t read_mode)
Definition: read.c:278
cdio_funcs_t::read_data_sectors
driver_return_code_t(* read_data_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize, uint32_t i_blocks)
Definition: cdio_private.h:394
M2RAW_SECTOR_SIZE
Definition: sector.h:190
DRIVER_OP_ERROR
Definition: device.h:211
_CdIo::op
cdio_funcs_t op
Definition: cdio_private.h:474
cdio_read
ssize_t cdio_read(const CdIo_t *p_cdio, void *p_buf, size_t i_size)
Definition: read.c:105
cdio_read_mode_t
cdio_read_mode_t
Definition: read.h:34
logging.h
Header to control logging and level of detail of output.
cdio_read_audio_sector
driver_return_code_t cdio_read_audio_sector(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn)
Definition: read.c:119
config.h
cdio_read_mode2_sector
driver_return_code_t cdio_read_mode2_sector(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2)
Definition: read.c:235
DRIVER_OP_SUCCESS
Definition: device.h:206
CDIO_CD_FRAMESIZE
Definition: sector.h:116
DRIVER_OP_UNINIT
Definition: device.h:217
check_lsn
#define check_lsn(i_lsn)
Definition: read.c:46
CDIO_READ_MODE_M1F1
Definition: read.h:36
check_lsn_blocks
#define check_lsn_blocks(i_lsn, i_blocks)
Definition: read.c:58
cdio_assert.h
cdio_funcs_t::read_mode1_sectors
int(* read_mode1_sectors)(void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2, unsigned int i_blocks)
Definition: cdio_private.h:426
cdio_read_mode2_sectors
driver_return_code_t cdio_read_mode2_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2, uint32_t i_blocks)
Definition: read.c:259
cdio_funcs_t::read
ssize_t(* read)(void *p_env, void *p_buf, size_t i_size)
Definition: cdio_private.h:367