Деян обнови решението на 10.11.2014 16:10 (преди около 10 години)
+module RBFS
+ class File
+ attr_reader :data_type, :data
+
+ def initialize(data = nil)
+ @data = data
+ @data_type = get_type_as_symbol(data)
+ end
+
+ def data=(data = nil)
+ @data = data
+ @data_type = get_type_as_symbol(data)
+ end
+
+ def serialize
+ data_type.to_s + ':' + data.to_s
+ end
+
+ def self.parse(string_data)
+ type_data_pair = string_data.split(':', 2)
+ actual_data = get_data_from(type_data_pair[0].to_sym, type_data_pair[1])
+ File.new(actual_data)
+ end
+
+ private
+
+ def get_type_as_symbol(data_type)
+ result_type = data_type.class.name.downcase.to_sym
+ case result_type
+ when :nilclass then :nil
+ when :falseclass, :trueclass then :boolean
+ when :fixnum, :float then :number
+ else result_type
+ end
+ end
+
+ def self.to_boolean(string)
+ return true if string == 'true'
+ false if string == 'false'
+ end
+
+ def self.to_number(string)
+ if string.include? '.'
+ string.to_f
+ else
+ string.to_i
+ end
+ end
+
+ def self.get_data_from(type, data)
+ case type
+ when :boolean then to_boolean(data)
+ when :symbol then data.to_sym
+ when :nil then nil
+ when :number then to_number(data)
+ when :string then data
+ end
+ end
+ end
+
+ class Directory
+ attr_reader :files, :directories
+
+ def initialize
+ @files = {}
+ @directories = {}
+ end
+
+ def add_file(name, file)
+ @files[name] = file
+ end
+
+ def add_directory(name, directory = nil)
+ @directories[name] = directory ? directory : Directory.new
+ end
+
+ def [](name)
+ @directories[name] || @files[name]
+ end
+
+ def serialize
+ result = "#{files.size}:"
+ files.each do |name, _|
+ result ="#{result}#{name}:#{self[name].serialize.size}:#{self[name].serialize}"
+ end
+ result = "#{result}#{directories.size}:"
+ directories.each do |name, _|
+ result = "#{result}#{name}:#{self[name].serialize.size}:#{self[name].serialize}"
+ end
+ result
+ end
+
+ def self.parse(string_data)
+ file_count = string_data.split(':', 2).first.to_i
+ root = Directory.new
+ string_data = string_data.split(':', 2)[1]
+ serialized_files = serialize_files(root, string_data, file_count)
+ directories_count = serialized_files.split(':', 2).first.to_i
+ string_data = serialized_files.split(':', 2)[1]
+ string_data = serialize_directories(root, string_data, directories_count)
+ root
+ end
+
+ def self.serialize_files(root, string_data, file_count)
+ 1.upto(file_count) do
+ file_name = string_data.split(':', 2).first
+ file_size = string_data.split(':', 3)[1]
+ file_data = string_data.split(':', 3)[2][0, file_size.to_i]
+ root.add_file(file_name, File.parse(file_data))
+ string_data = string_data.split(':', 3)[2].slice(file_size.to_i,string_data
+ .split(':', 4)[3].size)
+ end
+ string_data
+ end
+
+ def self.serialize_directories(root, string_data, directories_count)
+ 1.upto(directories_count) do
+ directory_name = string_data.split(':', 2).first
+ directory_size = string_data.split(':', 3)[1]
+ string_data = string_data.split(':', 3)[2][0, directory_size.to_i]
+ root.add_directory(directory_name, Directory.parse(string_data))
+ end
+ string_data
+ end
+ end
+end