Make udf_read_block more like 2 read. Implementation is closer

to the description (although it needs more work.)
udf_fs.h: break out udf_check_tag()
*.h: /*! -> /** - is more like Javadoc.
This commit is contained in:
rocky
2006-04-11 05:47:57 +00:00
parent e039fcee0e
commit d0d5ea424f
6 changed files with 111 additions and 51 deletions

View File

@@ -1,6 +1,6 @@
/* /*
$Id: udf_file.h,v 1.7 2005/11/06 19:12:35 rocky Exp $ $Id: udf_file.h,v 1.8 2006/04/11 05:47:57 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/*! /**
* \file udf_file.h * \file udf_file.h
* *
* \brief Routines involving UDF file operations * \brief Routines involving UDF file operations
@@ -31,44 +31,55 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! /**
Return the file id descriptor of the given file. Return the file id descriptor of the given file.
*/ */
bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent, bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_fileid_desc_t *p_udf_fid); /*out*/ udf_fileid_desc_t *p_udf_fid);
/*! /**
Return the name of the file Return the name of the file
*/ */
const char *udf_get_filename(const udf_dirent_t *p_udf_dirent); const char *udf_get_filename(const udf_dirent_t *p_udf_dirent);
/*! /**
Return the name of the file Return the name of the file
*/ */
bool udf_get_file_entry(const udf_dirent_t *p_udf_dirent, bool udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_file_entry_t *p_udf_fe); /*out*/ udf_file_entry_t *p_udf_fe);
/*! /**
Return the number of hard links of the file. Return 0 if error. Return the number of hard links of the file. Return 0 if error.
*/ */
uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent); uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent);
/*! /**
Return the file length the file. Return 2147483647L if error. Return the file length the file. Return 2147483647L if error.
*/ */
uint64_t udf_get_file_length(const udf_dirent_t *p_udf_dirent); uint64_t udf_get_file_length(const udf_dirent_t *p_udf_dirent);
/*! /**
Returns a POSIX mode for a given p_udf_dirent. Returns a POSIX mode for a given p_udf_dirent.
*/ */
mode_t udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent); mode_t udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent);
/*! /**
Return the next subdirectory. Return the next subdirectory.
*/ */
udf_dirent_t *udf_opendir(const udf_dirent_t *p_udf_dirent); udf_dirent_t *udf_opendir(const udf_dirent_t *p_udf_dirent);
/*! /**
Attempts to read up to count bytes from UDF directory entry
p_udf_dirent into the buffer starting at buf. buf should be a
multiple of UDF_BLOCKSIZE bytes.
If count is zero, read() returns zero and has no other results. If
count is greater than SSIZE_MAX, the result is unspecified.
If there is an error, cast the result to driver_return_code_t for
the specific error code.
*/
/**
Attempts to read up to count bytes from file descriptor fd into Attempts to read up to count bytes from file descriptor fd into
the buffer starting at buf. the buffer starting at buf.
@@ -78,7 +89,7 @@ extern "C" {
driver_return_code_t udf_read_block(const udf_dirent_t *p_udf_dirent, driver_return_code_t udf_read_block(const udf_dirent_t *p_udf_dirent,
void * buf, size_t count); void * buf, size_t count);
/*! /**
Advances p_udf_direct to the the next directory entry in the Advances p_udf_direct to the the next directory entry in the
pointed to by p_udf_dir. It also returns this as the value. NULL pointed to by p_udf_dir. It also returns this as the value. NULL
is returned on reaching the end-of-file or if an error. Also is returned on reaching the end-of-file or if an error. Also
@@ -88,12 +99,12 @@ extern "C" {
*/ */
udf_dirent_t *udf_readdir(udf_dirent_t *p_udf_dirent); udf_dirent_t *udf_readdir(udf_dirent_t *p_udf_dirent);
/*! /**
free free resources associated with p_udf_dirent. free free resources associated with p_udf_dirent.
*/ */
bool udf_dirent_free(udf_dirent_t *p_udf_dirent); bool udf_dirent_free(udf_dirent_t *p_udf_dirent);
/*! /**
Return true if the file is a directory. Return true if the file is a directory.
*/ */
bool udf_is_dir(const udf_dirent_t *p_udf_dirent); bool udf_is_dir(const udf_dirent_t *p_udf_dirent);

View File

@@ -30,7 +30,7 @@ libudf_la_AGE := 0
EXTRA_DIST = libudf.sym EXTRA_DIST = libudf.sym
noinst_HEADERS = udf_private.h noinst_HEADERS = udf_fs.h udf_private.h
lib_LTLIBRARIES = libudf.la lib_LTLIBRARIES = libudf.la

View File

