@Override protected void createStateMachines(final String[] httpVerbs, final String[] httpVersions, final String[] standardHeaders, final String className, final ClassFile file, final ClassMethod sctor, final AtomicInteger fieldCounter) { createStateMachine(httpVersions, className, file, sctor, fieldCounter, HANDLE_HTTP_VERSION, new VersionStateMachine(), false); createStateMachine(standardHeaders, className, file, sctor, fieldCounter, HANDLE_HEADER, new HeaderStateMachine(), false); }
protected void createStateMachines(final String[] httpVerbs, final String[] httpVersions, final String[] standardHeaders, final String className, final ClassFile file, final ClassMethod sctor, final AtomicInteger fieldCounter) { createStateMachine(httpVerbs, className, file, sctor, fieldCounter, HANDLE_HTTP_VERB, new VerbStateMachine(), false); createStateMachine(httpVersions, className, file, sctor, fieldCounter, HANDLE_HTTP_VERSION, new VersionStateMachine(), true); createStateMachine(standardHeaders, className, file, sctor, fieldCounter, HANDLE_HEADER, new HeaderStateMachine(), false); }
private static void addStates(final State initial, final String value, final List<State> allStates) { addStates(initial, value, 0, allStates); }
final RequestParserGenerator requestGenerator = new RequestParserGenerator(((TypeElement) element).getQualifiedName().toString()); final byte[] newClass = requestGenerator.createTokenizer(parser.methods(), parser.protocols(), parser.headers()); try { JavaFileObject file = filer.createClassFile(((TypeElement) element).getQualifiedName() + AbstractParserGenerator.CLASS_NAME_SUFFIX, element); ResponseParserGenerator responseGenerator = new ResponseParserGenerator(((TypeElement) element).getQualifiedName().toString()); final HttpResponseParserConfig parser = element.getAnnotation(HttpResponseParserConfig.class); if (parser == null) { continue; final byte[] newClass = responseGenerator.createTokenizer(new String[0], parser.protocols(), parser.headers()); try { JavaFileObject file = filer.createClassFile(((TypeElement) element).getQualifiedName() + AbstractParserGenerator.CLASS_NAME_SUFFIX, element);
private void invokeState(final String className, final ClassFile file, final CodeAttribute c, final State currentState, final State initialState, final CodeLocation noStateStart, final CodeLocation prefixStart, final CodeLocation returnIncompleteCode, final CodeLocation returnCompleteCode, final CustomStateMachine stateMachine, boolean expectNewline) { currentState.mark(c); c.pop(); handleReturnIfNoMoreBytes(c, returnIncompleteCode); c.aload(BYTE_BUFFER_VAR); c.invokevirtual(ByteBuffer.class.getName(), "get", "()B"); handleReturnIfNoMoreBytes(c, returnIncompleteCode); if (stateMachine.isHeader()) { c.iconst(':'); tokenEnds.add(c.ifIcmpeq()); stateMachine.handleStateMachineMatchedToken(c); tokenDone(c, returnCompleteCode, stateMachine); } else { if (stateMachine.initialNewlineMeansRequestDone()) { c.iconst('\n'); parseDone = c.ifIcmpeq(); setupLocalVariables(c); handleReturnIfNoMoreBytes(c, returnIncompleteCode); initialState.jumpTo(c); state.jumpTo(c);
stateNotFound(c, builder); setupLocalVariables(c); final CodeLocation returnIncompleteCode = c.mark(); c.aload(PARSE_STATE_VAR); c.putfield(parseStateClass, "parseState", "I"); c.returnInstruction(); setupLocalVariables(c); final CodeLocation returnCompleteCode = c.mark(); c.aload(PARSE_STATE_VAR); handleReturnIfNoMoreBytes(c, returnIncompleteCode); final Set<BranchEnd> prefixHandleSpace = new LinkedHashSet<BranchEnd>(); final Set<BranchEnd> badPrefixHandleSpace = new LinkedHashSet<BranchEnd>(); if (stateMachine.isHeader()) { c.iconst(':'); prefixHandleSpace.add(c.ifIcmpeq()); handleReturnIfNoMoreBytes(c, returnIncompleteCode); c.gotoInstruction(prefixLoop); c.iload(STATE_POS_VAR); c.invokespecial(HTTP_STRING_CLASS, "<init>", "([BII)V"); stateMachine.handleOtherToken(c); tokenDone(c, returnCompleteCode, stateMachine);
protected void createStateMachine(final String[] originalItems, final String className, final ClassFile file, final ClassMethod sctor, final AtomicInteger fieldCounter, final String methodName, final CustomStateMachine stateMachine, boolean expectNewline) { //list of all states except the initial final List<State> allStates = new ArrayList<State>(); final State initial = new State((byte) 0, ""); for (String value : originalItems) { addStates(initial, value, allStates); } //we want initial to be number 0 final AtomicInteger stateCounter = new AtomicInteger(-1); setupStateNo(initial, stateCounter, fieldCounter); for (State state : allStates) { setupStateNo(state, stateCounter, fieldCounter); createStateField(state, file, sctor.getCodeAttribute()); } final int noStates = stateCounter.get(); final ClassMethod handle = file.addMethod(Modifier.PROTECTED | Modifier.FINAL, methodName, "V", DescriptorUtils.makeDescriptor(ByteBuffer.class), parseStateDescriptor, httpExchangeDescriptor); handle.addCheckedExceptions(BAD_REQUEST_EXCEPTION); writeStateMachine(className, file, handle.getCodeAttribute(), initial, allStates, noStates, stateMachine, expectNewline); }
@HttpResponseParserConfig( protocols = { HTTP_0_9_STRING, HTTP_1_0_STRING, HTTP_1_1_STRING
@HttpParserConfig(methods = { OPTIONS_STRING, GET_STRING,
private static void addStates(final State current, final String value, final int i, final List<State> allStates) { if (i == value.length()) { return; } byte[] bytes = value.getBytes(StandardCharsets.UTF_8); final byte currentByte = bytes[i]; State newState = current.next.get(currentByte); if (newState == null) { current.next.put(currentByte, newState = new State(currentByte, value.substring(0, i + 1))); allStates.add(newState); } addStates(newState, value, i + 1, allStates); }
private void tokenDone(final CodeAttribute c, final CodeLocation returnCode, final CustomStateMachine stateMachine) { stateMachine.updateParseState(c); c.gotoInstruction(returnCode); }
public byte[] createTokenizer(final String[] httpVerbs, String[] httpVersions, String[] standardHeaders) { final String className = existingClassName + CLASS_NAME_SUFFIX; final ClassFile file = new ClassFile(className, existingClassName); final ClassMethod ctor = file.addMethod(AccessFlag.PUBLIC, "<init>", "V", DescriptorUtils.parameterDescriptors(constructorDescriptor)); ctor.getCodeAttribute().aload(0); ctor.getCodeAttribute().loadMethodParameters(); ctor.getCodeAttribute().invokespecial(existingClassName, "<init>", constructorDescriptor); ctor.getCodeAttribute().returnInstruction(); final ClassMethod sctor = file.addMethod(AccessFlag.PUBLIC | AccessFlag.STATIC, "<clinit>", "V"); final AtomicInteger fieldCounter = new AtomicInteger(1); sctor.getCodeAttribute().invokestatic(existingClassName, "httpStrings", "()" + DescriptorUtils.makeDescriptor(Map.class)); sctor.getCodeAttribute().astore(CONSTRUCTOR_HTTP_STRING_MAP_VAR); createStateMachines(httpVerbs, httpVersions, standardHeaders, className, file, sctor, fieldCounter); sctor.getCodeAttribute().returnInstruction(); return file.toBytecode(); }
@HttpResponseParserConfig( protocols = { HTTP_0_9_STRING, HTTP_1_0_STRING, HTTP_1_1_STRING
@HttpParserConfig(methods = { OPTIONS_STRING, GET_STRING,
@HttpResponseParserConfig( protocols = { HTTP_0_9_STRING, HTTP_1_0_STRING, HTTP_1_1_STRING
@HttpParserConfig(methods = { OPTIONS_STRING, GET_STRING,