2 * Copyright 2012, Jérôme Duval, korli@users.berlios.de.
3 * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com.
4 * Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net.
5 * Distributed under the terms of the MIT License.
12 #include "UdfStructures.h"
14 #include <util/kernel_cpp.h>
15 #include <util/SinglyLinkedList.h>
17 #include "CachedBlock.h"
19 class DirectoryIterator
;
23 /*! \brief Abstract interface to file entry structure members
24 that are not commonly accessible through file_icb_entry().
26 This is necessary, since we can't use virtual functions in
27 the disk structure structs themselves, since we generally
28 don't create disk structure objects by calling new, but
29 rather just cast a chunk of memory read off disk to be
30 a pointer to the struct of interest (which works fine
31 for regular functions, but fails miserably for virtuals
32 due to the vtable not being setup properly).
34 class AbstractFileEntry
{
36 virtual uint8
* AllocationDescriptors() = 0;
37 virtual uint32
AllocationDescriptorsLength() = 0;
41 template <class Descriptor
>
42 class FileEntry
: public AbstractFileEntry
{
44 FileEntry(CachedBlock
*descriptorBlock
= NULL
);
45 void SetTo(CachedBlock
*descriptorBlock
);
46 virtual uint8
* AllocationDescriptors();
47 virtual uint32
AllocationDescriptorsLength();
50 Descriptor
*_Descriptor();
51 CachedBlock
*fDescriptorBlock
;
55 class DirectoryIterator
: public SinglyLinkedListLinkImpl
<DirectoryIterator
> {
58 status_t
GetNextEntry(char *name
, uint32
*length
,
61 Icb
*Parent() { return fParent
; }
62 const Icb
*Parent() const { return fParent
; }
69 /* The following is called by Icb::GetDirectoryIterator() */
70 DirectoryIterator(Icb
*parent
);
71 /* The following is called by Icb::~Icb() */
72 void _Invalidate() { fParent
= NULL
; }
82 Icb(Volume
*volume
, long_address address
);
86 ino_t
Id() { return fId
; }
89 uint8
Type() { return _IcbTag().file_type(); }
90 bool IsFile() { return Type() == ICB_TYPE_REGULAR_FILE
; }
91 bool IsDirectory() { return (Type() == ICB_TYPE_DIRECTORY
92 || Type() == ICB_TYPE_STREAM_DIRECTORY
); }
94 uint32
Uid() { return _FileEntry()->uid(); }
95 uint32
Gid() { return 0; }
96 uint16
FileLinkCount() { return _FileEntry()->file_link_count(); }
97 uint64
Length() { return _FileEntry()->information_length(); }
98 mode_t
Mode() { return (IsDirectory() ? S_IFDIR
: S_IFREG
)
99 | S_IRUSR
| S_IRGRP
| S_IROTH
; }
100 void GetAccessTime(struct timespec
×pec
) const;
101 void GetModificationTime(struct timespec
×pec
) const;
103 uint8
*AllocationDescriptors()
104 { return _AbstractEntry()->AllocationDescriptors(); }
105 uint32
AllocationDescriptorsSize()
106 { return _AbstractEntry()->AllocationDescriptorsLength(); }
108 status_t
FindBlock(uint32 logicalBlock
, off_t
&block
,
110 status_t
Read(off_t pos
, void *buffer
, size_t *length
,
111 uint32
*block
= NULL
);
113 void * FileCache() { return fFileCache
; }
114 void * FileMap() { return fFileMap
; }
116 status_t
GetFileMap(off_t offset
, size_t size
,
117 struct file_io_vec
*vecs
, size_t *count
);
119 // for directories only
120 status_t
GetDirectoryIterator(DirectoryIterator
**iterator
);
121 status_t
Find(const char *filename
, ino_t
*id
);
123 Volume
*GetVolume() const { return fVolume
; }
126 AbstractFileEntry
*_AbstractEntry() const { return (_Tag().id()
127 == TAGID_EXTENDED_FILE_ENTRY
)
128 ? (AbstractFileEntry
*)&fExtendedEntry
129 : (AbstractFileEntry
*)&fFileEntry
; }
131 descriptor_tag
&_Tag() const { return ((icb_header
*)fData
.Block())->tag(); }
132 icb_entry_tag
&_IcbTag() const { return ((icb_header
*)fData
.Block())->icb_tag(); }
133 file_icb_entry
*_FileEntry() const
134 { return (file_icb_entry
*)fData
.Block(); }
135 extended_file_icb_entry
*_ExtendedEntry() const
136 { return (extended_file_icb_entry
*)fData
.Block(); }
138 template<class DescriptorList
>
139 status_t
_GetFileMap(DescriptorList
&list
, off_t offset
,
140 size_t size
, struct file_io_vec
*vecs
,
142 template<class DescriptorList
>
143 status_t
_Read(DescriptorList
&list
, off_t pos
,
144 void *buffer
, size_t *length
, uint32
*block
);
148 status_t fInitStatus
;
150 SinglyLinkedList
<DirectoryIterator
> fIteratorList
;
152 FileEntry
<file_icb_entry
> fFileEntry
;
153 FileEntry
<extended_file_icb_entry
> fExtendedEntry
;
159 template <class Descriptor
>
160 FileEntry
<Descriptor
>::FileEntry(CachedBlock
*descriptorBlock
)
161 : fDescriptorBlock(descriptorBlock
)
166 template <class Descriptor
>
168 FileEntry
<Descriptor
>::SetTo(CachedBlock
*descriptorBlock
)
170 fDescriptorBlock
= descriptorBlock
;
174 template <class Descriptor
>
176 FileEntry
<Descriptor
>::AllocationDescriptors()
178 Descriptor
* descriptor
= _Descriptor();
179 return descriptor
? descriptor
->allocation_descriptors() : NULL
;
183 template <class Descriptor
>
185 FileEntry
<Descriptor
>::AllocationDescriptorsLength()
187 Descriptor
* descriptor
= _Descriptor();
188 return descriptor
? descriptor
->allocation_descriptors_length() : 0;
192 template <class Descriptor
>
194 FileEntry
<Descriptor
>::_Descriptor()
196 return fDescriptorBlock
197 ? (Descriptor
*)fDescriptorBlock
->Block() : NULL
;