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 " }}}