左再帰
A : A B0
| A B1
...
| A Bn
| C0
| C1
...
| Cn
※1 B0 ... Bn はε(空)ではない
※2 C0 ... Cn は A を先頭に持たない
左再帰を消す
A : C0 A_tail?
| C1 A_tail?
...
| Cn A_tail?
A_tail : B0 A_tail?
| B1 A_tail?
...
| Bn A_tail?
いろいろやってみよう
左再帰
A : A B0
| A B1
...
| A Bn
| C0
| C1
...
| Cn
左再帰を消す
A : C0 A_tail?
| C1 A_tail?
...
| Cn A_tail?
A_tail : B0 A_tail?
| B1 A_tail?
...
| Bn A_tail?
厳密には正しくないけど今はまぁこれで十分な感じの正規表現
valid_chars = '[0-9A-Za-z_!#\$%&*+\-\/=\?^_{|}\~\.]+'
valid_pattern = Regexp.new("^(#{valid_chars})@(#{valid_chars})$", nil, 'n')
gif.rb
class GIF
attr_accessor :version, :width, :height, :bgcolor_index, :aspect_ratio, :sort_flag
attr_accessor :color_table, :blocks
def self.load(istream)
self.new.load(istream)
end
def self.load_file(filename)
self.new.load_file(filename)
end
def initialize
@blocks = []
end
def [](index)
@blocks[index]
end
def []=(index, block)
@blocks[index] = block
end
def <<(block)
@blocks << block
end
def clear
@blocks = []
@version = @width = @height = @bgcolor_index = @aspect_ratio = @sort_flag =
@color_table = nil
end
def load(istream)
clear
reader = Reader.new(self, istream)
reader.run
end
def load_file(filename)
File.open(filename, 'rb'){|f| load(f) }
end
class GraphicControlExtension
attr_accessor :disposal_method, :user_input_flag, :delay_time, :transparent_index
# case disposal_method
# when 0; # no action is required
# when 1; # do not dispose
# when 2; # restore to background color
# when 3; # restore to previous
# end
end
class CommentExtension
attr_accessor :data
end
class PlainTextExtension
attr_accessor :x, :y, :width, :height, :cell_width, :cell_height
attr_accessor :fgcolor_index, :bgcolor_index
attr_accessor :text
end
class ApplicationExtension
attr_accessor :app_id, :auth_code, :data
end
class ImageBlock
attr_accessor :x, :y, :width, :height, :interlace_flag, :sort_flag, :color_table
attr_accessor :code_size, :data
def decode
LZW.decode(@code_size, @data)
end
def encode(indexes)
largest = indexes.sort[-1]
@code_size = ("%b" % largest).size
@code_size = 2 if 2 > @code_size
@data = LZW.encode(@code_size, indexes)
end
def encode_with_code_size(indexes, code_size)
@data = LZW.encode(@code_size = code_size, indexes)
end
end
end
######################################################################
class GIF::Reader
def initialize(gif, istream)
@gif = gif
@istream = istream
end
def run
read_header
read_blocks
@gif
end
def read_header
sig,
@gif.version, @gif.width, @gif.height,
bits,
@gif.bgcolor_index, @gif.aspect_ratio = read_fmt('a3a3vvCCC')
gctf = 0 != (0b1000_0000 & bits) # global color table flag
cr = (0b0111 & (bits >> 4)) + 1 # color resolution
@gif.sort_flag = 0 != (0b1000 & bits)
gct_size = 2 ** ((0b0111 & bits) + 1) # size of global color table
@gif.color_table = (0...gct_size).map{ read_fmt('CCC') } if gctf
end
def read_blocks
loop do
case block_type = read_fmt('C')[0]
when 0x3B # trailer
break
when 0x21 # Extension
@gif << read_extension_block
when 0x2C # Image
@gif << read_image_block
else
raise "Not Yet Impl : BlockType is 0x#{"%02x" % block_type}"
end
end
end
def read_extension_block
label = read_fmt('C')[0]
case label
when 0xF9 # Graphic Control
read_graphic_control
when 0xFE # Comment Label
read_comment_label
when 0x01 # Plain Text
read_plain_text
when 0xFF # Application Extension
read_application_extension
else
raise 'Not Yet Impl'
end
end
def read_graphic_control
b = GIF::GraphicControlExtension.new
block_size, bits, b.delay_time, b.transparent_index, zero = read_fmt('CCvCC')
b.disposal_method = 0b111 & (bits >> 2)
b.user_input_flag = 0 != 0b10 & bits
transparent_color_flag = 0 != 0b1 & bits
b.transparent_index = nil unless transparent_color_flag
b
end
def read_comment_label
b = GIF::CommentExtension.new
b.data = read_block_data
b
end
def read_plain_text
b = GIF::PlainTextExtension.new
block_size, b.x, b.y, b.width, b.height,
b.cell_width, b.cell_height,
b.fgcolor_index, b.bgcolor_index = read_fmt('CvvvvCCCC')
b.text = read_block_data
b
end
def read_application_extension
b = GIF::ApplicationExtension.new
block_size, b.app_id, b.auth_code = read_fmt('Ca8a3')
b.data = read_block_data
b
end
def read_block_data
bytes = ''
loop do
size = read_fmt('C')[0]
return bytes if size == 0
bytes << read(size)
end
end
def read_image_block
b = GIF::ImageBlock.new
b.x, b.y, b.width, b.height, bits = read_fmt('vvvvC')
lctf = (0 != 0x80 & bits) # local color table flag
b.interlace_flag = (0 != 0x40 & bits)
b.sort_flag = (0 != 0x20 & bits)
lct_size = 2 ** ((0x07 & bits) + 1)
b.color_table = (0...lct_size).map{ read_fmt('CCC') } if lctf
b.code_size = read_fmt('C')[0]
b.data = read_block_data
b
end
def read(size)
bytes = @istream.read(size)
raise 'End of file' if bytes.nil?
raise 'Not enough' if bytes.size != size
bytes
end
def read_fmt(fmt)
read(pack_size(fmt)).unpack(fmt)
end
def pack_size(fmt)
total_size = 0
item_size = 0
fmt.scan(/[a-zA-Z]|[0-9]+/).each do |v|
case v
when 'C'; item_size = 1
when 'a'; item_size = 1
when 'v'; item_size = 2
when /[0-9]+/
item_size *= v.to_i - 1
else
raise 'Not Yet'
end
total_size += item_size
end
total_size
end
end
######################################################################
module GIF::LZW
MAX_NBITS = 12
module_function
def encode(nbits, istring)
GIF::LZW::Encoder.encode(nbits, ArrayReader.new(istring), StringIO.new).string
end
def decode(nbits, istring)
GIF::LZW::Decoder.decode(nbits, StringIO.new(istring), StringIO.new).string
end
def bit_mask(nbits)
(1 << nbits) - 1
end
end
######################################################################
class GIF::LZW::Dictionary
attr_reader :clear_code, :end_code
def initialize(nbits)
dict_size = 1 << nbits
@dict = (0...dict_size).map{|k| [nil, k] }
@clear_code = dict_size
@dict << nil # Clear Code
@end_code = dict_size + 1
@dict << nil # End Code
@code = {}
end
def reset
@dict.slice!(@end_code + 1, @dict.size)
@code = {}
end
def size
@dict.size
end
def add(w, k)
new_code = @code[(w << 8) + k] = @dict.size
@dict << [w, k]
return new_code
end
def code(w, k)
return k unless w
return @code[(w << 8) + k]
end
def string(code)
w, k = @dict[code]
return nil unless k
return string(w) << k if w
return [k]
end
end
######################################################################
# src[0] : <abcde> : 11100
# src[1] : <fghij> : 11000
# src[2] : <klmno> : 10000
#
# dst[0] : <hijabcde> : 00011100
# dst[1] : <.klmnofg> : 01000011
class GIF::LZW::BitWriter
attr_reader :stream
def initialize(stream)
@stream = stream
@value = @nbits = 0
end
def write(value, nbits)
@value |= (GIF::LZW.bit_mask(nbits) & value) << @nbits
@nbits += nbits
while 8 <= @nbits
@stream.write([0xFF & @value].pack('C'))
@value >>= 8
@nbits -= 8
end
end
def flush
if 0 < @nbits
@stream.write([0xFF & @value].pack('C'))
@value = @nbits = 0
end
@stream.flush
end
end
######################################################################
class GIF::LZW::BitReader
attr_reader :stream
def initialize(stream)
@stream = stream
@value = @nbits = 0
end
def read(nbits)
while @nbits < nbits
byte = @stream.read(1)
return nil unless byte
byte = byte.unpack('C')[0]
@value |= byte << @nbits
@nbits += 8
end
v = GIF::LZW.bit_mask(nbits) & @value
@value >>= nbits
@nbits -= nbits
return v
end
end
######################################################################
class GIF::LZW::ArrayReader
def initialize(array)
@array = array
@pos = 0
end
def getc
if @pos < @array.size
pos = @pos
@pos += 1
return @array[pos]
end
end
end
######################################################################
class GIF::LZW::Encoder
# @return ostream
def self.encode(nbits, istream, ostream)
encoder = self.new(nbits, istream, ostream)
encoder.run
end
def initialize(nbits, istream, ostream)
@nbits = nbits
@istream = istream
@bit_writer = GIF::LZW::BitWriter.new(ostream)
@code_size = nbits + 1
@dict = GIF::LZW::Dictionary.new(@nbits)
@w = nil
write_code(@dict.clear_code)
end
def run
while k = @istream.getc
write(k)
end
finish
end
def write(k)
if c = @dict.code(@w, k)
@w = c
return
end
c = @dict.add(@w, k)
write_code(@w)
@w = k
return if (1 << @code_size) != c
if @code_size < GIF::LZW::MAX_NBITS
@code_size += 1
return
end
write_code(@dict.clear_code)
@code_size = @nbits + 1
@dict.reset
end
def finish
write_code(@w) if @w
write_code(@dict.end_code)
@bit_writer.flush
end
def write_code(code)
@bit_writer.write(code, @code_size)
end
end
######################################################################
class GIF::LZW::Decoder
# @return ostream
def self.decode(nbits, istream, ostream)
decoder = self.new(nbits, istream, ostream)
decoder.run
end
def initialize(nbits, istream, ostream)
@nbits = nbits
@bit_reader = GIF::LZW::BitReader.new(istream)
@ostream = ostream
@code_size = nbits + 1
@dict = GIF::LZW::Dictionary.new(@nbits)
end
def run
decode_1st && while decode_2nd; end
@ostream.flush
end
def decode_1st
@w = read_code
@w = read_code while @dict.clear_code == @w
return nil if @w.nil? || @dict.end_code == @w
@ws = @dict.string(@w)
@ostream.write(@ws.pack('C*'))
true
end
def decode_2nd
@code_size += 1 if @dict.size == (1 << @code_size) && @code_size < GIF::LZW::MAX_NBITS
k = read_code
return if k.nil? || @dict.end_code == k
if @dict.clear_code == k
@code_size = @nbits + 1
@dict.reset
return decode_1st
end
ks = @dict.string(k)
ks = @ws + @ws.slice(0, 1) unless ks
@ostream.write(ks.pack('C*'))
@dict.add(@w, ks[0])
@w, @ws = k, ks
end
def read_code
@bit_reader.read(@code_size)
end
end
lzw.rb
#
# LZW Algorithm
#
class Dic
def initialize
@dict = (0...256).map{|k| [nil, k]}
@code = {}
end
def add(w, k)
new_code = @code[(w << 8) + k] = @dict.size
@dict << [w, k]
return new_code
end
def code(w, k)
return k unless w
return @code[(w << 8) + k]
end
def string(code)
w, k = @dict[code]
return nil unless k
return string(w) << k if w
return [k]
end
end
def encode(input)
output = []
dic = Dic.new
w = nil
while k = input.shift
c = dic.code(w, k)
if c
w = c
else
output << w
dic.add(w, k)
w = k
end
end
output << w if w
return output
end
def decode(input)
output = []
dic = Dic.new
w = input.shift
return output unless w
ws = dic.string(w)
ws.each{|v| output << v}
while k = input.shift
ks = dic.string(k)
ks = ws + ws.slice(0, 1) unless ks
ks.each{|v| output << v}
dic.add(w, ks[0])
w, ws = k, ks
end
return output
end
encode([0,1,0,1,0,1,0,1]) # => [0, 1, 256, 258, 1]
decode([0,1,256,258,1]) # => [0, 1, 0, 1, 0, 1, 0, 1]
if A < B < C
# 本体
end
a = A
b = B
if a < b
c = C
if b < c
# 本体
end
end
A < B < C
A < B <= C
A <= B < C
A <= B <= C
A > B > C
A > B >= C
A >= B > C
A >= B >= C
A > B && B < C → A > B < C
A > B && B < C → A > B < C
A < B && B < C && C > D && D < E → A < B < C > D < E
a = A
b = B
if a < b
c = C
if b < c
d = D
if c > d
e = E
d < e # 最後の条件判定の結果は使われていないのでif文を省略
end
end
end
sample.rb
def with(instance, &block)
instance.instance_eval(&block)
end
class Hello
def say
puts 'hello world'
end
end
with(Hello.new) do
say
say
say
end
ルートムービークリップのフレーム1のアクション
sp = -1; // スタックポインタの初期化
// 引数をスタックに積む
++sp;
eval( "s" add sp ) = 12;
call ( "fact" ); // 関数呼び出し
// 答えをスタックから取り除く
r = eval ( "s" add sp );
--sp;
trace ( r ); // 確認
stop();
ルートムービークリップのフレーム2のアクション
// 階乗を計算する関数
n = eval ( "s" add sp );
if ( n == 0 ) {
eval ( "s" add sp ) = 1; // 引数をスタックから取り除き、答えをスタックに積む。つまりspは変化しない。
} else {
// 引数をスタックに積む
++sp;
eval ( "s" add sp ) = n - 1;
call ( "fact" );
r = eval ( "s" add sp ); // 関数の答えを取得する。
--sp; // スタックポインタを戻す
n = eval ( "s" add sp ); // n は再帰呼び出しで変化してるので復帰させる。
eval ( "s" add sp ) = r * n; // 引数をスタックから取り除き、答えをスタックに積む。つまりspは変化しない。
}
prevday.as
// 前の日の日付を計算する
//
// @param a0 ... 西暦年 (例: 2009 )
// @param a1 ... 月 (1?12)
// @param a2 ... 日 (1?31)
//
// @return a0 ... 西暦年 (例: 2009 )
// @return a1 ... 月 (1?12)
// @return a2 ... 日 (1?31)
//
--a2;
if (0 >= a2) {
switch (a1) {
case 1:
a0 -= 1; a1 = 12; a2 = 31;
break;
case 2:
case 4:
case 6:
case 8:
case 9:
case 11:
--a1; a2 = 31;
break;
case 3:
a1 = 2;
if ((a0 % 4 == 0 && a0 % 100 != 0) || (a0 % 400 == 0)) { // 閏年
a2 = 29;
} else {
a2 = 28;
}
break;
case 5:
case 7:
case 10:
case 12:
--a1; a2 = 30;
break;
}
}
nextday.as
// 次の日の日付を計算する
//
// @param a0 ... 西暦年 (例: 2009 )
// @param a1 ... 月 (1?12)
// @param a2 ... 日 (1?31)
//
// @return a0 ... 西暦年 (例: 2009 )
// @return a1 ... 月 (1?12)
// @return a2 ... 日 (1?31)
//
++a2;
switch (a1) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
if (31 < a2) { ++a1; a2 = 1; }
break;
case 2:
if ((a0 % 4 == 0 && a0 % 100 != 0) || (a0 % 400 == 0)) { // 閏年
if (29 < a2) { ++a1; a2 = 1; }
} else {
if (28 < a2) { ++a1; a2 = 1; }
}
break;
case 4:
case 6:
case 9:
case 11:
if (30 < a2) { ++a1; a2 = 1; }
break;
case 12:
if (31 < a2) { ++a0; a1 = 1; a2 = 1; }
break;
}
weekday.as
// 日付から曜日を求める
//
// @param a0 ... 西暦年 (例: 2009)
// @param a1 ... 月 (1?12)
// @param a2 ... 日 (1?31)
//
// @return r0 ... 0?6 {0:日曜, 1:月曜, ... , 6:土曜}
//
if (2 >= a1) { // 1月と2月は前年の13月と14月と見なす
--a0;
a1 += 12;
}
// Zellerの公式の変形式
r0 = (a0+int(a0/4)-int(a0/100)+int(a0/400)+int((13*a1+8)/5)+a2)%7;
if (12 < a1) { // 13月と14月を元に戻す
++a0;
a1 -= 12;
}
eval(varInstName).varname = "value";
1: ActionPush "varInstName"
2: ActionGetVariable
3: ActionPush ":"
4: ActionStringAdd
5: ActionPush "varname"
6: ActionStringAdd
7: ActionPush "value"
8: ActionSetVariable
eval(varInstName add ":varname") = "value";
1: ActionPush "varInstName"
2: ActionGetVariable
3: ActionPush ":varname"
4: ActionStringAdd
5: ActionPush "value"
6: ActionSetVariable
eval("/InstName:varname") = "value";
_root.InstName.varname = "value";
1: ActionPush "/InstName:varname"
2: ActionPush "value"
3: ActionSetVariable
weekday.rb
#!/usr/bin/env ruby
# 曜日を求める
# y ... 西暦年
# m ... 月
# d ... 日
def weekday(y, m, d)
if 2 >= m
y -= 1
m += 12
end
(y + (y / 4) - (y / 100) + (y / 400) + (13 * m + 8) / 5 + d) % 7
end
require 'date'
def check
d = Date.new(2000, 1, 1)
50000.times do
unless d.wday == weekday(d.year, d.month, d.day)
puts "#{d} ng"
break
end
d = d.next
end
end
check
weekday.rb
#!/usr/bin/env ruby
# 曜日を求める
# y ... 西暦年
# m ... 月
# d ... 日
def weekday(y, m, d)
ms = [ 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 ]
x = y
if 2 >= m
y -= 1
end
(x + (y / 4) - (y / 100) + (y / 400) + ms[m-1] + (d-1)) % 7
end
require 'date'
def check
d = Date.new(2000, 1, 1)
50000.times do
unless d.wday == weekday(d.year, d.month, d.day)
puts "#{d} ng"
break
end
d = d.next
end
end
check
maze.rb
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require 'rubygems'
require 'win32console'
require 'term/ansicolor'
include Win32::Console::ANSI
include Term::ANSIColor
class Maze
PATHWAY = 1
WALL = 2
attr_accessor :width, :height
def initialize(width, height)
@width = width * 2 + 1
@height = height * 2 + 1
@map = [ PATHWAY ] * @width * @height
@console = Win32::Console.new(STD_OUTPUT_HANDLE)
prologue
dig
epilogue
end
def prologue
@console.Cls
print on_white
dig_edge
end
def epilogue
print reset
@console.Cursor(0, 1)
print ' '
@console.Cursor(@width - 1, @height - 2)
print ' '
@console.Cursor(0, @height + 1)
end
def dig
loop do
w0, w1 = select_next
break unless w0
set_wall(*w0)
set_wall(*w1)
loop do
w0, w1 = candidates(*w1)
break unless w0
set_wall(*w0)
set_wall(*w1)
sleep 0
end
end
end
def select_next
r = walls
loop do
i = rand(r.size)
x, y = r[i]
r.delete_at(i)
z = candidates(x, y)
return z if z
break if r.empty?
end
end
def candidates(x, y)
c = []
f0(c, x + 1, y, x + 2, y)
f0(c, x - 1, y, x - 2, y)
f0(c, x, y + 1, x, y + 2)
f0(c, x, y - 1, x, y - 2)
c[rand(c.size)] unless c.empty?
end
def f0(z, x, y, x1, x2)
if PATHWAY == self[x1, x2]
z << [ [x, y], [x1, x2] ]
end
end
def walls
r = []
0.step(@height - 1, 2) do |y|
0.step(@width - 1, 2) do |x|
r << [x, y] if WALL == self[x, y]
end
end
r
end
def dig_edge
x = @width - 1
@height.times do |y|
set_wall(0, y)
set_wall(x, y)
end
y = @height - 1
@width.times do |x|
set_wall(x, 0)
set_wall(x, y)
end
end
def set_wall(x, y)
@map[x + y * @width] = WALL
@console.Cursor(x, y)
print ' '
end
def [](x, y)
return nil if x < 0 || @width <= x
return nil if y < 0 || @height <= y
@map[x + y * @width]
end
end
m = Maze.new(39, 30)
maze.rb
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require 'rubygems'
require 'win32console'
require 'term/ansicolor'
include Win32::Console::ANSI
include Term::ANSIColor
class Maze
OUTSIDE = -1
PATHWAY = 0
WALL = 1
def initialize(width, height)
@console = Win32::Console.new(STD_OUTPUT_HANDLE)
@width = width * 2 + 1
@height = height * 2 + 1
@data = [WALL] * @width * @height
draw_bg
dig
finish
end
def finish
@console.Cursor(0, 1)
print ' '
@console.Cursor(@width + 1, @height)
print ' '
@console.Cursor(0, @height + 1)
end
def dig
x = rand(@width / 2) * 2
y = rand(@height / 2) * 2
loop do
dig_path(x, y)
r = select_next(x, y)
break unless r
set_pathway(*r[0])
x, y = r[1]
end
end
def select_next(x, y)
r = walk(x, y)
until r.empty?
i = rand(r.size)
x, y = r[i]
r.delete_at(i)
s = candidates(x, y)
return s[rand(s.size)] unless s.empty?
end
end
def walk(tx, ty, x = nil, y = nil, fx = nil, fy = nil, r = [])
return if fx == tx && fy == ty
return if PATHWAY != self[tx, ty]
r << [tx, ty] if tx % 2 == 0 && ty % 2 == 0
walk(tx + 1, ty, tx, ty, x, y, r)
walk(tx - 1, ty, tx, ty, x, y, r)
walk(tx, ty + 1, tx, ty, x, y, r)
walk(tx, ty - 1, tx, ty, x, y, r)
r
end
def dig_path(x, y)
set_pathway(x, y)
loop do
s = candidates(x, y)
break if s.empty?
s = s[rand(s.size)]
set_pathway(*s[0])
set_pathway(*s[1])
x, y = s[1]
end
end
def candidates(x, y)
r = []
try_dig(x, y, 1, 0, r)
try_dig(x, y, -1, 0, r)
try_dig(x, y, 0, 1, r)
try_dig(x, y, 0, -1, r)
r
end
def try_dig(x, y, dx, dy, r)
x += dx
y += dy
s = x + dx
t = y + dy
if WALL == self[s, t]
r << [[x, y], [s, t]]
end
end
def [](x, y)
return OUTSIDE if x < 0 || @width <= x
return OUTSIDE if y < 0 || @height <= y
@data[x + y * @width]
end
def set_pathway(x, y)
@data[x + y * @width] = PATHWAY
@console.Cursor(x + 1, y + 1)
print ' '
end
def draw_bg
@console.Cls
(@height + 2).times do
print on_white
print ' ' * (@width + 2)
print reset
puts
end
end
end
#Maze.new(38, 30)
Maze.new(10, 10)
swf.rb
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require 'stringio'
module SWF
def self.read(src)
header = src.read(9)
x = (header[8] >> 3) * 4 + 5
header_size = ((((8 - (x & 7)) & 7) + x) / 8) + 12 + 5
header << src.read(header_size - 9)
body = src.read
[header, body]
end
class Vars
HD = "\x3f\x03\x00\x00\x00\x00"
BE = "\x96"
ZE = "\x00"
ZB = ZE + BE
ED = "\x00\x1d"
def initialize
@vars = []
end
def add(key, value)
@vars << [key, value]
end
def to_bytes
bytes = StringIO.new
bytes << HD
@vars.each do |key, val|
bytes << BE << [key.size + 2].pack('v') << ZE << key
bytes << ZB << [val.size + 2].pack('v') << ZE << val << ED
end
bytes << ZE
bytes.seek 0
bytes = bytes.read
bytes[2, 4] = [bytes.size - 6].pack('V')
bytes
end
def apply(src_io, dst_io)
vars = to_bytes
header, body = SWF.read(src_io)
header[4, 4] = [header.size + body.size + vars.size].pack('V')
dst_io << header
dst_io << vars
dst_io << body
end
end
end
if __FILE__ == $0
require 'yaml'
require 'optparse'
dat, src, dst = nil
OptionParser.new do |opt|
opt.on('-v VARS.yaml'){|v| dat = v }
opt.on('-i INPUT.swf'){|v| src = v }
opt.on('-o OUTPUT.swf'){|v| dst = v }
opt.parse!(ARGV)
unless dat && src && dst
opt.parse!(["-help"])
end
end
vars = SWF::Vars.new
YAML.load_file(dat).each{|key, value| vars.add(key, value) }
File.open(src, 'rb') do |s|
File.open(dst, 'wb') do |d|
vars.apply(s, d)
end
end
end
import android.view.Window;
Window w = getWindow();
w.requestFeature(Window.FEATURE_LEFT_ICON);
setContentView(R.layout.search);
w.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon);
foo.c
#include <ruby.h>
#include <rubysig.h>
static VALUE g_cFoo = Qnil;
struct FooData
{
int x;
int y;
};
static void
Foo_free_data(struct FooData* data)
{
fprintf(stderr, "free 0x%08x\n", data);
#if defined(USE_RUBY_XMALLOC)
ruby_xfree(data);
#else
free(data);
#endif
}
static VALUE
Foo_alloc_data(VALUE self)
{
return Data_Wrap_Struct(self, 0, &Foo_free_data, 0);
}
static struct FooData*
Foo_data(VALUE self)
{
struct FooData* sval = NULL;
Data_Get_Struct(self, struct FooData, sval);
return sval;
}
static VALUE
Foo_initialize(VALUE self)
{
#if defined(USE_RUBY_XMALLOC)
DATA_PTR(self) = ruby_xmalloc(sizeof(struct FooData));
#else
DATA_PTR(self) = malloc(sizeof(struct FooData));
#endif
fprintf(stderr, "alloc 0x%08x\n", DATA_PTR(self));
return self;
}
Init_foo()
{
g_cFoo = rb_define_class("Foo", rb_cObject);
rb_define_alloc_func(g_cFoo, &Foo_alloc_data);
rb_define_method(g_cFoo, "initialize", &Foo_initialize, 0);
}
.emacs
;;;;
;;;; Ruby
;;;;
(add-to-list 'load-path "c:/somewhere/site-lisp")
(autoload 'ruby-mode "ruby-mode"
"Mode for editing ruby source files" t)
(setq auto-mode-alist
(append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
(setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
interpreter-mode-alist))
(autoload 'run-ruby "inf-ruby"
"Run an inferior Ruby process")
(autoload 'inf-ruby-keys "inf-ruby"
"Set local key defs for inf-ruby in ruby-mode")
(add-hook 'ruby-mode-hook
'(lambda ()
(inf-ruby-keys)))
dokan_lib.c.patch
110a111,118
> static VALUE
> DR_FileInfo_set_directory_p(
> VALUE self,
> VALUE value)
> {
> rb_iv_set(self, "@is_directory", value);
> return self;
> }
151a160
> VALUE is_dir;
154a164,166
>
> is_dir = rb_iv_get(FileInfo, "@is_directory");
> DokanFileInfo->IsDirectory = (Qfalse != is_dir && Qnil != is_dir);
> /* DokanFileInfo->IsDirectory = RTEST(is_dir); */ /* 普通はこう書くのかな? */
173c185,186
< rb_define_method(g_cFileInfo, "directory?", DR_FileInfo_directory_p, 0);
---
> rb_define_method(g_cFileInfo, "directory?", DR_FileInfo_directory_p, 0);
> rb_define_method(g_cFileInfo, "directory=", DR_FileInfo_set_directory_p, 1);
mirror.rb.patch
19c19,24
< File.file?(get_path(path))
---
> s = File.stat(get_path(path)) rescue nil
> if s
> fileinfo.directory = s.directory?
> true
> else
> false
> end
app.rb
#!ruby
require 'rubygems'
require 'sinatra'
require 'sinatra/authorization'
require 'erb'
require 'fileutils'
helpers do
def authorization_realm; 'Private Zone'; end
def authorize(login, password)
login == 'id' && password == 'pw'
end
end
module Uploader
attr_reader :upload_path, :upload_dir
def initialize
@upload_path = 'files'
@upload_dir = File.join(Sinatra::Application.public, @upload_path)
end
def files
Dir.entries(upload_dir).select do |x|
!File.directory?(x)
end
end
def floor3(x)
(x * 1000).floor / 1000.0
end
def file_size(x)
s = File.stat(File.join(upload_dir, x)).size
case
when 1024 * 1024 < s
"#{floor3(s/(1024.0 * 1024.0))} M"
when 1024 < s
"#{floor3(s/1024.0)} K"
else
"#{s} bytes"
end
end
end
helpers Uploader
get '/' do
login_required
erb :index
end
post '/upload' do
if params[:file]
save_file = File.join(upload_dir, File.basename(params[:file][:filename]))
File.open(save_file, 'wb'){|f| f.write(params[:file][:tempfile].read)}
end
redirect '/'
end
get '/remove' do
if params[:file]
FileUtils.rm(File.join(upload_dir, File.basename(params[:file]))) rescue nil
end
redirect '/'
end
get '/logout' do
redirect '/' unless Rack::Auth::Basic::Request.new(request.env).provided?
response["WWW-Authenticate"] = %(Basic realm="#{authorization_realm}")
halt 401, 'Authorization Required'
end
get '*' do
redirect '/'
end
__END__
@@ index
<html>
<head>
<title>K</title>
</head>
<body>
<a href="/logout">logout</a>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="file"><input type="submit" value="upload">
</form><%
files.sort.each do |x|
%><a href="<%=escape_html(File.join(upload_path, x))%>"><%
%><%=escape_html(x)%></a> (<%=file_size(x)%>)<%
%> <a href="/remove?file=<%=escape(x)%>">remove</a><br><%
end
%></body>
</html>
study_auth.rb
use Rack::Session::Cookie,
# :key => 'rack.session',
# :domain => 'takumakei.blogspot.com',
# :path => '/',
:expire_after => 3600,
:secret => 'changeme'
helpers do
def auth_ok?(id, pw)
id == 'id' && pw == 'pw'
end
def login
if auth_ok?(params['id'], params['pw'])
session[:login] = 'What should i have to put here ?'
redirect '/'
else
erb :login
end
end
def logout
session.delete(:login)
redirect '/'
end
def need_auth
unless session[:login]
erb :login
else
yield
end
end
end
app.rb
#!ruby
require 'rubygems'
require 'sinatra'
require 'erb'
require 'study_auth'
get '/' do
need_auth do
erb :index
end
end
get '/login' do
login
end
post '/login' do
login
end
get '/logout' do
logout
end
get '/*' do
login
end
index.erb
<html>
<head>
<title>index</title>
</head>
<body>
<%=Time.new.to_s%><br/>
<a href="logout">logout</a>
</body>
</html>
login.erb
<html>
<head>
<title>login</title>
</head>
<body>
<form action="login" method="POST">
<input type="text" name="id" value="<%=params['id']%>">
<input type="password" name="pw">
<input type="submit" value="LOGIN">
</form>
</body>
</html>
CountDown
//////////////////////////////////////////////////////////////////////
// 現在日時からXデーまでのカウントダウン
//
// 結果は4つの変数に算出する。「あと{dT}日と{HT}時間{MT}分{ST}秒」
//dT = 0; // 残り日数
//HT = 0; // 時間
//MT = 0; // 分
//ST = 0; // 秒
//////////////////////////////////////////////////////////////////////
// Xデー
yL = 2009;
mmL = 7;
dL = 7;
HL = 0;
ML = 0;
SL = 0;
//////////////////////////////////////////////////////////////////////
// 現在日時取得
yR =fscommand2("GetDateYear");
mmR = fscommand2("GetDateMonth");
dR = fscommand2("GetDateDay");
HR = fscommand2("GetTimeHours");
MR = fscommand2("GetTimeMinutes");
SR = fscommand2("GetTimeSeconds");
if(!yR){
debug_ = '現在時刻を取得できなかったYo';
stop();
}
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「年」を表示
yyyy_ = yL;
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「月」を2桁で表示
if(10 > mmL){
mo_ = '0' add mmL;
}
else{
mo_ = String(mmL);
}
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「日」を2桁で表示
if(10 > dL){
dd_ = '0' add dL;
}else{
dd_ = String(dL);
}
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「時」を2桁で表示
if(10 > HL){
hh_ = '0' add HL;
}else{
hh_ = String(HL);
}
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「分」を2桁で表示
if(10 > ML){
mi_ = '0' add ML;
}else{
mi_ = ML;
}
//////////////////////////////////////////////////////////////////////
// Xデーを表示する。「秒」を2桁で表示
if(10 > SL){
ss_ = '0' add SL;
}else{
ss_ = SL;
}
//////////////////////////////////////////////////////////////////////
// Xデーを2000年1月1日からの経過秒数に変換する。dtLが結果。
dtL = 0;
for(i = 2000; i < yL; ++i){
if((i % 4 == 0) ? ((i % 100 == 0) ? (i % 400 == 0) : true) : false){
dtL += 366;
} else {
dtL += 365;
}
}
switch(mmL){
case 2: dtL += 31; break;
case 3: dtL += 59; break;
case 4: dtL += 90; break;
case 5: dtL += 120; break;
case 6: dtL += 151; break;
case 7: dtL += 181; break;
case 8: dtL += 212; break;
case 9: dtL += 243; break;
case 10: dtL += 273; break;
case 11: dtL += 304; break;
case 12: dtL += 334; break;
}
if(2 < mmL && ((yL % 4 == 0) ? ((yL % 100 == 0) ? (yL % 400 == 0) : true) : false)){
dtL += 1;
}
dtL += dL;
dtL = (dtL * 24 * 60 * 60) + (HL * 60 * 60) + (ML * 60) + SL;
//////////////////////////////////////////////////////////////////////
// 現在日時を2000年1月1日からの経過秒数に変換する。dtRが結果。
dtR = 0;
for(i = 2000; i < yR; ++i){
if((i % 4 == 0) ? ((i % 100 == 0) ? (i % 400 == 0) : true) : false){
dtR += 366;
} else {
dtR += 365;
}
}
switch(mmR){
case 2: dtR += 31; break;
case 3: dtR += 59; break;
case 4: dtR += 90; break;
case 5: dtR += 120; break;
case 6: dtR += 151; break;
case 7: dtR += 181; break;
case 8: dtR += 212; break;
case 9: dtR += 243; break;
case 10: dtR += 273; break;
case 11: dtR += 304; break;
case 12: dtR += 334; break;
}
if(2 < mmR && ((yR % 4 == 0) ? ((yR % 100 == 0) ? (yR % 400 == 0) : true) : false)){
dtR += 1;
}
dtR += dR;
dtR = (dtR * 24 * 60 * 60) + (HR * 60 * 60) + (MR * 60) + SR;
//////////////////////////////////////////////////////////////////////
// Xデーと現在日時の差を計算して、{dT}日{HT}時間{MT}分{ST}秒にする。
if(dtL < dtR){
debug_ = 'もう過ぎてるYo';
stop();
}
dtT = dtL - dtR;
dT = int(dtT / (24 * 60 * 60));
HT = int((dtT / (60 * 60)) % 24);
MT = int((dtT / 60) % 60);
ST = int(dtT % 60);
//////////////////////////////////////////////////////////////////////
// Xデーまでの「日数」を4桁で表示
if(10 > dT){
dT_ = '000' add dT;
}
else if(100 > dT){
dT_ = '00' add dT;
}
else if(1000 > dT){
dT_ = '0' add dT;
}
else{
dT_ = String(dT);
}
//////////////////////////////////////////////////////////////////////
// Xデーまでの「時間」を2桁で表示
if(10 > HT){
HT_ = '0' add HT;
}
else{
HT_ = String(HT);
}
//////////////////////////////////////////////////////////////////////
// Xデーまでの「分」を2桁で表示
if(10 > MT){
MT_ = '0' add MT;
}
else{
MT_ = String(MT);
}
//////////////////////////////////////////////////////////////////////
// Xデーまでの「秒」を2桁で表示
if(10 > ST){
ST_ = '0' add ST;
}
else{
ST_ = String(ST);
}
//////////////////////////////////////////////////////////////////////
QRcodeG.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
showStatusBar="false" paddingBottom="3" paddingLeft="3" paddingRight="3" paddingTop="3"
width="174" height="188"
minWidth="174" minHeight="188">
<mx:Script>
<![CDATA[
private const GOOGLE_CHART:String
= 'http://chart.apis.google.com/chart?chs=150x150&cht=qr&chl=';
private function create():void
{
var url:String = GOOGLE_CHART + encodeURIComponent(txt_.text);
qrImage_.scaleContent = true;
qrImage_.source = url;
}
]]>
</mx:Script>
<mx:HBox width="100%">
<mx:TextInput id="txt_" width="100%"/>
<mx:Button label="QR" click="create()"/>
</mx:HBox>
<mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<mx:Image id="qrImage_" width="100%" height="100%"
source="icons/icon_128.png" scaleContent="false"
autoLoad="true" verticalAlign="middle" horizontalAlign="center"/>
</mx:HBox>
</mx:WindowedApplication>
parseIso8601
private static const ISO8601_RE:RegExp
= /^(\d{4})(-?(((\d{2})(-?(\d{2}))?)|(\d{3})|(W(\d{2})-?(\d)))([T ](\d{2})(:?(\d{2})(:?(\d{2})([,\.](\d+))?)?)?(Z|(([+-])(\d{2})(:?(\d{2}))?))?)?)?$/;
public static function parseIso8601(s:String):Date
{
var year:int = 1970;
var month:int = 0;
var date:int = 1;
var hour:int = 0;
var minute:int = 0;
var second:int = 0;
var millisec:int = 0;
var offset:int = 0;
var m:Array = s.match(ISO8601_RE);
if(!m) return null;
if(m[1]) year = int(m[1]);
if(m[3]) date = int(m[3]);
if(m[5]) month = int(m[5]) - 1;
if(m[7]) date = int(m[7]);
if(m[10] && m[11]){
var first:Date = new Date(year, 0, 1);
var w:int = (first.day == 0 ? 6 : first.day - 1);
date = 8 - w + (int(m[11]) - 1) + 7 * (int(m[10]) - 2);
}
if(m[13]) hour = int(m[13]) % 24;
if(m[15]) minute = int(m[15]);
if(m[17]) second = int(m[17]);
if(m[19]) millisec = int(m[19]);
if(m[20] && m[20] == 'Z')
return new Date(Date.UTC(year, month, date, hour, minute, second, millisec));
if(m[23]) offset = int(m[23]) * 60;
if(m[25]) offset += int(m[25]);
if(m[22] && m[22] == '-') offset = -offset;
offset *= 60 * 1000;
return new Date(Date.UTC(year, month, date, hour, minute, second, millisec) - offset);
}
day
public final class Day {
public static const MONDAY:Day = new Day();
public static const TUESDAY:Day = new Day();
...
}
nasty day
public final class NastyDay {
public static const GALACTICDAY:Day = new Day();
}
WidgetWindow.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Window xmlns:mx="http://www.adobe.com/2006/mxml"
maximizable="false"
minimizable="false"
resizable="false"
systemChrome="none"
showFlexChrome="false"
transparent="true"
type="lightweight"
layout="absolute"
width="100"
height="100"
close="exit()">
<mx:Script>
<![CDATA[
private function exit():void
{
NativeApplication.nativeApplication.exit(0);
}
]]>
</mx:Script>
<mx:Canvas width="100%" height="100%"
cornerRadius="8" borderStyle="solid" backgroundColor="#F3F3D1"
mouseDown="nativeWindow.startMove()" backgroundAlpha="0.7"/>
<mx:VBox horizontalCenter="0" verticalCenter="0" horizontalAlign="center">
<mx:Label text="Hello world"/>
<mx:Button label="close" click="exit()"/>
</mx:VBox>
</mx:Window>
Widget.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
initialize="init()">
<mx:Script>
<![CDATA[
private function init():void
{
new WidgetWindow().open();
}
]]>
</mx:Script>
</mx:Application>
scan.as
package com.blogspot.takumakei.utils
{
public function scan(str:String, re:RegExp):Array
{
if(!re.global){
var flags:String = 'g';
if(re.dotall)
flags += 's';
if(re.multiline)
flags += 'm';
if(re.ignoreCase)
flags += 'i';
if(re.extended)
flags += 'x';
re = new RegExp(re.source, flags);
}
var r:Array = [];
var m:Array = re.exec(str);
while(null != m){
if(1 == m.length)
r.push(m[0]);
else
r.push(m.slice(1, m.length));
m = re.exec(str);
}
return r;
}
}
サンプルスクリプト
p(scan('foobar', /./));
p(scan('foobar', /(.)/));
p(scan('foobarbazfoobarbaz', /ba./));
p(scan('foobarbazfoobarbaz', /(ba)(.)/));
実行結果
["f","o","o","b","a","r"]
[["f"],["o"],["o"],["b"],["a"],["r"]]
["bar","baz","bar","baz"]
[["ba","r"],["ba","z"],["ba","r"],["ba","z"]]
inspect.as
package com.blogspot.takumakei.utils
{
import flash.utils.getQualifiedClassName;
public function inspect(x:*):String
{
if(x == null)
return "null";
if(x is Boolean)
return (x ? 'true' : 'false');
if(x is int || x is uint || x is Number)
return x.toString();
if(x is String)
return '"' + x + '"';
if(x is Array){
var r:String = '[';
if(0 < x.length){
r += inspect(x[0]);
for(var i:int = 1; i < x.length; ++i){
r += ',';
r += inspect(x[i]);
}
}
r += ']';
return r;
}
return '#<' + flash.utils.getQualifiedClassName(x) + ':"' + x.toString() + '">';
}
}
p.as
package com.blogspot.takumakei.utils
{
public function p(x:*):void
{
trace(inspect(x));
}
}
target.c
#include "alias.h"
#pragma comment(lib, "alias")
int target_function_name()
{
return alias_function_name();
}
alias.c
#include "target.h"
#pragma comment(lib, "original")
int alias_function_name()
{
return target_function_name();
}
case.cc
#include <locale>
#include <string>
template<typename Elem>
std::basic_string<Elem> tolower(const std::basic_string<Elem>& x, const std::locale& loc = std::locale())
{
std::basic_string<Elem> r;
r.reserve(x.size());
typedef typename std::basic_string<Elem>::const_iterator iterator;
iterator itr = x.begin();
iterator end = x.end();
for(; itr != end; ++itr)
r.push_back(std::tolower(*itr, loc));
return r;
}
template<typename Elem>
std::basic_string<Elem> toupper(const std::basic_string<Elem>& x, const std::locale& loc = std::locale())
{
std::basic_string<Elem> r;
r.reserve(x.size());
typedef typename std::basic_string<Elem>::const_iterator iterator;
iterator itr = x.begin();
iterator end = x.end();
for(; itr != end; ++itr)
r.push_back(std::toupper(*itr, loc));
return r;
}
read_file.cc
#include <fstream>
#include <iterator>
template<typename Container>
bool read(const char* filename, Container& cont)
{
std::ifstream in(filename, std::ios_base::in | std::ios_base::binary);
if(!in)
return false;
in.unsetf(std::ios::skipws);
std::copy(
std::istream_iterator<typename Container::value_type>(in),
std::istream_iterator<typename Container::value_type>(),
std::back_inserter(cont));
return true;
}
#include <list>
#include <string>
int main(int, char*[])
{
std::list<char> x;
read(__FILE__, x);
std::string s;
read(__FILE__, s);
return 0;
}
float.cpp
namespace Float {
double base(double direction, int volume)
{
double position = 1.0;
for(int i = 0; i < volume; ++i)
{
position *= direction;
}
return position;
}
double to_f(const char* itr, const char* end)
{
if(itr == end){ return 0.0; } // NG
double flag = 1.0;
switch(*itr)
{
case '-':
flag = -1.0;
// no break needed
case '+':
while(true)
{
++itr;
if(itr == end){ return 0.0; } // NG
if(*itr != ' '){ break; }
}
break;
}
double mantissa = 0.0;
if(Integer::DecimalNumber::acceptable(*itr))
{
mantissa = Integer::DecimalNumber::to_i(*itr);
while(true)
{
++itr;
if(itr == end){ return flag * mantissa; } // OK
if(*itr == '_')
{
++itr;
if(itr == end){ return flag * mantissa; } // OK (with garbage)
}
if(!Integer::DecimalNumber::acceptable(*itr))
{
break;
}
mantissa = mantissa * 10.0 + Integer::DecimalNumber::to_i(*itr);
}
}
if('.' == *itr)
{
++itr;
if(itr == end){ return flag * mantissa; } // OK (with garbage)
if(!Integer::DecimalNumber::acceptable(*itr))
{
return flag * mantissa; // OK (with garbage)
}
double position = 0.1;
while(true)
{
mantissa += position * Integer::DecimalNumber::to_i(*itr);
++itr;
if(itr == end){ break; }
if('_' == *itr)
{
++itr;
if(itr == end){ break; }
}
if(!Integer::DecimalNumber::acceptable(*itr)){ break; }
position *= 0.1;
}
}
if('e' != *itr && 'E' != *itr){ return flag * mantissa; }
++itr;
if(itr == end){ return flag * mantissa; }
if('-' == *itr)
return flag * mantissa * base(0.1, Integer::parse_first<Integer::DecimalNumber>(itr, end));
if('+' == *itr)
return flag * mantissa * base(10.0, Integer::parse_first<Integer::DecimalNumber>(itr, end));
if(Integer::DecimalNumber::acceptable(*itr))
return flag * mantissa * base(10.0, Integer::parse_last<Integer::DecimalNumber>(itr, end));
return flag * mantissa;
}
}
integer.cpp
namespace Integer {
struct BinaryNumber
{
static const int BASE = 2;
static bool acceptable(char ch)
{
return '0' == ch || '1' == ch;
}
static int to_i(char ch)
{
return ch - '0';
}
};
struct OctalNumber
{
static const int BASE = 8;
static bool acceptable(char ch)
{
return '0' <= ch && ch <= '7';
}
static int to_i(char ch)
{
return ch - '0';
}
};
struct DecimalNumber
{
static const int BASE = 10;
static bool acceptable(char ch)
{
return '0' <= ch && ch <= '9';
}
static int to_i(char ch)
{
return ch - '0';
}
};
struct HexadecimalNumber
{
static const int BASE = 16;
static bool acceptable(char ch)
{
return
('0' <= ch && ch <= '9')
|| ('a' <= ch && ch <= 'f')
|| ('A' <= ch && ch <= 'F');
}
static int to_i(char ch)
{
if('0' <= ch && ch <= '9'){ return ch - '0'; }
if('a' <= ch && ch <= 'f'){ return ch - 'a' + 10; }
return ch - 'A' + 10;
}
};
template<typename BaseNumberTraits>
int parse_last(const char* itr, const char* end)
{
int value = BaseNumberTraits::to_i(*itr);
while(true)
{
++itr;
if(itr == end){ return value; } // OK
if(*itr == '_'){
++itr;
if(itr == end){ return value; } // OK (with garbage)
}
if(!BaseNumberTraits::acceptable(*itr)){ return value; } // OK (with garbage)
value =
value * BaseNumberTraits::BASE
+ BaseNumberTraits::to_i(*itr);
}
}
template<typename BaseNumberTraits>
int parse_first(const char* itr, const char* end)
{
++itr;
if(itr == end){ return 0; } // NG
if(!BaseNumberTraits::acceptable(*itr)){ return 0; } // NG
return parse_last<BaseNumberTraits>(itr, end);
}
int to_i(const char* itr, const char* end)
{
if(itr == end){ return 0; } // NG
int flag = 1;
switch(*itr)
{
case '-':
flag = -1;
// no break needed
case '+':
while(true)
{
++itr;
if(itr == end){ return 0; } // NG
if(*itr != ' '){ break; }
}
break;
}
if(*itr == '0')
{
++itr;
if(itr == end){ return 0; } // OK
if('x' == *itr || 'X' == *itr)
return flag * parse_first<HexadecimalNumber>(itr, end);
if(OctalNumber::acceptable(*itr))
return flag * parse_last<OctalNumber>(itr, end);
if('_' == *itr)
return flag * parse_first<OctalNumber>(itr, end);
if('o' == *itr || 'O' == *itr)
return flag * parse_first<OctalNumber>(itr, end);
if('b' == *itr || 'B' == *itr)
return flag * parse_first<BinaryNumber>(itr, end);
if('d' == *itr || 'D' == *itr)
return flag * parse_first<DecimalNumber>(itr, end);
return 0; // NG
}
if(DecimalNumber::acceptable(*itr))
return flag * parse_last<DecimalNumber>(itr, end);
return 0; // NG
}
}
evhttpd.cc
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <event.h>
#include <evhttp.h>
#pragma comment(lib, "ws2_32")
struct EnableWinsock
{
EnableWinsock(){
WSADATA wsaData;
const int r = WSAStartup(MAKEWORD(2, 2), &wsaData);
}
~EnableWinsock(){
WSACleanup();
}
};
void root_handler(evhttp_request* req, void* arg)
{
evbuffer* buf = evbuffer_new();
if(!buf){
puts("failed to create response buffer");
return;
}
evbuffer_add_printf(buf, "Hello: %s\n", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}
void generic_handler(evhttp_request* req, void* arg)
{
evbuffer* buf = evbuffer_new();
if(!buf){
puts("failed to create response buffer");
return;
}
evbuffer_add_printf(buf, "Requested: %s\n", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}
int wmain(int argc, wchar_t* argv[])
{
EnableWinsock enableWinsock;
event_init();
evhttp* httpd = evhttp_start("0.0.0.0", 8880);
if(!httpd){ return 1; }
evhttp_set_cb(httpd, "/", root_handler, NULL);
evhttp_set_gencb(httpd, generic_handler, NULL);
event_dispatch();
evhttp_free(httpd);
return 0;
}
StudyCrypto.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
showStatusBar="false"
width="320" height="300"
styleName="study"
borderThickness="1">
<mx:Style>
.study {
paddingBottom: 3;
paddingLeft: 3;
paddingRight: 3;
paddingTop: 3;
}
</mx:Style>
<mx:Script>
<![CDATA[
import com.hurlant.crypto.Crypto;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.IVMode;
import com.hurlant.crypto.symmetric.PKCS5;
import com.hurlant.util.Base64;
import com.hurlant.util.Hex;
public static function encrypt(name:String, k:String, s:String):ByteArray {
var e:ByteArray = new ByteArray();
var key:ByteArray = Hex.toArray(Hex.fromString(k));
var data:ByteArray = Hex.toArray(Hex.fromString(s));
var pad:IPad = new PKCS5();
var cipher:ICipher = Crypto.getCipher(name, key, pad);
pad.setBlockSize(cipher.getBlockSize());
cipher.encrypt(data);
e.writeObject(data);
if(cipher is IVMode){
var ivmode:IVMode = cipher as IVMode;
e.writeObject(ivmode.IV);
}
e.position = 0;
return e;
}
public static function decrypt(name:String, k:String, e:ByteArray):String {
var data:ByteArray = e.readObject();
var kdata:ByteArray = Hex.toArray(Hex.fromString(k));
var pad:IPad = new PKCS5();
var cipher:ICipher = Crypto.getCipher(name, kdata, pad);
if(cipher is IVMode){
var ivmode:IVMode = cipher as IVMode;
ivmode.IV = e.readObject();
}
cipher.decrypt(data);
return Hex.toString(Hex.fromArray(data));
}
private function run():void {
const name:String = 'aes-cbc';
var e:ByteArray = encrypt(name, key.text, src.text);
o0.text = Base64.encode(Hex.fromArray(e));
o1.text = decrypt(name, key.text, Hex.toArray(Base64.decode(o0.text)));
}
]]>
</mx:Script>
<mx:Form styleName="study" width="100%" cornerRadius="6" borderColor="#218BD5" borderStyle="solid">
<mx:FormItem label="Password" width="100%">
<mx:TextInput width="100%" id="key" change="btn.enabled = (4 <= key.text.length)"/>
</mx:FormItem>
<mx:FormItem label="Input" width="100%">
<mx:TextInput width="100%" id="src"/>
</mx:FormItem>
<mx:FormItem width="100%">
<mx:Button id="btn" label="run" click="run()" enabled="false"/>
</mx:FormItem>
</mx:Form>
<mx:Form styleName="study" width="100%" height="100%" cornerRadius="6" borderColor="#218BD5" borderStyle="solid">
<mx:FormItem label="Encrypt" width="100%" height="100%">
<mx:TextArea width="100%" height="100%" id="o0"/>
</mx:FormItem>
<mx:FormItem label="Decrypt" width="100%" height="100%">
<mx:TextArea width="100%" height="100%" id="o1"/>
</mx:FormItem>
</mx:Form>
</mx:WindowedApplication>
dll_to_def.rb
#!ruby -Ku
# Generate the .def file from .dll using 'dumpbin.exe'
# 2009-04-30 23:43:20
class ExportsList
FUNCTION_LINE_PATTERN = /^\s+(\d+)\s+[0-9A-Fa-f]+\s+[0-9A-Fa-f]+\s+(.*)$/
def initialize(dllname)
@dllname = dllname
@max_name_length = 0
@exports = []
dumpbin(dllname) do |line|
next unless line =~ FUNCTION_LINE_PATTERN
@exports << [$1, $2]
@max_name_length = $2.length if @max_name_length < $2.length
end
end
def save_as_def
width = ((@max_name_length + 7) / 8) * 8
basename = File.basename(@dllname, '.dll')
File.open(basename + '.def', 'w') do |f|
f.puts(%Q|LIBRARY "#{basename}"|)
f.puts
f.puts('EXPORTS')
@exports.each do |i, name|
f.print("\t#{name}")
f.print("\t" * ((width + 7 - name.length) / 8))
f.puts("@#{i}")
end
end
end
private
def dumpbin(dllname)
raise "Command not found: dumpbin" unless cmd_exist?('dumpbin')
Kernel.open("|dumpbin /exports #{dllname}") do |f|
while line = f.gets
yield(line)
end
end
end
def cmd_exist?(cmd)
ENV['PATH'].split(';').each do |path|
(';' + ENV['PATHEXT']).split(';').each do |ext|
pathname = File.join(File.expand_path(path), cmd + ext)
return true if File.exist?(pathname)
end
end
nil
end
end
if $0 == __FILE__
ARGV.each do |dllname|
ExportsList.new(dllname).save_as_def
end
end