BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / udf / Icb.h
blobab61ae71b02ce9c71b91df7df6f2478f29930f9d
1 /*
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.
6 */
7 #ifndef _UDF_ICB_H
8 #define _UDF_ICB_H
10 /*! \file Icb.h */
12 #include "UdfStructures.h"
14 #include <util/kernel_cpp.h>
15 #include <util/SinglyLinkedList.h>
17 #include "CachedBlock.h"
19 class DirectoryIterator;
20 class Icb;
21 class Volume;
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 {
35 public:
36 virtual uint8* AllocationDescriptors() = 0;
37 virtual uint32 AllocationDescriptorsLength() = 0;
41 template <class Descriptor>
42 class FileEntry : public AbstractFileEntry {
43 public:
44 FileEntry(CachedBlock *descriptorBlock = NULL);
45 void SetTo(CachedBlock *descriptorBlock);
46 virtual uint8* AllocationDescriptors();
47 virtual uint32 AllocationDescriptorsLength();
49 private:
50 Descriptor *_Descriptor();
51 CachedBlock *fDescriptorBlock;
55 class DirectoryIterator : public SinglyLinkedListLinkImpl<DirectoryIterator> {
56 public:
58 status_t GetNextEntry(char *name, uint32 *length,
59 ino_t *id);
61 Icb *Parent() { return fParent; }
62 const Icb *Parent() const { return fParent; }
64 void Rewind();
66 private:
67 friend class Icb;
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; }
74 bool fAtBeginning;
75 Icb *fParent;
76 off_t fPosition;
80 class Icb {
81 public:
82 Icb(Volume *volume, long_address address);
83 ~Icb();
85 status_t InitCheck();
86 ino_t Id() { return fId; }
88 // categorization
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 &timespec) const;
101 void GetModificationTime(struct timespec &timespec) const;
103 uint8 *AllocationDescriptors()
104 { return _AbstractEntry()->AllocationDescriptors(); }
105 uint32 AllocationDescriptorsSize()
106 { return _AbstractEntry()->AllocationDescriptorsLength(); }
108 status_t FindBlock(uint32 logicalBlock, off_t &block,
109 bool &recorded);
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; }
125 private:
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,
141 size_t *count);
142 template<class DescriptorList>
143 status_t _Read(DescriptorList &list, off_t pos,
144 void *buffer, size_t *length, uint32 *block);
146 Volume *fVolume;
147 CachedBlock fData;
148 status_t fInitStatus;
149 ino_t fId;
150 SinglyLinkedList<DirectoryIterator> fIteratorList;
151 uint16 fPartition;
152 FileEntry<file_icb_entry> fFileEntry;
153 FileEntry<extended_file_icb_entry> fExtendedEntry;
154 void * fFileCache;
155 void * fFileMap;
159 template <class Descriptor>
160 FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock)
161 : fDescriptorBlock(descriptorBlock)
166 template <class Descriptor>
167 void
168 FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
170 fDescriptorBlock = descriptorBlock;
174 template <class Descriptor>
175 uint8*
176 FileEntry<Descriptor>::AllocationDescriptors()
178 Descriptor* descriptor = _Descriptor();
179 return descriptor ? descriptor->allocation_descriptors() : NULL;
183 template <class Descriptor>
184 uint32
185 FileEntry<Descriptor>::AllocationDescriptorsLength()
187 Descriptor* descriptor = _Descriptor();
188 return descriptor ? descriptor->allocation_descriptors_length() : 0;
192 template <class Descriptor>
193 Descriptor*
194 FileEntry<Descriptor>::_Descriptor()
196 return fDescriptorBlock
197 ? (Descriptor *)fDescriptorBlock->Block() : NULL;
200 #endif // _UDF_ICB_H