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

juzu.io.OutputStream Maven / Gradle / Ivy

/*
 * Copyright 2013 eXo Platform SAS
 *
 * Licensed 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 juzu.io;

import juzu.impl.common.Tools;
import juzu.impl.io.AppendableStream;
import juzu.impl.io.BinaryOutputStream;
import juzu.impl.io.SinkStream;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.LinkedList;

/** @author Julien Viet */
public abstract class OutputStream implements Stream, Closeable {

  /** . */
  public static final int BUFFER_SIZE = 512;

  /** . */
  private LinkedList errors = null;

  public static OutputStream create(Charset charset, Appendable out) {
    return new AppendableStream(charset, out);
  }

  public static OutputStream create(Charset charset, Appendable out, Flushable flushable, Closeable closeable) {
    return new AppendableStream(charset, out, flushable, closeable);
  }

  public static OutputStream create(Charset charset, java.io.OutputStream out) {
    return new BinaryOutputStream(charset, out);
  }

  public static SinkStream create() {
    return SinkStream.INSTANCE;
  }

  public void provide(Chunk chunk) {
    try {
      if (chunk instanceof Chunk.Data) {
        Chunk.Data data = (Chunk.Data)chunk;
        if (data instanceof Chunk.Data.Bytes) {
          append(((Chunk.Data.Bytes)data).data);
        } else if (data instanceof Chunk.Data.Chars) {
          append(CharBuffer.wrap(((Chunk.Data.Chars)data).data));
        } else if (data instanceof Chunk.Data.CharSequence) {
          Chunk.Data.CharSequence cs = (Chunk.Data.CharSequence)data;
          append(cs.data, cs.start, cs.end);
        } else if (data instanceof Chunk.Data.Char) {
          Chunk.Data.Char cs = (Chunk.Data.Char)data;
          append(cs.value);
        } else if (data instanceof Chunk.Data.InputStream) {
          ByteArrayOutputStream baos = Tools.copy(((Chunk.Data.InputStream)data).data, new ByteArrayOutputStream());
          append(baos.toByteArray());
        } else if (data instanceof Chunk.Data.Readable) {
          Readable readable = ((Chunk.Data.Readable)data).data;
          CharBuffer buffer = CharBuffer.allocate(512);
          for (int i = readable.read(buffer);i != -1;i = readable.read(buffer)) {
            buffer.flip();
            append(buffer);
            buffer.clear();
          }
          if (readable instanceof Closeable) {
            Tools.safeClose((Closeable)readable);
          }
        } else {
          throw new IOException("Not yet handled");
        }
      }
    }
    catch (IOException e) {
      reportError(e);
    }
  }

  public void close(Thread.UncaughtExceptionHandler errorHandler) {
    try {
      close();
    }
    catch (Exception e) {
      reportError(e);
    }
    if (errorHandler != null && errors != null) {
      for (Error error : errors) {
        errorHandler.uncaughtException(error.thread, error.uncaught);
      }
    }
  }

  private void reportError(Throwable t) {
    if (errors == null) {
      errors = new LinkedList();
    }
    errors.add(new Error(Thread.currentThread(), t));
  }

  public abstract void append(CharBuffer buffer) throws IOException;

  public abstract void append(CharSequence csq) throws IOException;

  public abstract void append(CharSequence csq, int start, int end) throws IOException;

  public abstract void append(ByteBuffer buffer) throws IOException;

  public abstract void append(char c) throws IOException;

  public abstract void append(byte[] data) throws IOException;

  public abstract void append(byte[] data, int off, int len) throws IOException;

  private static class Error {
    final Thread thread;
    final Throwable uncaught;
    private Error(Thread thread, Throwable uncaught) {
      this.thread = thread;
      this.uncaught = uncaught;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy