Станислав обнови решението на 02.11.2014 23:06 (преди около 10 години)
+
+module RBFS
+
+ class File
+
+ attr_accessor :data
+
+ def initialize(*data)
+ @data = data[0] ? data[0] : nil
+ end
+
+ def data_type
+ if @data.is_a? String then return :string end
+ if @data.is_a? Symbol then return :symbol end
+ if @data.is_a? Numeric then return :number end
+ if @data === true || @data === false then return :boolean end
+ if @data == nil then return :nil end
+ end
+
+ def serialize
+ self.data_type.to_s + ":" + @data.to_s
+ end
+
+ def File.parse(data_string)
+ object_info = data_string.partition(":")
+ case object_info[0] #=> data type
+ when 'string' then File.new(String.new(object_info[2])) #=> data as object
+ when 'symbol' then File.new(Symbol.new(object_info[2])) #=> data as object
+ when 'number' then File.new(Number.new(object_info[2])) #=> data as object
+ when 'boolean' then File.new(object_info[2] == 'true') #=> data as object
+ else File.new(nil)
+ end
+ end
+
+ def size
+ self.serialize.size.to_s
+ end
+
+ end
+
+ class Directory
+
+ def add_file(name, file)
+ name.gsub!(':', '')
+ @files[name] = file
+ end
+
+ def initialize
+ @directories = {}
+ @files = {}
+ end
+
+ def add_directory(name, *directory)
+ name.gsub!(':', '')
+ @directories[name] = directory[0] || RBFS::Directory.new
+ end
+
+ def [](name)
+ if @directories[name]
+ @directories[name]
+ else
+ @files[name]
+ end
+ end
+
+ def files
+ @files
+ end
+
+ def directories
+ @directories
+ end
+
+ def serialize
+ string = @files.size.to_s + ':'
+ @files.each {|name, file|
+ string = string << name << ':' << file.size << ':' << file.serialize
+ }
+ string = string << @directories.size.to_s << ':'
+ @directories.each {|name, dir|
+ string << name << ':' << dir.serialize.size.to_s << ':' << dir.serialize
+ }
+ string
+ end
+
+ def Directory.parse(serialized_string)
+ data_array = serialized_string.split(':')
+ parent_directory = RBFS::Directory.new
+ last_file_data = RBFS::Additional::parse_files_string(data_array, parent_directory)
+ if last_file_data
+ directories_array = serialized_string.partition(last_file_data)[2].split(':')
+ RBFS::Additional::parse_directories_string(directories_array, parent_directory)
+ end
+ parent_directory
+ end
+
+ end
+
+ class Additional
+ def Additional.parse_files_string(data_a, directory_obj)
+ files_number, i, file = data_a[0].to_i, 3
+ files_number.times { i-=1
+ i1, i2, i3, i4, i5 = i+=1, i+=1, i-=2, i-=1, i+=3
+ file_data = (data_a[i1] << ':' << data_a[i2]).slice!(0..(data_a[i3].to_i-1))
+ directory_obj.add_file(data_a[i4], file = RBFS::File::parse(file_data))
+ data_a[i5], i = data_a[i5].gsub(file.data, ''), i+2
+ }
+ file ? file.data : nil
+ end
+
+ def Additional.parse_directories_string(data_a, directory_obj)
+ directories_number, i = data_a[0].to_i, 0
+ directories_number.times {
+ i1, i2, i3 = i+=1, i+=1, i+=1
+ directory_obj.add_directory(data_a[i1], directory_content(data_a, i2)[0])
+ i = directory_content(data_a, i3)[1]
+ }
+ end
+
+ def Additional.directory_content(data_a, position)
+ directory_string, step = "", position
+ while directory_string.size <= data_a[position].to_i
+ step+=1
+ directory_string << data_a[step].to_s << ":"
+ end
+ [RBFS::Directory::parse(directory_string), step]
+ end
+ end
+
+end