- Updated _NextUniqueId() to wrap appropriately after lower 32-bits

hit 0xffffffff.
- Added logical volume integrity sequence output.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5924 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder 2004-01-06 06:01:44 +00:00
parent 8fc7439cef
commit aae8e9f936
2 changed files with 74 additions and 1 deletions

View File

@ -101,6 +101,7 @@ UdfBuilder::UdfBuilder(const char *outputFile, uint32 blockSize, bool doUdf,
, fBuildTime(0) // set at start of Build()
, fBuildTimeStamp() // ditto
, fNextUniqueId(16) // Starts at 16 thanks to MacOS... See UDF-2.50 3.2.1
, f32BitIdsNoLongerUnique(false) // Set to true once fNextUniqueId requires > 32bits
{
DEBUG_INIT_ETC("UdfBuilder", ("blockSize: %ld, doUdf: %s, doIso: %s",
blockSize, bool_to_string(doUdf), bool_to_string(doIso)));
@ -725,6 +726,62 @@ UdfBuilder::Build()
}
}
// Write the integrity sequence
if (!error && _DoUdf()) {
_PrintUpdate(VERBOSITY_MEDIUM, "udf: Writing logical volume integrity sequence");
Udf::MemoryChunk chunk(_BlockSize());
error = chunk.InitCheck();
// write closed integrity descriptor
if (!error) {
memset(chunk.Data(), 0, _BlockSize());
Udf::logical_volume_integrity_descriptor *lvid =
reinterpret_cast<Udf::logical_volume_integrity_descriptor*>(chunk.Data());
lvid->recording_time() = _BuildTimeStamp();
lvid->set_integrity_type(Udf::INTEGRITY_CLOSED);
lvid->next_integrity_extent() = kNullExtent;
memset(lvid->logical_volume_contents_use().data, 0,
lvid->logical_volume_contents_use().size());
lvid->set_next_unique_id(_NextUniqueId());
lvid->set_partition_count(1);
lvid->set_implementation_use_length(
Udf::logical_volume_integrity_descriptor::minimum_implementation_use_length);
lvid->free_space_table()[0] = 0;
lvid->size_table()[0] = _PartitionAllocator().Length();
lvid->implementation_id() = Udf::kImplementationId;
lvid->set_file_count(_Stats().Files());
lvid->set_directory_count(_Stats().Directories());
lvid->set_minimum_udf_read_revision(0x0201);
lvid->set_minimum_udf_write_revision(0x0201);
lvid->set_maximum_udf_write_revision(0x0201);
lvid->tag().set_id(Udf::TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR);
lvid->tag().set_version(3);
lvid->tag().set_serial_number(0);
lvid->tag().set_location(integrityExtent.location());
lvid->tag().set_checksums(*lvid);
PDUMP(lvid);
// write lvid
ssize_t bytes = _OutputFile().WriteAt(integrityExtent.location() << _BlockShift(),
lvid, _BlockSize());
error = check_size_error(bytes, _BlockSize());
}
// write terminating descriptor
if (!error) {
memset(chunk.Data(), 0, _BlockSize());
Udf::terminating_descriptor *terminator =
reinterpret_cast<Udf::terminating_descriptor*>(chunk.Data());
terminator->tag().set_id(Udf::TAGID_TERMINATING_DESCRIPTOR);
terminator->tag().set_version(3);
terminator->tag().set_serial_number(0);
terminator->tag().set_location(integrityExtent.location()+1);
terminator->tag().set_checksums(*terminator);
PDUMP(terminator);
// write terminator
ssize_t bytes = _OutputFile().WriteAt((integrityExtent.location()+1) << _BlockShift(),
terminator, _BlockSize());
error = check_size_error(bytes, _BlockSize());
}
}
// Pad the end of the file to an even multiple of the block
// size, if necessary
if (!error) {
@ -756,6 +813,20 @@ UdfBuilder::Build()
RETURN(error);
}
/*! \brief Returns the next unique id, then increments the id (the lower
32-bits of which wrap to 16 instead of 0, per UDF-2.50 3.2.1.1).
*/
uint64
UdfBuilder::_NextUniqueId()
{
uint64 result = fNextUniqueId++;
if ((fNextUniqueId & 0xffffffff) == 0) {
fNextUniqueId |= 0x10;
f32BitIdsNoLongerUnique = true;
}
return result;
}
/*! \brief Sets the time at which image building began.
*/
void

View File

@ -61,7 +61,8 @@ private:
Statistics& _Stats() { return fStatistics; }
time_t _BuildTime() const { return fBuildTime; }
Udf::timestamp& _BuildTimeStamp() { return fBuildTimeStamp; }
uint64 _NextUniqueId() { return fNextUniqueId++; }
uint64 _NextUniqueId();
bool _32BitIdsNoLongerUnique() const { return f32BitIdsNoLongerUnique; }
void _SetBuildTime(time_t time);
@ -96,6 +97,7 @@ private:
time_t fBuildTime;
Udf::timestamp fBuildTimeStamp;
uint64 fNextUniqueId;
bool f32BitIdsNoLongerUnique;
};