get root
This commit is contained in:
parent
600d3c134b
commit
787559680c
7 changed files with 136 additions and 11 deletions
1
Makefile
1
Makefile
|
@ -1,6 +1,7 @@
|
|||
CXX=g++ -std=c++11
|
||||
|
||||
CAPNP_SOURCES=\
|
||||
src/capnp/AnyPointer.java\
|
||||
src/capnp/FieldSize.java\
|
||||
src/capnp/FromStructReader.java\
|
||||
src/capnp/InputStreamMessageReader.java\
|
||||
|
|
17
src/capnp/AnyPointer.java
Normal file
17
src/capnp/AnyPointer.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package capnp;
|
||||
|
||||
public class AnyPointer {
|
||||
|
||||
public static class Reader {
|
||||
public PointerReader reader;
|
||||
|
||||
public Reader(PointerReader reader) {
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
public <T> T getAsStruct(FromStructReader<T> factory) {
|
||||
return factory.fromStructReader(this.reader.getStruct());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,24 +3,75 @@ package capnp;
|
|||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public class InputStreamMessageReader {
|
||||
static MessageReader create(InputStream is) throws IOException {
|
||||
byte[] firstWord = new byte[8];
|
||||
|
||||
static byte[] readExact(InputStream is, int length) throws IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < 8) {
|
||||
int n = is.read(firstWord, bytesRead, 8 - bytesRead);
|
||||
if (n < 0) {
|
||||
while (bytesRead < length) {
|
||||
int r = is.read(bytes, bytesRead, length - bytesRead);
|
||||
if (r < 0) {
|
||||
throw new IOException("premature EOF");
|
||||
}
|
||||
bytesRead += n;
|
||||
bytesRead += r;
|
||||
}
|
||||
|
||||
ByteBuffer.wrap(firstWord);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static ByteBuffer makeByteBuffer(byte[] bytes) {
|
||||
ByteBuffer result = ByteBuffer.wrap(bytes);
|
||||
result.order(ByteOrder.LITTLE_ENDIAN);
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Error();
|
||||
public static MessageReader create(InputStream is) throws IOException {
|
||||
ByteBuffer firstWord = makeByteBuffer(readExact(is, 8));
|
||||
|
||||
int segmentCount = 1 + firstWord.getInt();
|
||||
|
||||
int segment0Size = 0;
|
||||
if (segmentCount > 0) {
|
||||
segment0Size = firstWord.getInt(1);
|
||||
}
|
||||
|
||||
int totalWords = segment0Size;
|
||||
|
||||
if (segmentCount > 512) {
|
||||
throw new IOException("too many segments");
|
||||
}
|
||||
|
||||
Vector<Integer> moreSizes = new Vector<Integer>();
|
||||
|
||||
if (segmentCount > 1) {
|
||||
ByteBuffer moreSizesRaw = makeByteBuffer(readExact(is, 4 * (segmentCount & ~1)));
|
||||
for(int ii = 0; ii < segmentCount - 1; ++ii) {
|
||||
int size = moreSizesRaw.getInt(ii);
|
||||
moreSizes.add(size);
|
||||
totalWords += size;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO check that totalWords is reasonable
|
||||
|
||||
byte[] allSegments = readExact(is, totalWords * 8);
|
||||
|
||||
ByteBuffer[] segmentSlices = new ByteBuffer[segmentCount];
|
||||
|
||||
segmentSlices[0] = ByteBuffer.wrap(allSegments, 0, segment0Size);
|
||||
int offset = segment0Size;
|
||||
|
||||
for (int ii = 1; ii < segmentCount; ++ii) {
|
||||
segmentSlices[ii] = ByteBuffer.wrap(allSegments, offset, moreSizes.get(ii - 1));
|
||||
offset += moreSizes.get(ii - 1);
|
||||
}
|
||||
|
||||
return new MessageReader(segmentSlices);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
package capnp;
|
||||
|
||||
public class MessageReader {
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MessageReader {
|
||||
ByteBuffer[] segmentSlices;
|
||||
|
||||
public MessageReader(ByteBuffer[] segmentSlices) {
|
||||
this.segmentSlices = segmentSlices;
|
||||
}
|
||||
|
||||
public <T> T getRoot(FromStructReader<T> factory) {
|
||||
SegmentReader segment = new SegmentReader(this.segmentSlices[0]);
|
||||
PointerReader pointerReader = PointerReader.getRoot(segment,
|
||||
new WordPointer(this.segmentSlices[0], 0),
|
||||
0x7fffffff /* XXX */);
|
||||
AnyPointer.Reader any = new AnyPointer.Reader(pointerReader);
|
||||
return any.getAsStruct(factory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,27 @@ public class PointerReader {
|
|||
this.nestingLimit = nestingLimit;
|
||||
}
|
||||
|
||||
public static PointerReader getRoot(SegmentReader segment,
|
||||
WordPointer location,
|
||||
int nestingLimit) {
|
||||
// TODO bounds check
|
||||
return new PointerReader(segment, location.offset, nestingLimit);
|
||||
}
|
||||
|
||||
public StructReader getStruct() {
|
||||
WirePointer ref = new WirePointer(this.segment.ptr, this.pointer);
|
||||
return WireHelpers.readStructPointer(this.segment,
|
||||
ref,
|
||||
this.nestingLimit);
|
||||
}
|
||||
|
||||
public ListReader getList(byte expectedElementSize) {
|
||||
// TODO check nullness
|
||||
WirePointer ref = new WirePointer(this.segment.ptr, this.pointer);
|
||||
return WireHelpers.readListPointer(this.segment,
|
||||
ref,
|
||||
expectedElementSize);
|
||||
expectedElementSize,
|
||||
this.nestingLimit);
|
||||
}
|
||||
|
||||
public Text.Reader getText() {
|
||||
|
|
|
@ -4,4 +4,8 @@ import java.nio.ByteBuffer;
|
|||
|
||||
public class SegmentReader {
|
||||
ByteBuffer ptr;
|
||||
|
||||
public SegmentReader(ByteBuffer ptr) {
|
||||
this.ptr = ptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,30 @@ package capnp;
|
|||
|
||||
class WireHelpers {
|
||||
|
||||
public static StructReader readStructPointer(SegmentReader segment,
|
||||
WirePointer ref,
|
||||
int nestingLimit) {
|
||||
|
||||
// TODO error handling
|
||||
|
||||
WordPointer ptr = ref.target();
|
||||
StructPointer structPtr = (StructPointer)ref;
|
||||
int dataSizeWords = structPtr.dataSize();
|
||||
|
||||
return new StructReader(segment,
|
||||
ptr.offset * 8,
|
||||
(ptr.offset + dataSizeWords) * 8,
|
||||
dataSizeWords * 64,
|
||||
structPtr.ptrCount(),
|
||||
(byte)0,
|
||||
nestingLimit - 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static ListReader readListPointer(SegmentReader segment,
|
||||
WirePointer ref,
|
||||
byte expectedElementSize,
|
||||
int nestingLimit) {
|
||||
|
||||
// TODO check for null, follow fars, nestingLimit
|
||||
|
@ -30,7 +52,7 @@ class WireHelpers {
|
|||
// TODO check whether the size is compatible
|
||||
|
||||
return new ListReader(segment, // TODO follow fars
|
||||
ptr.offset, //
|
||||
ptr.offset * 8, //
|
||||
size,
|
||||
wordsPerElement * 64,
|
||||
structPtr.dataSize() * 64,
|
||||
|
|
Loading…
Reference in a new issue