// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.
import (
"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
"strconv"
)
/**
* MS-DOS date and time are packed 16-bit values that specify local date/time.
* The time is always stored in the current UTC time offset set on the computer
* which created the file. Note that the daylight saving time (DST) shifts
* also change the UTC time offset.
*
* For example, if you pack two files A and B into a ZIP archive, file A last modified
* at 2020-03-29 00:59 UTC+00:00 (GMT) and file B at 2020-03-29 02:00 UTC+01:00 (BST),
* the file modification times saved in MS-DOS format in the ZIP file will vary depending
* on whether the computer packing the files is set to GMT or BST at the time of ZIP creation.
*
* - If set to GMT:
* - file A: 2020-03-29 00:59 (UTC+00:00)
* - file B: 2020-03-29 01:00 (UTC+00:00)
* - If set to BST:
* - file A: 2020-03-29 01:59 (UTC+01:00)
* - file B: 2020-03-29 02:00 (UTC+01:00)
*
* It follows that you are unable to determine the actual last modified time
* of any file stored in the ZIP archive, if you don't know the locale time
* setting of the computer at the time it created the ZIP.
*
* This format is used in some data formats from the MS-DOS era, for example:
*
* - [zip](/zip/)
* - [rar](/rar/)
* - [vfat](/vfat/) (FAT12)
* - [lzh](/lzh/)
* - [cab](http://justsolve.archiveteam.org/wiki/Cabinet)
* @see Source
* @see Source
* @see DosDateTimeToFileTime
* @see page 25/34
*/
type DosDatetime struct {
Time *DosDatetime_Time
Date *DosDatetime_Date
_io *kaitai.Stream
_root *DosDatetime
_parent interface{}
}
func NewDosDatetime() *DosDatetime {
return &DosDatetime{
}
}
func (this *DosDatetime) Read(io *kaitai.Stream, parent interface{}, root *DosDatetime) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp1 := NewDosDatetime_Time()
err = tmp1.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Time = tmp1
tmp2 := NewDosDatetime_Date()
err = tmp2.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Date = tmp2
return err
}
type DosDatetime_Time struct {
SecondDiv2 uint64
Minute uint64
Hour uint64
_io *kaitai.Stream
_root *DosDatetime
_parent *DosDatetime
_f_second bool
second int
_f_paddedSecond bool
paddedSecond string
_f_paddedMinute bool
paddedMinute string
_f_paddedHour bool
paddedHour string
}
func NewDosDatetime_Time() *DosDatetime_Time {
return &DosDatetime_Time{
}
}
func (this *DosDatetime_Time) Read(io *kaitai.Stream, parent *DosDatetime, root *DosDatetime) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp3, err := this._io.ReadBitsIntLe(5)
if err != nil {
return err
}
this.SecondDiv2 = tmp3
if !(this.SecondDiv2 <= 29) {
return kaitai.NewValidationGreaterThanError(29, this.SecondDiv2, this._io, "/types/time/seq/0")
}
tmp4, err := this._io.ReadBitsIntLe(6)
if err != nil {
return err
}
this.Minute = tmp4
if !(this.Minute <= 59) {
return kaitai.NewValidationGreaterThanError(59, this.Minute, this._io, "/types/time/seq/1")
}
tmp5, err := this._io.ReadBitsIntLe(5)
if err != nil {
return err
}
this.Hour = tmp5
if !(this.Hour <= 23) {
return kaitai.NewValidationGreaterThanError(23, this.Hour, this._io, "/types/time/seq/2")
}
return err
}
func (this *DosDatetime_Time) Second() (v int, err error) {
if (this._f_second) {
return this.second, nil
}
this.second = int((2 * this.SecondDiv2))
this._f_second = true
return this.second, nil
}
func (this *DosDatetime_Time) PaddedSecond() (v string, err error) {
if (this._f_paddedSecond) {
return this.paddedSecond, nil
}
var tmp6 string;
tmp7, err := this.Second()
if err != nil {
return "", err
}
if (tmp7 <= 9) {
tmp6 = "0"
} else {
tmp6 = ""
}
tmp8, err := this.Second()
if err != nil {
return "", err
}
this.paddedSecond = string(tmp6 + strconv.FormatInt(int64(tmp8), 10))
this._f_paddedSecond = true
return this.paddedSecond, nil
}
func (this *DosDatetime_Time) PaddedMinute() (v string, err error) {
if (this._f_paddedMinute) {
return this.paddedMinute, nil
}
var tmp9 string;
if (this.Minute <= 9) {
tmp9 = "0"
} else {
tmp9 = ""
}
this.paddedMinute = string(tmp9 + strconv.FormatInt(int64(this.Minute), 10))
this._f_paddedMinute = true
return this.paddedMinute, nil
}
func (this *DosDatetime_Time) PaddedHour() (v string, err error) {
if (this._f_paddedHour) {
return this.paddedHour, nil
}
var tmp10 string;
if (this.Hour <= 9) {
tmp10 = "0"
} else {
tmp10 = ""
}
this.paddedHour = string(tmp10 + strconv.FormatInt(int64(this.Hour), 10))
this._f_paddedHour = true
return this.paddedHour, nil
}
type DosDatetime_Date struct {
Day uint64
Month uint64
YearMinus1980 uint64
_io *kaitai.Stream
_root *DosDatetime
_parent *DosDatetime
_f_year bool
year int
_f_paddedDay bool
paddedDay string
_f_paddedMonth bool
paddedMonth string
_f_paddedYear bool
paddedYear string
}
func NewDosDatetime_Date() *DosDatetime_Date {
return &DosDatetime_Date{
}
}
func (this *DosDatetime_Date) Read(io *kaitai.Stream, parent *DosDatetime, root *DosDatetime) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp11, err := this._io.ReadBitsIntLe(5)
if err != nil {
return err
}
this.Day = tmp11
if !(this.Day >= 1) {
return kaitai.NewValidationLessThanError(1, this.Day, this._io, "/types/date/seq/0")
}
tmp12, err := this._io.ReadBitsIntLe(4)
if err != nil {
return err
}
this.Month = tmp12
if !(this.Month >= 1) {
return kaitai.NewValidationLessThanError(1, this.Month, this._io, "/types/date/seq/1")
}
if !(this.Month <= 12) {
return kaitai.NewValidationGreaterThanError(12, this.Month, this._io, "/types/date/seq/1")
}
tmp13, err := this._io.ReadBitsIntLe(7)
if err != nil {
return err
}
this.YearMinus1980 = tmp13
return err
}
/**
* only years from 1980 to 2107 (1980 + 127) can be represented
*/
func (this *DosDatetime_Date) Year() (v int, err error) {
if (this._f_year) {
return this.year, nil
}
this.year = int((1980 + this.YearMinus1980))
this._f_year = true
return this.year, nil
}
func (this *DosDatetime_Date) PaddedDay() (v string, err error) {
if (this._f_paddedDay) {
return this.paddedDay, nil
}
var tmp14 string;
if (this.Day <= 9) {
tmp14 = "0"
} else {
tmp14 = ""
}
this.paddedDay = string(tmp14 + strconv.FormatInt(int64(this.Day), 10))
this._f_paddedDay = true
return this.paddedDay, nil
}
func (this *DosDatetime_Date) PaddedMonth() (v string, err error) {
if (this._f_paddedMonth) {
return this.paddedMonth, nil
}
var tmp15 string;
if (this.Month <= 9) {
tmp15 = "0"
} else {
tmp15 = ""
}
this.paddedMonth = string(tmp15 + strconv.FormatInt(int64(this.Month), 10))
this._f_paddedMonth = true
return this.paddedMonth, nil
}
func (this *DosDatetime_Date) PaddedYear() (v string, err error) {
if (this._f_paddedYear) {
return this.paddedYear, nil
}
var tmp16 string;
tmp17, err := this.Year()
if err != nil {
return "", err
}
if (tmp17 <= 999) {
var tmp18 string;
tmp19, err := this.Year()
if err != nil {
return "", err
}
if (tmp19 <= 99) {
var tmp20 string;
tmp21, err := this.Year()
if err != nil {
return "", err
}
if (tmp21 <= 9) {
tmp20 = "0"
} else {
tmp20 = ""
}
tmp18 = "0" + tmp20
} else {
tmp18 = ""
}
tmp16 = "0" + tmp18
} else {
tmp16 = ""
}
tmp22, err := this.Year()
if err != nil {
return "", err
}
this.paddedYear = string(tmp16 + strconv.FormatInt(int64(tmp22), 10))
this._f_paddedYear = true
return this.paddedYear, nil
}