JNI ready for testing. -fPIC enabled for objects in src and jni.
This commit is contained in:
parent
1529c0641e
commit
106b8bb6a7
25 changed files with 954 additions and 145 deletions
2
Makefile
2
Makefile
|
|
@ -3,7 +3,7 @@
|
||||||
# and kick off a recursive make
|
# and kick off a recursive make
|
||||||
# Also, "make src/all" turns into "make -C src all"
|
# Also, "make src/all" turns into "make -C src all"
|
||||||
|
|
||||||
SUBDIRS = src examples
|
SUBDIRS = src examples jni
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ include $(TOPLEVEL)/config.mk
|
||||||
TEST_CFLAGS = $(shell pkg-config --cflags glib-2.0) -DINCLUDE_TESTS
|
TEST_CFLAGS = $(shell pkg-config --cflags glib-2.0) -DINCLUDE_TESTS
|
||||||
TEST_LDFLAGS = $(shell pkg-config --libs glib-2.0)
|
TEST_LDFLAGS = $(shell pkg-config --libs glib-2.0)
|
||||||
|
|
||||||
CFLAGS := -std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-attributes
|
CFLAGS := -std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-attributes -g
|
||||||
LDFLAGS :=
|
LDFLAGS :=
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,18 @@
|
||||||
|
import com.upstandinghackers.hammer.*;
|
||||||
|
import java.util.Arrays;
|
||||||
/**
|
/**
|
||||||
* Example JHammer usage
|
* Example JHammer usage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Example
|
public class Example
|
||||||
{
|
{
|
||||||
|
|
||||||
private HParser initParser()
|
static {
|
||||||
{
|
System.loadLibrary("jhammer");
|
||||||
HParser digit = Hammer.chRange(0x30, 0x39);
|
|
||||||
HParser alpha = Hammer.choice({Hammer.chRange(0x41, 0x5a), Hammer.chRange(0x61, 0x7a)});
|
|
||||||
|
|
||||||
HParser plus = Hammer.ch('+');
|
|
||||||
HParser slash = Hammer.ch('/');
|
|
||||||
HParser equals = Hammer.ch('=');
|
|
||||||
HParser bsfdig = Hammer.choice({alpha, digit, plus, slash});
|
|
||||||
|
|
||||||
byte[] AEIMQUYcgkosw048 = "AEIMQUYcgkosw048".getBytes();
|
|
||||||
HParser bsfdig_4bit = Hammer.in(AEIMQUYcgkosw048, AEIMQUYcgkosw048.length);
|
|
||||||
byte[] AQgw = "AQgw".getBytes();
|
|
||||||
HParser bsfdig_2bit = Hammer.in(AQgw, AQgw.length);
|
|
||||||
HParser base64_3 = Hammer.repeatN(bsfdig, 4);
|
|
||||||
HParser base64_2 = Hammer.sequence({bsfdig, bsfdig, bsfdig_4bit, equals});
|
|
||||||
HParser base64_1 = Hammer.sequence({bsfdig, bsfdig_2bit, equals, equals});
|
|
||||||
HParser base64 = Hammer.sequence({ Hammer.many(base64_3),
|
|
||||||
Hammer.optional(Hammer.choice({base64_2, base64_1}))
|
|
||||||
});
|
|
||||||
|
|
||||||
return Hammer.sequence({Hammer.whitespace(base64), Hammer.whitespace(Hammer.endP()}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[])
|
private static void handle(ParseResult result)
|
||||||
{
|
{
|
||||||
byte[] input = "RXMgaXN0IFNwYXJnZWx6ZWl0IQo=".getBytes();
|
|
||||||
int length = input.length;
|
|
||||||
HParsedResult result = Hammer.parse(initParser(), input, length);
|
|
||||||
if(result == null)
|
if(result == null)
|
||||||
{
|
{
|
||||||
System.out.println("FAIL");
|
System.out.println("FAIL");
|
||||||
|
|
@ -40,10 +20,73 @@ public static void main(String args[])
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println("PASS");
|
System.out.println("PASS");
|
||||||
//TODO: Pretty print
|
handleToken(result.getAst());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void handleToken(ParsedToken p)
|
||||||
|
{
|
||||||
|
if(p==null)
|
||||||
|
{
|
||||||
|
System.out.println("Empty AST");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(p.getTokenType())
|
||||||
|
{
|
||||||
|
case NONE: out("NONE token type"); break;
|
||||||
|
case BYTES: out("BYTES token type, value: " + Arrays.toString(p.getBytesValue())); break;
|
||||||
|
case SINT: out("SINT token type, value: " + p.getSIntValue()); break;
|
||||||
|
case UINT: out("UINT token type, value: " + p.getUIntValue()); break;
|
||||||
|
case SEQUENCE: out("SEQUENCE token type"); for(ParsedToken tok : p.getSeqValue()) {handleToken(tok);} break;
|
||||||
|
case ERR: out("ERR token type"); break;
|
||||||
|
case USER: out("USER token type"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void out(String msg)
|
||||||
|
{
|
||||||
|
System.out.println(">> " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[])
|
||||||
|
{
|
||||||
|
out("chRange");
|
||||||
|
handle(Hammer.parse(Hammer.chRange((byte)0x30, (byte)0x39), "1".getBytes(), 1));
|
||||||
|
handle(Hammer.parse(Hammer.chRange((byte)0x30, (byte)0x39), "a".getBytes(), 1));
|
||||||
|
|
||||||
|
out("ch");
|
||||||
|
handle(Hammer.parse(Hammer.ch((byte)0x31), "1".getBytes(), 1));
|
||||||
|
handle(Hammer.parse(Hammer.ch((byte)0x31), "0".getBytes(), 1));
|
||||||
|
|
||||||
|
out("token");
|
||||||
|
handle(Hammer.parse(Hammer.token("herp".getBytes(), 4), "herp".getBytes(), 4));
|
||||||
|
handle(Hammer.parse(Hammer.token("herp".getBytes(), 4), "derp".getBytes(), 4));
|
||||||
|
|
||||||
|
out("intRange");
|
||||||
|
byte inbytes[] = {0x31, 0x31, 0x31, 0x31};
|
||||||
|
handle(Hammer.parse(Hammer.intRange(Hammer.uInt8(), 0L, 0x32), inbytes, inbytes.length));
|
||||||
|
handle(Hammer.parse(Hammer.intRange(Hammer.uInt8(), 0L, 0x30), inbytes, inbytes.length));
|
||||||
|
|
||||||
|
out("bits");
|
||||||
|
handle(Hammer.parse(Hammer.bits(7, false), inbytes, inbytes.length));
|
||||||
|
|
||||||
|
out("int64");
|
||||||
|
byte ints[] = {(byte)0x8F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
||||||
|
handle(Hammer.parse(Hammer.int64(), ints, ints.length));
|
||||||
|
handle(Hammer.parse(Hammer.int64(), inbytes, inbytes.length));
|
||||||
|
|
||||||
|
out("choice");
|
||||||
|
Parser two32s[] = {Hammer.intRange(Hammer.uInt32(), 0x00, 0x01), Hammer.int32()};
|
||||||
|
handle(Hammer.parse(Hammer.choice(two32s), ints, ints.length));
|
||||||
|
|
||||||
|
out("sequence");
|
||||||
|
byte i3[] = {(byte)'i', (byte)3, (byte)0xFF};
|
||||||
|
Parser i3parsers[] = {Hammer.ch((byte)'i'), Hammer.uInt8(), Hammer.int8()};
|
||||||
|
handle(Hammer.parse(Hammer.sequence(i3parsers), i3, i3.length));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
42
jni/Makefile
Normal file
42
jni/Makefile
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
JSOURCES := Action.java Hammer.java ParsedToken.java ParseResult.java Parser.java Predicate.java
|
||||||
|
JSOURCES_NATIVE := Hammer ParsedToken Parser ParseResult
|
||||||
|
CSOURCES := com_upstandinghackers_hammer_Hammer.c com_upstandinghackers_hammer_ParsedToken.c com_upstandinghackers_hammer_Parser.c com_upstandinghackers_hammer_ParseResult.c
|
||||||
|
|
||||||
|
# ls *.h *.o *.so com/upstandinghackers/hammer/*.class | grep -v jhammer.h | tr '\n' ' '; replace single $ with $$
|
||||||
|
OUTPUTS := com/upstandinghackers/hammer/Action.class com/upstandinghackers/hammer/Hammer.class com_upstandinghackers_hammer_Hammer.h com_upstandinghackers_hammer_Hammer.o com/upstandinghackers/hammer/Hammer\$TokenType.class com_upstandinghackers_hammer_Hammer_TokenType.h com/upstandinghackers/hammer/ParsedToken.class com_upstandinghackers_hammer_ParsedToken.h com_upstandinghackers_hammer_ParsedToken.o com/upstandinghackers/hammer/Parser.class com/upstandinghackers/hammer/ParseResult.class com_upstandinghackers_hammer_ParseResult.h com_upstandinghackers_hammer_ParseResult.o com_upstandinghackers_hammer_Parser.h com_upstandinghackers_hammer_Parser.o com/upstandinghackers/hammer/Predicate.class libjhammer.so
|
||||||
|
|
||||||
|
TOPLEVEL := ../
|
||||||
|
|
||||||
|
JC=javac
|
||||||
|
JH=javah
|
||||||
|
CP=com/upstandinghackers/hammer
|
||||||
|
PACKAGE=com.upstandinghackers.hammer
|
||||||
|
|
||||||
|
include ../common.mk
|
||||||
|
|
||||||
|
JNI_INCLUDE := /usr/lib/jvm/java-6-openjdk/include/
|
||||||
|
CFLAGS += -fPIC -I. -I $(TOPLEVEL)/src/ -I jni -I $(JNI_INCLUDE)
|
||||||
|
|
||||||
|
%.java: $(call ifsilent,| $(HUSH))
|
||||||
|
$(call hush, "Compiling Java source $@") $(JC) $(CP)/$@
|
||||||
|
|
||||||
|
all: javacc prepare compile link
|
||||||
|
|
||||||
|
link: compile
|
||||||
|
$(call hush, "Generating libjhammer.so") $(CC) -shared $(CFLAGS) -o libjhammer.so *.o ../src/*.o ../src/backends/*.o ../src/parsers/*.o
|
||||||
|
|
||||||
|
$(CSOURCES): prepare
|
||||||
|
$(call hush, "Compiling $@") $(CC) -c $(CFLAGS) $@
|
||||||
|
|
||||||
|
compile: prepare $(CSOURCES)
|
||||||
|
|
||||||
|
prepare: javacc $(JSOURCES_NATIVE)
|
||||||
|
|
||||||
|
$(JSOURCES_NATIVE): javacc
|
||||||
|
$(call hush, "Generating JNI headers for $@") $(JH) $(PACKAGE).$@
|
||||||
|
|
||||||
|
javacc: $(JSOURCES)
|
||||||
|
|
||||||
|
#TODO make this not-as-hardcoded
|
||||||
|
#clean:
|
||||||
|
# rm $(CP)/*.class && rm com_upstandinghackers_*.h && rm com_upstandinghackers_*.o && rm libjhammer.so
|
||||||
30
jni/NOTES
30
jni/NOTES
|
|
@ -1,12 +1,26 @@
|
||||||
Compilation:
|
USING THE JNI BINDINGS:
|
||||||
javac com/upstandinghackers/hammer/*.java
|
1. import com.upstandinghackers.hammer.*;
|
||||||
|
2. Add a static initializer block that loads the correct library, like this: static { System.loadLibrary("jhammer"); }
|
||||||
|
3. Code stuff. Just look at Example.java for a few handy snippets (for walking the resulting syntax tree [AST] etc)
|
||||||
|
4. Compile your java sources like always
|
||||||
|
5. Add the folder containing libhammer.so/dll/whatever to Java's library path to run it, for example: java -Djava.library.path=. <CLASS>
|
||||||
|
|
||||||
Conversion to JNI headers:
|
UNIMPLEMENTED:
|
||||||
find -name "*.class" | sed -e 's/.class$//' | tr '/' '.' | cut -c 3- | xargs javah
|
User-defined types, predicates and actions are unimplemented.
|
||||||
|
Memory leaks because there is no reliable garbage collection.
|
||||||
Not working:
|
|
||||||
enums aren't converted at all, no idea why
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
Implement the entire JNI side
|
|
||||||
Testing
|
Testing
|
||||||
|
|
||||||
|
|
||||||
|
TYPE MAPPING:
|
||||||
|
Hammer Java JNI
|
||||||
|
uint8_t byte jbyte jbyte/byte is signed
|
||||||
|
char byte jbyte jchar would be 16 bit wide
|
||||||
|
size_t int jint signed as well; jsize == jint, actually
|
||||||
|
int64_t long jlong
|
||||||
|
uint64_t long jlong signed!
|
||||||
|
bool boolean jboolean JNI_TRUE / JNI_FALSE
|
||||||
|
float float jfloat
|
||||||
|
double double jdouble
|
||||||
|
void void void
|
||||||
|
|
|
||||||
8
jni/com/upstandinghackers/hammer/Action.java
Normal file
8
jni/com/upstandinghackers/hammer/Action.java
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.upstandinghackers.hammer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface Action
|
||||||
|
{
|
||||||
|
public List<ParsedToken> execute(ParseResult p);
|
||||||
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package com.upstandinghackers.hammer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface HAction
|
|
||||||
{
|
|
||||||
public List<HParsedToken> execute(HParseResult p);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package com.upstandinghackers.hammer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HParseResult
|
|
||||||
{
|
|
||||||
public native List<HParsedToken> getAst();
|
|
||||||
public native long getBitLength();
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package com.upstandinghackers.hammer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HParsedToken
|
|
||||||
{
|
|
||||||
public native Hammer.HTokenType getTokenType();
|
|
||||||
public native int getIndex();
|
|
||||||
public native byte getBitOffset();
|
|
||||||
public native byte[] getBytesValue();
|
|
||||||
public native long getSIntValue();
|
|
||||||
public native long getUIntValue();
|
|
||||||
public native double getDoubleValue();
|
|
||||||
public native float getFloatValue();
|
|
||||||
public native List<HParsedToken> getSeqValue();
|
|
||||||
public native Object getUserValue();
|
|
||||||
|
|
||||||
native void setTokenType(Hammer.HTokenType type);
|
|
||||||
native void setIndex(int index);
|
|
||||||
native void setBitOffset(byte offset);
|
|
||||||
native void setBytesValue(byte[] value);
|
|
||||||
native void setSIntValue(long value);
|
|
||||||
native void setUIntValue(long value);
|
|
||||||
native void setDoubleValue(double value);
|
|
||||||
native void setFloatValue(float value);
|
|
||||||
native void setSeqValue(List<HParsedToken> value);
|
|
||||||
native void setUserValue(Object value);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package com.upstandinghackers.hammer;
|
|
||||||
|
|
||||||
public class HParser
|
|
||||||
{
|
|
||||||
public native void bindIndirect(HParser inner);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package com.upstandinghackers.hammer;
|
|
||||||
|
|
||||||
public interface HPredicate
|
|
||||||
{
|
|
||||||
public boolean apply(HParseResult p);
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
package com.upstandinghackers.hammer;
|
package com.upstandinghackers.hammer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class Hammer
|
public class Hammer
|
||||||
{
|
{
|
||||||
|
|
@ -7,59 +8,69 @@ public class Hammer
|
||||||
public final static byte BYTE_LITTLE_ENDIAN = 0x0;
|
public final static byte BYTE_LITTLE_ENDIAN = 0x0;
|
||||||
public final static byte BIT_LITTLE_ENDIAN = 0x0;
|
public final static byte BIT_LITTLE_ENDIAN = 0x0;
|
||||||
|
|
||||||
public enum HTokenType
|
static final HashMap<Integer, TokenType> tokenTypeMap = new HashMap<Integer, TokenType>();
|
||||||
|
|
||||||
|
public enum TokenType
|
||||||
{
|
{
|
||||||
TT_NONE(1),
|
NONE(1),
|
||||||
TT_BYTES(2),
|
BYTES(2),
|
||||||
TT_SINT(4),
|
SINT(4),
|
||||||
TT_UINT(8),
|
UINT(8),
|
||||||
TT_SEQUENCE(16),
|
SEQUENCE(16),
|
||||||
TT_ERR(32),
|
ERR(32),
|
||||||
TT_USER(64),
|
USER(64);
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
public int getValue() { return this.value; }
|
public int getValue() { return this.value; }
|
||||||
private HTokenType(int value) { this.value = value; }
|
private TokenType(int value) { this.value = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native HParseResult parse(HParser parser, byte[] input, int length);
|
static
|
||||||
public static native HParser token(byte[] str, int length);
|
{
|
||||||
public static native HParser ch(byte c);
|
for(TokenType tt : TokenType.values())
|
||||||
public static native HParser chRange(byte from, byte to);
|
{
|
||||||
public static native HParser intRange(HParser p, int lower, int upper);
|
Hammer.tokenTypeMap.put(new Integer(tt.getValue()), tt);
|
||||||
public static native HParser bits(int len, boolean sign);
|
}
|
||||||
public static native HParser int64();
|
}
|
||||||
public static native HParser int32();
|
|
||||||
public static native HParser int16();
|
public static native ParseResult parse(Parser parser, byte[] input, int length);
|
||||||
public static native HParser int8();
|
public static native Parser token(byte[] str, int length);
|
||||||
public static native HParser uInt64();
|
public static native Parser ch(byte c);
|
||||||
public static native HParser uInt32();
|
public static native Parser chRange(byte from, byte to);
|
||||||
public static native HParser uInt16();
|
public static native Parser intRange(Parser p, long lower, long upper);
|
||||||
public static native HParser uInt8();
|
public static native Parser bits(int len, boolean sign);
|
||||||
public static native HParser whitespace(HParser p);
|
public static native Parser int64();
|
||||||
public static native HParser left(HParser p, HParser q);
|
public static native Parser int32();
|
||||||
public static native HParser right(HParser p, HParser q);
|
public static native Parser int16();
|
||||||
public static native HParser middle(HParser p, HParser x, HParser q);
|
public static native Parser int8();
|
||||||
public static native HParser action(HParser p, HAction a);
|
public static native Parser uInt64();
|
||||||
public static native HParser in(byte[] charset, int length);
|
public static native Parser uInt32();
|
||||||
public static native HParser endP();
|
public static native Parser uInt16();
|
||||||
public static native HParser nothingP();
|
public static native Parser uInt8();
|
||||||
public static native HParser sequence(HParser[] parsers);
|
public static native Parser whitespace(Parser p);
|
||||||
public static native HParser choice(HParser[] parsers);
|
public static native Parser left(Parser p, Parser q);
|
||||||
public static native HParser butNot(HParser p1, HParser p2);
|
public static native Parser right(Parser p, Parser q);
|
||||||
public static native HParser difference(HParser p1, HParser p2);
|
public static native Parser middle(Parser p, Parser x, Parser q);
|
||||||
public static native HParser xor(HParser p1, HParser p2);
|
// public static native Parser action(Parser p, Action a);
|
||||||
public static native HParser many(HParser p);
|
public static native Parser in(byte[] charset, int length);
|
||||||
public static native HParser many1(HParser p);
|
public static native Parser endP();
|
||||||
public static native HParser repeatN(HParser p, int n);
|
public static native Parser nothingP();
|
||||||
public static native HParser optional(HParser p);
|
public static native Parser sequence(Parser[] parsers);
|
||||||
public static native HParser ignore(HParser p);
|
public static native Parser choice(Parser[] parsers);
|
||||||
public static native HParser sepBy(HParser p, HParser sep);
|
public static native Parser butNot(Parser p1, Parser p2);
|
||||||
public static native HParser sepBy1(HParser p, HParser sep);
|
public static native Parser difference(Parser p1, Parser p2);
|
||||||
public static native HParser epsilonP();
|
public static native Parser xor(Parser p1, Parser p2);
|
||||||
public static native HParser lengthValue(HParser length, HParser value);
|
public static native Parser many(Parser p);
|
||||||
public static native HParser attrBool(HParser p, HPredicate pred);
|
public static native Parser many1(Parser p);
|
||||||
public static native HParser and(HParser p);
|
public static native Parser repeatN(Parser p, int n);
|
||||||
public static native HParser not(HParser p);
|
public static native Parser optional(Parser p);
|
||||||
public static native HParser indirect();
|
public static native Parser ignore(Parser p);
|
||||||
|
public static native Parser sepBy(Parser p, Parser sep);
|
||||||
|
public static native Parser sepBy1(Parser p, Parser sep);
|
||||||
|
public static native Parser epsilonP();
|
||||||
|
public static native Parser lengthValue(Parser length, Parser value);
|
||||||
|
// public static native Parser attrBool(Parser p, Predicate pred);
|
||||||
|
public static native Parser and(Parser p);
|
||||||
|
public static native Parser not(Parser p);
|
||||||
|
public static native Parser indirect();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
jni/com/upstandinghackers/hammer/ParseResult.java
Normal file
15
jni/com/upstandinghackers/hammer/ParseResult.java
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.upstandinghackers.hammer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ParseResult
|
||||||
|
{
|
||||||
|
public native ParsedToken getAst();
|
||||||
|
public native long getBitLength();
|
||||||
|
|
||||||
|
public native void free();
|
||||||
|
public long getInner() {return this.inner;}
|
||||||
|
|
||||||
|
private long inner;
|
||||||
|
ParseResult(long inner) {this.inner=inner;}
|
||||||
|
}
|
||||||
40
jni/com/upstandinghackers/hammer/ParsedToken.java
Normal file
40
jni/com/upstandinghackers/hammer/ParsedToken.java
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.upstandinghackers.hammer;
|
||||||
|
|
||||||
|
public class ParsedToken
|
||||||
|
{
|
||||||
|
public Hammer.TokenType getTokenType()
|
||||||
|
{
|
||||||
|
int tt = this.getTokenTypeInternal();
|
||||||
|
if(0==tt)
|
||||||
|
return null;
|
||||||
|
return Hammer.tokenTypeMap.get(new Integer(tt));
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int getTokenTypeInternal();
|
||||||
|
public native int getIndex();
|
||||||
|
public native byte getBitOffset();
|
||||||
|
public native byte[] getBytesValue();
|
||||||
|
public native long getSIntValue();
|
||||||
|
public native long getUIntValue();
|
||||||
|
public native double getDoubleValue();
|
||||||
|
public native float getFloatValue();
|
||||||
|
public native ParsedToken[] getSeqValue();
|
||||||
|
// public native Object getUserValue();
|
||||||
|
|
||||||
|
native void setTokenType(Hammer.TokenType type);
|
||||||
|
native void setIndex(int index);
|
||||||
|
native void setBitOffset(byte offset);
|
||||||
|
native void setBytesValue(byte[] value);
|
||||||
|
native void setSIntValue(long value);
|
||||||
|
native void setUIntValue(long value);
|
||||||
|
native void setDoubleValue(double value);
|
||||||
|
native void setFloatValue(float value);
|
||||||
|
native void setSeqValue(ParsedToken value[]);
|
||||||
|
// native void setUserValue(Object value);
|
||||||
|
|
||||||
|
// public native void free();
|
||||||
|
public long getInner() {return this.inner;}
|
||||||
|
|
||||||
|
private long inner;
|
||||||
|
ParsedToken(long inner) {this.inner=inner;}
|
||||||
|
}
|
||||||
11
jni/com/upstandinghackers/hammer/Parser.java
Normal file
11
jni/com/upstandinghackers/hammer/Parser.java
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.upstandinghackers.hammer;
|
||||||
|
|
||||||
|
public class Parser
|
||||||
|
{
|
||||||
|
public native void bindIndirect(Parser inner);
|
||||||
|
public native void free();
|
||||||
|
public long getInner() {return this.inner;}
|
||||||
|
|
||||||
|
private long inner;
|
||||||
|
Parser(long inner) {this.inner=inner;}
|
||||||
|
}
|
||||||
6
jni/com/upstandinghackers/hammer/Predicate.java
Normal file
6
jni/com/upstandinghackers/hammer/Predicate.java
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.upstandinghackers.hammer;
|
||||||
|
|
||||||
|
public interface Predicate
|
||||||
|
{
|
||||||
|
public boolean apply(ParseResult p);
|
||||||
|
}
|
||||||
335
jni/com_upstandinghackers_hammer_Hammer.c
Normal file
335
jni/com_upstandinghackers_hammer_Hammer.c
Normal file
|
|
@ -0,0 +1,335 @@
|
||||||
|
#include "jhammer.h"
|
||||||
|
#include "com_upstandinghackers_hammer_Hammer.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_parse
|
||||||
|
(JNIEnv *env, jclass class, jobject obj, jbyteArray input_, jint length_)
|
||||||
|
{
|
||||||
|
HParser *parser;
|
||||||
|
uint8_t* input;
|
||||||
|
size_t length;
|
||||||
|
HParseResult *result;
|
||||||
|
jclass resultClass;
|
||||||
|
jobject retVal;
|
||||||
|
|
||||||
|
parser = UNWRAP(env, obj);
|
||||||
|
|
||||||
|
input = (uint8_t *) ((*env)->GetByteArrayElements(env, input_, NULL));
|
||||||
|
length = (size_t) length_;
|
||||||
|
|
||||||
|
result = h_parse(parser, input, length);
|
||||||
|
|
||||||
|
if(result==NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
FIND_CLASS(resultClass, env, "com/upstandinghackers/hammer/ParseResult");
|
||||||
|
|
||||||
|
NEW_INSTANCE(retVal, env, resultClass, result);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_token
|
||||||
|
(JNIEnv *env, jclass class, jbyteArray str, jint len)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_token((uint8_t *) ((*env)->GetByteArrayElements(env, str, NULL)), (size_t) len));
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_ch
|
||||||
|
(JNIEnv *env, jclass class, jbyte c)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_ch((uint8_t) c));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_chRange
|
||||||
|
(JNIEnv *env, jclass class, jbyte lower, jbyte upper)
|
||||||
|
{
|
||||||
|
|
||||||
|
RETURNWRAP(env, h_ch_range((uint8_t) lower, (uint8_t) upper));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_intRange
|
||||||
|
(JNIEnv *env, jclass class, jobject obj, jlong lower, jlong upper)
|
||||||
|
{
|
||||||
|
HParser *parser;
|
||||||
|
parser = UNWRAP(env, obj);
|
||||||
|
RETURNWRAP(env, h_int_range(parser, (int64_t) lower, (int64_t) upper));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_bits
|
||||||
|
(JNIEnv *env, jclass class, jint len, jboolean sign)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_bits((size_t) len, (bool)(sign & JNI_TRUE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_int64
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_int64());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_int32
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_int32());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_int16
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_int16());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_int8
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_int8());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_uInt64
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_uint64());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_uInt32
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_uint32());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_uInt16
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_uint16());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_uInt8
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_uint8());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_whitespace
|
||||||
|
(JNIEnv *env, jclass class, jobject parser)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_whitespace(UNWRAP(env, parser)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_left
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_left(UNWRAP(env, p), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_right
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_right(UNWRAP(env, p), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_middle
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject x, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_middle(UNWRAP(env, p), UNWRAP(env, x), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_in
|
||||||
|
(JNIEnv *env, jclass class, jbyteArray charset, jint length)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_in((uint8_t *) ((*env)->GetByteArrayElements(env, charset, NULL)), (size_t)length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_endP
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_end_p());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_nothingP
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_nothing_p());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_sequence
|
||||||
|
(JNIEnv *env, jclass class, jobjectArray sequence)
|
||||||
|
{
|
||||||
|
jsize length;
|
||||||
|
void **parsers;
|
||||||
|
int i;
|
||||||
|
jobject current;
|
||||||
|
const HParser *result;
|
||||||
|
|
||||||
|
length = (*env)->GetArrayLength(env, sequence);
|
||||||
|
parsers = malloc(sizeof(void *)*(length+1));
|
||||||
|
if(NULL==parsers)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<length; i++)
|
||||||
|
{
|
||||||
|
current = (*env)->GetObjectArrayElement(env, sequence, (jsize)i);
|
||||||
|
parsers[i] = UNWRAP(env, current);
|
||||||
|
}
|
||||||
|
parsers[length] = NULL;
|
||||||
|
|
||||||
|
result = h_sequence__a(parsers);
|
||||||
|
RETURNWRAP(env, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_choice
|
||||||
|
(JNIEnv *env, jclass class, jobjectArray choices)
|
||||||
|
{
|
||||||
|
jsize length;
|
||||||
|
void **parsers;
|
||||||
|
int i;
|
||||||
|
jobject current;
|
||||||
|
const HParser *result;
|
||||||
|
|
||||||
|
length = (*env)->GetArrayLength(env, choices);
|
||||||
|
parsers = malloc(sizeof(HParser *)*(length+1));
|
||||||
|
if(NULL==parsers)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<length; i++)
|
||||||
|
{
|
||||||
|
current = (*env)->GetObjectArrayElement(env, choices, (jsize)i);
|
||||||
|
parsers[i] = UNWRAP(env, current);
|
||||||
|
}
|
||||||
|
parsers[length] = NULL;
|
||||||
|
|
||||||
|
result = h_choice__a(parsers);
|
||||||
|
RETURNWRAP(env, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_butNot
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_butnot(UNWRAP(env, p), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_difference
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_difference(UNWRAP(env, p), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_xor
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject q)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_xor(UNWRAP(env, p), UNWRAP(env, q)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_many
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_many(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_many1
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_many1(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_repeatN
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jint n)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_repeat_n(UNWRAP(env, p), (size_t)n));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_optional
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_optional(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_ignore
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_ignore(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_sepBy
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject sep)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_sepBy(UNWRAP(env, p), UNWRAP(env, sep)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_sepBy1
|
||||||
|
(JNIEnv *env, jclass class, jobject p, jobject sep)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_sepBy1(UNWRAP(env, p), UNWRAP(env, sep)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_epsilonP
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_epsilon_p());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_lengthValue
|
||||||
|
(JNIEnv *env, jclass class, jobject length, jobject value)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_length_value(UNWRAP(env, length), UNWRAP(env, value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_and
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_and(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_not
|
||||||
|
(JNIEnv *env, jclass class, jobject p)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_not(UNWRAP(env, p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_Hammer_indirect
|
||||||
|
(JNIEnv *env, jclass class)
|
||||||
|
{
|
||||||
|
RETURNWRAP(env, h_indirect());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
45
jni/com_upstandinghackers_hammer_ParseResult.c
Normal file
45
jni/com_upstandinghackers_hammer_ParseResult.c
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "jhammer.h"
|
||||||
|
#include "com_upstandinghackers_hammer_ParseResult.h"
|
||||||
|
|
||||||
|
HParseResult *unwrap_parse_result(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
jclass parseResultClass;
|
||||||
|
jfieldID parseResultInner;
|
||||||
|
FIND_CLASS(parseResultClass, env, "com/upstandinghackers/hammer/ParseResult");
|
||||||
|
parseResultInner = (*env)->GetFieldID(env, parseResultClass, "inner", "J");
|
||||||
|
return (HParseResult *)((*env)->GetLongField(env, obj, parseResultInner));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_upstandinghackers_hammer_ParseResult_getAst
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HParseResult *inner;
|
||||||
|
jclass parsedTokenClass;
|
||||||
|
jobject retVal;
|
||||||
|
|
||||||
|
if(this == NULL)
|
||||||
|
return NULL; // parse unsuccessful
|
||||||
|
inner = unwrap_parse_result(env, this);
|
||||||
|
if(inner->ast == NULL)
|
||||||
|
return NULL; // parse successful, but empty
|
||||||
|
|
||||||
|
FIND_CLASS(parsedTokenClass, env, "com/upstandinghackers/hammer/ParsedToken");
|
||||||
|
NEW_INSTANCE(retVal, env, parsedTokenClass, inner->ast);
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_upstandinghackers_hammer_ParseResult_getBitLength
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HParseResult *inner = unwrap_parse_result(env, this);
|
||||||
|
return (jlong) (inner->bit_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParseResult_free
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
//XXX: NOT IMPLEMENTED
|
||||||
|
}
|
||||||
|
|
||||||
195
jni/com_upstandinghackers_hammer_ParsedToken.c
Normal file
195
jni/com_upstandinghackers_hammer_ParsedToken.c
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
#include "jhammer.h"
|
||||||
|
#include "com_upstandinghackers_hammer_ParsedToken.h"
|
||||||
|
|
||||||
|
#define HPT_UNWRAP(env, this) HParsedToken *inner = unwrap_parsed_token(env, this); assert(inner!=NULL)
|
||||||
|
|
||||||
|
HParsedToken *unwrap_parsed_token(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
jclass parsedTokenClass;
|
||||||
|
jfieldID parsedTokenInner;
|
||||||
|
FIND_CLASS(parsedTokenClass, env, "com/upstandinghackers/hammer/ParsedToken");
|
||||||
|
parsedTokenInner = (*env)->GetFieldID(env, parsedTokenClass, "inner", "J");
|
||||||
|
return (HParsedToken *)((*env)->GetLongField(env, obj, parsedTokenInner));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getTokenTypeInternal
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
if(inner==NULL)
|
||||||
|
return (jint)0;
|
||||||
|
return (jint)(inner->token_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getIndex
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jint) (inner->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jbyte JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getBitOffset
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jbyte) (inner->bit_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jbyteArray JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getBytesValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
jbyteArray outArray;
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
outArray = (*env)->NewByteArray(env, (jsize)inner->bytes.len);
|
||||||
|
(*env)->SetByteArrayRegion(env, outArray, (jsize) 0, (jsize)(inner->bytes.len), (jbyte *)(inner->bytes.token));
|
||||||
|
return outArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getSIntValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jlong) (inner->sint);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getUIntValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jlong) (inner->uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jdouble JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getDoubleValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jdouble) (inner->dbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jfloat JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getFloatValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
return (jfloat) (inner->flt);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray JNICALL Java_com_upstandinghackers_hammer_ParsedToken_getSeqValue
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
jsize i;
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
jsize returnSize = inner->seq->used;
|
||||||
|
jobject currentObject;
|
||||||
|
jclass returnClass;
|
||||||
|
FIND_CLASS(returnClass, env, "com/upstandinghackers/hammer/ParsedToken");
|
||||||
|
jobjectArray retVal = (*env)->NewObjectArray(env, returnSize, returnClass, NULL);
|
||||||
|
for(i = 0; i<returnSize; i++)
|
||||||
|
{
|
||||||
|
NEW_INSTANCE(currentObject, env, returnClass, inner->seq->elements[i]);
|
||||||
|
(*env)->SetObjectArrayElement(env, retVal, i, currentObject);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setTokenType
|
||||||
|
(JNIEnv *env, jobject this, jobject tokenType)
|
||||||
|
{
|
||||||
|
jclass tokenTypeClass;
|
||||||
|
jmethodID getValue;
|
||||||
|
jint typeVal;
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
|
||||||
|
FIND_CLASS(tokenTypeClass, env, "com/upstandinghackers/hammer/Hammer$TokenType");
|
||||||
|
getValue = (*env)->GetMethodID(env, tokenTypeClass, "getValue", "()I");
|
||||||
|
typeVal = (*env)->CallIntMethod(env, tokenType, getValue);
|
||||||
|
|
||||||
|
inner->token_type = (int32_t) typeVal; // unsafe cast, but enums should be of type int
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setIndex
|
||||||
|
(JNIEnv *env, jobject this, jint index)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
inner->index = (size_t)index;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setBitOffset
|
||||||
|
(JNIEnv *env, jobject this, jbyte bit_offset)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
inner->bit_offset = (char)bit_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setBytesValue
|
||||||
|
(JNIEnv *env, jobject this, jbyteArray bytes_)
|
||||||
|
{
|
||||||
|
HBytes bytes;
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
|
||||||
|
bytes.token = (uint8_t *) ((*env)->GetByteArrayElements(env, bytes_, NULL));
|
||||||
|
bytes.len = (size_t) (*env)->GetArrayLength(env, bytes_);
|
||||||
|
|
||||||
|
inner->bytes = bytes;
|
||||||
|
inner->token_type = TT_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setSIntValue
|
||||||
|
(JNIEnv *env, jobject this, jlong sint)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
inner->token_type = TT_SINT;
|
||||||
|
inner->sint = (int64_t)sint;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setUIntValue
|
||||||
|
(JNIEnv *env, jobject this, jlong uint)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
inner->token_type = TT_UINT;
|
||||||
|
inner->uint = (uint64_t)uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setDoubleValue
|
||||||
|
(JNIEnv *env, jobject this, jdouble dbl)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
//token_type?
|
||||||
|
inner->dbl = (double)dbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setFloatValue
|
||||||
|
(JNIEnv *env, jobject this, jfloat flt)
|
||||||
|
{
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
//token_type?
|
||||||
|
inner->flt = (float)flt;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_ParsedToken_setSeqValue
|
||||||
|
(JNIEnv *env, jobject this, jobjectArray values)
|
||||||
|
{
|
||||||
|
HArena *arena;
|
||||||
|
size_t len, i;
|
||||||
|
jobject currentValue;
|
||||||
|
HParsedToken *currentValueInner;
|
||||||
|
HCountedArray *seq;
|
||||||
|
HPT_UNWRAP(env, this);
|
||||||
|
len = (size_t) (*env)->GetArrayLength(env, values);
|
||||||
|
arena = h_new_arena(&system_allocator, 0);
|
||||||
|
seq = h_carray_new_sized(arena, len);
|
||||||
|
|
||||||
|
// unwrap each value and append it to the new HCountedArray
|
||||||
|
for(i = 0; i<len; i++)
|
||||||
|
{
|
||||||
|
currentValue = (*env)->GetObjectArrayElement(env, values, (jsize)i);
|
||||||
|
if(NULL == currentValue)
|
||||||
|
continue;
|
||||||
|
currentValueInner = unwrap_parsed_token(env, currentValue);
|
||||||
|
if(currentValueInner)
|
||||||
|
h_carray_append(seq, (void *)currentValueInner);
|
||||||
|
}
|
||||||
|
|
||||||
|
inner->token_type = TT_SEQUENCE;
|
||||||
|
inner->seq = seq;
|
||||||
|
}
|
||||||
15
jni/com_upstandinghackers_hammer_Parser.c
Normal file
15
jni/com_upstandinghackers_hammer_Parser.c
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "jhammer.h"
|
||||||
|
#include "com_upstandinghackers_hammer_Parser.h"
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_Parser_bindIndirect
|
||||||
|
(JNIEnv *env, jobject this, jobject parser)
|
||||||
|
{
|
||||||
|
h_bind_indirect(UNWRAP(env, this), UNWRAP(env, parser));
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_upstandinghackers_hammer_Parser_free
|
||||||
|
(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
//XXX NOT IMPLEMENTED
|
||||||
|
//h_free(UNWRAP(env, this));
|
||||||
|
}
|
||||||
31
jni/jhammer.h
Normal file
31
jni/jhammer.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef JHAMMER_H
|
||||||
|
#define JHAMMER_H
|
||||||
|
#include <jni.h>
|
||||||
|
#include "internal.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
// Unsafe (non-asserting) helpers
|
||||||
|
#define FIND_CLASS_(env, class) (*env)->FindClass(env, class)
|
||||||
|
#define REFCONSTRUCTOR_(env, class) (*env)->GetMethodID(env, class, "<init>", "(J)V")
|
||||||
|
#define NEW_INSTANCE_(env, class, inner) (*env)->NewObject(env, class, REFCONSTRUCTOR_(env, class), (jlong)inner)
|
||||||
|
|
||||||
|
// Safer versions, assert that the result is not NULL
|
||||||
|
// If one of those asserts fails, it most likely means that there's a typo (wrong class name or method signature) or big trouble (OOM)
|
||||||
|
#define FIND_CLASS(target, env, class) target = FIND_CLASS_(env, class); assert(target != NULL)
|
||||||
|
#define REFCONSTRUCTOR(target, env, class) target = REFCONSTRUCTOR_(env, class); assert(target != NULL)
|
||||||
|
#define NEW_INSTANCE(target, env, class, inner) target = NEW_INSTANCE_(env, class, inner); assert(target != NULL)
|
||||||
|
|
||||||
|
|
||||||
|
// Since there's a LOT of wrapping/unwrapping HParsers, these macros make it a bit more readable
|
||||||
|
#define PARSER_CLASS "com/upstandinghackers/hammer/Parser"
|
||||||
|
#define PARSER_REF(env) (*env)->GetFieldID(env, FIND_CLASS_(env, PARSER_CLASS), "inner", "J")
|
||||||
|
|
||||||
|
#define RETURNWRAP(env, inner) jclass __cls=FIND_CLASS_(env, PARSER_CLASS); \
|
||||||
|
assert(__cls != NULL); \
|
||||||
|
jmethodID __constructor = REFCONSTRUCTOR_(env, __cls); \
|
||||||
|
assert(__constructor != NULL); \
|
||||||
|
return (*env)->NewObject(env, __cls, __constructor, (jlong)inner)
|
||||||
|
|
||||||
|
#define UNWRAP(env, object) (HParser *)((*env)->GetLongField(env, object, PARSER_REF(env)))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -62,6 +62,8 @@ include ../common.mk
|
||||||
$(TESTS): CFLAGS += $(TEST_CFLAGS)
|
$(TESTS): CFLAGS += $(TEST_CFLAGS)
|
||||||
$(TESTS): LDFLAGS += $(TEST_LDFLAGS)
|
$(TESTS): LDFLAGS += $(TEST_LDFLAGS)
|
||||||
|
|
||||||
|
CFLAGS += -fPIC
|
||||||
|
|
||||||
all: libhammer.a
|
all: libhammer.a
|
||||||
|
|
||||||
libhammer.a: $(HAMMER_PARTS)
|
libhammer.a: $(HAMMER_PARTS)
|
||||||
|
|
|
||||||
|
|
@ -167,14 +167,18 @@ typedef struct HBenchmarkResults_ {
|
||||||
rtype_t name(__VA_ARGS__, ...); \
|
rtype_t name(__VA_ARGS__, ...); \
|
||||||
rtype_t name##__m(HAllocator* mm__, __VA_ARGS__, ...); \
|
rtype_t name##__m(HAllocator* mm__, __VA_ARGS__, ...); \
|
||||||
rtype_t name##__mv(HAllocator* mm__, __VA_ARGS__, va_list ap); \
|
rtype_t name##__mv(HAllocator* mm__, __VA_ARGS__, va_list ap); \
|
||||||
rtype_t name##__v(__VA_ARGS__, va_list ap)
|
rtype_t name##__v(__VA_ARGS__, va_list ap); \
|
||||||
|
rtype_t name##__a(void *args[]); \
|
||||||
|
rtype_t name##__ma(HAllocator *mm__, void *args[])
|
||||||
|
|
||||||
// Note: this drops the attributes on the floor for the __v versions
|
// Note: this drops the attributes on the floor for the __v versions
|
||||||
#define HAMMER_FN_DECL_VARARGS_ATTR(attr, rtype_t, name, ...) \
|
#define HAMMER_FN_DECL_VARARGS_ATTR(attr, rtype_t, name, ...) \
|
||||||
rtype_t name(__VA_ARGS__, ...) attr; \
|
rtype_t name(__VA_ARGS__, ...) attr; \
|
||||||
rtype_t name##__m(HAllocator* mm__, __VA_ARGS__, ...) attr; \
|
rtype_t name##__m(HAllocator* mm__, __VA_ARGS__, ...) attr; \
|
||||||
rtype_t name##__mv(HAllocator* mm__, __VA_ARGS__, va_list ap); \
|
rtype_t name##__mv(HAllocator* mm__, __VA_ARGS__, va_list ap); \
|
||||||
rtype_t name##__v(__VA_ARGS__, va_list ap)
|
rtype_t name##__v(__VA_ARGS__, va_list ap); \
|
||||||
|
rtype_t name##__a(void *args[]); \
|
||||||
|
rtype_t name##__ma(HAllocator *mm__, void *args[])
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,3 +72,27 @@ const HParser* h_choice__mv(HAllocator* mm__, const HParser* p, va_list ap_) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HParser* h_choice__a(void *args[]) {
|
||||||
|
return h_choice__ma(&system_allocator, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HParser* h_choice__ma(HAllocator* mm__, void *args[]) {
|
||||||
|
size_t len = -1; // because do...while
|
||||||
|
const HParser *arg;
|
||||||
|
|
||||||
|
do {
|
||||||
|
arg=((HParser **)args)[++len];
|
||||||
|
} while(arg);
|
||||||
|
|
||||||
|
HSequence *s = h_new(HSequence, 1);
|
||||||
|
s->p_array = h_new(const HParser *, len);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
s->p_array[i] = ((HParser **)args)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
s->len = len;
|
||||||
|
HParser *ret = h_new(HParser, 1);
|
||||||
|
ret->vtable = &choice_vt; ret->env = (void*)s;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,3 +73,28 @@ const HParser* h_sequence__mv(HAllocator* mm__, const HParser *p, va_list ap_) {
|
||||||
ret->vtable = &sequence_vt; ret->env = (void*)s;
|
ret->vtable = &sequence_vt; ret->env = (void*)s;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HParser* h_sequence__a(void *args[]) {
|
||||||
|
return h_sequence__ma(&system_allocator, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HParser* h_sequence__ma(HAllocator* mm__, void *args[]) {
|
||||||
|
size_t len = -1; // because do...while
|
||||||
|
const HParser *arg;
|
||||||
|
|
||||||
|
do {
|
||||||
|
arg=((HParser **)args)[++len];
|
||||||
|
} while(arg);
|
||||||
|
|
||||||
|
HSequence *s = h_new(HSequence, 1);
|
||||||
|
s->p_array = h_new(const HParser *, len);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
s->p_array[i] = ((HParser **)args)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
s->len = len;
|
||||||
|
HParser *ret = h_new(HParser, 1);
|
||||||
|
ret->vtable = &sequence_vt; ret->env = (void*)s;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue