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
|
||||
# Also, "make src/all" turns into "make -C src all"
|
||||
|
||||
SUBDIRS = src examples
|
||||
SUBDIRS = src examples jni
|
||||
|
||||
include config.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ include $(TOPLEVEL)/config.mk
|
|||
TEST_CFLAGS = $(shell pkg-config --cflags glib-2.0) -DINCLUDE_TESTS
|
||||
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 :=
|
||||
|
||||
CC ?= gcc
|
||||
|
|
|
|||
|
|
@ -1,38 +1,18 @@
|
|||
import com.upstandinghackers.hammer.*;
|
||||
import java.util.Arrays;
|
||||
/**
|
||||
* Example JHammer usage
|
||||
*/
|
||||
|
||||
public class Example
|
||||
{
|
||||
|
||||
private HParser initParser()
|
||||
{
|
||||
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()}});
|
||||
static {
|
||||
System.loadLibrary("jhammer");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
System.out.println("FAIL");
|
||||
|
|
@ -40,10 +20,73 @@ public static void main(String args[])
|
|||
else
|
||||
{
|
||||
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:
|
||||
javac com/upstandinghackers/hammer/*.java
|
||||
USING THE JNI BINDINGS:
|
||||
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:
|
||||
find -name "*.class" | sed -e 's/.class$//' | tr '/' '.' | cut -c 3- | xargs javah
|
||||
|
||||
Not working:
|
||||
enums aren't converted at all, no idea why
|
||||
UNIMPLEMENTED:
|
||||
User-defined types, predicates and actions are unimplemented.
|
||||
Memory leaks because there is no reliable garbage collection.
|
||||
|
||||
TODO:
|
||||
Implement the entire JNI side
|
||||
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;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Hammer
|
||||
{
|
||||
|
|
@ -7,59 +8,69 @@ public class Hammer
|
|||
public final static byte BYTE_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),
|
||||
TT_BYTES(2),
|
||||
TT_SINT(4),
|
||||
TT_UINT(8),
|
||||
TT_SEQUENCE(16),
|
||||
TT_ERR(32),
|
||||
TT_USER(64),
|
||||
NONE(1),
|
||||
BYTES(2),
|
||||
SINT(4),
|
||||
UINT(8),
|
||||
SEQUENCE(16),
|
||||
ERR(32),
|
||||
USER(64);
|
||||
|
||||
private int 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);
|
||||
public static native HParser token(byte[] str, int length);
|
||||
public static native HParser ch(byte c);
|
||||
public static native HParser chRange(byte from, byte to);
|
||||
public static native HParser intRange(HParser p, int lower, int upper);
|
||||
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 HParser int8();
|
||||
public static native HParser uInt64();
|
||||
public static native HParser uInt32();
|
||||
public static native HParser uInt16();
|
||||
public static native HParser uInt8();
|
||||
public static native HParser whitespace(HParser p);
|
||||
public static native HParser left(HParser p, HParser q);
|
||||
public static native HParser right(HParser p, HParser q);
|
||||
public static native HParser middle(HParser p, HParser x, HParser q);
|
||||
public static native HParser action(HParser p, HAction a);
|
||||
public static native HParser in(byte[] charset, int length);
|
||||
public static native HParser endP();
|
||||
public static native HParser nothingP();
|
||||
public static native HParser sequence(HParser[] parsers);
|
||||
public static native HParser choice(HParser[] parsers);
|
||||
public static native HParser butNot(HParser p1, HParser p2);
|
||||
public static native HParser difference(HParser p1, HParser p2);
|
||||
public static native HParser xor(HParser p1, HParser p2);
|
||||
public static native HParser many(HParser p);
|
||||
public static native HParser many1(HParser p);
|
||||
public static native HParser repeatN(HParser p, int n);
|
||||
public static native HParser optional(HParser p);
|
||||
public static native HParser ignore(HParser p);
|
||||
public static native HParser sepBy(HParser p, HParser sep);
|
||||
public static native HParser sepBy1(HParser p, HParser sep);
|
||||
public static native HParser epsilonP();
|
||||
public static native HParser lengthValue(HParser length, HParser value);
|
||||
public static native HParser attrBool(HParser p, HPredicate pred);
|
||||
public static native HParser and(HParser p);
|
||||
public static native HParser not(HParser p);
|
||||
public static native HParser indirect();
|
||||
static
|
||||
{
|
||||
for(TokenType tt : TokenType.values())
|
||||
{
|
||||
Hammer.tokenTypeMap.put(new Integer(tt.getValue()), tt);
|
||||
}
|
||||
}
|
||||
|
||||
public static native ParseResult parse(Parser parser, byte[] input, int length);
|
||||
public static native Parser token(byte[] str, int length);
|
||||
public static native Parser ch(byte c);
|
||||
public static native Parser chRange(byte from, byte to);
|
||||
public static native Parser intRange(Parser p, long lower, long upper);
|
||||
public static native Parser bits(int len, boolean sign);
|
||||
public static native Parser int64();
|
||||
public static native Parser int32();
|
||||
public static native Parser int16();
|
||||
public static native Parser int8();
|
||||
public static native Parser uInt64();
|
||||
public static native Parser uInt32();
|
||||
public static native Parser uInt16();
|
||||
public static native Parser uInt8();
|
||||
public static native Parser whitespace(Parser p);
|
||||
public static native Parser left(Parser p, Parser q);
|
||||
public static native Parser right(Parser p, Parser q);
|
||||
public static native Parser middle(Parser p, Parser x, Parser q);
|
||||
// public static native Parser action(Parser p, Action a);
|
||||
public static native Parser in(byte[] charset, int length);
|
||||
public static native Parser endP();
|
||||
public static native Parser nothingP();
|
||||
public static native Parser sequence(Parser[] parsers);
|
||||
public static native Parser choice(Parser[] parsers);
|
||||
public static native Parser butNot(Parser p1, Parser p2);
|
||||
public static native Parser difference(Parser p1, Parser p2);
|
||||
public static native Parser xor(Parser p1, Parser p2);
|
||||
public static native Parser many(Parser p);
|
||||
public static native Parser many1(Parser p);
|
||||
public static native Parser repeatN(Parser p, int n);
|
||||
public static native Parser optional(Parser p);
|
||||
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): LDFLAGS += $(TEST_LDFLAGS)
|
||||
|
||||
CFLAGS += -fPIC
|
||||
|
||||
all: libhammer.a
|
||||
|
||||
libhammer.a: $(HAMMER_PARTS)
|
||||
|
|
|
|||
|
|
@ -167,14 +167,18 @@ typedef struct HBenchmarkResults_ {
|
|||
rtype_t name(__VA_ARGS__, ...); \
|
||||
rtype_t name##__m(HAllocator* mm__, __VA_ARGS__, ...); \
|
||||
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
|
||||
#define HAMMER_FN_DECL_VARARGS_ATTR(attr, rtype_t, name, ...) \
|
||||
rtype_t name(__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##__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;
|
||||
}
|
||||
|
||||
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;
|
||||
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