class Object
Constants
- AUTHOR_EMAIL
- AUTHOR_GITHUB
- AUTHOR_INFO
- AUTHOR_NAME
- VERSION
Public Instance Methods
compile_proto(filename)
click to toggle source
# File bin/proto-convert, line 43 def compile_proto(filename) puts "\n>> Compile .proto file" if $verbose file_path = File.expand_path(filename) file_dir = File.dirname(file_path) if $verbose protoc_version = `protoc --version`.chomp.split(' ')[1] puts " protoc version : #{protoc_version}" puts " proto file path : #{file_path}" end protoc_cmd = " protoc \\\n" \ " --ruby_out=#{file_dir} \\\n" \ " --proto_path=#{file_dir} \\\n" \ " #{file_path}" puts "\n#{protoc_cmd}" if $verbose `#{protoc_cmd}` abort "ERROR: Invalid schema! [#{filename}] Resolve error(s)." unless $CHILD_STATUS.success? compiled_proto = "#{file_dir}/#{File.basename(file_path, '.proto')}_pb.rb" abort "ERROR: Compiled schema not found! [#{compiled_proto}]" unless File.file?(compiled_proto) puts "\n generated file : #{compiled_proto}" if $verbose compiled_proto end
convert(compiled_proto, args)
click to toggle source
# File bin/proto-convert, line 104 def convert(compiled_proto, args) msg_type = args[:msgtype] conversion_mode = args[:mode] input_file = args[:input] output_file = args[:output] if $verbose puts "\n>> Convert" puts " file : #{input_file}" puts " mode : #{conversion_mode}" end pb_msg_class = msg_class(compiled_proto, msg_type) abort "ERROR: Message type ['#{msg_type}'] not registered!'" if pb_msg_class.nil? begin case conversion_mode when :binary2json input_msg = File.open(input_file, 'rb').read puts ">> [B] #{input_file} (#{input_msg.length} bytes)" decoded_msg = pb_msg_class.decode(input_msg) output_msg = pb_msg_class.encode_json(decoded_msg) File.open(output_file, 'w').write(output_msg) puts "<< [J] #{output_file} (#{output_msg.length} bytes)" when :json2binary input_msg = File.open(input_file, 'r').read puts ">> [J] #{input_file} (#{input_msg.length} bytes)" decoded_msg = pb_msg_class.decode_json(input_msg) output_msg = pb_msg_class.encode(decoded_msg) File.open(output_file, 'wb').write(output_msg) puts "<< [B] #{output_file} (#{output_msg.length} bytes)" end rescue Google::Protobuf::ParseError abort "ERROR: Incompatible input message! [msgtype: #{msg_type}] #{$ERROR_INFO}" rescue StandardError abort "ERROR: Conversion failed! #{$ERROR_INFO}" end puts ">> Converted! [#{input_file}] => [#{output_file}]" if $verbose end
msg_class(compiled_proto, msg_type)
click to toggle source
# File bin/proto-convert, line 98 def msg_class(compiled_proto, msg_type) require compiled_proto msg = Google::Protobuf::DescriptorPool.generated_pool.lookup(msg_type) msg.msgclass end
start()
click to toggle source
# File bin/proto-convert, line 149 def start mandatory_args = %i[mode proto msgtype input output].freeze args = {} mandatory_args.each { |arg| args[arg] = nil } parser = OptionParser.new do |opts| opts.banner = "Usage: #{$PROGRAM_NAME} -m [mode] -p [proto] -t [msgtype] -i [input] -o [output]" opts.separator "\nOPTIONS:\n\n" modes = %i[binary2json b2j json2binary j2b].freeze opts.on('-m', '--mode [MODE]', String, "conversion mode #{modes.map(&:to_s)}") do |mode| abort 'ERROR: Missing mode!' if mode.nil? mode = mode.to_sym abort "ERROR: Invalid mode! [#{mode}]" unless modes.include?(mode) case mode when :b2j mode = :binary2json when :j2b mode = :json2binary end args[:mode] = mode end opts.on('-p', '--proto [FILENAME]', String, 'protobuf schema (.proto)') do |filename| abort 'ERROR: Missing schema filename!' if filename.nil? abort "ERROR: Protobuf schema not found! [#{filename}]" unless File.file?(filename) args[:proto] = filename end opts.on('-t', '--msgtype [TYPE]', String, 'fully-qualified message type') do |msgtype| abort 'ERROR: Missing msgtype!' if msgtype.nil? args[:msgtype] = msgtype end opts.on('-i', '--input [FILENAME]', String, 'source file (JSON/binary)') do |filename| abort 'ERROR: Missing input filename!' if filename.nil? abort "ERROR: Input file not found! [#{filename}]" unless File.file?(filename) args[:input] = filename end opts.on('-o', '--output [FILENAME]', String, 'destination file (binary/JSON)') do |filename| abort 'ERROR: Missing output filename!' if filename.nil? args[:output] = filename end opts.on('-v', '--verbose', 'print verbose information') do $verbose = true end opts.on('-h', '--help', 'print help') do puts "#{$PROGRAM_NAME} #{VERSION}\n\n#{opts}\n#{AUTHOR_INFO}\n#{AUTHOR_GITHUB}" exit end end begin parser.parse! puts ">> #{$PROGRAM_NAME} #{VERSION} [verbose mode]" if $verbose # Validate missing mandatory arguments missing_args = mandatory_args.select { |arg| args[arg].nil? } abort "ERROR: Missing required arguments! --#{missing_args.join(', --')}" unless missing_args.empty? if $verbose puts "\n>> Arguments" args.each do |arg, val| puts format(' %<arg>8s : %<val>s', arg: arg, val: val) end end # Compile and validate proto and msgtype compiled_proto = compile_proto(args[:proto]) abort unless valid_msgtype?(compiled_proto, args[:msgtype]) convert(compiled_proto, args) rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument puts $ERROR_INFO abort "\n#{$PROGRAM_NAME} #{VERSION}\n\n#{parser}\n#{AUTHOR_INFO}\n#{AUTHOR_GITHUB}" rescue LoadError abort "ERROR: Possible 'import' issue! #{$ERROR_INFO}" rescue StandardError abort "ERROR: #{$ERROR_INFO}" ensure File.delete(compiled_proto) if !compiled_proto.nil? && File.file?(compiled_proto) end end
valid_msgtype?(compiled_proto, msg_type)
click to toggle source
# File bin/proto-convert, line 74 def valid_msgtype?(compiled_proto, msg_type) if $verbose puts "\n>> Validate msgtype" puts " msgtype : #{msg_type}" puts " pb file : #{compiled_proto}" end msg_types = [] File.foreach(compiled_proto) do |line| if line.lstrip.start_with?('add_message') extracted_msg_type = line[/"([^"]*)"/, 1].freeze # regex: <add_message> 'msg_type' <do> msg_types.push(extracted_msg_type) unless extracted_msg_type.nil? end end is_valid = msg_types.include?(msg_type) unless is_valid puts "ERROR: Invalid msgtype! [#{msg_type}]" puts " Available types: #{msg_types}" end is_valid end