Writing With Typeclasses

Details on how output is converted to bytes and how the design can be extended and used

Custom Data Types

Declaring custom converters.

Naturally being able to write objects other than those defined by Scala IO can be beneficial and it is a simple process. All that is needed is a new implementation of a OutputConverter which is imported into scopoe.

The examples below show two design patterns.

    import scalax.io._
    import Resource._
    import OutputConverter._
    val out = fromFileString("out")
    // Simplest design pattern is to create a new implicit object in scope
    implicit object DateConverter extends OutputConverter[Date] {
      def sizeInBytes = 8
      def toBytes(data: Date) = LongConverter.toBytes(data.getTime)
    }

    out.write(new Date(2012,01,01))

    // write, append, patch and insert all follow the same pattern
    out.append(3)

    // The second (an more reusable design pattern) is to create an object
    // that contains the converters that you want to use and then they can be
    // reused through out the code base.
    object CustomConverters {
      case class User(name:String,id:Int)
      // first you need converter for a collection of your type
      implicit object UserTraversableConverter extends OutputConverter[TraversableOnce[User]] {
        def sizeInBytes = 2

        def toBytes(users: TraversableOnce[User]):TraversableOnce[Byte] = {
          // Create a single instance of a buffer for encoding the id value.
          val idBuffer = new OutputConverter.Buffer[Int](4,(byteBuffer,data) => {byteBuffer.putInt(data)})
          users.toIterator.flatMap{
            user =>
              user.name.getBytes("ASCII").toIterator ++ idBuffer.put(user.id)
          }
        }
      }
      // next you need converters for the basic type and arrays
      implicit object UserConverter extends NonTraversableAdapter(UserTraversableConverter)
      implicit object UserArrayConverter extends ArrayAdapter(UserTraversableConverter)
    }

    // finally you can import the definitions into scope and write away
    import CustomConverters._

    out.write(User("Jesse Eichar",888888))
    out.insert(2,User("Jesse",23421))