1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 // by the OpenBeOS license.
5 // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //----------------------------------------------------------------------
10 Main UDF image building class interface declarations.
13 #ifndef _UDF_BUILDER_H
14 #define _UDF_BUILDER_H
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.
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
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
,
48 status_t
InitCheck() const;
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
,
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
);
97 FileStream fOutputFile
;
98 std::string fOutputFilename
;
102 Udf::String fUdfVolumeName
;
104 uint16 fUdfDescriptorVersion
;
105 const Udf::entity_id
&fUdfDomainId
;
107 Udf::String fIsoVolumeName
;
108 BEntry fRootDirectory
;
109 std::string fRootDirectoryName
;
110 const ProgressListener
&fListener
;
111 Allocator fAllocator
;
112 PhysicalPartitionAllocator fPartitionAllocator
;
113 Statistics fStatistics
;
115 Udf::timestamp fBuildTimeStamp
;
116 uint64 fNextUniqueId
;
117 bool f32BitIdsNoLongerUnique
;
120 template <class FileEntry
>
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);
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();
180 for (a
= dataAddresses
.begin();
181 a
!= dataAddresses
.end() && error
== B_OK
;
184 PRINT(("Dumping address:\n"));
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());
196 _PrintUpdate(VERBOSITY_MEDIUM
, "udf: Writing 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()));
208 #endif // _UDF_BUILDER_H