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

wycc.io.BinaryOutputStream Maven / Gradle / Ivy

// Copyright 2011 The Whiley Project Developers
//
// 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 wycc.io;

import java.io.*;

public class BinaryOutputStream extends OutputStream {
	protected OutputStream output;
	protected int value;
	protected int count;
	protected int length;

	/**
	 * Write out data in big-endian format.
	 * @param output
	 */
	public BinaryOutputStream(OutputStream output) {
		this.output = output;
	}

	/**
	 * Get number of bytes written.
	 * @return
	 */
	public int length() {
		return length;
	}

	/**
	 * Write an unsigned integer value using 8bits using a big-endian encoding.
	 *
	 * @param w
	 * @throws IOException
	 */
	@Override
	public void write(int i) throws IOException {
		if(count == 0) {
			output.write(i & 0xFF);
			length++;
		} else {
			write_un(i & 0xFF,8);
		}
	}

	@Override
	public void write(byte[] bytes) throws IOException {
		for(byte b : bytes) {
			write(b);
		}
	}

	@Override
	public void write(byte[] bytes, int offset, int length) throws IOException {
		for(;offset < length;++offset) {
			write(bytes[offset]);
		}
	}

	/**
	 * Write an unsigned integer value using 8bits using a big-endian encoding.
	 *
	 * @param w
	 * @throws IOException
	 */
	public void write_u8(int w) throws IOException {
		if(count == 0) {
			output.write(w & 0xFF);
			length++;
		} else {
			write_un(w & 0xFF,8);
		}
	}

	/**
	 * Write an unsigned integer value using 16bits using a big-endian encoding.
	 *
	 * @param w
	 * @throws IOException
	 */
	public void write_u16(int w) throws IOException {
		write_u8((w >> 8) & 0xFF);
		write_u8(w & 0xFF);
	}

	/**
	 * Write an unsigned integer value using 32bits using a big-endian encoding.
	 *
	 * @param w
	 * @throws IOException
	 */
	public void write_u32(int w) throws IOException {
		write_u8((w >> 24) & 0xFF);
		write_u8((w >> 16) & 0xFF);
		write_u8((w >> 8) & 0xFF);
		write_u8(w & 0xFF);
	}

	/**
	 * Write an unsigned integer value using a variable amount of space. The
	 * value is split into 4 bit (big-endian) chunks, where the msb of each
	 * chunk is a flag indicating whether there are more chunks. Therefore,
	 * values between 0 and 7 fit into 4 bits. Similarly, values between 8 and
	 * 63 fit into 8 bits, etc
	 *
	 * @param w
	 *            --- number to convert (which cannot be negative)
	 * @throws IOException
	 */
	public void write_uv(int w) throws IOException {
		if(w < 0) {
			throw new IllegalArgumentException("cannot write negative number in a variable amount of space");
		}
		do {
			int t = w & 7;
			w = w >> 3;
			if(w != 0) {
				write_un(8|t,4);
			} else {
				write_un(t,4);
			}
		} while(w != 0);
	}

	/**
	 * Write an unsigned integer value using n bits using a big-endian encoding.
	 *
	 * @param w
	 * @throws IOException
	 */
	public void write_un(int bits, int n) throws IOException {
		int mask = 1;
		for(int i=0;i> 1;
		if(bit) {
			value |= 128;
		}
		count = count + 1;
		if(count == 8) {
			count = 0;
			output.write(value);
			length++;
			value = 0;
		}
	}

	/**
	 * Pad out stream to nearest byte boundary
	 * @throws IOException
	 */
	public void pad_u8() throws IOException {
		if (count > 0) {
			output.write(value >>> (8-count));
			length++;
			value = 0;
			count = 0;
		}
	}

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

	@Override
	public void flush() throws IOException {
		if(count != 0) {
			// In this case, we're closing but we have a number of bits left to
			// write. This means we have to pad out the remainder of a byte.
			// Instead of padding with zeros, I pad with ones. The reason for
			// this is that it forces an EOF when reading back in with read_uv().
			value = value >>> (8-count);
			int mask = 0xff & ((~0) << count);
			value = value | mask;
			output.write(value);
			length++;
		}
	}

	public static String bin2str(int v) {
		if(v == 0) {
			return "0";
		}
		int mask = 1 << 31;
		String r = "";
		boolean leading = true;
		for(int i=0;i!=32;++i) {
			if((v&mask) != 0) {
				r = r + "1";
				leading=false;
			} else if(!leading) {
				r = r + "0";
			}
			v = v << 1;
		}
		return r;
	}

	public static void main(String[] argss) {
		try {
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			BinaryOutputStream binout = new BinaryOutputStream(bout);

			binout.write_uv(11);
			binout.flush();
			binout.close();
			ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
			BinaryInputStream binin = new BinaryInputStream(bin);
			while(true) {
				boolean bit = binin.read_bit();
				System.out.println(bit ? "1" : "0");
			}
			//binin.close();
		} catch(IOException e) {

		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy