com.github.stephenc.javaisotools.udflib.UDFLayoutInformation Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2010. Stephen Connolly.
* Copyright (c) 2006. Björn Stickler .
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.github.stephenc.javaisotools.udflib;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import com.github.stephenc.javaisotools.udflib.structures.ExtendedFileEntry;
import com.github.stephenc.javaisotools.udflib.structures.FileEntry;
import com.github.stephenc.javaisotools.udflib.structures.FileIdentifierDescriptor;
import com.github.stephenc.javaisotools.udflib.tools.UniqueIdDisposer;
public class UDFLayoutInformation {
private UniqueIdDisposer myUniqueIdDisposer;
public int blockSize;
public int metadataAllocationUnitSize;
public int metadataAlignmentUnitSize;
public long fileCount;
public long directoryCount;
public long AVDP1Block; // anchor volume descriptor sequence pointer 1
public long AVDP2Block; // anchor volume descriptor sequence pointer 2
public long MVDSStartingBlock; // main volume descriptor sequence start
public long MVDSEndingBlock; // main volume descriptor sequence end
public long RVDSStartingBlock; // reserve volume descriptor sequence start
public long RVDSEndingBlock; // reserve volume descriptor sequence end
public long LVIDSStartingBlock; // logical volume integrity sequence start
public long LVIDSEndingBlock; // logical volume integrity sequence end
public long physicalPartitionStartingBlock;
public long physicalPartitionEndingBlock;
public long metadataPartitionStartingBlock;
public long metadataPartitionEndingBlock;
public long mainMetadataFileBlock;
public long mainMetadataFileLocation;
public long mirrorMetadataFileBlock;
public long mirrorMetadataFileLocation;
public long metadataEmptyArea;
public int partitionToStoreMetadataOn;
public long FSDBlock; // fileset descriptor location
public long FSDLocation; // fileset descriptor location inside the partition
public long rootFEBlock; // root directory file entry location
public long rootFELocation; // root directory file entry location inside the partition
public long PVD1Block; // primary volume descriptor location (main volume descriptor sequence)
public long PVD2Block; // primary volume descriptor location (reserve volume descriptor sequence)
public long PD1Block; // partition descriptor location (main volume descriptor sequence)
public long PD2Block; // partition descriptor location (reserve volume descriptor sequence)
public long LVD1Block; // logical volume descriptor location (main volume descriptor sequence)
public long LVD2Block; // logical volume descriptor location (reserve volume descriptor sequence)
public long USD1Block; // unallocated space descriptor location (main volume descriptor sequence)
public long USD2Block; // unallocated space descriptor location (reserve volume descriptor sequence)
public long IUVD1Block; // implementation use volume descriptor location (main volume descriptor sequence)
public long IUVD2Block; // implementation use volume descriptor location (reserve volume descriptor sequence)
public long TD1Block; // terminating descriptor location (main volume descriptor sequence)
public long TD2Block; // terminating descriptor location (reserve volume descriptor sequence)
public long[] sizeTable; // partition size information
public long[] freespaceTable; // partition freespace information
public long nextUniqueId;
public class FileEntryPosition {
long entryBlock; // location of the (extended-) file entry itself
long entryLocation; // location of the (extended-) file entry itself inside the partition
long dataBlock; // location of the file data if not embedded inline
long dataLocation; // location of the file data if not embedded inline inside the partition
}
public Hashtable fileEntryPositions;
public ArrayList linearUDFImageBuilderFileOrdering;
public Hashtable uniqueIds;
public UDFLayoutInformation(UDFImageBuilderFile rootUDFImageBuilderFile, UDFRevision myUDFRevision, int blockSize)
throws Exception {
myUniqueIdDisposer = new UniqueIdDisposer();
fileEntryPositions = new Hashtable();
linearUDFImageBuilderFileOrdering = new ArrayList();
uniqueIds = new Hashtable();
this.blockSize = blockSize;
metadataAllocationUnitSize = 32;
metadataAlignmentUnitSize = 1;
fileCount = rootUDFImageBuilderFile.getFileCount();
directoryCount = rootUDFImageBuilderFile.getDirectoryCount();
AVDP1Block = 256;
MVDSStartingBlock = 257;
MVDSEndingBlock = MVDSStartingBlock + 16;
// setup main volume descriptor sequence element locations
PVD1Block = MVDSStartingBlock;
PD1Block = MVDSStartingBlock + 1;
LVD1Block = MVDSStartingBlock + 2;
USD1Block = MVDSStartingBlock + 3;
IUVD1Block = MVDSStartingBlock + 4;
TD1Block = MVDSStartingBlock + 5;
LVIDSStartingBlock = MVDSEndingBlock;
LVIDSEndingBlock = LVIDSStartingBlock + 4;
physicalPartitionStartingBlock = LVIDSEndingBlock;
if (myUDFRevision == UDFRevision.Revision260) {
partitionToStoreMetadataOn = 1;
mainMetadataFileBlock = physicalPartitionStartingBlock + 1;
mainMetadataFileLocation = mainMetadataFileBlock - physicalPartitionStartingBlock;
metadataPartitionStartingBlock = physicalPartitionStartingBlock + 2;
FSDBlock = physicalPartitionStartingBlock + 2;
FSDLocation = 0;
rootFEBlock = physicalPartitionStartingBlock + 3;
rootFELocation = 1;
} else {
partitionToStoreMetadataOn = 0;
FSDBlock = physicalPartitionStartingBlock + 1;
FSDLocation = 1;
rootFEBlock = physicalPartitionStartingBlock + 2;
rootFELocation = 2;
}
long[] currentBlock =
recursiveGetFileEntryLocation(rootUDFImageBuilderFile, new long[]{rootFEBlock, 0}, myUDFRevision);
nextUniqueId = myUniqueIdDisposer.getNextUniqueId();
if (myUDFRevision == UDFRevision.Revision260) {
if (((currentBlock[0]) - metadataPartitionStartingBlock) % metadataAllocationUnitSize != 0) {
metadataEmptyArea = metadataAllocationUnitSize -
(((currentBlock[0]) - metadataPartitionStartingBlock) % metadataAllocationUnitSize);
currentBlock[0] += metadataEmptyArea;
}
metadataPartitionEndingBlock = currentBlock[0];
mirrorMetadataFileBlock = currentBlock[0] + currentBlock[1];
mirrorMetadataFileLocation = mirrorMetadataFileBlock - physicalPartitionStartingBlock;
physicalPartitionEndingBlock = mirrorMetadataFileBlock + 1;
} else {
physicalPartitionEndingBlock = currentBlock[0] + currentBlock[1];
}
// update data locations
Enumeration myEnumeration = fileEntryPositions.keys();
while (myEnumeration.hasMoreElements()) {
UDFImageBuilderFile myUDFImageBuilderFile = (UDFImageBuilderFile) myEnumeration.nextElement();
if (myUDFImageBuilderFile.getFileType() == UDFImageBuilderFile.FileType.File) {
FileEntryPosition myFileEntryPosition = fileEntryPositions.get(myUDFImageBuilderFile);
if (myFileEntryPosition.dataBlock != -1) {
myFileEntryPosition.dataBlock += currentBlock[0];
myFileEntryPosition.dataLocation += myFileEntryPosition.dataBlock - physicalPartitionStartingBlock;
}
}
}
// calculate partition sizes and freespace
if (myUDFRevision == UDFRevision.Revision260) {
sizeTable = new long[2];
sizeTable[0] = (physicalPartitionEndingBlock - physicalPartitionStartingBlock);
sizeTable[1] = (metadataPartitionEndingBlock - metadataPartitionStartingBlock);
freespaceTable = new long[2]; // no freespace
} else {
sizeTable = new long[1];
sizeTable[0] = (physicalPartitionEndingBlock - physicalPartitionStartingBlock);
freespaceTable = new long[1]; // no freespace
}
RVDSStartingBlock = physicalPartitionEndingBlock;
RVDSEndingBlock = RVDSStartingBlock + 16;
// setup reserve volume descriptor sequence element locations
PVD2Block = RVDSStartingBlock;
PD2Block = RVDSStartingBlock + 1;
LVD2Block = RVDSStartingBlock + 2;
USD2Block = RVDSStartingBlock + 3;
IUVD2Block = RVDSStartingBlock + 4;
TD2Block = RVDSStartingBlock + 5;
AVDP2Block = RVDSEndingBlock + 1;
}
private long[] recursiveGetFileEntryLocation(UDFImageBuilderFile currentUDFImageBuilderFile, long[] currentBlock,
UDFRevision myUDFRevision)
throws Exception {
if (currentUDFImageBuilderFile.getIdentifier().equals("")) {
uniqueIds.put(currentUDFImageBuilderFile, new Long(0));
} else {
uniqueIds.put(currentUDFImageBuilderFile, new Long(myUniqueIdDisposer.getNextUniqueId()));
}
linearUDFImageBuilderFileOrdering.add(currentUDFImageBuilderFile);
FileEntryPosition currentFileEntryPosition = new FileEntryPosition();
currentFileEntryPosition.entryBlock = currentBlock[0];
currentBlock[0]++;
if (myUDFRevision == UDFRevision.Revision260) {
currentFileEntryPosition.entryLocation =
currentFileEntryPosition.entryBlock - metadataPartitionStartingBlock;
} else {
currentFileEntryPosition.entryLocation =
currentFileEntryPosition.entryBlock - physicalPartitionStartingBlock;
}
if (currentUDFImageBuilderFile.getFileType() == UDFImageBuilderFile.FileType.File) {
// if filedata cannot be stored inline reserve data blocks and setup data location
if (((myUDFRevision == UDFRevision.Revision102) &&
currentUDFImageBuilderFile.getFileLength() > (blockSize - FileEntry.fixedPartLength))
|| (currentUDFImageBuilderFile.getFileLength() > (blockSize - ExtendedFileEntry.fixedPartLength))) {
currentFileEntryPosition.dataBlock = currentBlock[1];
currentBlock[1] += currentUDFImageBuilderFile.getFileLength() / blockSize;
if (currentUDFImageBuilderFile.getFileLength() % blockSize != 0) {
currentBlock[1]++;
}
} else {
currentFileEntryPosition.dataBlock = -1;
}
} else //if( myUDFImageBuilderFile.getFileType() == UDFImageBuilderFile.FileType.Directory )
{
long FileIdentifierDescriptorsLength = 0;
FileIdentifierDescriptor parentDirectoryFileIdentifierDescriptor = new FileIdentifierDescriptor();
FileIdentifierDescriptorsLength += parentDirectoryFileIdentifierDescriptor.getLength();
UDFImageBuilderFile[] childUDFImageBuilderFiles = currentUDFImageBuilderFile.getChilds();
for (int i = 0; i < childUDFImageBuilderFiles.length; ++i) {
FileIdentifierDescriptor childFileIdentifierDescriptor = new FileIdentifierDescriptor();
childFileIdentifierDescriptor.setFileIdentifier(childUDFImageBuilderFiles[i].getIdentifier());
FileIdentifierDescriptorsLength += childFileIdentifierDescriptor.getLength();
}
if (((myUDFRevision == UDFRevision.Revision102) &&
FileIdentifierDescriptorsLength > (blockSize - FileEntry.fixedPartLength))
|| (FileIdentifierDescriptorsLength > (blockSize - ExtendedFileEntry.fixedPartLength))) {
currentFileEntryPosition.dataBlock = currentBlock[0];
if (myUDFRevision == UDFRevision.Revision260) {
currentFileEntryPosition.dataLocation =
currentFileEntryPosition.dataBlock - metadataPartitionStartingBlock;
} else {
currentFileEntryPosition.dataLocation =
currentFileEntryPosition.dataBlock - physicalPartitionStartingBlock;
}
currentBlock[0] += FileIdentifierDescriptorsLength / blockSize;
if (FileIdentifierDescriptorsLength % blockSize != 0) {
currentBlock[0]++;
}
} else {
currentFileEntryPosition.dataBlock = -1;
}
for (int i = 0; i < childUDFImageBuilderFiles.length; ++i) {
currentBlock = recursiveGetFileEntryLocation(childUDFImageBuilderFiles[i], currentBlock, myUDFRevision);
}
}
fileEntryPositions.put(currentUDFImageBuilderFile, currentFileEntryPosition);
return currentBlock;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy