Class: Archive::Zip::ExtraField::ExtendedTimestamp

Inherits:
Object
  • Object
show all
Defined in:
lib/archive/zip/extra_field/extended_timestamp.rb

Overview

Archive::Zip::Entry::ExtraField::ExtendedTimestamp represents an extra field which optionally contains the last modified time, last accessed time, and file creation time for a ZIP archive entry and stored in a Unix time format (seconds since the epoc).

Constant Summary collapse

ID =

The identifier reserved for this extra field type.

0x5455

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mtime, atime, crtime) ⇒ ExtendedTimestamp

Creates a new instance of this class. mtime, atime, and crtime should be Time instances or nil. When set to nil the field is considered to be unset and will not be stored in the archive.


112
113
114
115
116
117
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 112

def initialize(mtime, atime, crtime)
  @header_id = ID
  self.mtime = mtime unless mtime.nil?
  self.atime = atime unless atime.nil?
  self.crtime = crtime unless crtime.nil?
end

Instance Attribute Details

#atimeObject

The last accessed time for an entry. Set to either a Time instance or nil.


126
127
128
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 126

def atime
  @atime
end

#crtimeObject

The creation time for an entry. Set to either a Time instance or nil.


128
129
130
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 128

def crtime
  @crtime
end

#header_idObject (readonly)

Returns the header ID for this ExtraField.


120
121
122
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 120

def header_id
  @header_id
end

#mtimeObject

The last modified time for an entry. Set to either a Time instance or nil.


123
124
125
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 123

def mtime
  @mtime
end

Class Method Details

.parse_central(data) ⇒ Object

This method signature is part of the interface contract expected by Archive::Zip::Entry for extra field objects.

Parses data which is expected to be a String formatted according to the documentation provided with InfoZip's sources.

Raises Archive::Zip::ExtraFieldError if data contains invalid data.


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 25

def parse_central(data)
  unless data.size == 5 || data.size == 9 || data.size == 13 then
    raise Zip::ExtraFieldError,
      "invalid size for extended timestamp: #{data.size}"
  end
  flags, *times = data.unpack('CV*')
  mtime = nil
  atime = nil
  crtime = nil
  if flags & 0b001 != 0 then
    if times.size == 0 then
      # Report an error if the flags indicate that the last modified time
      # field should be present when it is not.
      raise Zip::ExtraFieldError,
        'corrupt extended timestamp: last modified time field not present'
    end
    mtime = Time.at(times.shift)
  end
  if flags & 0b010 != 0 then
    # If parsing the central file record version of this field, this flag
    # may be set without having the corresponding time value.
    # Use the time value if available, but ignore it if it's missing.
    if times.size > 0 then
      atime = Time.at(times.shift)
    end
  end
  if flags & 0b100 != 0 then
    # If parsing the central file record version of this field, this flag
    # may be set without having the corresponding time value.
    # Use the time value if available, but ignore it if it's missing.
    if times.size > 0 then
      crtime = Time.at(times.shift)
    end
  end
  new(mtime, atime, crtime)
end

.parse_local(data) ⇒ Object

This method signature is part of the interface contract expected by Archive::Zip::Entry for extra field objects.

Parses data which is expected to be a String formatted according to the documentation provided with InfoZip's sources.

Raises Archive::Zip::ExtraFieldError if data contains invalid data.


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 69

def parse_local(data)
  unless data.size == 5 || data.size == 9 || data.size == 13 then
    raise Zip::ExtraFieldError,
      "invalid size for extended timestamp: #{data.size}"
  end
  flags, *times = data.unpack('CV*')
  mtime = nil
  atime = nil
  crtime = nil
  if flags & 0b001 != 0 then
    if times.size == 0 then
      # Report an error if the flags indicate that the last modified time
      # field should be present when it is not.
      raise Zip::ExtraFieldError,
        'corrupt extended timestamp: last modified time field not present'
    end
    mtime = Time.at(times.shift)
  end
  if flags & 0b010 != 0 then
    if times.size == 0 then
      # Report an error if the flags indicate that the last modified time
      # field should be present when it is not.
      raise Zip::ExtraFieldError,
        'corrupt extended timestamp: last accessed time field not present'
    end
    atime = Time.at(times.shift)
  end
  if flags & 0b100 != 0 then
    if times.size == 0 then
      # Report an error if the flags indicate that the file creation time
      # field should be present when it is not.
      raise Zip::ExtraFieldError,
        'corrupt extended timestamp: file creation time field not present'
    end
    crtime = Time.at(times.shift)
  end
  new(mtime, atime, crtime)
end

Instance Method Details

#dump_centralObject

This method signature is part of the interface contract expected by Archive::Zip::Entry for extra field objects.

Returns a String suitable to writing to a central file record in a ZIP archive file which contains the data for this object.


153
154
155
156
157
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 153

def dump_central
  times = []
  times << mtime.to_i unless mtime.nil?
  ([ID, 4 * times.size + 1, flags] + times).pack('vvC' + 'V' * times.size)
end

#dump_localObject

This method signature is part of the interface contract expected by Archive::Zip::Entry for extra field objects.

Returns a String suitable to writing to a local file record in a ZIP archive file which contains the data for this object.


164
165
166
167
168
169
170
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 164

def dump_local
  times = []
  times << mtime.to_i unless mtime.nil?
  times << atime.to_i unless atime.nil?
  times << crtime.to_i unless crtime.nil?
  ([ID, 4 * times.size + 1, flags] + times).pack('vvC' + 'V' * times.size)
end

#merge(other) ⇒ Object

This method signature is part of the interface contract expected by Archive::Zip::Entry for extra field objects.

Merges the attributes of other into this object and returns self.

Raises ArgumentError if other is not the same class as this object.


136
137
138
139
140
141
142
143
144
145
146
# File 'lib/archive/zip/extra_field/extended_timestamp.rb', line 136

def merge(other)
  if self.class != other.class then
    raise ArgumentError, "#{self.class} is not the same as #{other.class}"
  end

  @mtime = other.mtime unless other.mtime.nil?
  @atime = other.atime unless other.atime.nil?
  @crtime = other.crtime unless other.crtime.nil?

  self
end