Class: BC3::File

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/bc3/file.rb

Overview

File definition for BC3 handling.

If you need the original File inside BC3-module, use

::File#new
::File#open

Constant Summary collapse

KEYS =
[:filename,  :filesize ]
KEYS_OPTIONAL =
[
  :timestamp, :crc, :attributes,
  :version, :utfpath, :utfsymlink,
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helper

crc32, #fixnum2int16, #fixnum2int32, #fixnum2int64, #shortstring2bcss

Constructor Details

#initialize(args) ⇒ File

Definition of a file in a snapshot.

Arguments are given in a hash. Must contain KEYS and supports KEYS_OPTIONAL

Raises:

  • (ArgumentError)


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/bc3/file.rb', line 25

def initialize( args )
  raise ArgumentError, "No hash given (#{args.inspect})" unless args.kind_of?(Hash)
  KEYS.each{|key|
    raise ArgumentError, "Missing Key #{key}" unless args.has_key?(key)
  }
  (args.keys - (KEYS + KEYS_OPTIONAL)).each{|key|
    $log.warn("Undefined key #{key} for #{self.inspect}" )
  }
  @filename = args[:filename]
  @filesize = args[:filesize]
  @crc = args[:crc]
  
  @timestamp = args[:timestamp] || Time.now
  @attributes = args[:attributes] || Attrib::Archive
  
  @version = args[:version]  #-> Extended File
  @utfpath = args[:utfpath]  #-> Extended File
  @utfsymlink = args[:utfsymlink]  #-> Extended File
  
  @snapshotpath = {}
  #Test content
  raise ArgumentError, "timestamp is no time-object" unless @timestamp.kind_of?(Time)
end

Instance Attribute Details

#attributesObject (readonly)

File attributes



85
86
87
# File 'lib/bc3/file.rb', line 85

def attributes
  @attributes
end

#crcObject (readonly)

Returns the value of attribute crc.



81
82
83
# File 'lib/bc3/file.rb', line 81

def crc
  @crc
end

#filenameObject (readonly) Also known as: basename

Name of the file



78
79
80
# File 'lib/bc3/file.rb', line 78

def filename
  @filename
end

#snapshotpathObject (readonly)

Path (location) in snapshots



83
84
85
# File 'lib/bc3/file.rb', line 83

def snapshotpath
  @snapshotpath
end

Class Method Details

.new_by_filename(filename, with_crc = true) ⇒ Object

Creates a BC3::File-object, based on data from file system.

The argument must contain:

  • filename

  • flag, if crc schould be added (default: true)



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/bc3/file.rb', line 56

def self.new_by_filename( filename, with_crc = true )
  $log.debug("Build file #{filename} from file system")
  
  #fixme: get attributes from file system
  #~ p ::File.stat(filename)
  #~ Get attributes: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/68298
  
  settings = {
    filename: filename,
    filesize: ::File.size(filename),
    attributes: Attrib.fileattrib(filename),
    #The timestamp must be 'local time' -> ignore local time zone for generation
    timestamp: ::File.mtime(filename) + Time.now.gmt_offset,
  }
  
  #Binary read needed, else the crc may differ from BC3
  ::File.open( filename, 'rb'){|f| 
    settings[:crc]  = Helper::crc32(f.read)
  } if with_crc
  return File.new( settings )
end

Instance Method Details

#bcssObject

Prepare for snapshot (bcss-file).

ID_FILE (0x02)

Represents a file on the system.  

Name           : ShortString
Last Modified  : FileTime
DOS Attributes : UInt32
Size           : Int32[+Int64]
   If Size > 2GB, store as Int32(-1) followed by Int64
CRC32          : UInt32


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/bc3/file.rb', line 118

def bcss() 
  bcss = "".force_encoding('BINARY')
  if @version or @utfpath or @utfsymlink
    bcss << 3 #with file extended_headers
  else
    bcss << 2
  end
  bcss << shortstring2bcss(@filename)
  bcss << fixnum2int64(@timestamp.time2ad)
  #DOS Attributes
  bcss << @attributes  #little endian storage
  bcss << 0
  bcss << 0
  bcss << 0
  #Size
  bcss << fixnum2int32(@filesize)
  
  #CRC32
  bcss << fixnum2int32(@crc || 0)
  #extended header
  bcss << bcss_extended_headers if @version or @utfpath or @utfsymlink

  bcss
end

#bcss_extended_headersObject

ID_FILE (0x02) +

ExtraLen       : UInt16
ExtraData      : Byte[ExtraLen]

File Extended Headers

Like extended headers, file extended headers should be written in ascending numeric order. Multiple headers may occur within a single ID_FILE_EX record, and compliant parsers should break once they read a type they don’t recognize.

FILE_EX_VERSION (0x01)

String representation of an executable file's Major/Minor/Maint/Build

version (e.g., “2.11.28.3542”).

Length : UByte
Data   : char[Length]

FILE_EX_UTF8 (0x02)

UTF-8 encoded filename.  Stored as a FileExString.  Only used if the UTF-8

name doesn’t match the ANSI encoded one or if the filename is longer than 255 characters.

FILE_EX_LINK_PATH (0x03)

UTF-8 encoded symbolic link path.  Stored as a FileExString.


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/bc3/file.rb', line 174

def bcss_extended_headers()
  ehead = ''.force_encoding('binary')
  if @version 
    ehead << 1
    ehead << @version.size
    ehead << @version
  end
  if @utfpath
    ehead << 2
    utfpath = @utfpath.dup.force_encoding('binary')
    ehead << utfpath.size
    ehead << utfpath
  end
  if @utfsymlink
    ehead << 3
    utfsymlink = @utfsymlink.dup.force_encoding('binary')
    ehead << utfsymlink.size
    ehead << utfsymlink
  end
  
  bcss = ''.force_encoding('binary')
  bcss << fixnum2int16(ehead.size + 2) #size including this length
  bcss << ehead
  
  bcss
end

#inspectObject



101
102
103
# File 'lib/bc3/file.rb', line 101

def inspect()
  "<BC3::File #{@filename}>"
end

#to_hashObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/bc3/file.rb', line 87

def to_hash()
  hash = { 
    filename: @filename,
    filesize: @filesize,
    crc: @crc,
    attributes: @attributes,
    timestamp: @timestamp,
  }
  hash[:version] = @version if @version
  hash[:utfpath] = @utfpath if @utfpath
  hash[:utfsymlink] = @utfsymlink if @utfsymlink

  hash
end