Created
June 20, 2009 19:09
-
-
Save nrk/133246 to your computer and use it in GitHub Desktop.
Dead-simple bencoding using the Io language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # See http://en.wikipedia.org/wiki/Bencode for reference | |
| # encoding objects | |
| Number asBencode := method( | |
| Sequence with("i", self asString, "e") | |
| ) | |
| Sequence asBencode := method( | |
| Sequence with(self size asString, ":", self) | |
| ) | |
| List asBencode := method( | |
| Sequence with("l", self map(value, value asBencode) join, "e") | |
| ) | |
| Map asBencode := method( | |
| Sequence with("d", self keys sort map(key, key asBencode .. self at(key) asBencode) join, "e") | |
| ) | |
| # decoding from string | |
| Sequence fromBencode := method( | |
| offset := 0 | |
| endOfCollection := block( | |
| if (self at(offset) asCharacter == "e", offset = offset + 1) | |
| ) | |
| decodeMap := block( | |
| map := Map clone | |
| while (true, | |
| if (endOfCollection call, break) | |
| map atPut(decode call, decode call) | |
| ) | |
| map | |
| ) | |
| decodeList := block( | |
| collection := List clone | |
| while (true, | |
| if (endOfCollection call, break) | |
| collection append(decode call) | |
| ) | |
| collection | |
| ) | |
| decodeNumber := block(delimiter, | |
| delimiter ifNil(delimiter := "e") | |
| number := Sequence clone | |
| while ((digit := self at(offset) asCharacter) != delimiter, | |
| number appendSeq(digit) | |
| offset = offset + 1 | |
| ) | |
| offset = offset + 1 | |
| number asNumber | |
| ) | |
| decodeString := block( | |
| offset = offset - 1 | |
| stringSize := decodeNumber call(":") | |
| self exSlice(offset, (offset = offset + stringSize)) | |
| ) | |
| decodingMap := Map with( | |
| "d", decodeMap, | |
| "l", decodeList, | |
| "i", decodeNumber, | |
| "0", decodeString, | |
| "1", decodeString, | |
| "2", decodeString, | |
| "3", decodeString, | |
| "4", decodeString, | |
| "5", decodeString, | |
| "6", decodeString, | |
| "7", decodeString, | |
| "8", decodeString | |
| ) | |
| decode := block( | |
| char := self at(offset) asCharacter | |
| offset = offset + 1 | |
| decodingMap at(char)? call | |
| ) | |
| decode call | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment