# HG changeset patch # User Steve Losh # Date 1449354230 0 # Node ID f4101563743e1e9780f20a1d82ea51bfcfb6aefc Initial commit diff -r 000000000000 -r f4101563743e README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.markdown Sat Dec 05 22:23:50 2015 +0000 @@ -0,0 +1,55 @@ + _ _ _ + _ _|_|_____ ___| |_ ___ ___ ___ ___ _| |___ + | | | | |___| . | -_| | _| . | . | -_| + \_/|_|_|_|_| |___|___|_|_|___|___|___|___| + +If you're reading this you probably want to do one of the following: + +* Generate a bencoded string of a Vim datastructure +* Parse a bencoded string into a Vi data structure + +If so, you're in luck. + +API +--- + +`vim-bencode` provides three functions. + +### `bencode#Bencode(vimobject)` + +Take a Vim object and return a bencoded string. Do whatever you want with it. + +Example: + + :echo bencode#Bencode([1, "dogs"]) + li1e4:dogse + +### `bencode#Bdecode(somestring)` + +Take a bencoded string and return a Vim Number/String/List/Dict representing the +first bencoded item in the stream. + +If there's more than one thing in the stream the rest will be ignored. + +If you pass this function garbage all bets are off. God help you. + +Example: + + :echo bencode#Bdecode("i1ei2e") + 1 + +### `bencode#BdecodeAll(somestring)` + +Take a bencoded string and return a list of Vim objects of all the things that +were in the bencoded string. + +God help you if you pass this something that's not valid bencode data. + + :echo bencode#BdecodeAll("i1ei2e") + [1, 2] + + +License +======= + +MIT/X11 diff -r 000000000000 -r f4101563743e autoload/bencode.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/bencode.vim Sat Dec 05 22:23:50 2015 +0000 @@ -0,0 +1,124 @@ +" 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 != "" + 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) " {{{ + if a:bstring[0] == 'i' + return s:BdecodeInteger(a:bstring) + elseif a:bstring[0] =~ '[0-9]' + return s:BdecodeString(a:bstring) + elseif a:bstring[0] == 'l' + return s:BdecodeList(a:bstring) + elseif a:bstring[0] == 'd' + return s:BdecodeDict(a:bstring) + else + throw "shits fucked, yo" + endif +endfunction " }}} + +function! s:BdecodeInteger(bstring) " {{{ + let i = 1 + while a:bstring[i] != 'e' + let i += 1 + endwhile + return [0 + a:bstring[1:i - 1], a:bstring[i+1:]] +endfunction " }}} + +function! s:BdecodeString(bstring) " {{{ + let i = 0 + while a:bstring[i] != ':' + let i += 1 + endwhile + let slen = 0 + a:bstring[0:i-1] + return [a:bstring[i+1:i+slen], 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 val = dec[0] + let rest = dec[1] + + let result[key] = val + + if rest[0] == 'e' + " strip off the trailing e from the dict + return [result, rest[1:]] + else + let data = rest + endif + endwhile +endfunction " }}}