Class: FastLib

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlib.rb

Overview

The FastLib class implements the meat of the FASTLIB archive format

Constant Summary collapse

VERSION =
"0.0.3"
@@cache =
{}

Class Method Summary collapse

Class Method Details

.dump(lib, bdir, *dirs) ⇒ Object

This method provides a way to create a FASTLIB archive programatically, the key arguments are the name of the destination archive, the base directory that should be excluded from the archived path, and finally the list of specific files and directories to include in the archive.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/fastlib.rb', line 186

def self.dump(lib, bdir, *dirs)
	head = ""
	data = ""
	hidx = 0
	didx = 0
	
	bdir = bdir.gsub(/\/$/, '')
	brex = /^#{Regexp.escape(bdir)}\//
	
	dirs.each do |dir|
		::Find.find(dir).each do |path|
			next if not ::File.file?(path)
			name = fastlib_filter_name( path.sub( brex, "" ) )
			buff = ""
			::File.open(path, "rb") do |fd|
				buff = fd.read(fd.stat.size)
			end
		
			head << [ name.length, didx, buff.length ].pack("NNN")
			head << name
			hidx = hidx + 12 + name.length
		
			data << fastlib_filter( buff )
			didx = didx + buff.length
		end
	end
	
	head << [0,0,0].pack("NNN")
	
	::File.open(lib, "wb") do |fd|
		fd.write("FAST")
		fd.write( [ head.length ].pack("N") )
		fd.write( head )
		fd.write( data )
	end	
end

.fastlib_filter(data) ⇒ Object

This method provides a way to hook the translation of file content from the archive to the final content. This can be used to provide encryption or compression.



176
177
178
# File 'lib/fastlib.rb', line 176

def self.fastlib_filter(data)
	data
end

.fastlib_filter_name(name) ⇒ Object

This method provides a way to hook the translation of file names from the dictionary in the file to the final string. This can be used to provide encryption or compression.



167
168
169
# File 'lib/fastlib.rb', line 167

def self.fastlib_filter_name(name)
	name
end

.list(lib) ⇒ Object

This archive provides a way to list the contents of an archive file, returning the names only in sorted order.



227
228
229
230
# File 'lib/fastlib.rb', line 227

def self.list(lib)
	load_cache(lib)
	( @@cache[lib] || {} ).keys.map{|x| x.to_s }.sort
end

.load(lib, name, noprocess = false) ⇒ Object

This method loads content from a specific archive file by name. If the noprocess argument is set to true, the contents will not be expanded to include workarounds for things such as __FILE__. This is useful when loading raw binary data where these strings may occur



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fastlib.rb', line 118

def self.load(lib, name, noprocess=false)
	data = ""
	load_cache(lib)

	return if not ( @@cache[lib] and @@cache[lib][name] )
	
	
	::File.open(lib, "rb") do |fd|
		fd.seek(
			@@cache[lib][:fastlib_header][0] +
			@@cache[lib][:fastlib_header][1] + 
			@@cache[lib][name][0]
		)
		data = fastlib_filter( fd.read(@@cache[lib][name][1] ))
	end
	
	# Return the contents in raw or processed form
	noprocess ? data : post_process(lib, name, data)
end

.load_cache(lib) ⇒ Object

This method caches the file list and offsets within the archive



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/fastlib.rb', line 141

def self.load_cache(lib)
	return if @@cache[lib]
	dict = {}
	::File.open(lib, 'rb') do |fd|
		head = fd.read(4)
		return if head != "FAST"
		hlen = fd.read(4).unpack("N")[0]
		dict[:fastlib_header] = [8, hlen]
		
		nlen, doff, dlen = fd.read(12).unpack("N*")
		
		while nlen > 0
			name = fastlib_filter_name( fd.read(nlen) )
			dict[name] = [doff, dlen]
			
			nlen, doff, dlen = fd.read(12).unpack("N*")
		end
		@@cache[lib] = dict
	end
end

.post_process(lib, name, data) ⇒ Object

This method is called on the loaded is required to expand __FILE__ and other inline dynamic constants to map to the correct location.



236
237
238
# File 'lib/fastlib.rb', line 236

def self.post_process(lib, name, data)
	data.gsub('__FILE__', "'#{ ::File.expand_path(::File.join(::File.dirname(lib), name)) }'")
end

.versionObject

This method returns the version of the fastlib library



108
109
110
# File 'lib/fastlib.rb', line 108

def self.version
	VERSION
end