001/* 002 * Copyright 2013 Chris Pheby 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.jadira.lang.io.buffered; 017 018import java.io.OutputStream; 019import java.nio.ByteBuffer; 020import java.nio.ByteOrder; 021 022/** 023 * A BufferedOutputStream where the buffer is provided by a NIO DirectByteBuffer. Use this class as an alternative to {@link java.io.BufferedOutputStream} 024 */ 025public class DirectBytesBufferedOutputStream extends AbstractBufferedOutputStream { 026 027 private ByteBuffer buf; 028 029 /** 030 * Creates a new instance with the default buffer size 031 * @param out OutputStream to be decorated 032 * @see java.io.BufferedOutputStream#BufferedOutputStream(OutputStream) 033 */ 034 public DirectBytesBufferedOutputStream(OutputStream out) { 035 this(out, DEFAULT_BUFFER_SIZE); 036 } 037 038 /** 039 * Creates a new instance with the given buffer size in bytes. 040 * @param out OutputStream to be decorated 041 * @param size The size of the buffer in bytes 042 * @see java.io.BufferedOutputStream#BufferedOutputStream(OutputStream, int) 043 */ 044 public DirectBytesBufferedOutputStream(OutputStream out, int size) { 045 super(out); 046 if (size <= 0) { 047 throw new IllegalArgumentException("Buffer size may not be less than or equal to zero"); 048 } 049 buf = ByteBuffer.allocateDirect(size); 050 } 051 052 /** 053 * Creates a new instance with the given buffer size in bytes. 054 * @param out OutputStream to be decorated 055 * @param size The size of the buffer in bytes 056 * @param useNativeByteOrder If true, native byte ordering will be used 057 * @see java.io.BufferedOutputStream#BufferedOutputStream(OutputStream, int) 058 */ 059 public DirectBytesBufferedOutputStream(OutputStream out, int size, boolean useNativeByteOrder) { 060 this(out, size); 061 buf.order(ByteOrder.nativeOrder()); 062 } 063 064 /** 065 * Creates a new instance with the given buffer size in bytes. 066 * @param out OutputStream to be decorated 067 * @param size The size of the buffer in bytes 068 * @param byteOrder Indicates the byte order to be used. 069 * @see java.io.BufferedOutputStream#BufferedOutputStream(OutputStream, int) 070 */ 071 public DirectBytesBufferedOutputStream(OutputStream out, int size, ByteOrder byteOrder) { 072 this(out, size); 073 buf.order(byteOrder); 074 } 075 076 @Override 077 protected byte[] bytes() { 078 return buf.array(); 079 } 080 081 @Override 082 protected void put(byte b) { 083 put(b); 084 } 085 086 @Override 087 protected void put(int count, byte[] b, int off, int len) { 088 if (off == 0) { 089 buf.put(b, count, len); 090 } else { 091 byte[] bc = new byte[len]; 092 System.arraycopy(b, off, bc, 0, len); 093 buf.put(bc, count, len); 094 } 095 } 096 097 @Override 098 protected int limit() { 099 return buf.limit(); 100 } 101 102 @SuppressWarnings("restriction") 103 @Override 104 protected void clean() { 105 106 if (buf == null) { 107 return; 108 } 109 110 sun.misc.Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buf).cleaner(); 111 112 if (cleaner != null) { 113 cleaner.clean(); 114 } 115 } 116}