btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / makeudfimage / UdfBuilder.h
bloba36cf744e52620e57aecb3766b0f43eeadb4ec2c
1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 // by the MIT License.
4 //
5 // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //----------------------------------------------------------------------
8 /*! \file UdfBuilder.h
10 Main UDF image building class interface declarations.
13 #ifndef _UDF_BUILDER_H
14 #define _UDF_BUILDER_H
16 #include <Entry.h>
17 #include <list>
18 #include <Node.h>
19 #include <stdarg.h>
20 #include <string>
21 #include <SupportDefs.h>
23 #include "Allocator.h"
24 #include "FileStream.h"
25 #include "MemoryStream.h"
26 #include "PhysicalPartitionAllocator.h"
27 #include "ProgressListener.h"
28 #include "Statistics.h"
29 #include "UdfString.h"
31 /*! \brief Handy struct into which all the interesting information about
32 a processed directory, file, or whatever is placed by the corresponding
33 UdfBuilder::_Process*() function.
35 struct node_data {
36 Udf::long_address icbAddress; //!< Udf icb address
37 std::list<Udf::long_address> udfData; //!< Dataspace for node in Udf partition space
38 std::list<Udf::extent_address> isoData; //!< Dataspace for node in physical space
41 class UdfBuilder {
42 public:
43 UdfBuilder(const char *outputFile, uint32 blockSize, bool doUdf,
44 const char *udfVolumeName, uint16 udfRevision, bool doIso,
45 const char *isoVolumeName,
46 const char *rootDirectory, const ProgressListener &listener,
47 bool truncate);
48 status_t InitCheck() const;
49 status_t Build();
50 private:
51 //! Maximum length of string generated by calls to any _Print*() functions
52 static const int kMaxUpdateStringLength = 1024;
54 FileStream& _OutputFile() { return fOutputFile; }
55 uint32 _BlockSize() const { return fBlockSize; }
56 uint32 _BlockShift() const { return fBlockShift; }
57 bool _DoUdf() const { return fDoUdf; }
58 Udf::String& _UdfVolumeName() { return fUdfVolumeName; }
59 uint16 _UdfRevision() const { return fUdfRevision; }
60 uint16 _UdfDescriptorVersion() const { return fUdfDescriptorVersion; }
61 const Udf::entity_id& _UdfDomainId() const { return fUdfDomainId; }
62 bool _DoIso() const { return fDoIso; }
63 Udf::String& _IsoVolumeName() { return fIsoVolumeName; }
64 BEntry& _RootDirectory() { return fRootDirectory; }
65 Allocator& _Allocator() { return fAllocator; }
66 PhysicalPartitionAllocator& _PartitionAllocator() { return fPartitionAllocator; }
67 Statistics& _Stats() { return fStatistics; }
68 time_t _BuildTime() const { return fBuildTime; }
69 Udf::timestamp& _BuildTimeStamp() { return fBuildTimeStamp; }
70 uint64 _NextUniqueId();
71 bool _32BitIdsNoLongerUnique() const { return f32BitIdsNoLongerUnique; }
73 void _SetBuildTime(time_t time);
75 status_t _FormatString(char *message, const char *formatString, va_list arguments) const;
76 void _PrintError(const char *formatString, ...) const;
77 void _PrintWarning(const char *formatString, ...) const;
78 void _PrintUpdate(VerbosityLevel level, const char *formatString, ...) const;
80 status_t _ProcessDirectory(BEntry &entry, const char *path, struct stat stats,
81 node_data &node, Udf::long_address parentIcbAddress,
82 bool isRootDirectory = false);
83 status_t _ProcessFile(BEntry &entry, const char *path, struct stat stats,
84 node_data &node);
85 status_t _ProcessSymlink(BEntry &symlink);
86 status_t _ProcessAttributes(BNode &node);
88 template <class FileEntry>
89 status_t _WriteFileEntry(FileEntry *icb, uint8 fileType, uint16 linkCount,
90 uint64 dataLength, uint64 objectSize, struct stat stats,
91 uint64 uniqueId, uint32 allocationDescriptorsLength,
92 Udf::tag_id fileEntryType, Udf::long_address icbAddress,
93 Udf::extent_address icbExtent,
94 std::list<Udf::long_address> dataAddresses);
96 status_t fInitStatus;
97 FileStream fOutputFile;
98 std::string fOutputFilename;
99 uint32 fBlockSize;
100 uint32 fBlockShift;
101 bool fDoUdf;
102 Udf::String fUdfVolumeName;
103 uint16 fUdfRevision;
104 uint16 fUdfDescriptorVersion;
105 const Udf::entity_id &fUdfDomainId;
106 bool fDoIso;
107 Udf::String fIsoVolumeName;
108 BEntry fRootDirectory;
109 std::string fRootDirectoryName;
110 const ProgressListener &fListener;
111 Allocator fAllocator;
112 PhysicalPartitionAllocator fPartitionAllocator;
113 Statistics fStatistics;
114 time_t fBuildTime;
115 Udf::timestamp fBuildTimeStamp;
116 uint64 fNextUniqueId;
117 bool f32BitIdsNoLongerUnique;
120 template <class FileEntry>
121 status_t
122 UdfBuilder::_WriteFileEntry(FileEntry *icb, uint8 fileType, uint16 linkCount,
123 uint64 dataLength, uint64 objectSize, struct stat stats,
124 uint64 uniqueId, uint32 allocationDescriptorsLength,
125 Udf::tag_id fileEntryType, Udf::long_address icbAddress,
126 Udf::extent_address icbExtent,
127 std::list<Udf::long_address> dataAddresses)
129 DEBUG_INIT_ETC("UdfBuilder", ("type: %s", icb->descriptor_name()));
130 status_t error = B_ERROR;
131 Udf::icb_entry_tag &itag = icb->icb_tag();
132 itag.set_prior_recorded_number_of_direct_entries(0);
133 itag.set_strategy_type(Udf::ICB_STRATEGY_SINGLE);
134 memset(itag.strategy_parameters().data, 0,
135 itag.strategy_parameters().size());
136 itag.set_entry_count(1);
137 itag.reserved() = 0;
138 itag.set_file_type(fileType);
139 itag.parent_icb_location() = kNullLogicalBlock;
140 Udf::icb_entry_tag::flags_accessor &iflags = itag.flags_access();
141 // clear flags, then set those of interest
142 iflags.all_flags = 0;
143 iflags.flags.descriptor_flags = Udf::ICB_DESCRIPTOR_TYPE_LONG;
144 iflags.flags.archive = 1;
145 icb->set_uid(0xffffffff);
146 icb->set_gid(0xffffffff);
147 icb->set_permissions(Udf::OTHER_EXECUTE | Udf::OTHER_READ
148 | Udf::GROUP_EXECUTE | Udf::GROUP_READ
149 | Udf::USER_EXECUTE | Udf::USER_READ);
150 icb->set_file_link_count(linkCount);
151 icb->set_record_format(0);
152 icb->set_record_display_attributes(0);
153 icb->set_record_length(0);
154 icb->set_information_length(dataLength);
155 icb->set_object_size(objectSize); // EFE only
156 icb->set_logical_blocks_recorded(_Allocator().BlocksFor(dataLength));
157 icb->access_date_and_time() = Udf::timestamp(stats.st_atime);
158 icb->modification_date_and_time() = Udf::timestamp(stats.st_mtime);
159 icb->creation_date_and_time() = Udf::timestamp(stats.st_crtime); // EFE only
160 icb->attribute_date_and_time() = icb->creation_date_and_time();
161 icb->set_checkpoint(1);
162 icb->set_reserved(0); // EFE only
163 icb->extended_attribute_icb() = kNullAddress;
164 icb->stream_directory_icb() = kNullAddress; // EFE only
165 icb->implementation_id() = Udf::kImplementationId;
166 icb->set_unique_id(uniqueId);
167 icb->set_extended_attributes_length(0);
168 icb->set_allocation_descriptors_length(allocationDescriptorsLength);
169 icb->tag().set_id(fileEntryType);
170 icb->tag().set_version(_UdfDescriptorVersion());
171 icb->tag().set_serial_number(0);
172 icb->tag().set_location(icbAddress.block());
174 // write allocation descriptors
175 std::list<Udf::long_address>::iterator a;
176 MemoryStream descriptorStream(icb->allocation_descriptors(),
177 allocationDescriptorsLength);
178 error = descriptorStream.InitCheck();
179 if (!error) {
180 for (a = dataAddresses.begin();
181 a != dataAddresses.end() && error == B_OK;
182 a++)
184 PRINT(("Dumping address:\n"));
185 DUMP(*a);
186 Udf::long_address &address = *a;
187 ssize_t bytes = descriptorStream.Write(&address, sizeof(address));
188 error = check_size_error(bytes, sizeof(address));
191 icb->tag().set_checksums(*icb, icb->descriptor_size());
192 PDUMP(icb);
194 // Write udf icb
195 if (!error) {
196 _PrintUpdate(VERBOSITY_MEDIUM, "udf: Writing icb");
197 // write icb
198 _OutputFile().Seek(off_t(icbExtent.location()) << _BlockShift(), SEEK_SET);
199 PRINT(("position, icbsize: %Ld, %ld\n", _OutputFile().Position(), sizeof(icb)));
200 ssize_t bytes = _OutputFile().Write(icb, _BlockSize());
201 PRINT(("position: %Ld\n", _OutputFile().Position()));
202 error = check_size_error(bytes, _BlockSize());
203 PRINT(("position: %Ld\n", _OutputFile().Position()));
205 RETURN(error);
208 #endif // _UDF_BUILDER_H