mharrys / bencode

Encoder and decoder for the BitTorrent protocol "Bencode"

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bencode

Encoder and decoder for the BitTorrent protocol "Bencode".

Run tests

This assumes sbt is installed and exist in your path.

$ sbt
... text omitted
> test

Examples

Remember to import bencode._ before running the examples. Run console once inside sbt.

Encode

scala> encode(BInt(42))
=> i42e

scala> encode(BStr("foo"))
=> 3:foo

scala> encode(BList(BInt(42), BStr("foo")))
=> li42e3:fooe

scala> encode(BDict("foo" -> BInt(42)))
=> d3:fooi42ee

Decode

scala> decode("i42e")
=> Right(42)

scala> decode("3:foo")
=> Right(foo)

scala> decode("li42e3:fooe")
=> Right([42 foo])

scala> decode("d3:fooi42ee")
=> Right({foo -> 42})

Zipper

The decoded results can easily be explored with a zipper.

val ds = decode("li42eld3:food3:barl5:helloeeeei100ee").right.get
// => [42 [{foo -> {bar -> [hello]}}] 100]

val z = BValueZipper(ds, Nil)
// => BValueZipper([42 [{foo -> {bar -> [hello]}}] 100],List())

val result = for {
  z2 <- z.downList
  z3 <- z2.forward
  z4 <- z3.downList
  z5 <- z4.downDict("foo")
  z6 <- z5.downDict("bar")
  z7 <- z6.downList
  // replace the nested string "hello" with "world"
  z8 = z7.set(BStr("world"))
  z9 <- z8.up
  z10 <- z9.up
  // append new int to nested dictionary
  z11 <- z10.putDict("zot", BInt(1337))
} yield (z11)

// walk up from dictionary focus to root and print result
result match {
  case Some(z) =>
    println(z.root.focus)
  case None =>
    println("Failure")
}
// => [42 [{foo -> {bar -> [world] zot -> 1337}}] 100]
//                          ^^^^^  ^^^^^^^^^^^
//                            |         |
//                            |         +- new item
//                            + hello replaced

About

Encoder and decoder for the BitTorrent protocol "Bencode"

License:GNU Lesser General Public License v3.0


Languages

Language:Scala 100.0%