require "vr/vruby" require "vr/clipboard" require "digest/md5" require "yaml" # exerb用 # カレントディレクトリを実行ファイルと同じディレクトリにする if $Exerb Dir.chdir( ExerbRuntime.filepath.sub( /[\\\/][^\\\/]*?$/, "" ) ) end CTypes = File.open( "mime.yaml" ) { |f| YAML.load( f ) } def CTypes.ext( mime ) return self[ mime ] ? self[ mime ] : nil end def CTypes.mime( ext ) mime = self.index( ext ) return mime ? mime : "unknown-type" end class Base64 def initialize @text = "" @bin = "" @mime = "" @ext = "" end attr_accessor :text, :bin, :mime, :ext end def decode64( base64_text ) base64 = Base64.new base64.text = base64_text base64.text.gsub!( /^\s+|\s+$/, "" ) base64.text.gsub!( /base64,/, "" ) base64.text.gsub!( /data:(.*?);/ ) do base64.mime = $1 "" end ext = CTypes.ext( base64.mime ) base64.ext = "." + ext if ext base64.bin = base64.text.unpack( "m" )[0] return base64 end def encode64( bin, file = "" ) base64 = Base64.new base64.bin = bin base64.text = [ base64.bin ].pack( "m" ).gsub( /\s/, "" ) mime = CTypes.mime( file.sub( /^[^.]+\./, "" ) ) base64.mime = mime if mime return base64 end class Base64Window < VRForm def construct if ARGV.length == 1 and File.exist?( ARGV[0] ) # ファイルを渡した場合、ファイルをバイナリから # base64に変換してクリップボードに格納 bin = File.open( ARGV[0], "rb" ).read( ) base64 = encode64( bin, ARGV[0] ) b64text = "data:" + base64.mime + ";base64," + base64.text # 正しく変換されているか元ファイルと比較 cmp64 = decode64( b64text ) if base64.bin == cmp64.bin Clipboard.open( self.hWnd ) do |cb| cb.setText( "data:" + base64.mime + ";base64," + base64.text ) end else raise "decode failed." end else # 拡張子無しの場合、クリップボードの中身を # base64としてバイナリに変換 Clipboard.open( self.hWnd ) do |cb| cliptext = cb.getText base64 = decode64( cliptext ) # 正しく変換されているか元ファイルと比較 cmp64 = encode64( base64.bin ) if cliptext == cmp64.text md5 = Digest::MD5.hexdigest( base64.bin ) File.open( md5 + base64.ext, "wb" ) { |r| r.puts base64.bin } else raise "encode failed." end end end exit end end VRLocalScreen.showForm( Base64Window, 0, 0, 0, 0 )