/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.avro.io;

import java.io.IOException;
import java.io.OutputStream;

/**
 * An {@link Encoder} for Avro's binary encoding that does not buffer output.
 * <p/>
 * This encoder does not buffer writes, and as a result is slower than
 * {@link BufferedBinaryEncoder}. However, it is lighter-weight and useful when the
 * buffering in BufferedBinaryEncoder is not desired and/or the Encoder is
 * very short lived.
 * <p/>
 * To construct, use
 * {@link EncoderFactory#directBinaryEncoder(OutputStream, BinaryEncoder)}
 *  <p/>
 * DirectBinaryEncoder is not thread-safe
 * @see BinaryEncoder
 * @see EncoderFactory
 * @see Encoder
 * @see Decoder
 */
public class DirectBinaryEncoder extends BinaryEncoder {
  private OutputStream out;
  // the buffer is used for writing floats, doubles, and large longs.
  private final byte[] buf = new byte[12];

  /** Create a writer that sends its output to the underlying stream
   *  <code>out</code>.
   **/
  DirectBinaryEncoder(OutputStream out) {
    configure(out);
  }

  DirectBinaryEncoder configure(OutputStream out) {
    if (null == out) throw new NullPointerException("OutputStream cannot be null!");
    this.out = out;
    return this;
  }

  @Override
  public void flush() throws IOException {
    out.flush();
  }

  @Override
  public void writeBoolean(boolean b) throws IOException {
    out.write(b ? 1 : 0);
  }

  /* buffering is slower for ints that encode to just 1 or
   * two bytes, and and faster for large ones.
   * (Sun JRE 1.6u22, x64 -server) */
  @Override
  public void writeInt(int n) throws IOException {
    int val = (n << 1) ^ (n >> 31);
    if ((val & ~0x7F) == 0) {
      out.write(val);
      return;
    } else if ((val & ~0x3FFF) == 0) {
      out.write(0x80 | val);
      out.write(val >>> 7);
      return;
    }
    int len = BinaryData.encodeInt(n, buf, 0);
    out.write(buf, 0, len);
  }

  /* buffering is slower for writeLong when the number is small enough to
   * fit in an int.
   * (Sun JRE 1.6u22, x64 -server) */
  @Override
  public void writeLong(long n) throws IOException {
    long val = (n << 1) ^ (n >> 63); // move sign to low-order bit
    if ((val & ~0x7FFFFFFFL) == 0) {
      int i = (int) val;
      while ((i & ~0x7F) != 0) {
        out.write((byte)((0x80 | i) & 0xFF));
        i >>>= 7;
      }
      out.write((byte)i);
      return;
    }
    int len = BinaryData.encodeLong(n, buf, 0);
    out.write(buf, 0, len);
  }

  @Override
  public void writeFloat(float f) throws IOException {
    int len = BinaryData.encodeFloat(f, buf, 0);
    out.write(buf, 0, len);
  }

  @Override
  public void writeDouble(double d) throws IOException {
    byte[] buf = new byte[8];
    int len = BinaryData.encodeDouble(d, buf, 0);
    out.write(buf, 0, len);
  }

  @Override
  public void writeFixed(byte[] bytes, int start, int len) throws IOException {
    out.write(bytes, start, len);
  }

  @Override
  protected void writeZero() throws IOException {
    out.write(0);
  }

  @Override
  public int bytesBuffered() {
    return 0;
  }

}
