会员
周边
众包
新闻
博问
闪存
赞助商
所有博客
当前博客
我的博客
我的园子
账号设置
简洁模式
...
退出登录
注册
登录
李超
cc编程笔记本。
博客园
::
首页
::
博问
::
闪存
::
新随笔
::
联系
::
订阅
::
管理
::
公告
ruby写的BT种子解析器
class
MyFile
<
File
def
peek(len)
str
=
self.read(len)
self.pos
-=
len
str
end
end
#
字段信息
class
TVal
attr_accessor :Type
attr_accessor :Value
def
to_s()
@Value
end
end
#
文件信息
class
TFile
attr_reader :Length
attr_reader :Path
attr_reader :Name
attr_reader :FirstPiece
attr_reader :PieceLength
def
initialize(size, fullPath, pStart, pLen)
@Length
=
Size
@FirstPiece
=
pStart
@PieceLength
=
pLen
fileNamePos
=
fullPath.rindex(
'
\\
'
)
if
fileNamePos.nil? then
@Path
=
""
@Name
=
fullPath
else
@Path
=
fullPath[0..fileNamePos]
@Name
=
fullPath[fileNamePos..fullPath.length
-
1
]
end
end
end
class
TorrentParser
attr_accessor :Root
def
initialize(tPath)
@Path
=
tPath
@Size
=
nil
@Root
=
nil
@Files
=
nil
@Torrent
=
nil
@TotalValues
=
0
@InfoStart
=
nil
@InfoEnd
=
nil
end
#
主函数
def
Process()
raise
"
File doesn't exist
"
if
!MyFile.exist? @Path
#
检测文件路径
@TotalValues
=
0
@Torrent
=
MyFile.new @Path
@Torrent.binmode
raise
"
Torrent File Error
"
if
@Torrent.read(
1
)
!=
'
d
'
@Root
=
ProcessDict()
@Files
=
GetFiles()
end
#
读取一个字典
def
ProcessDict()
tempDict
=
Hash.new
while
@Torrent.peek(
1
)
!=
'
e
'
#
向后读一个字符 看看是不是e 如果是e的话 说明dictionary结束了
key
=
ProcessString()
#
读取一个Key Name
if
key
==
'
info
'
then
#
如果是名字为info的key
@InfoStart
=
@Torrent.pos
#
设置info start的index
end
if
key
==
'
pieces
'
then
#
如果是pieces的key 则按照特殊的byte方式读取
val
=
TVal.new
val.Type
=
"
BYTE
"
val.Value
=
ProcessByte()
tempDict[key]
=
val
else
val
=
ProcessVal()
#
否则读该key的Val
tempDict[key]
=
val
end
if
key
==
"
info
"
then
@InfoEnd
=
@Torrent.pos
-
@InfoStart
end
end
@Torrent.read
1
#
读掉结尾的"e"
return
tempDict
end
#
读取一个字串
def
ProcessString()
tempLen
=
''
tempLen
+=
@Torrent.read(
1
)
while
@Torrent.peek(
1
)
!=
'
:
'
#
获取字串长度
@Torrent.read(
1
)
#
将后面的冒号读掉
content
=
@Torrent.read(tempLen.to_i)
#
然后读指定长度的字符串 并返回
return
content
end
#
读取字节串
def
ProcessByte()
tempLen
=
''
tempLen
+=
@Torrent.read(
1
)
while
@Torrent.peek(
1
)
!=
'
:
'
#
获取字串长度
@Torrent.read(
1
)
#
将后面的冒号读掉
chrs
=
Array.new
(
1
..tempLen.to_i).each{
|
idx
|
byte
=
@Torrent.readchar
chrs
<<
"
%02X
"
%
byte
}
chrs
end
#
读一个数字
def
ProcessInt()
tempInt
=
''
tempInt
+=
@Torrent.read(
1
)
while
@Torrent.peek(
1
)
!=
'
e
'
@Torrent.read(
1
)
#
把最后的e读掉
tempInt.to_i
end
#
读一个列表
def
ProcessList()
tempList
=
Array.new
while
@Torrent.peek(
1
)
!=
'
e
'
tempList
<<
ProcessVal
end
tempList
end
#
读取一个Val
def
ProcessVal()
@TotalValues
+=
1
val
=
TVal.new
case @Torrent.peek(
1
)
when
'
d
'
@Torrent.read(
1
)
#
把d读掉
val.Type
=
"
DICT
"
val.Value
=
ProcessDict()
when
'
l
'
@Torrent.read(
1
)
#
把l读掉
val.Type
=
"
LIST
"
val.Value
=
ProcessList()
when
'
i
'
@Torrent.read(
1
)
#
把i读掉
val.Type
=
"
INT
"
val.Value
=
ProcessInt()
else
val.Type
=
"
STRING
"
val.Value
=
ProcessString()
end
val
end
end
begin
_torrent
=
TorrentParser.new ARGV.shift
_torrent.Process
_torrent.Root.map{
|
key,value
|
case value.Type
when
'
LIST
'
puts
"
#{key}(#{value.Type})\t\t#{value.Value}
"
when
'
BYTE
'
puts
"
#{key}(#{value.Type})\t\t%0X
"
, value.Value
when
'
DICT
'
value.Value.map{
|
skey,svalue
|
puts
"
--#{skey}(#{svalue.Type})\t\t#{svalue.Value}
"
}
else
puts
"
#{key}(#{value.Type})\t\t#{value.Value}
"
end
}
rescue
puts $!
puts $@
end
posted on
2008-04-08 18:17
coderlee
阅读(
1196
) 评论(
0
)
编辑
收藏
举报
会员力量,点亮园子希望
刷新页面
返回顶部