Start porting udf

- Cleaning up AllocationDescriptorList in order to follow our coding guidelines
- Moving methods implentation outside the class

I've already ported udf but I'm going to commit it one file at the time
so it's easier to review, plus I still have to clean up the code.

Please review.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26880 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2008-08-08 22:53:36 +00:00
parent 8c5620e78f
commit 4ef471dec0
@@ -1,23 +1,21 @@
//---------------------------------------------------------------------- /*
// This software is part of the OpenBeOS distribution and is covered * Copyright 2008, Salvatore Benedetto, [email protected]
// by the OpenBeOS license. * Copyright 2003, Tyler Dauwalder, [email protected].
// * Distributed under the terms of the MIT License.
// Copyright (c) 2003 Tyler Dauwalder, [email protected] */
//---------------------------------------------------------------------
#ifndef _UDF_ALLOCATION_DESCRIPTOR_LIST_H #ifndef _UDF_ALLOCATION_DESCRIPTOR_LIST_H
#define _UDF_ALLOCATION_DESCRIPTOR_LIST_H #define _UDF_ALLOCATION_DESCRIPTOR_LIST_H
/*! \file AllocationDescriptorList.h /*! \file AllocationDescriptorList.h */
*/
#include "kernel_cpp.h"
#include "UdfDebug.h" #include "UdfDebug.h"
#include "UdfStructures.h"
#include "Icb.h" #include "Icb.h"
#include "UdfStructures.h"
#include "Volume.h" #include "Volume.h"
namespace Udf { #include <util/kernel_cpp.h>
/*! \brief Common interface for dealing with the three standard /*! \brief Common interface for dealing with the three standard
forms of allocation descriptors used in UDF icbs. forms of allocation descriptors used in UDF icbs.
@@ -35,89 +33,139 @@ template <class Accessor>
class AllocationDescriptorList { class AllocationDescriptorList {
private: private:
typedef typename Accessor::DescriptorType Descriptor; typedef typename Accessor::DescriptorType Descriptor;
public: public:
AllocationDescriptorList(Icb *icb, Accessor accessor = Accessor()) AllocationDescriptorList(Icb *icb,
: fIcb(icb) Accessor accessor = Accessor());
, fVolume(icb->GetVolume())
, fIcbDescriptors(reinterpret_cast<Descriptor*>(icb->AllocationDescriptors())) status_t FindExtent(off_t start, long_address *extent,
, fIcbDescriptorsSize(icb->AllocationDescriptorsSize()) bool *isEmpty);
, fAdditionalDescriptors(icb->GetVolume())
, fReadFromIcb(true) private:
, fAccessor(accessor)
, fDescriptorIndex(0) off_t _BlockIndex() const { return fBlockIndex; }
, fDescriptorNumber(0) Descriptor *_CurrentDescriptor() const;
, fBlockIndex(0) Descriptor *_DescriptorArray() const;
{ size_t _DescriptorArraySize() const;
int32 _DescriptorIndex() const { return fDescriptorIndex; }
int32 _DescriptorNumber() const { return fDescriptorNumber; }
status_t _MoveToNextDescriptor();
void _Rewind();
void _WalkContinuationChain(Descriptor *descriptor);
CachedBlock fAdditionalDescriptors;
Icb *fIcb;
Descriptor *fIcbDescriptors;
int32 fIcbDescriptorsSize;
bool fReadFromIcb;
Volume *fVolume;
Accessor fAccessor;
int32 fDescriptorIndex;
int32 fDescriptorNumber;
off_t fBlockIndex;
};
template<class Accessor>
AllocationDescriptorList<Accessor>::AllocationDescriptorList(Icb *icb,
Accessor accessor)
:
fAccessor(accessor),
fAdditionalDescriptors(icb->GetVolume()),
fBlockIndex(0),
fIcb(icb),
fIcbDescriptors((Descriptor *)icb->AllocationDescriptors()),
fDescriptorIndex(0),
fDescriptorNumber(0),
fIcbDescriptorsSize(icb->AllocationDescriptorsSize()),
fReadFromIcb(true),
fVolume(icb->GetVolume())
{
DEBUG_INIT("AllocationDescriptorList<>"); DEBUG_INIT("AllocationDescriptorList<>");
_WalkContinuationChain(_CurrentDescriptor()); _WalkContinuationChain(_CurrentDescriptor());
} }
/*! \brief Finds the extent for the given address in the stream, /*! \brief Finds the extent for the given address in the stream,
returning it in the address pointed to by \a blockRun. returning it in the address pointed to by \a blockRun.
\param start The byte address of interest \param start The byte address of interest
\param extent The extent containing the stream address given \param extent The extent containing the stream address given
by \c start. by \c start.
\param isEmpty If set to true, indicates that the given extent is unrecorded \param isEmpty If set to true, indicates that the given extent is
and thus its contents should be interpreted as all zeros. unrecorded and thus its contents should be interpreted
*/ as all zeros.
status_t FindExtent(off_t start, long_address *extent, bool *isEmpty) { */
DEBUG_INIT_ETC("AllocationDescriptorList<>", template<class Accessor>
("start: %Ld, extent: %p, isEmpty: %p", start, extent, isEmpty)); status_t
AllocationDescriptorList<Accessor>::FindExtent(off_t start,
long_address *extent, bool *isEmpty)
{
TRACE(("UDF: AllocationDescriptorList<>::FindExtent: start: %Ld, "
"extent: %p, isEmpty: %p", start, extent, isEmpty));
off_t startBlock = start >> fVolume->BlockShift(); off_t startBlock = start >> fVolume->BlockShift();
// This should never have to happen, as FindExtent is only called by // This should never have to happen, as FindExtent is only called by
// Icb::_Read() sequentially as a file read is performed, but you // Icb::_Read() sequentially, as a file read is performed, but you
// never know. :-) // never know. :-)
if (startBlock < _BlockIndex()) if (startBlock < _BlockIndex())
_Rewind(); _Rewind();
status_t error = B_OK; status_t status = B_OK;
while (true) { while (true) {
Descriptor *descriptor = _CurrentDescriptor(); Descriptor *descriptor = _CurrentDescriptor();
if (descriptor) { if (descriptor) {
if (_BlockIndex() <= startBlock if (_BlockIndex() <= startBlock && startBlock
&& startBlock < _BlockIndex()+fAccessor.GetLength(*descriptor)) < _BlockIndex() + fAccessor.GetLength(*descriptor)) {
{
// The start block is somewhere in this extent, so return // The start block is somewhere in this extent, so return
// the applicable tail end portion. // the applicable tail end portion.
off_t offset = startBlock - _BlockIndex(); off_t offset = startBlock - _BlockIndex();
extent->set_block(fAccessor.GetBlock(*descriptor)+offset); extent->set_block(fAccessor.GetBlock(*descriptor) + offset);
extent->set_partition(fAccessor.GetPartition(*descriptor)); extent->set_partition(fAccessor.GetPartition(*descriptor));
extent->set_length(fAccessor.GetLength(*descriptor)-(offset*fVolume->BlockSize())); extent->set_length(fAccessor.GetLength(*descriptor)
- (offset*fVolume->BlockSize()));
extent->set_type(fAccessor.GetType(*descriptor)); extent->set_type(fAccessor.GetType(*descriptor));
break; break;
} else { } else {
_MoveToNextDescriptor(); _MoveToNextDescriptor();
} }
} else { } else {
PRINT(("Descriptor #%ld found NULL\n", _DescriptorNumber())); TRACE_ERROR(("UDF: AllocationDescriptorList<>::FindExtent: "
error = B_ERROR; "Descriptor #%ld found NULL\n", _DescriptorNumber()));
status = B_ERROR;
break; break;
} }
} }
RETURN(error);
}
private: return status;
}
Descriptor* _CurrentDescriptor() const {
// #pragma - Private methods
template<class Accessor>
AllocationDescriptorList<Accessor>::Descriptor*
AllocationDescriptorList<Accessor>::_CurrentDescriptor() const
{
DEBUG_INIT("AllocationDescriptorList<>"); DEBUG_INIT("AllocationDescriptorList<>");
PRINT(("(_DescriptorIndex()+1)*sizeof(Descriptor) = %ld\n", (_DescriptorIndex()+1)*sizeof(Descriptor))); PRINT(("(_DescriptorIndex()+1)*sizeof(Descriptor) = %ld\n", (_DescriptorIndex()+1)*sizeof(Descriptor)));
PRINT(("_DescriptorArraySize() = %ld\n", _DescriptorArraySize())); PRINT(("_DescriptorArraySize() = %ld\n", _DescriptorArraySize()));
PRINT(("_DescriptorArray() = %p\n", _DescriptorArray())); PRINT(("_DescriptorArray() = %p\n", _DescriptorArray()));
return ((_DescriptorIndex()+1)*sizeof(Descriptor) <= _DescriptorArraySize()) return ((_DescriptorIndex() + 1) * sizeof(Descriptor)
<= _DescriptorArraySize())
? &(_DescriptorArray()[_DescriptorIndex()]) ? &(_DescriptorArray()[_DescriptorIndex()])
: NULL; : NULL;
} }
status_t _MoveToNextDescriptor() {
DEBUG_INIT("AllocationDescriptorList<>");
template<class Accessor>
status_t
AllocationDescriptorList<Accessor>::_MoveToNextDescriptor()
{
Descriptor* descriptor = _CurrentDescriptor(); Descriptor* descriptor = _CurrentDescriptor();
if (!descriptor) { if (!descriptor)
RETURN(B_ENTRY_NOT_FOUND); return B_ENTRY_NOT_FOUND;
} else {
// Increment our indices and get the next descriptor // Increment our indices and get the next descriptor
// from this extent. // from this extent.
fBlockIndex += fAccessor.GetLength(*descriptor); fBlockIndex += fAccessor.GetLength(*descriptor);
@@ -135,16 +183,17 @@ private:
// most one block in length by UDF-2.01 5.1 and UDF-2.01 // most one block in length by UDF-2.01 5.1 and UDF-2.01
// 2.3.11). // 2.3.11).
_WalkContinuationChain(descriptor); _WalkContinuationChain(descriptor);
}
return B_ERROR;
}
RETURN(B_ERROR); template<class Accessor>
} void
AllocationDescriptorList<Accessor>::_WalkContinuationChain(Descriptor *descriptor)
void _WalkContinuationChain(Descriptor *descriptor) { {
DEBUG_INIT_ETC("AllocationDescriptorList<>", if (descriptor
("descriptor: %p", descriptor)); && fAccessor.GetType(*descriptor) == EXTENT_TYPE_CONTINUATION) {
if (descriptor && fAccessor.GetType(*descriptor) == EXTENT_TYPE_CONTINUATION) {
// Load the new block, make sure we're not trying // Load the new block, make sure we're not trying
// to read from the icb descriptors anymore, and // to read from the icb descriptors anymore, and
// reset the descriptor index. // reset the descriptor index.
@@ -156,106 +205,100 @@ private:
// another continuation. That would be stupid, but not // another continuation. That would be stupid, but not
// technically illegal. // technically illegal.
_WalkContinuationChain(_CurrentDescriptor()); _WalkContinuationChain(_CurrentDescriptor());
} }
}
} template<class Accessor>
void
void _Rewind() { AllocationDescriptorList<Accessor>::_Rewind()
{
fDescriptorIndex = 0; fDescriptorIndex = 0;
fDescriptorNumber = 0; fDescriptorNumber = 0;
fReadFromIcb = true; fReadFromIcb = true;
} }
Descriptor *_DescriptorArray() const {
return fReadFromIcb
? fIcbDescriptors
: reinterpret_cast<Descriptor*>(fAdditionalDescriptors.Block());
}
size_t _DescriptorArraySize() const { template<class Accessor>
return fReadFromIcb ? fIcbDescriptorsSize : fAdditionalDescriptors.BlockSize(); AllocationDescriptorList<Accessor>::Descriptor*
} AllocationDescriptorList<Accessor>::_DescriptorArray() const
{
return fReadFromIcb ? fIcbDescriptors
: (AllocationDescriptorList<Accessor>::Descriptor *)
fAdditionalDescriptors.Block();
}
int32 _DescriptorIndex() const {
return fDescriptorIndex;
}
int32 _DescriptorNumber() const { template<class Accessor>
return fDescriptorNumber; size_t
} AllocationDescriptorList<Accessor>::_DescriptorArraySize() const
{
return fReadFromIcb ? fIcbDescriptorsSize
: fAdditionalDescriptors.BlockSize();
}
off_t _BlockIndex() const {
return fBlockIndex;
}
Icb *fIcb; // pragma - Accessors
Volume *fVolume;
Descriptor *fIcbDescriptors;
int32 fIcbDescriptorsSize;
CachedBlock fAdditionalDescriptors;
bool fReadFromIcb;
Accessor fAccessor;
int32 fDescriptorIndex;
int32 fDescriptorNumber;
off_t fBlockIndex;
};
// Accessors
class ShortDescriptorAccessor { class ShortDescriptorAccessor {
public: public:
ShortDescriptorAccessor(uint16 partition) ShortDescriptorAccessor(uint16 partition)
: fPartition(partition) :
fPartition(partition)
{ {
} }
typedef short_address DescriptorType; typedef short_address DescriptorType;
inline uint8 GetType(DescriptorType &descriptor) const { inline uint32 GetBlock(DescriptorType &descriptor) const
return descriptor.type(); {
}
inline uint32 GetBlock(DescriptorType &descriptor) const {
return descriptor.block(); return descriptor.block();
} }
inline uint16 GetPartition(DescriptorType &descriptor) const { inline uint32 GetLength(DescriptorType &descriptor) const
{
return descriptor.length();
}
inline uint16 GetPartition(DescriptorType &descriptor) const
{
return fPartition; return fPartition;
} }
inline uint32 GetLength(DescriptorType &descriptor) const { inline uint8 GetType(DescriptorType &descriptor) const
return descriptor.length(); {
return descriptor.type();
} }
private: private:
uint16 fPartition; uint16 fPartition;
}; };
class LongDescriptorAccessor { class LongDescriptorAccessor {
public: public:
typedef long_address DescriptorType; typedef long_address DescriptorType;
inline uint8 GetType(DescriptorType &descriptor) const { inline uint32 GetBlock(DescriptorType &descriptor) const
return descriptor.type(); {
}
inline uint32 GetBlock(DescriptorType &descriptor) const {
return descriptor.block(); return descriptor.block();
} }
inline uint16 GetPartition(DescriptorType &descriptor) const { inline uint32 GetLength(DescriptorType &descriptor) const
{
return descriptor.length();
}
inline uint16 GetPartition(DescriptorType &descriptor) const
{
return descriptor.partition(); return descriptor.partition();
} }
inline uint32 GetLength(DescriptorType &descriptor) const { inline uint8 GetType(DescriptorType &descriptor) const
return descriptor.length(); {
return descriptor.type();
} }
}; };
}; // namespace Udf
#endif // _UDF_ALLOCATION_DESCRIPTOR_LIST_H #endif // _UDF_ALLOCATION_DESCRIPTOR_LIST_H