You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
5.1 KiB
JavaScript

'use strict';
const moment = require("moment");
const removeRightPadding = require("../remove-right-padding");
/* Basic ISO 9660 types: (ref http://wiki.osdev.org/ISO_9660#Numerical_formats)
* int8 Unsigned 8-bit integer.
* sint8 Signed 8-bit integer.
* int16_LSB Little-endian encoded unsigned 16-bit integer.
* int16_MSB Big-endian encoded unsigned 16-bit integer.
* int16_LSB-MSB Little-endian followed by big-endian encoded unsigned 16-bit integer.
* sint16_LSB Little-endian encoded signed 16-bit integer.
* sint16_MSB Big-endian encoded signed 16-bit integer.
* sint16_LSB-MSB Little-endian followed by big-endian encoded signed 16-bit integer.
* int32_LSB Little-endian encoded unsigned 32-bit integer.
* int32_MSB Big-endian encoded unsigned 32-bit integer.
* int32_LSB-MSB Little-endian followed by big-endian encoded unsigned 32-bit integer.
* sint32_LSB Little-endian encoded signed 32-bit integer.
* sint32_MSB Big-endian encoded signed 32-bit integer.
* sint32_LSB-MSB Little-endian followed by big-endian encoded signed 32-bit integer.
*
* "Where a both-endian format is present, the x86 architecture makes use of the first little-endian sequence and ignores the big-endian sequence."
*/
function offsetInMinutes(value) {
/* "Time zone offset from GMT in 15 minute intervals, starting at interval -48 (west) and running up to interval 52 (east).
* So value 0 indicates interval -48 which equals GMT-12 hours, and value 100 indicates interval 52 which equals GMT+13 hours."
*
* ref: http://wiki.osdev.org/ISO_9660#Date.2Ftime_format
*/
return (value - 48) * 15;
}
module.exports = {
/* String types */
strA: function parseStrA(buffer) {
return removeRightPadding(buffer.toString("ascii"));
},
strD: function parseStrD(buffer) {
return this.strA(buffer);
},
strFilename: function parseStrFilename(buffer) {
let str = this.strA(buffer);
let [filename, version] = str.split(";");
return {filename, version};
},
/* 8-bit integers */
int8: function parseInt8(buffer) {
return buffer.readUInt8(0);
},
sint8: function parseSInt8(buffer) {
return buffer.readInt8(0);
},
/* 16-bit integers */
int16_LSB: function parseInt16_LSB(buffer) {
return buffer.readUInt16LE(0);
},
int16_MSB: function parseInt16_LSB(buffer) {
return buffer.readUInt16BE(0);
},
int16_LSB_MSB: function parseInt16_LSB(buffer) {
return this.int16_LSB(buffer.slice(0, 2));
},
sint16_LSB: function parseSInt16_LSB(buffer) {
return buffer.readInt16LE(0);
},
sint16_MSB: function parseSInt16_LSB(buffer) {
return buffer.readInt16BE(0);
},
sint16_LSB_MSB: function parseSInt16_LSB(buffer) {
return this.sint16_LSB(buffer.slice(0, 2));
},
/* 32-bit integers */
int32_LSB: function parseInt32_LSB(buffer) {
return buffer.readUInt32LE(0);
},
int32_MSB: function parseInt32_LSB(buffer) {
return buffer.readUInt32BE(0);
},
int32_LSB_MSB: function parseInt32_LSB(buffer) {
return this.int32_LSB(buffer.slice(0, 4));
},
sint32_LSB: function parseSInt32_LSB(buffer) {
return buffer.readInt32LE(0);
},
sint32_MSB: function parseSInt32_LSB(buffer) {
return buffer.readInt32BE(0);
},
sint32_LSB_MSB: function parseSInt32_LSB(buffer) {
return this.sint32_LSB(buffer.slice(0, 4));
},
/* Date/time */
decDatetime: function parseDecDatetime(buffer) {
let year = parseInt(this.strD(buffer.slice(0, 4)));
let month = parseInt(this.strD(buffer.slice(4, 6))) - 1; // "Note that like moment(Array) and new Date(year, month, date), months are 0 indexed."
let day = parseInt(this.strD(buffer.slice(6, 8)));
let hour = parseInt(this.strD(buffer.slice(8, 10)));
let minute = parseInt(this.strD(buffer.slice(10, 12)));
let second = parseInt(this.strD(buffer.slice(12, 14)));
let centisecond = parseInt(this.strD(buffer.slice(14, 16)));
let timezoneOffset = this.int8(buffer.slice(16, 17));
if (year === 0 && month === 0 && day === 0 && hour === 0 && minute === 0 && second === 0 && centisecond === 0 && timezoneOffset === 0) {
return null;
} else {
return moment({
year, month, day, hour, minute, second,
millisecond: centisecond * 10,
}).utcOffset(offsetInMinutes(timezoneOffset));
}
},
directoryDatetime: function parseDirectoryDatetime(buffer) {
return moment({
year: 1900 + this.int8(buffer.slice(0, 0 + 1)),
month: this.int8(buffer.slice(1, 1 + 1)) - 1,
day: this.int8(buffer.slice(2, 2 + 1)),
hour: this.int8(buffer.slice(3, 3 + 1)),
minute: this.int8(buffer.slice(4, 4 + 1)),
second: this.int8(buffer.slice(5, 5 + 1)),
}).utcOffset(offsetInMinutes(this.int8(buffer.slice(6, 6 + 1))));
}
};