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.
183 lines
6.4 KiB
JavaScript
183 lines
6.4 KiB
JavaScript
'use strict';
|
|
|
|
const moment = require("moment");
|
|
|
|
const bufferReaderFactory = require("../buffer-reader");
|
|
const decode = require("./decode");
|
|
const removeRightPadding = require("../remove-right-padding");
|
|
|
|
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 = function createReader(buffer, {encoding} = {encoding: "ascii"}) {
|
|
let bufferReaderRules = {
|
|
/* String types */
|
|
strA: {
|
|
decode: function parseStrA(buffer) {
|
|
return removeRightPadding(decode(buffer, "ascii"));
|
|
}
|
|
},
|
|
strD: {
|
|
decode: function parseStrD(buffer) {
|
|
return bufferReaderRules.strA.decode(buffer);
|
|
}
|
|
},
|
|
strA1: {
|
|
decode: function parseStrA(buffer) {
|
|
return removeRightPadding(decode(buffer, encoding));
|
|
}
|
|
},
|
|
strD1: {
|
|
decode: function parseStrD(buffer) {
|
|
return bufferReaderRules.strA1.decode(buffer);
|
|
}
|
|
},
|
|
strFilename: {
|
|
decode: function parseStrFilename(buffer) {
|
|
let decodedString = decode(buffer, encoding);
|
|
let [filename, version] = decodedString.split(";");
|
|
|
|
return {filename, version};
|
|
}
|
|
},
|
|
|
|
/* 8-bit integers */
|
|
int8: {
|
|
length: 1,
|
|
decode: function parseInt8(buffer) {
|
|
return buffer.readUInt8(0);
|
|
}
|
|
},
|
|
sint8: {
|
|
length: 1,
|
|
decode: function parseSInt8(buffer) {
|
|
return buffer.readInt8(0);
|
|
}
|
|
},
|
|
|
|
/* 16-bit integers */
|
|
int16_LSB: {
|
|
length: 2,
|
|
decode: function parseInt16_LSB(buffer) {
|
|
return buffer.readUInt16LE(0);
|
|
}
|
|
},
|
|
int16_MSB: {
|
|
length: 2,
|
|
decode: function parseInt16_LSB(buffer) {
|
|
return buffer.readUInt16BE(0);
|
|
}
|
|
},
|
|
int16_LSB_MSB: {
|
|
length: 4,
|
|
decode: function parseInt16_LSB(buffer) {
|
|
return bufferReaderRules.int16_LSB.decode(buffer.slice(0, 2));
|
|
}
|
|
},
|
|
sint16_LSB: {
|
|
length: 2,
|
|
decode: function parseSInt16_LSB(buffer) {
|
|
return buffer.readInt16LE(0);
|
|
}
|
|
},
|
|
sint16_MSB: {
|
|
length: 2,
|
|
decode: function parseSInt16_LSB(buffer) {
|
|
return buffer.readInt16BE(0);
|
|
}
|
|
},
|
|
sint16_LSB_MSB: {
|
|
length: 4,
|
|
decode: function parseSInt16_LSB(buffer) {
|
|
return bufferReaderRules.sint16_LSB.decode(buffer.slice(0, 2));
|
|
}
|
|
},
|
|
|
|
/* 32-bit integers */
|
|
int32_LSB: {
|
|
length: 4,
|
|
decode: function parseInt32_LSB(buffer) {
|
|
return buffer.readUInt32LE(0);
|
|
}
|
|
},
|
|
int32_MSB: {
|
|
length: 4,
|
|
decode: function parseInt32_LSB(buffer) {
|
|
return buffer.readUInt32BE(0);
|
|
}
|
|
},
|
|
int32_LSB_MSB: {
|
|
length: 8,
|
|
decode: function parseInt32_LSB(buffer) {
|
|
return bufferReaderRules.int32_LSB.decode(buffer.slice(0, 4));
|
|
}
|
|
},
|
|
sint32_LSB: {
|
|
length: 4,
|
|
decode: function parseSInt32_LSB(buffer) {
|
|
return buffer.readInt32LE(0);
|
|
}
|
|
},
|
|
sint32_MSB: {
|
|
length: 4,
|
|
decode: function parseSInt32_LSB(buffer) {
|
|
return buffer.readInt32BE(0);
|
|
}
|
|
},
|
|
sint32_LSB_MSB: {
|
|
length: 8,
|
|
decode: function parseSInt32_LSB(buffer) {
|
|
return bufferReaderRules.sint32_LSB.decode(buffer.slice(0, 4));
|
|
}
|
|
},
|
|
|
|
/* Date/time */
|
|
decDatetime: {
|
|
length: 17,
|
|
decode: function parseDecDatetime(buffer) {
|
|
let year = parseInt(bufferReaderRules.strD.decode(buffer.slice(0, 4)));
|
|
let month = parseInt(bufferReaderRules.strD.decode(buffer.slice(4, 6))) - 1; // "Note that like moment(Array) and new Date(year, month, date), months are 0 indexed."
|
|
let day = parseInt(bufferReaderRules.strD.decode(buffer.slice(6, 8)));
|
|
|
|
let hour = parseInt(bufferReaderRules.strD.decode(buffer.slice(8, 10)));
|
|
let minute = parseInt(bufferReaderRules.strD.decode(buffer.slice(10, 12)));
|
|
let second = parseInt(bufferReaderRules.strD.decode(buffer.slice(12, 14)));
|
|
let centisecond = parseInt(bufferReaderRules.strD.decode(buffer.slice(14, 16)));
|
|
|
|
let timezoneOffset = bufferReaderRules.int8.decode(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: {
|
|
length: 7,
|
|
decode: function parseDirectoryDatetime(buffer) {
|
|
return moment({
|
|
year: 1900 + bufferReaderRules.int8.decode(buffer.slice(0, 0 + 1)),
|
|
month: bufferReaderRules.int8.decode(buffer.slice(1, 1 + 1)) - 1,
|
|
day: bufferReaderRules.int8.decode(buffer.slice(2, 2 + 1)),
|
|
hour: bufferReaderRules.int8.decode(buffer.slice(3, 3 + 1)),
|
|
minute: bufferReaderRules.int8.decode(buffer.slice(4, 4 + 1)),
|
|
second: bufferReaderRules.int8.decode(buffer.slice(5, 5 + 1)),
|
|
}).utcOffset(offsetInMinutes(bufferReaderRules.int8.decode(buffer.slice(6, 6 + 1))));
|
|
}
|
|
}
|
|
}
|
|
|
|
return bufferReaderFactory(bufferReaderRules)(buffer);
|
|
};
|