# 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 )