views:

623

answers:

2

Hello :)

I need to port code from Java to C#. In the Java code, the methods "ByteBuffer.flip()" and "ByteBuffer.slice" is used, and I don't know how to translate this.

I've read this question (http://stackoverflow.com/questions/607587/an-equivalent-of-javax-nio-buffer-flip-in-c), but although an answer is given, I cannot figure how to apply it. According to Tom Hawtin, I should "Set the limit to the current position and then set the position to zero" in the underlying array. I am unsure as of how to change these values. (If you could explain the underlying logic, it would help me a lot :)

As for the ByteBuffer.slice, I have no clue on how to translate it.

EDIT: If it can be clearer with the actual code, I'll post it:

Java:

ByteBuffer buff;
buff.putShort((short) 0);
buff.put(customArray);
buff.flip();
buff.putShort((short) 0);
ByteBuffer b = buff.slice();

short size = (short) (customFunction(b) + 2);
buff.putShort(0, size);
buff.position(0).limit(size);

So far, my translation in C#.NET:

BinaryWriter b = new BinaryWriter(); //ByteBuffer buff;
b.Write((short)0); // buff.putShort((short) 0);
b.Write(paramStream.ToArray()); // buff.put(customArray);
b.BaseStream.SetLength(b.BaseStream.Position); // buff.flip; (not sure)
b.BaseStream.Position = 0; // buff.flip; too (not sure)
b.Write((short)0); // buff.putShort((short) 0)
??? // ByteBuffer b = buff.slice();

// Not done but I can do it, short size = (short) (customFunction(b) + 2);
??? // How do I write at a particular position?
??? // buff.position(0).limit(size); I don't know how to do this

Thank you!

EDIT: Changed b.BaseStream.SetLength(b.BaseStream.Length); to b.BaseStream.SetLength(b.BaseStream.Position);, based on the Java docs.

+1  A: 

(See See http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#slice%28%29 and http://java.sun.com/javase/6/docs/api/java/nio/Buffer.html#flip%28%29 for java's calls)

Flip is a quick way to reset the buffer. So for example (pseudocode)

void flip()
{
   Length = currentPos;
   currentPos = 0;
}

Allows you to quickly setup the buffer you presumably just wrote to for reading from the beginning.

Update: Splice is a bit trickier due to the requirement that "Changes to this buffer's content will be visible in the new buffer, and vice versa; the two buffers' position, limit, and mark values will be independent". There unfortunately is no concept of a shared portion of buffer (that i know of - theres always using arrays, detailed below) without making your own class. The closest thing you could do is this:

Old Code:

ByteBuffer b = buff.slice();

New Code (assuming a List)

List<Byte> b= buff;
int bStart = buffPos; // buffPos is your way of tracking your mark

the downside to the code above is that there is no way for c# to hold the new starting point of the new buffer and still share it. You'll have to manually use the new starting point whenever you do anything, from for loops (for i=bStart;...) to indexing (newList[i + bStart]...)

Your other option is to do use Byte[] arrays instead, and do something like this:

Byte[] b = &buff[buffPos];

... however that requires unsafe operations to be enabled, and I cannot vouch for its saftey, due to the garbage collector and my avoidance of the "unsafe" features.

Outside of that, theres always making your own ByteBuffer class.

cyberconte
Thank you for your answer. Would you please read the post again, including the code examples? I think I did a correct job on the the "flip()" equivalent, correct me if I'm wrong. I'll try to implement your slice() method now. I'll post it and hope it's good. :)
Lazlo
I have modified my flip method to fit yours. I think it is more appropriate now. I'm still waiting for your slice method. Thanks for helping. :)
Lazlo
I updated it again, I hope it helps.
cyberconte
+1  A: 

Untested, but if I understand the java bits correctly, this would give you an idea on how to implement.

public class ByteBuffer {

 private int _Position;
 private int _Capacity;
 private byte[] _Buffer;

 private int _Start;


 private ByteBuffer(int capacity, int position, int start, byte[] buffer) {
  _Capacity = capacity;
  _Position = position;
  _Start = start;
  _Buffer = buffer;
 }

 public ByteBuffer(int capacity) : this(capacity, 0 , 0, new byte[capacity]) {
 }


 public void Write(byte item) {

  if (_Position >= _Capacity) {
   throw new InvalidOperationException();
  }
  _Buffer[_Start + _Position++] = item;
 }

 public byte Read() {

  if (_Position >= _Capacity) {
   throw new InvalidOperationException();
  }

  return _Buffer[_Start + _Position++];
 }

 public void Flip() {

  _Capacity = _Position;
  _Position = _Start;
 }

 public ByteBuffer Slice() {
  return new ByteBuffer(_Capacity-_Position, 0, _Position, _Buffer);
 }
}
MaLio
I might try creating my own ByteBuffer class, but it really is hard to do.
Lazlo