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
|
CXX=g++ -std=c++11
|
||||||
|
|
||||||
CAPNP_SOURCES=\
|
CAPNP_SOURCES=\
|
||||||
|
src/capnp/AnyPointer.java\
|
||||||
src/capnp/FieldSize.java\
|
src/capnp/FieldSize.java\
|
||||||
src/capnp/FromStructReader.java\
|
src/capnp/FromStructReader.java\
|
||||||
src/capnp/InputStreamMessageReader.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.InputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
public class InputStreamMessageReader {
|
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;
|
int bytesRead = 0;
|
||||||
while (bytesRead < 8) {
|
while (bytesRead < length) {
|
||||||
int n = is.read(firstWord, bytesRead, 8 - bytesRead);
|
int r = is.read(bytes, bytesRead, length - bytesRead);
|
||||||
if (n < 0) {
|
if (r < 0) {
|
||||||
throw new IOException("premature EOF");
|
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;
|
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;
|
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) {
|
public ListReader getList(byte expectedElementSize) {
|
||||||
// TODO check nullness
|
// TODO check nullness
|
||||||
WirePointer ref = new WirePointer(this.segment.ptr, this.pointer);
|
WirePointer ref = new WirePointer(this.segment.ptr, this.pointer);
|
||||||
return WireHelpers.readListPointer(this.segment,
|
return WireHelpers.readListPointer(this.segment,
|
||||||
ref,
|
ref,
|
||||||
expectedElementSize);
|
expectedElementSize,
|
||||||
|
this.nestingLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Text.Reader getText() {
|
public Text.Reader getText() {
|
||||||
|
|
|
@ -4,4 +4,8 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class SegmentReader {
|
public class SegmentReader {
|
||||||
ByteBuffer ptr;
|
ByteBuffer ptr;
|
||||||
|
|
||||||
|
public SegmentReader(ByteBuffer ptr) {
|
||||||
|
this.ptr = ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,30 @@ package capnp;
|
||||||
|
|
||||||
class WireHelpers {
|
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,
|
public static ListReader readListPointer(SegmentReader segment,
|
||||||
WirePointer ref,
|
WirePointer ref,
|
||||||
|
byte expectedElementSize,
|
||||||
int nestingLimit) {
|
int nestingLimit) {
|
||||||
|
|
||||||
// TODO check for null, follow fars, nestingLimit
|
// TODO check for null, follow fars, nestingLimit
|
||||||
|
@ -30,7 +52,7 @@ class WireHelpers {
|
||||||
// TODO check whether the size is compatible
|
// TODO check whether the size is compatible
|
||||||
|
|
||||||
return new ListReader(segment, // TODO follow fars
|
return new ListReader(segment, // TODO follow fars
|
||||||
ptr.offset, //
|
ptr.offset * 8, //
|
||||||
size,
|
size,
|
||||||
wordsPerElement * 64,
|
wordsPerElement * 64,
|
||||||
structPtr.dataSize() * 64,
|
structPtr.dataSize() * 64,
|
||||||
|
|
Loading…
Reference in a new issue