'use strict' ;
const moment = require ( "moment" ) ;
const bufferReaderFactory = require ( "../buffer-reader" ) ;
const decode = require ( "./decode" ) ;
const removeRightPadding = require ( "../remove-right-padding" ) ;
function offsetInMinutes ( value ) {
/ * " T i m e z o n e o f f s e t f r o m G M T i n 1 5 m i n u t e i n t e r v a l s , s t a r t i n g a t i n t e r v a l - 4 8 ( w e s t ) a n d r u n n i n g u p t o i n t e r v a l 5 2 ( e a s t ) .
* 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 ) ;
} ;