@@ -1,7 +1,7 @@
/* /*
$Id: udf_file.c,v 1.8 2006/04/11 01:05:44 rocky Exp $ $Id: udf_file.c,v 1.9 2006/04/11 05:47:58 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
#include <cdio/bytesex.h> #include <cdio/bytesex.h>
#include "udf_private.h" #include "udf_private.h"
#include "udf_fs.h"
#ifdef HAVE_STRING_H #ifdef HAVE_STRING_H
# include <string.h> # include <string.h>
@@ -28,6 +29,8 @@
#include <stdio.h> /* Remove when adding cdio/logging.h */ #include <stdio.h> /* Remove when adding cdio/logging.h */
#define MIN(a, b) (a>b) ? (a) : (b)
const char * const char *
udf_get_filename(const udf_dirent_t *p_udf_dirent) udf_get_filename(const udf_dirent_t *p_udf_dirent)
{ {
@@ -93,21 +96,29 @@ udf_is_dir(const udf_dirent_t *p_udf_dirent)
return p_udf_dirent->b_dir; return p_udf_dirent->b_dir;
} }
/*! /**
Attempts to read up to count bytes from file descriptor fd into Attempts to read up to count bytes from UDF directory entry
the buffer starting at buf. p_udf_dirent into the buffer starting at buf. buf should be a
multiple of UDF_BLOCKSIZE bytes.
If count is zero, read() returns zero and has no other results. If If count is zero, read() returns zero and has no other results. If
count is greater than SSIZE_MAX, the result is unspecified. count is greater than SSIZE_MAX, the result is unspecified.
If there is an error, cast the result to driver_return_code_t for
the specific error code.
*/ */
driver_return_code_t ssize_t
udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count) udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count)
{ {
if (count == 0) return 0;
else {
const udf_t *p_udf = p_udf_dirent->p_udf; const udf_t *p_udf = p_udf_dirent->p_udf;
uint8_t data[UDF_BLOCKSIZE]; uint8_t data[UDF_BLOCKSIZE];
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) data; const udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) data;
driver_return_code_t ret = driver_return_code_t ret;
udf_read_sectors(p_udf, data, p_udf_dirent->fe.unique_ID, 1); const unsigned long int i_file_length = udf_get_file_length(p_udf_dirent);
ret = udf_read_sectors(p_udf, data, p_udf_dirent->fe.unique_ID, 1);
if (ret == DRIVER_OP_SUCCESS) { if (ret == DRIVER_OP_SUCCESS) {
if (!udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) { if (!udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {
uint32_t i_lba_start, i_lba_end; uint32_t i_lba_start, i_lba_end;
@@ -116,13 +127,18 @@ udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count)
if ( (i_lba_end - i_lba_start+1) < count ) { if ( (i_lba_end - i_lba_start+1) < count ) {
printf("Warning: don't know how to handle yet\n" ); printf("Warning: don't know how to handle yet\n" );
count = i_lba_end - i_lba_start+1; count = i_lba_end - i_lba_start+1;
} else {
const uint32_t i_lba = p_udf->i_part_start+i_lba_start;
ret = udf_read_sectors(p_udf, buf, i_lba, count);
if (DRIVER_OP_SUCCESS == ret) {
return MIN(i_file_length, count * UDF_BLOCKSIZE);
} }
return udf_read_sectors(p_udf, buf, p_udf->i_part_start+i_lba_start,
count);
} }
else {
} else {
return DRIVER_OP_ERROR; return DRIVER_OP_ERROR;
} }
} }
return ret; return ret;
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_fs.c,v 1.16 2006/04/11 00:26:54 rocky Exp $ $Id: udf_fs.c,v 1.17 2006/04/11 05:47:58 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -69,6 +69,7 @@ const char VSD_STD_ID_TEA01[] = {'T', 'E', 'A', '0', '1'};
#include <cdio/bytesex.h> #include <cdio/bytesex.h>
#include "udf_private.h" #include "udf_private.h"
#include "udf_fs.h"
/* /*
* The UDF specs are pretty clear on how each data structure is made * The UDF specs are pretty clear on how each data structure is made
@@ -122,7 +123,7 @@ udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
* Return zero if all is good, -1 if not. * Return zero if all is good, -1 if not.
*/ */
int int
udf_checktag(udf_tag_t *p_tag, udf_Uint16_t tag_id) udf_checktag(const udf_tag_t *p_tag, udf_Uint16_t tag_id)
{ {
uint8_t *itag; uint8_t *itag;
uint8_t i; uint8_t i;

39
lib/udf/udf_fs.h Normal file
View File

@@ -0,0 +1,39 @@
/*
$Id: udf_fs.h,v 1.1 2006/04/11 05:47:58 rocky Exp $
Copyright (C) 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __CDIO_UDF_FS_H__
#define __CDIO_UDF_FS_H__
/**
* Check the descriptor tag for both the correct id and correct checksum.
* Return zero if all is good, -1 if not.
*/
int udf_checktag(const udf_tag_t *p_tag, udf_Uint16_t tag_id);
#endif /* __CDIO_UDF_FS_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,7 +1,7 @@
/* /*
$Id: udf_private.h,v 1.7 2006/04/11 00:26:54 rocky Exp $ $Id: udf_private.h,v 1.8 2006/04/11 05:47:58 rocky Exp $
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -65,13 +65,6 @@ struct udf_dirent_s
bool udf_get_lba(const udf_file_entry_t *p_udf_fe, bool udf_get_lba(const udf_file_entry_t *p_udf_fe,
/*out*/ uint32_t *start, /*out*/ uint32_t *end); /*out*/ uint32_t *start, /*out*/ uint32_t *end);
/* FIXME createudf_fs.h and put this in there. */
/**
* Check the descriptor tag for both the correct id and correct checksum.
* Return zero if all is good, -1 if not.
*/
int udf_checktag(udf_tag_t *p_tag, udf_Uint16_t tag_id);
#endif /* __CDIO_UDF_PRIVATE_H__ */ #endif /* __CDIO_UDF_PRIVATE_H__ */