diff --git a/filesystem/iso9660/ByteParser.java b/filesystem/iso9660/ByteParser.java new file mode 100644 index 0000000..4adc7fd --- /dev/null +++ b/filesystem/iso9660/ByteParser.java @@ -0,0 +1,43 @@ +package filesystem.iso9660; + +public class ByteParser { + byte[] array; + int offset; + + public ByteParser(byte[] array, int offset) { + this.array = array; + this.offset = offset; + } + + public static int shortLE(int i0, int i1) { + return ((i1 << 8) + | (i0 << 0)); + } + + public static int intLE(int i0, int i1, int i2, int i3) { + return ((i3 << 24) + | (i2 << 16) + | (i1 << 8) + | (i0 << 0)); + } + + public int getByte(int pos) { + return array[offset + pos]; + } + + public int getShortLE(int pos) { + int i0 = array[offset + pos + 0]; + int i1 = array[offset + pos + 1]; + + return shortLE(i0, i1); + } + + public int getIntLE(int pos) { + int i0 = array[offset + pos + 0]; + int i1 = array[offset + pos + 1]; + int i2 = array[offset + pos + 2]; + int i3 = array[offset + pos + 3]; + + return intLE(i0, i1, i2, i3); + } +} diff --git a/filesystem/iso9660/DirectoryRecord.java b/filesystem/iso9660/DirectoryRecord.java new file mode 100644 index 0000000..6e8409f --- /dev/null +++ b/filesystem/iso9660/DirectoryRecord.java @@ -0,0 +1,50 @@ +package filesystem.iso9660; + +public class DirectoryRecord extends ByteParser { + public static final int LENGTH_OF_DIRECTORY_RECORD_START = 0; + public static final int LENGTH_OF_DIRECTORY_RECORD_END = 0; + public static final int EXTENDED_ATTRIBUTE_RECORD_LENGTH_START = 1; + public static final int EXTENDED_ATTRIBUTE_RECORD_LENGTH_END = 1; + public static final int LOCATION_OF_EXTENT_START = 2; + public static final int LOCATION_OF_EXTENT_END = 9; + public static final int DATA_LENGTH_START = 10; + public static final int DATA_LENGTH_END = 17; + public static final int RECORDING_DATE_AND_TIME_START = 18; + public static final int RECORDING_DATE_AND_TIME_END = 24; + public static final int FILE_FLAGS_START = 25; + public static final int FILE_FLAGS_END = 25; + public static final int FILE_UNIT_SIZE_START = 26; + public static final int FILE_UNIT_SIZE_END = 26; + public static final int INTERLEAVE_GAP_SIZE_START = 27; + public static final int INTERLEAVE_GAP_SIZE_END = 27; + public static final int VOLUME_SEQUENCE_NUMBER_START = 28; + public static final int VOLUME_SEQUENCE_NUMBER_END = 31; + public static final int LENGTH_OF_FILE_IDENTIFIER_START = 32; + public static final int LENGTH_OF_FILE_IDENTIFIER_END = 32; + public static final int FILE_IDENTIFIER_START = 33; + public static final int FILE_IDENTIFIER_END = 32; + public static final int lengthOfDirectoryRecord() { + return getByte(LENGTH_OF_DIRECTORY_RECORD_START); + } + public static final int extendedAttributeRecordLength() { + return getByte(EXTENDED_ATTRIBUTE_RECORD_LENGTH_START); + } + public static final int locationOfExtent() { + return getIntBE(LOCATION_OF_EXTENT_START); + } + public static final int dataLength() { + return getIntBE(DATA_LENGTH_START); + } + public static final int fileUnitSize() { + return getByte(FILE_UNIT_SIZE_START); + } + public static final int interleaveGapSize() { + return getByte(INTERLEAVE_GAP_SIZE_START); + } + public static final int volumeSequenceNumber() { + return getShortBE(VOLUME_SEQUENCE_NUMBER_START); + } + public static final int lengthOfFileIdentifier() { + return getByte(LENGTH_OF_FILE_IDENTIFIER_START); + } +} diff --git a/filesystem/iso9660/PrimaryVolumeDescriptor.java b/filesystem/iso9660/PrimaryVolumeDescriptor.java new file mode 100644 index 0000000..72768e3 --- /dev/null +++ b/filesystem/iso9660/PrimaryVolumeDescriptor.java @@ -0,0 +1,96 @@ +package filesystem.iso9660; + +public class PrimaryVolumeDescriptor extends ByteParser { + public static final int VOLUME_DESCRIPTOR_TYPE_START = 0; + public static final int VOLUME_DESCRIPTOR_TYPE_END = 0; + public static final int STANDARD_IDENTIFIER_START = 1; + public static final int STANDARD_IDENTIFIER_END = 5; + public static final int VOLUME_DESCRIPTOR_VERSION_START = 6; + public static final int VOLUME_DESCRIPTOR_VERSION_END = 6; + public static final int SYSTEM_IDENTIFIER_START = 8; + public static final int SYSTEM_IDENTIFIER_END = 39; + public static final int VOLUME_IDENTIFIER_START = 40; + public static final int VOLUME_IDENTIFIER_END = 71; + public static final int VOLUME_SPACE_SIZE_START = 80; + public static final int VOLUME_SPACE_SIZE_END = 87; + public static final int VOLUME_SET_SIZE_START = 120; + public static final int VOLUME_SET_SIZE_END = 123; + public static final int VOLUME_SEQUENCE_NUMBER_START = 124; + public static final int VOLUME_SEQUENCE_NUMBER_END = 127; + public static final int LOGICAL_BLOCK_SIZE_START = 128; + public static final int LOGICAL_BLOCK_SIZE_END = 131; + public static final int PATH_TABLE_SIZE_START = 132; + public static final int PATH_TABLE_SIZE_END = 139; + public static final int LOCATION_OF_OCCURRENCE_OF_TYPE_L_PATH_TABLE_START = 140; + public static final int LOCATION_OF_OCCURRENCE_OF_TYPE_L_PATH_TABLE_END = 143; + public static final int LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_L_PATH_TABLE_START = 144; + public static final int LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_L_PATH_TABLE_END = 147; + public static final int LOCATION_OF_OCCURENCE_OF_TYPE_M_PATH_TABLE_START = 148; + public static final int LOCATION_OF_OCCURENCE_OF_TYPE_M_PATH_TABLE_END = 151; + public static final int LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_M_PATH_TABLE_START = 152; + public static final int LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_M_PATH_TABLE_END = 155; + public static final int DIRECTORY_RECORD_FOR_ROOT_DIRECTORY_START = 156; + public static final int DIRECTORY_RECORD_FOR_ROOT_DIRECTORY_END = 189; + public static final int VOLUME_SET_IDENTIFIER_START = 190; + public static final int VOLUME_SET_IDENTIFIER_END = 317; + public static final int PUBLISHER_IDENTIFIER_START = 318; + public static final int PUBLISHER_IDENTIFIER_END = 445; + public static final int DATA_PREPARER_IDENTIFIER_START = 446; + public static final int DATA_PREPARER_IDENTIFIER_END = 573; + public static final int APPLICATION_IDENTIFIER_START = 574; + public static final int APPLICATION_IDENTIFIER_END = 701; + public static final int COPYRIGHT_FILE_IDENTIFIER_START = 702; + public static final int COPYRIGHT_FILE_IDENTIFIER_END = 738; + public static final int ABSTRACT_FILE_IDENTIFIER_START = 739; + public static final int ABSTRACT_FILE_IDENTIFIER_END = 775; + public static final int BIBLIOGRAPHIC_FILE_IDENTIFIER_START = 776; + public static final int BIBLIOGRAPHIC_FILE_IDENTIFIER_END = 812; + public static final int VOLUME_CREATION_DATE_AND_TIME_START = 813; + public static final int VOLUME_CREATION_DATE_AND_TIME_END = 829; + public static final int VOLUME_MODIFICATION_DATE_AND_TIME_START = 830; + public static final int VOLUME_MODIFICATION_DATE_AND_TIME_END = 846; + public static final int VOLUME_EXPIRATION_DATE_AND_TIME_START = 847; + public static final int VOLUME_EXPIRATION_DATE_AND_TIME_END = 863; + public static final int VOLUME_EFFECTIVE_DATE_AND_TIME_START = 864; + public static final int VOLUME_EFFECTIVE_DATE_AND_TIME_END = 880; + public static final int FILE_STRUCTURE_VERSION_START = 881; + public static final int FILE_STRUCTURE_VERSION_END = 881; + public static final int APPLICATION_USE_START = 883; + public static final int APPLICATION_USE_END = 1394; + PrimaryVolumeDescriptor(byte[] array, int offset) { + super(array, offset); + } + public int volumeDescriptorType() { + return getByte(VOLUME_DESCRIPTOR_TYPE_START); + } + public int volumeDescriptorVersion() { + return getByte(VOLUME_DESCRIPTOR_VERSION_START); + } + public int volumeSpaceSize() { + return getIntLE(VOLUME_SPACE_SIZE_START); + } + public int volumeSetSize() { + return getShortLE(VOLUME_SET_SIZE_START); + } + public int volumeSequenceNumber() { + return getShortLE(VOLUME_SEQUENCE_NUMBER_START); + } + public int logicalBlockSize() { + return getShortLE(LOGICAL_BLOCK_SIZE_START); + } + public int pathTableSize() { + return getIntLE(PATH_TABLE_SIZE_START); + } + public int locationOfOccurrenceOfTypeLPathTable() { + return getShortLE(LOCATION_OF_OCCURRENCE_OF_TYPE_L_PATH_TABLE_START); + } + public int locationOfOptionalOccurenceOfTypeLPathTable() { + return getShortLE(LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_L_PATH_TABLE_START); + } + public int locationOfOccurenceOfTypeMPathTable() { + return getShortLE(LOCATION_OF_OCCURENCE_OF_TYPE_M_PATH_TABLE_START); + } + public int locationOfOptionalOccurenceOfTypeMPathTable() { + return getShortLE(LOCATION_OF_OPTIONAL_OCCURENCE_OF_TYPE_M_PATH_TABLE_START); + } +} diff --git a/java/nio/ByteBuffer.java b/java/nio/ByteBuffer.java index 5160472..2f02349 100644 --- a/java/nio/ByteBuffer.java +++ b/java/nio/ByteBuffer.java @@ -31,6 +31,11 @@ public class ByteBuffer extends Buffer { return this; } + public ByteBuffer offset(int off) { + offset = off; + return this; + } + private static int intBE(int i0, int i1, int i2, int i3) { return ((i0 << 24) | (i1 << 16) @@ -55,20 +60,24 @@ public class ByteBuffer extends Buffer { | (i1 << 8)); } + private int ix(int pos) { + return offset + pos; + } + public byte get() { - byte i0 = array[position]; + byte i0 = array[ix(position)]; position += 1; return i0; } public byte get(int pos) { - byte i0 = array[pos]; + byte i0 = array[ix(pos)]; return i0; } public short getShort() { - int i0 = array[position + 0]; - int i1 = array[position + 1]; + int i0 = array[ix(position) + 0]; + int i1 = array[ix(position) + 1]; position += 2; @@ -80,8 +89,8 @@ public class ByteBuffer extends Buffer { } public short getShort(int pos) { - int i0 = array[pos + 0]; - int i1 = array[pos + 1]; + int i0 = array[ix(pos) + 0]; + int i1 = array[ix(pos) + 1]; if (bigEndian) { return (short)shortBE(i0, i1); @@ -91,10 +100,10 @@ public class ByteBuffer extends Buffer { } public int getInt() { - int i0 = array[position + 0]; - int i1 = array[position + 1]; - int i2 = array[position + 2]; - int i3 = array[position + 3]; + int i0 = array[ix(position) + 0]; + int i1 = array[ix(position) + 1]; + int i2 = array[ix(position) + 2]; + int i3 = array[ix(position) + 3]; position += 4; @@ -106,10 +115,10 @@ public class ByteBuffer extends Buffer { } public int getInt(int pos) { - int i0 = array[pos + 0]; - int i1 = array[pos + 1]; - int i2 = array[pos + 2]; - int i3 = array[pos + 3]; + int i0 = array[ix(pos) + 0]; + int i1 = array[ix(pos) + 1]; + int i2 = array[ix(pos) + 2]; + int i3 = array[ix(pos) + 3]; if (bigEndian) { return intBE(i0, i1, i2, i3); diff --git a/p/ISOParser.java b/p/ISOParser.java new file mode 100644 index 0000000..5a1a046 --- /dev/null +++ b/p/ISOParser.java @@ -0,0 +1,19 @@ +package p; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.io.IOException; + +import filesystem.iso9660.PrimaryVolumeDescriptor; + +class ISOParser { + public static void main(String[] args) throws IOException { + byte[] buf = Files.readAllBytes(Paths.get("test.iso")); + + for (int i = PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_START; i <= PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_END; i++) { + System.out.print(buf[i]); + } + System.out.println(); + + } +}