/*
* 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.cassandra.io.util;
import java.io.DataOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UTFDataFormatException;
public abstract class AbstractDataOutput extends OutputStream implements DataOutput
{
/*
!! DataOutput methods below are copied from the implementation in Apache Harmony RandomAccessFile.
*/
/**
* Writes the entire contents of the byte array <code>buffer</code> to
* this RandomAccessFile starting at the current file pointer.
*
* @param buffer
* the buffer to be written.
*
* @throws IOException
* If an error occurs trying to write to this RandomAccessFile.
*/
public void write(byte[] buffer) throws IOException {
write(buffer, 0, buffer.length);
}
/**
* Writes <code>count</code> bytes from the byte array <code>buffer</code>
* starting at <code>offset</code> to this RandomAccessFile starting at
* the current file pointer..
*
* @param buffer
* the bytes to be written
* @param offset
* offset in buffer to get bytes
* @param count
* number of bytes in buffer to write
*
* @throws IOException
* If an error occurs attempting to write to this
* RandomAccessFile.
* @throws IndexOutOfBoundsException
* If offset or count are outside of bounds.
*/
public abstract void write(byte[] buffer, int offset, int count) throws IOException;
/**
* Writes the specified byte <code>oneByte</code> to this RandomAccessFile
* starting at the current file pointer. Only the low order byte of
* <code>oneByte</code> is written.
*
* @param oneByte
* the byte to be written
*
* @throws IOException
* If an error occurs attempting to write to this
* RandomAccessFile.
*/
public abstract void write(int oneByte) throws IOException;
/**
* Writes a boolean to this output stream.
*
* @param val
* the boolean value to write to the OutputStream
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeBoolean(boolean val) throws IOException {
write(val ? 1 : 0);
}
/**
* Writes a 8-bit byte to this output stream.
*
* @param val
* the byte value to write to the OutputStream
*
* @throws java.io.IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeByte(int val) throws IOException {
write(val & 0xFF);
}
/**
* Writes the low order 8-bit bytes from a String to this output stream.
*
* @param str
* the String containing the bytes to write to the OutputStream
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeBytes(String str) throws IOException {
byte bytes[] = new byte[str.length()];
for (int index = 0; index < str.length(); index++) {
bytes[index] = (byte) (str.charAt(index) & 0xFF);
}
write(bytes);
}
/**
* Writes the specified 16-bit character to the OutputStream. Only the lower
* 2 bytes are written with the higher of the 2 bytes written first. This
* represents the Unicode value of val.
*
* @param val
* the character to be written
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeChar(int val) throws IOException {
write((val >>> 8) & 0xFF);
write((val >>> 0) & 0xFF);
}
/**
* Writes the specified 16-bit characters contained in str to the
* OutputStream. Only the lower 2 bytes of each character are written with
* the higher of the 2 bytes written first. This represents the Unicode
* value of each character in str.
*
* @param str
* the String whose characters are to be written.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeChars(String str) throws IOException {
byte newBytes[] = new byte[str.length() * 2];
for (int index = 0; index < str.length(); index++) {
int newIndex = index == 0 ? index : index * 2;
newBytes[newIndex] = (byte) ((str.charAt(index) >> 8) & 0xFF);
newBytes[newIndex + 1] = (byte) (str.charAt(index) & 0xFF);
}
write(newBytes);
}
/**
* Writes a 64-bit double to this output stream. The resulting output is the
* 8 bytes resulting from calling Double.doubleToLongBits().
*
* @param val
* the double to be written.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeDouble(double val) throws IOException {
writeLong(Double.doubleToLongBits(val));
}
/**
* Writes a 32-bit float to this output stream. The resulting output is the
* 4 bytes resulting from calling Float.floatToIntBits().
*
* @param val
* the float to be written.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeFloat(float val) throws IOException {
writeInt(Float.floatToIntBits(val));
}
/**
* Writes a 32-bit int to this output stream. The resulting output is the 4
* bytes, highest order first, of val.
*
* @param val
* the int to be written.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public void writeInt(int val) throws IOException {
write((val >>> 24) & 0xFF);
write((val >>> 16) & 0xFF);
write((val >>> 8) & 0xFF);
write((val >>> 0) & 0xFF);
}
/**
* Writes a 64-bit long to this output stream. The resulting output is the 8
* bytes, highest order first, of val.
*
* @param val
* the long to be written.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public void writeLong(long val) throws IOException {
write((int)(val >>> 56) & 0xFF);
write((int)(val >>> 48) & 0xFF);
write((int)(val >>> 40) & 0xFF);
write((int)(val >>> 32) & 0xFF);
write((int)(val >>> 24) & 0xFF);
write((int)(val >>> 16) & 0xFF);
write((int)(val >>> 8) & 0xFF);
write((int)(val >>> 0) & 0xFF);
}
/**
* Writes the specified 16-bit short to the OutputStream. Only the lower 2
* bytes are written with the higher of the 2 bytes written first.
*
* @param val
* the short to be written
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public void writeShort(int val) throws IOException {
writeChar(val);
}
/**
* Writes the specified String out in UTF format.
*
* @param str
* the String to be written in UTF format.
*
* @throws IOException
* If an error occurs attempting to write to this
* DataOutputStream.
*/
public final void writeUTF(String str) throws IOException {
int utfCount = 0, length = str.length();
for (int i = 0; i < length; i++) {
int charValue = str.charAt(i);
if (charValue > 0 && charValue <= 127) {
utfCount++;
} else if (charValue <= 2047) {
utfCount += 2;
} else {
utfCount += 3;
}
}
if (utfCount > 65535) {
throw new UTFDataFormatException(); //$NON-NLS-1$
}
byte utfBytes[] = new byte[utfCount + 2];
int utfIndex = 2;
for (int i = 0; i < length; i++) {
int charValue = str.charAt(i);
if (charValue > 0 && charValue <= 127) {
utfBytes[utfIndex++] = (byte) charValue;
} else if (charValue <= 2047) {
utfBytes[utfIndex++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
} else {
utfBytes[utfIndex++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
}
}
utfBytes[0] = (byte) (utfCount >> 8);
utfBytes[1] = (byte) utfCount;
write(utfBytes);
}
}