f4101563743e

Initial commit
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 05 Dec 2015 22:23:50 +0000
parents
children 1f8c437ae3c8
branches/tags (none)
files README.markdown autoload/bencode.vim

Changes

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