/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.filesystems.umdiso.iso9660;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
*
* @author gigaherz
*/
public class Iso9660File {
private int fileLBA;
private long fileSize;
private int fileProperties;
// padding: byte[3]
private String fileName; //[128+1];
//Iso9660Date date; // byte[7]
private Date timestamp;
private static final Charset jolietCharset = Charset.forName("UTF-16BE");
private static final Charset normalCharset = Charset.forName("US-ASCII");
private static int Ubyte(byte b) {
return b & 0xFF;
}
public Iso9660File(byte[] data, int length, boolean jolietExtension) throws IOException {
/*
1 Length of Directory Record (LEN-DR) -- read by the Iso9660Directory
2 Extended Attribute Record Length
3 to 10 Location of Extent
11 to 18 Data Length
19 to 25 Recording Date and Time
26 File Flags
27 File Unit Size
28 Interleave Gap Size
29 to 32 Volume Sequence Number
33 Length of File Identifier (LEN_FI)
34 to (33+LEN_FI) File Identifier
(34 + LEN_FI) Padding Field
*/
fileLBA = Ubyte(data[1]) | (Ubyte(data[2])<<8) | (Ubyte(data[3])<<16) | (data[4]<<24);
fileSize = Ubyte(data[9]) | (Ubyte(data[10])<<8) | (Ubyte(data[11])<<16) | (((long) Ubyte(data[12]))<<24);
int year = Ubyte(data[17]);
int month = Ubyte(data[18]);
int day = Ubyte(data[19]);
int hour = Ubyte(data[20]);
int minute = Ubyte(data[21]);
int second = Ubyte(data[22]);
int gmtOffset = data[23]; // Offset from Greenwich Mean Time in number of 15 min intervals from -48 (West) to + 52 (East)
int gmtOffsetHours = gmtOffset / 4;
int gmtOffsetMinutes = (gmtOffset % 4) * 15;
// Build TimeZone name as e.g.
// "GMT+1015", meaning GMT + 10 hours and 15 minutes
String timeZoneName = "GMT";
if (gmtOffset >= 0) {
timeZoneName += "+";
}
timeZoneName += gmtOffsetHours;
if (gmtOffsetMinutes > 0) {
if (gmtOffsetMinutes < 10) {
timeZoneName += "0";
}
timeZoneName += gmtOffsetMinutes;
}
TimeZone timeZone = TimeZone.getTimeZone(timeZoneName);
Calendar timestampCalendar = Calendar.getInstance(timeZone);
timestampCalendar.set(1900 + year, month - 1, day, hour, minute, second);
timestamp = timestampCalendar.getTime();
fileProperties = data[24];
if (fileLBA < 0 || fileSize < 0) {
throw new IOException("Invalid ISO, size or lba < 0");
}
int fileNameLength = data[31];
if (jolietExtension) {
if (fileNameLength == 1) {
char c = (char) data[32];
if (c == 0) {
c = '.';
}
fileName = Character.toString(c);
} else {
fileName = new String(data, 32, fileNameLength, jolietCharset);
int end = fileName.indexOf(';');
if (end >= 0) {
fileName = fileName.substring(0, end);
}
}
} else {
// Replace all '\0' bytes by '.' in the filename
for (int i = 0; i < fileNameLength; i++) {
if (data[32 + i] == (byte) 0) {
data[32 + i] = (byte) '.';
}
}
fileName = new String(data, 32, fileNameLength, normalCharset);
}
}
public int getLBA()
{
return fileLBA;
}
public long getSize()
{
return fileSize;
}
public int getProperties()
{
return fileProperties;
}
public String getFileName()
{
return fileName;
}
public Date getTimestamp()
{
return timestamp;
}
@Override
public String toString() {
return fileName;
}
}