autoload/bencode.vim @ 2975b6f50397
default tip
Try to detect truncated data
author |
Steve Losh <steve@stevelosh.com> |
date |
Sun, 24 Jul 2016 17:27:46 +0000 |
parents |
5d747e72d1f2 |
children |
(none) |
" Encoding --------------------------------------------------------------------
function! bencode#Bencode(o) " {{{
let typ = type(a:o)
if typ == 0
return s:BencodeInteger(a:o)
elseif typ == 1
return s:BencodeString(a:o)
elseif typ == 3
return s:BencodeList(a:o)
elseif typ == 4
return s:BencodeDict(a:o)
else
throw "sorry m8 i can't bencode that"
endif
endfunction " }}}
function! s:BencodeInteger(o) " {{{
return "i" . string(a:o) . "e"
endfunction " }}}
function! s:BencodeString(o) " {{{
return string(len(a:o)) . ":" . a:o
endfunction " }}}
function! s:BencodeList(o) " {{{
let contents = map(a:o, 'bencode#Bencode(v:val)')
return 'l' . join(contents, '') . 'e'
endfunction " }}}
function! s:BencodeDict(o) " {{{
let contents = 'd'
for key in sort(copy(keys(a:o)))
let contents .= bencode#Bencode(key) . bencode#Bencode(a:o[key])
endfor
return contents . 'e'
endfunction " }}}
" Decoding --------------------------------------------------------------------
function! bencode#BdecodeAll(bstring) " {{{
let results = []
let remaining = a:bstring
while remaining !~# '\v^\s*$'
let dec = s:ActuallyBdecode(remaining)
call add(results, dec[0])
let remaining = dec[1]
endwhile
return results
endfunction " }}}
function! bencode#Bdecode(bstring) " {{{
return s:ActuallyBdecode(a:bstring)[0]
endfunction " }}}
function! s:ActuallyBdecode(bstring) " {{{
let bs = substitute(a:bstring, '\v^\s*', '', '')
if bs == ''
throw "bencode: received truncated data"
endif
if bs[0] == 'i'
return s:BdecodeInteger(bs)
elseif bs[0] =~ '[0-9]'
return s:BdecodeString(bs)
elseif bs[0] == 'l'
return s:BdecodeList(bs)
elseif bs[0] == 'd'
return s:BdecodeDict(bs)
else
throw "shits fucked, yo"
endif
endfunction " }}}
function! s:FindDelimiter(bstring, delimiter) "{{{
let i = 1
let len = len(a:bstring)
while a:bstring[i] != a:delimiter
if i >= len
throw "bencode: received truncated data"
endif
let i += 1
endwhile
return i
endfunction " }}}
function! s:BdecodeInteger(bstring) " {{{
let i = s:FindDelimiter(a:bstring, 'e')
return [0 + a:bstring[1:i - 1], a:bstring[i+1:]]
endfunction " }}}
function! s:BdecodeString(bstring) " {{{
let i = s:FindDelimiter(a:bstring, ':')
let slen = 0 + a:bstring[0:i-1]
let strcontents = a:bstring[i+1:i+slen]
if len(strcontents) < slen
throw "bencode: received truncated data"
endif
return [strcontents, a:bstring[i+slen+1:]]
endfunction " }}}
function! s:BdecodeList(bstring) " {{{
let data = a:bstring[1:]
let result = []
while 1
let dec = s:ActuallyBdecode(data)
let val = dec[0]
let rest = dec[1]
call add(result, val)
if rest[0] == 'e'
" strip off the trailing e from the list
return [result, rest[1:]]
else
let data = rest
endif
endwhile
endfunction " }}}
function! s:BdecodeDict(bstring) " {{{
let data = a:bstring[1:]
let result = {}
while 1
let dec = s:ActuallyBdecode(data)
let key = dec[0]
let rest = dec[1]
let dec = s:ActuallyBdecode(rest)
let result[key] = dec[0]
let rest = dec[1]
if rest[0] == 'e'
" strip off the trailing e from the dict
return [result, rest[1:]]
else
let data = rest
endif
endwhile
endfunction " }}}