All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalax.io.Output.scala Maven / Gradle / Ivy

The newest version!
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2009-2010, Jesse Eichar             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scalax.io

import resource._
import scala.collection.Traversable
import java.io.{File, OutputStream}

/**
 * A trait for objects that can have data written to them. For example an
 * OutputStream and File can be an Output object (or be converted to one).
 *
 * Note: Each invocation of a method will typically open a new stream or
 * channel.  That behaviour can be overridden by the implementation but
 * it is the default behaviour.
 *
 * @author Jesse Eichar
 * @since 1.0
 *
 * @see [[scalax.io.ReadChars]]
 * @see [[scalax.io.Input]]
 * @see [[scalax.io.WriteChars]]
 */
trait Output {

  protected def underlyingOutput : OutputResource[OutputStream]

  /**
   * Write data to the underlying object.  In the case of writing ints and bytes it is often
   * recommended to write arrays of data since normally the underlying object can write arrays
   * of bytes or integers most efficiently.
   *
   * Since Characters require a codec to write to an OutputStream characters cannot be written with this method
   * unless a OutputWriterFunction.CharFunction object is provided as the writer.
   *
   * @see #writeChars for more on writing characters
   *
   * @param data
   *          The data to write to underlying object.  Any data that has a resolvable [[scalax.io.OutputConverter]] can
   *          be written.  See the [[scalax.io.OutputConverter]] object for the defined [[scalax.io.OutputConverter]]
   *          implementations and classes to assist implementing more.
   * @param writer
   *          The strategy used to write the data to the underlying object.  Many standard data-types are implicitly
   *          resolved and do not need to be supplied
   */
  def write[T](data:T)(implicit writer:OutputConverter[T]):Unit = underlyingOutput.foreach {writer(_,data)}

  /**
   * Since the [[scalax.io.OutputConverter]] object defined for writing Ints encodes Ints using 4 bytes this method
   * is provided to simply write an array of Ints as if they are Bytes.  In other words just taking the first
   * byte.  This is pretty common in Java.io style IO.  IE
   *
   * {{{ outputStream.write(1) }}}
   *
   * 1 is written as a single byte.
   */
  def writeIntsAsBytes(data: Int*) = write(data)(OutputConverter.TraversableIntAsByteConverter)
  /**
  * Writes a string.
  *
  * @param string
  *          the data to write
  * @param codec
  *          the codec of the string to be written. The string will
  *          be converted to the encoding of {@link sourceCodec}
  *          Default is sourceCodec
  */
  def write(string: String)(implicit codec: Codec): Unit = {
      underlyingOutput.writer writeString string
  }

  /*
   * Writes Characters to the underlying object.
   *
   * @param characters the characters to write
   * @param codec the codec to use for encoding the characters
   */
  def writeChars(characters: TraversableOnce[Char])(implicit codec: Codec) : Unit = {
    write(characters)(OutputConverter.charsToOutputFunction)
  }

  /**
  * Write several strings.
  *
  * @param strings
  *          The data to write
  * @param separator
  *          A string to add between each string.
  *          It is not added to the before the first string
  *          or after the last.
  * @param codec
  *          The codec of the strings to be written. The strings will
  *          be converted to the encoding of {@link sourceCodec}
  */
  def writeStrings(strings: Traversable[String], separator:String = "")(implicit codec: Codec): Unit = {
      underlyingOutput.writer.writeStrings(strings,separator)
  }
}

object Output {
  class AsOutput(op: => Output) {
    /** An object to an Output object */
    def asOutput: Output = op
  }

  /**
   * Wrap an arbitraty object as and AsOutput object allowing the object to be converted to an Output object.
   *
   * The possible types of src are the subclasses of [[scalax.io.AsOutputConverter]]
   */
  implicit def asOutputConverter[B](src:B)(implicit converter:AsOutputConverter[B]) =
    new AsOutput(converter.toOutput(src))
    
  /**
   * Used by the [[scalax.io.Output]] object for converting an arbitrary object to an Output Object
   *
   * Note: this is a classic use of the type class pattern
   */
  trait AsOutputConverter[-A] {
    def toOutput(t:A) : Output
  }
  
  /**
   * contains several implementations of [[scalax.io.AsOutputConverter]].  They will be implicitely resolved allowing
   * a user of the library to simple call A.asOutput and the converter will be found without the user needing to look up these classes
   */
  object AsOutputConverter {
  
    /**
     * Converts a File to an Output object
     */
    implicit object FileConverter extends AsOutputConverter[File]{
      def toOutput(file: File) = Resource.fromFile(file)
    }

    /**
     * Converts a OutputStream to an Output object
     */
    implicit object OutputStreamConverter extends AsOutputConverter[OutputStream]{
      def toOutput(out: OutputStream) = Resource.fromOutputStream(out)
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy