Bitwise Operation Issues

[s]I can’t figure out why this isn’t writing/reading properly.

Basically what I’m trying to do is write numbers to an array of bytes, and then read them. It’s pretty self-explanatory if you take a look.

Any help would be greatly appreciated.[/s]

Test.java:

import org.valhalla.io.Payload;

public class Test
{

	public Test()
	{
		try {
			Payload p = new Payload(32);
			p.putLong(0x7fffffffffffffffL);
			p.putInt(0xFFFFFF);
			p.putShort(0xFFFF);
			p.put(0xFF);
			p.putFloat(1.234f);
			
			p.reset(); // Resets the position back to zero.
			
			System.out.println("Value: " + p.getLong() + ", " + p.getInt() + ", " + p.getShort() + ", " + p.get() + ", " + p.getFloat());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new Test();
	}

}

Output:

Value: -1, 16777215, 65535, 255, 1.234

Payload.java:

package org.valhalla.io;

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

public class Payload
{

	private byte[] data;
	private int position = 0;
	private OutputStream out;

	public Payload(int size)
	{
		this.data = new byte[size];
	}

	public Payload(OutputStream out, int size)
	{
		this.out = out;
		this.data = new byte[size];
	}

	public Payload(byte[] data)
	{
		this.data = data;
	}

	public int get() {
		return (data[position++] & 0xFF);
	}

	public Payload put(int i) {
		this.data[position++] = (byte) (i & 0xFF);
		return this;
	}

	public boolean getBoolean() {
		return get() == 1;
	}

	public Payload putBoolean(boolean flag) {
		this.put(flag ? 1 : 0);
		return this;
	}

	public int getShort() {
		return get() << 8 | get();
	}

	public Payload putShort(int i) {
		put(i >>> 8);
		put(i);
		return this;
	}

	public int getInt() {
		return getShort() << 16 | getShort();
	}

	public Payload putInt(int i) {
		putShort(i >>> 16);
		putShort(i);
		return this;
	}

	public long getLong() {
		return getInt() << 32L | getInt();
	}

	public Payload putLong(long l) {
		putInt((int) (l >>> 32L));
		putInt((int) l);
		return this;
	}

	public double getDouble() {
		return Double.longBitsToDouble(getLong());
	}

	public Payload putDouble(double d) {
		this.putLong(Double.doubleToLongBits(d));
		return this;
	}

	public float getFloat() {
		return Float.intBitsToFloat(getInt());
	}

	public Payload putFloat(float f) {
		this.putInt(Float.floatToIntBits(f));
		return this;
	}

	public Payload reset() {
		this.position = 0;
		return this;
	}

	public Payload clean() {
		for (int i = 0; i < this.data.length; i++) {
			this.data[i] = 0;
		}
		return this;
	}

	public Payload flush() throws IOException {
		if (this.getOutputStream() == null) {
			System.out.println("Warning: Attempted to flush payload with no output stream!");
			return this;
		}
		out.write(this.data);
		return this.clean().reset();
	}

	public Payload setData(byte[] data) {
		this.data = data;
		return this;
	}

	public final byte[] getData() {
		return this.data;
	}

	public Payload setOutputStream(OutputStream out) {
		this.out = out;
		return this;
	}

	public OutputStream getOutputStream() {
		return this.out;
	}

}

You clean your payload on every get, since the Pair constructor calls clean() on it…


      public Pair(Payload payload, T value)
      {
         this.payload = payload;
         this.value = value;
@@         this.payload.clean().reset();
      }

Unoffensive tip: learn how stepping and variable inspection work in your IDEs debugger :wink:

Btw. this code produces a lot of garbage (memory management wise), since you effectively creating multiple temporary Pair objects on every get call. Better refactor the gets to some equivalents of your put mechanism.

Thanks for this, I don’t know what I was thinking when I put that in the constructor. Completely my fault for working on this at 3AM in the morning.

Also I hope I refactored properly, I’ve edited the original post with the updated source. :slight_smile:

Edit: Also it appears getDouble or putDouble may not be working properly.

			Payload p = new Payload(32);
@@			 p.putDouble(123.10d);
			p.putFloat(123.10f);
			p.putLong(0x73FD73FDL);

			p.reset();

			System.out.println("Double: " + p.getDouble() + ", Float: " + p.getFloat() + ", Long: " + Long.toHexString(p.getLong()));

Output:

Double: 8.49591604E-315, Float: 123.1, Long: 73fd73fd