* Removed DirectoryIterator.{h,cpp} and included them in Icp.{h,cpp}
* Porting Icb to new file cache system git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27017 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003, Tyler Dauwalder, [email protected].
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \file DirectoryIterator.cpp */
|
|
||||||
|
|
||||||
#include "DirectoryIterator.h"
|
|
||||||
|
|
||||||
#include "Icb.h"
|
|
||||||
#include "UdfString.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
|
|
||||||
{
|
|
||||||
DEBUG_INIT_ETC("DirectoryIterator",
|
|
||||||
("name: %p, length: %p, id: %p", name, length, id));
|
|
||||||
|
|
||||||
if (!id || !name || !length)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
PRINT(("fPosition: %Ld\n", fPosition));
|
|
||||||
PRINT(("Parent()->Length(): %Ld\n", Parent()->Length()));
|
|
||||||
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (fAtBeginning) {
|
|
||||||
sprintf(name, ".");
|
|
||||||
*length = 2;
|
|
||||||
*id = Parent()->Id();
|
|
||||||
fAtBeginning = false;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (uint64(fPosition) >= Parent()->Length())
|
|
||||||
RETURN(B_ENTRY_NOT_FOUND);
|
|
||||||
|
|
||||||
uint8 data[kMaxFileIdSize];
|
|
||||||
file_id_descriptor *entry = reinterpret_cast<file_id_descriptor*>(data);
|
|
||||||
|
|
||||||
uint32 block = 0;
|
|
||||||
off_t offset = fPosition;
|
|
||||||
|
|
||||||
size_t entryLength = kMaxFileIdSize;
|
|
||||||
// First read in the static portion of the file id descriptor,
|
|
||||||
// then, based on the information therein, read in the variable
|
|
||||||
// length tail portion as well.
|
|
||||||
error = Parent()->Read(offset, entry, &entryLength, &block);
|
|
||||||
if (!error && entryLength >= sizeof(file_id_descriptor)
|
|
||||||
&& entry->tag().init_check(block) == B_OK) {
|
|
||||||
PDUMP(entry);
|
|
||||||
offset += entry->total_length();
|
|
||||||
|
|
||||||
if (entry->is_parent()) {
|
|
||||||
sprintf(name, "..");
|
|
||||||
*length = 3;
|
|
||||||
} else {
|
|
||||||
UdfString string(entry->id(), entry->id_length());
|
|
||||||
PRINT(("id == `%s'\n", string.Utf8()));
|
|
||||||
DUMP(entry->icb());
|
|
||||||
sprintf(name, "%s", string.Utf8());
|
|
||||||
*length = string.Utf8Length();
|
|
||||||
}
|
|
||||||
*id = to_vnode_id(entry->icb());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!error)
|
|
||||||
fPosition = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* \brief Rewinds the iterator to point to the first entry in the directory. */
|
|
||||||
void
|
|
||||||
DirectoryIterator::Rewind()
|
|
||||||
{
|
|
||||||
fAtBeginning = true;
|
|
||||||
fPosition = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma - Private methods
|
|
||||||
|
|
||||||
|
|
||||||
DirectoryIterator::DirectoryIterator(Icb *parent)
|
|
||||||
:
|
|
||||||
fAtBeginning(true),
|
|
||||||
fParent(parent),
|
|
||||||
fPosition(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003, Tyler Dauwalder, [email protected].
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _UDF_DIRECTORY_ITERATOR_H
|
|
||||||
#define _UDF_DIRECTORY_ITERATOR_H
|
|
||||||
|
|
||||||
/*! \file DirectoryIterator.h */
|
|
||||||
|
|
||||||
#include "UdfDebug.h"
|
|
||||||
|
|
||||||
#include <util/kernel_cpp.h>
|
|
||||||
|
|
||||||
class Icb;
|
|
||||||
|
|
||||||
class DirectoryIterator {
|
|
||||||
public:
|
|
||||||
|
|
||||||
status_t GetNextEntry(char *name, uint32 *length,
|
|
||||||
ino_t *id);
|
|
||||||
|
|
||||||
Icb *Parent() { return fParent; }
|
|
||||||
const Icb *Parent() const { return fParent; }
|
|
||||||
|
|
||||||
void Rewind();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class Icb;
|
|
||||||
|
|
||||||
/* The following is called by Icb::GetDirectoryIterator() */
|
|
||||||
DirectoryIterator(Icb *parent);
|
|
||||||
/* The following is called by Icb::~Icb() */
|
|
||||||
void _Invalidate() { fParent = NULL; }
|
|
||||||
|
|
||||||
bool fAtBeginning;
|
|
||||||
Icb *fParent;
|
|
||||||
off_t fPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _UDF_DIRECTORY_ITERATOR_H
|
|
||||||
@@ -9,19 +9,98 @@
|
|||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
#include "AllocationDescriptorList.h"
|
#include "AllocationDescriptorList.h"
|
||||||
#include "DirectoryIterator.h"
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
using namespace Udf;
|
|
||||||
|
status_t
|
||||||
|
DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
|
||||||
|
{
|
||||||
|
DEBUG_INIT_ETC("DirectoryIterator",
|
||||||
|
("name: %p, length: %p, id: %p", name, length, id));
|
||||||
|
|
||||||
|
if (!id || !name || !length)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
PRINT(("fPosition: %Ld\n", fPosition));
|
||||||
|
PRINT(("Parent()->Length(): %Ld\n", Parent()->Length()));
|
||||||
|
|
||||||
|
status_t error = B_OK;
|
||||||
|
if (fAtBeginning) {
|
||||||
|
sprintf(name, ".");
|
||||||
|
*length = 2;
|
||||||
|
*id = Parent()->Id();
|
||||||
|
fAtBeginning = false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (uint64(fPosition) >= Parent()->Length())
|
||||||
|
RETURN(B_ENTRY_NOT_FOUND);
|
||||||
|
|
||||||
|
uint8 data[kMaxFileIdSize];
|
||||||
|
file_id_descriptor *entry = reinterpret_cast<file_id_descriptor*>(data);
|
||||||
|
|
||||||
|
uint32 block = 0;
|
||||||
|
off_t offset = fPosition;
|
||||||
|
|
||||||
|
size_t entryLength = kMaxFileIdSize;
|
||||||
|
// First read in the static portion of the file id descriptor,
|
||||||
|
// then, based on the information therein, read in the variable
|
||||||
|
// length tail portion as well.
|
||||||
|
error = Parent()->Read(offset, entry, &entryLength, &block);
|
||||||
|
if (!error && entryLength >= sizeof(file_id_descriptor)
|
||||||
|
&& entry->tag().init_check(block) == B_OK) {
|
||||||
|
PDUMP(entry);
|
||||||
|
offset += entry->total_length();
|
||||||
|
|
||||||
|
if (entry->is_parent()) {
|
||||||
|
sprintf(name, "..");
|
||||||
|
*length = 3;
|
||||||
|
} else {
|
||||||
|
UdfString string(entry->id(), entry->id_length());
|
||||||
|
PRINT(("id == `%s'\n", string.Utf8()));
|
||||||
|
DUMP(entry->icb());
|
||||||
|
sprintf(name, "%s", string.Utf8());
|
||||||
|
*length = string.Utf8Length();
|
||||||
|
}
|
||||||
|
*id = to_vnode_id(entry->icb());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
fPosition = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* \brief Rewinds the iterator to point to the first entry in the directory. */
|
||||||
|
void
|
||||||
|
DirectoryIterator::Rewind()
|
||||||
|
{
|
||||||
|
fAtBeginning = true;
|
||||||
|
fPosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma - Private methods
|
||||||
|
|
||||||
|
|
||||||
|
DirectoryIterator::DirectoryIterator(Icb *parent)
|
||||||
|
:
|
||||||
|
fAtBeginning(true),
|
||||||
|
fParent(parent),
|
||||||
|
fPosition(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Icb::Icb(Volume *volume, long_address address)
|
Icb::Icb(Volume *volume, long_address address)
|
||||||
: fVolume(volume)
|
:
|
||||||
, fData(volume)
|
fVolume(volume),
|
||||||
, fInitStatus(B_NO_INIT)
|
fData(volume),
|
||||||
, fId(to_vnode_id(address))
|
fInitStatus(B_NO_INIT),
|
||||||
, fFileEntry(&fData)
|
fId(to_vnode_id(address)),
|
||||||
, fExtendedEntry(&fData)
|
fFileEntry(&fData),
|
||||||
|
fExtendedEntry(&fData)
|
||||||
{
|
{
|
||||||
DEBUG_INIT_ETC("Icb", ("volume: %p, address(block: %ld, "
|
DEBUG_INIT_ETC("Icb", ("volume: %p, address(block: %ld, "
|
||||||
"partition: %d, length: %ld)", volume, address.block(),
|
"partition: %d, length: %ld)", volume, address.block(),
|
||||||
@@ -31,7 +110,7 @@ Icb::Icb(Volume *volume, long_address address)
|
|||||||
off_t block;
|
off_t block;
|
||||||
error = fVolume->MapBlock(address, &block);
|
error = fVolume->MapBlock(address, &block);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
icb_header *header = reinterpret_cast<icb_header*>(fData.SetTo(block));
|
icb_header *header = (icb_header *)fData.SetTo(block);
|
||||||
if (header->tag().id() == TAGID_FILE_ENTRY) {
|
if (header->tag().id() == TAGID_FILE_ENTRY) {
|
||||||
file_icb_entry *entry = reinterpret_cast<file_icb_entry*>(header);
|
file_icb_entry *entry = reinterpret_cast<file_icb_entry*>(header);
|
||||||
PDUMP(entry);
|
PDUMP(entry);
|
||||||
@@ -50,24 +129,45 @@ Icb::Icb(Volume *volume, long_address address)
|
|||||||
PRINT(("result: 0x%lx, `%s'\n", error, strerror(error)));
|
PRINT(("result: 0x%lx, `%s'\n", error, strerror(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Icb::GetDirectoryIterator(DirectoryIterator **iterator)
|
||||||
|
{
|
||||||
|
status_t error = iterator ? B_OK : B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
*iterator = new(std::nothrow) DirectoryIterator(this);
|
||||||
|
if (*iterator)
|
||||||
|
fIteratorList.Add(*iterator);
|
||||||
|
else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Icb::InitCheck()
|
Icb::InitCheck()
|
||||||
{
|
{
|
||||||
return fInitStatus;
|
return fInitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
Icb::AccessTime()
|
Icb::AccessTime()
|
||||||
{
|
{
|
||||||
return make_time(FileEntry()->access_date_and_time());
|
return make_time(_FileEntry()->access_date_and_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
Icb::ModificationTime()
|
Icb::ModificationTime()
|
||||||
{
|
{
|
||||||
return make_time(FileEntry()->modification_date_and_time());
|
return make_time(_FileEntry()->modification_date_and_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
|
Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
|
||||||
{
|
{
|
||||||
@@ -82,7 +182,7 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (IcbTag().descriptor_flags()) {
|
switch (_IcbTag().descriptor_flags()) {
|
||||||
case ICB_DESCRIPTOR_TYPE_SHORT: {
|
case ICB_DESCRIPTOR_TYPE_SHORT: {
|
||||||
PRINT(("descriptor type: short\n"));
|
PRINT(("descriptor type: short\n"));
|
||||||
AllocationDescriptorList<ShortDescriptorAccessor> list(this, ShortDescriptorAccessor(0));
|
AllocationDescriptorList<ShortDescriptorAccessor> list(this, ShortDescriptorAccessor(0));
|
||||||
@@ -112,28 +212,12 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PRINT(("Invalid icb descriptor flags! (flags = %d)\n", IcbTag().descriptor_flags()));
|
PRINT(("Invalid icb descriptor flags! (flags = %d)\n", _IcbTag().descriptor_flags()));
|
||||||
RETURN(B_BAD_VALUE);
|
RETURN(B_BAD_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
|
||||||
Icb::GetDirectoryIterator(DirectoryIterator **iterator)
|
|
||||||
{
|
|
||||||
status_t error = iterator ? B_OK : B_BAD_VALUE;
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
*iterator = new(nothrow) DirectoryIterator(this);
|
|
||||||
if (*iterator) {
|
|
||||||
error = fIteratorList.PushBack(*iterator);
|
|
||||||
} else {
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Icb::Find(const char *filename, ino_t *id)
|
Icb::Find(const char *filename, ino_t *id)
|
||||||
|
|||||||
@@ -1,36 +1,22 @@
|
|||||||
//----------------------------------------------------------------------
|
/*
|
||||||
// This software is part of the Haiku distribution and is covered
|
* Copyright 2008, Salvatore Benedetto, [email protected].
|
||||||
// by the MIT license.
|
* Copyright 2003, Tyler Dauwalder, [email protected].
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
*/
|
||||||
//---------------------------------------------------------------------
|
|
||||||
#ifndef _UDF_ICB_H
|
#ifndef _UDF_ICB_H
|
||||||
#define _UDF_ICB_H
|
#define _UDF_ICB_H
|
||||||
|
|
||||||
/*! \file Icb.h
|
/*! \file Icb.h */
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _IMPEXP_KERNEL
|
#include "UdfStructures.h"
|
||||||
# define _IMPEXP_KERNEL
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILE_FOR_R5
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
#include "fsproto.h"
|
|
||||||
#ifdef COMPILE_FOR_R5
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "kernel_cpp.h"
|
#include <util/kernel_cpp.h>
|
||||||
#include "UdfDebug.h"
|
#include <util/SinglyLinkedList.h>
|
||||||
|
|
||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
#include "UdfStructures.h"
|
|
||||||
#include "SinglyLinkedList.h"
|
|
||||||
|
|
||||||
namespace Udf {
|
|
||||||
|
|
||||||
class DirectoryIterator;
|
class DirectoryIterator;
|
||||||
|
class Icb;
|
||||||
class Volume;
|
class Volume;
|
||||||
|
|
||||||
/*! \brief Abstract interface to file entry structure members
|
/*! \brief Abstract interface to file entry structure members
|
||||||
@@ -50,6 +36,7 @@ public:
|
|||||||
virtual uint32 AllocationDescriptorsLength() = 0;
|
virtual uint32 AllocationDescriptorsLength() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
class FileEntry : public AbstractFileEntry {
|
class FileEntry : public AbstractFileEntry {
|
||||||
public:
|
public:
|
||||||
@@ -57,12 +44,38 @@ public:
|
|||||||
void SetTo(CachedBlock *descriptorBlock);
|
void SetTo(CachedBlock *descriptorBlock);
|
||||||
virtual uint8* AllocationDescriptors();
|
virtual uint8* AllocationDescriptors();
|
||||||
virtual uint32 AllocationDescriptorsLength();
|
virtual uint32 AllocationDescriptorsLength();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Descriptor *_Descriptor();
|
Descriptor *_Descriptor();
|
||||||
|
|
||||||
CachedBlock *fDescriptorBlock;
|
CachedBlock *fDescriptorBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryIterator : public SinglyLinkedListLinkImpl<DirectoryIterator> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
status_t GetNextEntry(char *name, uint32 *length,
|
||||||
|
ino_t *id);
|
||||||
|
|
||||||
|
Icb *Parent() { return fParent; }
|
||||||
|
const Icb *Parent() const { return fParent; }
|
||||||
|
|
||||||
|
void Rewind();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Icb;
|
||||||
|
|
||||||
|
/* The following is called by Icb::GetDirectoryIterator() */
|
||||||
|
DirectoryIterator(Icb *parent);
|
||||||
|
/* The following is called by Icb::~Icb() */
|
||||||
|
void _Invalidate() { fParent = NULL; }
|
||||||
|
|
||||||
|
bool fAtBeginning;
|
||||||
|
Icb *fParent;
|
||||||
|
off_t fPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Icb {
|
class Icb {
|
||||||
public:
|
public:
|
||||||
Icb(Volume *volume, long_address address);
|
Icb(Volume *volume, long_address address);
|
||||||
@@ -70,23 +83,27 @@ public:
|
|||||||
ino_t Id() { return fId; }
|
ino_t Id() { return fId; }
|
||||||
|
|
||||||
// categorization
|
// categorization
|
||||||
uint8 Type() { return IcbTag().file_type(); }
|
uint8 Type() { return _IcbTag().file_type(); }
|
||||||
bool IsFile() { return InitCheck() == B_OK && Type() == ICB_TYPE_REGULAR_FILE; }
|
bool IsFile() { return Type() == ICB_TYPE_REGULAR_FILE; }
|
||||||
bool IsDirectory() { return InitCheck() == B_OK
|
bool IsDirectory() { return (Type() == ICB_TYPE_DIRECTORY
|
||||||
&& (Type() == ICB_TYPE_DIRECTORY || Type() == ICB_TYPE_STREAM_DIRECTORY); }
|
|| Type() == ICB_TYPE_STREAM_DIRECTORY); }
|
||||||
|
|
||||||
uint32 Uid() { return 0; }//FileEntry()->uid(); }
|
uint32 Uid() { return _FileEntry()->uid(); }
|
||||||
uint32 Gid() { return 0; }
|
uint32 Gid() { return 0; }
|
||||||
uint16 FileLinkCount() { return FileEntry()->file_link_count(); }
|
uint16 FileLinkCount() { return _FileEntry()->file_link_count(); }
|
||||||
uint64 Length() { return FileEntry()->information_length(); }
|
uint64 Length() { return _FileEntry()->information_length(); }
|
||||||
mode_t Mode() { return (IsDirectory() ? S_IFDIR : S_IFREG) | S_IRUSR | S_IRGRP | S_IROTH; }
|
mode_t Mode() { return (IsDirectory() ? S_IFDIR : S_IFREG)
|
||||||
|
| S_IRUSR | S_IRGRP | S_IROTH; }
|
||||||
time_t AccessTime();
|
time_t AccessTime();
|
||||||
time_t ModificationTime();
|
time_t ModificationTime();
|
||||||
|
|
||||||
uint8 *AllocationDescriptors() { return AbstractEntry()->AllocationDescriptors(); }
|
uint8 *AllocationDescriptors()
|
||||||
uint32 AllocationDescriptorsSize() { return AbstractEntry()->AllocationDescriptorsLength(); }
|
{ return _AbstractEntry()->AllocationDescriptors(); }
|
||||||
|
uint32 AllocationDescriptorsSize()
|
||||||
|
{ return _AbstractEntry()->AllocationDescriptorsLength(); }
|
||||||
|
|
||||||
status_t Read(off_t pos, void *buffer, size_t *length, uint32 *block = NULL);
|
status_t Read(off_t pos, void *buffer, size_t *length,
|
||||||
|
uint32 *block = NULL);
|
||||||
|
|
||||||
// for directories only
|
// for directories only
|
||||||
status_t GetDirectoryIterator(DirectoryIterator **iterator);
|
status_t GetDirectoryIterator(DirectoryIterator **iterator);
|
||||||
@@ -95,37 +112,30 @@ public:
|
|||||||
Volume *GetVolume() const { return fVolume; }
|
Volume *GetVolume() const { return fVolume; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Icb(); // unimplemented
|
AbstractFileEntry *_AbstractEntry() { return (_Tag().id()
|
||||||
|
== TAGID_EXTENDED_FILE_ENTRY)
|
||||||
|
? &fExtendedEntry : &fFileEntry; }
|
||||||
|
|
||||||
descriptor_tag & Tag() { return (reinterpret_cast<icb_header*>(fData.Block()))->tag(); }
|
descriptor_tag &_Tag() { return ((icb_header *)fData.Block())->tag(); }
|
||||||
icb_entry_tag& IcbTag() { return (reinterpret_cast<icb_header*>(fData.Block()))->icb_tag(); }
|
icb_entry_tag &_IcbTag() { return ((icb_header *)fData.Block())->icb_tag(); }
|
||||||
AbstractFileEntry* AbstractEntry() {
|
file_icb_entry *_FileEntry() { return (file_icb_entry *)fData.Block(); }
|
||||||
DEBUG_INIT("Icb");
|
extended_file_icb_entry &_ExtendedEntry() { return *(extended_file_icb_entry *)fData.Block(); }
|
||||||
return (Tag().id() == TAGID_EXTENDED_FILE_ENTRY)
|
|
||||||
// ? reinterpret_cast<extended_file_icb_entry*>(fData.Block())
|
|
||||||
// : reinterpret_cast<file_icb_entry*>(fData.Block()));
|
|
||||||
? &fExtendedEntry
|
|
||||||
: &fFileEntry;
|
|
||||||
}
|
|
||||||
file_icb_entry* FileEntry() { return (reinterpret_cast<file_icb_entry*>(fData.Block())); }
|
|
||||||
extended_file_icb_entry& ExtendedEntry() { return *(reinterpret_cast<extended_file_icb_entry*>(fData.Block())); }
|
|
||||||
|
|
||||||
template <class DescriptorList>
|
template <class DescriptorList>
|
||||||
status_t _Read(DescriptorList &list, off_t pos, void *buffer, size_t *length, uint32 *block);
|
status_t _Read(DescriptorList &list, off_t pos,
|
||||||
|
void *buffer, size_t *length, uint32 *block);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Volume *fVolume;
|
Volume *fVolume;
|
||||||
CachedBlock fData;
|
CachedBlock fData;
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
ino_t fId;
|
ino_t fId;
|
||||||
SinglyLinkedList<DirectoryIterator*> fIteratorList;
|
SinglyLinkedList<DirectoryIterator> fIteratorList;
|
||||||
/* [zooey]: gcc-2.95.3 requires the explicit namespace here, otherwise
|
FileEntry<file_icb_entry> fFileEntry;
|
||||||
it complains about a syntax error(!). This is most probably a bug. */
|
FileEntry<extended_file_icb_entry> fExtendedEntry;
|
||||||
Udf::FileEntry<file_icb_entry> fFileEntry;
|
|
||||||
Udf::FileEntry<extended_file_icb_entry> fExtendedEntry;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Does the dirty work of reading using the given DescriptorList object
|
/*! \brief Does the dirty work of reading using the given DescriptorList object
|
||||||
to access the allocation descriptors properly.
|
to access the allocation descriptors properly.
|
||||||
*/
|
*/
|
||||||
@@ -133,10 +143,8 @@ template <class DescriptorList>
|
|||||||
status_t
|
status_t
|
||||||
Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block)
|
Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block)
|
||||||
{
|
{
|
||||||
DEBUG_INIT_ETC("Icb", ("list: %p, pos: %Ld, buffer: %p, length: (%p)->%ld",
|
TRACE(("Icb::_Read(): list: %p, pos: %Ld, buffer: %p, length: (%p)->%ld",
|
||||||
&list, pos, _buffer, length, (length ? *length : 0)));
|
&list, pos, _buffer, length, (length ? *length : 0)));
|
||||||
if (!_buffer || !length)
|
|
||||||
RETURN(B_BAD_VALUE);
|
|
||||||
|
|
||||||
uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos;
|
uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos;
|
||||||
size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length;
|
size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length;
|
||||||
@@ -144,20 +152,20 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
|||||||
|
|
||||||
Volume *volume = GetVolume();
|
Volume *volume = GetVolume();
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
uint8 *buffer = reinterpret_cast<uint8*>(_buffer);
|
uint8 *buffer = (uint8 *)_buffer;
|
||||||
bool isFirstBlock = true;
|
bool isFirstBlock = true;
|
||||||
|
|
||||||
while (bytesLeft > 0 && !error) {
|
while (bytesLeft > 0 && !error) {
|
||||||
|
|
||||||
PRINT(("pos: %Ld\n", pos));
|
TRACE(("Icb::_Read(): pos: %Ld\n, bytesLeft: %ld\n", pos, bytesLeft));
|
||||||
PRINT(("bytesLeft: %ld\n", bytesLeft));
|
|
||||||
|
|
||||||
long_address extent;
|
long_address extent;
|
||||||
bool isEmpty = false;
|
bool isEmpty = false;
|
||||||
error = list.FindExtent(pos, &extent, &isEmpty);
|
error = list.FindExtent(pos, &extent, &isEmpty);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
PRINT(("found extent for offset %Ld: (block: %ld, partition: %d, length: %ld, type: %d)\n",
|
TRACE(("Icb::_Read(): found extent for offset %Ld: (block: %ld, "
|
||||||
pos, extent.block(), extent.partition(), extent.length(), extent.type()));
|
"partition: %d, length: %ld, type: %d)\n", pos, extent.block(),
|
||||||
|
extent.partition(), extent.length(), extent.type()));
|
||||||
|
|
||||||
switch (extent.type()) {
|
switch (extent.type()) {
|
||||||
case EXTENT_TYPE_RECORDED:
|
case EXTENT_TYPE_RECORDED:
|
||||||
@@ -170,7 +178,8 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PRINT(("Invalid extent type found: %d\n", extent.type()));
|
TRACE_ERROR(("Icb::_Read(): Invalid extent type "
|
||||||
|
"found: %d\n", extent.type()));
|
||||||
error = B_ERROR;
|
error = B_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -184,33 +193,36 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
|||||||
*block = extent.block();
|
*block = extent.block();
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t blockOffset = pos - off_t((pos >> volume->BlockShift()) << volume->BlockShift());
|
off_t blockOffset = pos - off_t((pos >> volume->BlockShift())
|
||||||
|
<< volume->BlockShift());
|
||||||
size_t fullBlocksLeft = bytesLeft >> volume->BlockShift();
|
size_t fullBlocksLeft = bytesLeft >> volume->BlockShift();
|
||||||
|
|
||||||
if (fullBlocksLeft > 0 && blockOffset == 0) {
|
if (fullBlocksLeft > 0 && blockOffset == 0) {
|
||||||
PRINT(("reading full block (or more)\n"));
|
TRACE(("Icb::_Read(): reading full block (or more)\n"));
|
||||||
// Block aligned and at least one full block left. Read in using
|
// Block aligned and at least one full block left. Read
|
||||||
// cached_read() calls.
|
// in using cached_read() calls.
|
||||||
off_t diskBlock;
|
off_t diskBlock;
|
||||||
error = volume->MapBlock(extent, &diskBlock);
|
error = volume->MapBlock(extent, &diskBlock);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
size_t fullBlockBytesLeft = fullBlocksLeft << volume->BlockShift();
|
size_t fullBlockBytesLeft =
|
||||||
|
fullBlocksLeft << volume->BlockShift();
|
||||||
size_t readLength = fullBlockBytesLeft < extent.length()
|
size_t readLength = fullBlockBytesLeft < extent.length()
|
||||||
? fullBlockBytesLeft
|
? fullBlockBytesLeft : extent.length();
|
||||||
: extent.length();
|
|
||||||
|
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
PRINT(("reading %ld empty bytes as zeros\n", readLength));
|
TRACE(("Icb::_Read(): reading %ld empty bytes "
|
||||||
|
"as zeros\n", readLength));
|
||||||
memset(buffer, 0, readLength);
|
memset(buffer, 0, readLength);
|
||||||
} else {
|
} else {
|
||||||
off_t diskBlock;
|
off_t diskBlock;
|
||||||
error = volume->MapBlock(extent, &diskBlock);
|
error = volume->MapBlock(extent, &diskBlock);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
PRINT(("reading %ld bytes from disk block %Ld using cached_read()\n",
|
TRACE(("Icb::_Read(): reading %ld bytes from "
|
||||||
|
"disk block %Ld using cached_read()\n",
|
||||||
readLength, diskBlock));
|
readLength, diskBlock));
|
||||||
error = cached_read(volume->Device(), diskBlock, buffer,
|
size_t length = readLength >> volume->BlockShift();
|
||||||
readLength >> volume->BlockShift(),
|
error = file_cache_read(volume->BlockCache(),
|
||||||
volume->BlockSize());
|
NULL, pos, buffer, &length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,11 +263,11 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
|||||||
if (!error) {
|
if (!error) {
|
||||||
PRINT(("reading %ld bytes from disk block %Ld using get_block()\n",
|
PRINT(("reading %ld bytes from disk block %Ld using get_block()\n",
|
||||||
partialLength, diskBlock));
|
partialLength, diskBlock));
|
||||||
uint8 *data = (uint8*)get_block(volume->Device(), diskBlock, volume->BlockSize());
|
uint8 *data = (uint8*)block_cache_get_etc((void*)volume->BlockCache(), diskBlock, 0, partialLength);
|
||||||
error = data ? B_OK : B_BAD_DATA;
|
error = data ? B_OK : B_BAD_DATA;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
memcpy(buffer, data+partialOffset, partialLength);
|
memcpy(buffer, data+partialOffset, partialLength);
|
||||||
release_block(volume->Device(), diskBlock);
|
block_cache_put(volume->BlockCache(), diskBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,12 +292,14 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
|||||||
RETURN(error);
|
RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock)
|
FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock)
|
||||||
: fDescriptorBlock(descriptorBlock)
|
: fDescriptorBlock(descriptorBlock)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
void
|
void
|
||||||
FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
|
FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
|
||||||
@@ -293,6 +307,7 @@ FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
|
|||||||
fDescriptorBlock = descriptorBlock;
|
fDescriptorBlock = descriptorBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
uint8*
|
uint8*
|
||||||
FileEntry<Descriptor>::AllocationDescriptors()
|
FileEntry<Descriptor>::AllocationDescriptors()
|
||||||
@@ -301,6 +316,7 @@ FileEntry<Descriptor>::AllocationDescriptors()
|
|||||||
return descriptor ? descriptor->allocation_descriptors() : NULL;
|
return descriptor ? descriptor->allocation_descriptors() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
uint32
|
uint32
|
||||||
FileEntry<Descriptor>::AllocationDescriptorsLength()
|
FileEntry<Descriptor>::AllocationDescriptorsLength()
|
||||||
@@ -309,13 +325,13 @@ FileEntry<Descriptor>::AllocationDescriptorsLength()
|
|||||||
return descriptor ? descriptor->allocation_descriptors_length() : 0;
|
return descriptor ? descriptor->allocation_descriptors_length() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Descriptor>
|
template <class Descriptor>
|
||||||
Descriptor*
|
Descriptor*
|
||||||
FileEntry<Descriptor>::_Descriptor()
|
FileEntry<Descriptor>::_Descriptor()
|
||||||
{
|
{
|
||||||
return fDescriptorBlock ? reinterpret_cast<Descriptor*>(fDescriptorBlock->Block()) : NULL;
|
return fDescriptorBlock
|
||||||
|
? (Descriptor *)fDescriptorBlock->Block() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace Udf
|
|
||||||
|
|
||||||
#endif // _UDF_ICB_H
|
#endif // _UDF_ICB_H
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
#include "DirectoryIterator.h"
|
|
||||||
#include "Icb.h"
|
#include "Icb.h"
|
||||||
#include "Recognition.h"
|
#include "Recognition.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user