All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.core.parsetools.impl.RecordParserImpl Maven / Gradle / Ivy

There is a newer version: 4.5.10
Show newest version
/*
 * Copyright (c) 2011-2013 The original author or authors
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 *     The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 *
 *     The Apache License v2.0 is available at
 *     http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

package io.vertx.core.parsetools.impl;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.Arguments;
import io.vertx.core.parsetools.RecordParser;

import java.util.Objects;

/**
 * @author Tim Fox
 * @author Lars Timm
 */
public class RecordParserImpl implements RecordParser {

  private Buffer buff;
  private int pos;            // Current position in buffer
  private int start;          // Position of beginning of current record
  private int delimPos;       // Position of current match in delimiter array
  private boolean reset;      // Allows user to toggle mode / change delim when records are emitted

  private boolean delimited;
  private byte[] delim;
  private int recordSize;
  private Handler output;

  private RecordParserImpl(Handler output) {
    this.output = output;
  }

  public void setOutput(Handler output) {
    Objects.requireNonNull(output, "output");
    this.output = output;
  }

  /**
   * Helper method to convert a latin-1 String to an array of bytes for use as a delimiter
   * Please do not use this for non latin-1 characters
   *
   * @param str  the string
   * @return The byte[] form of the string
   */
  public static Buffer latin1StringToBytes(String str) {
    byte[] bytes = new byte[str.length()];
    for (int i = 0; i < str.length(); i++) {
      char c = str.charAt(i);
      bytes[i] = (byte) (c & 0xFF);
    }
    return Buffer.buffer(bytes);
  }

  /**
   * Create a new {@code RecordParser} instance, initially in delimited mode, and where the delimiter can be represented
   * by the String {@code} delim endcoded in latin-1 . Don't use this if your String contains other than latin-1 characters.
   * 

* {@code output} Will receive whole records which have been parsed. * * @param delim the initial delimiter string * @param output handler that will receive the output */ public static RecordParser newDelimited(String delim, Handler output) { return newDelimited(latin1StringToBytes(delim), output); } /** * Create a new {@code RecordParser} instance, initially in delimited mode, and where the delimiter can be represented * by the {@code buffer} delim. *

* {@code output} Will receive whole records which have been parsed. * * @param delim the initial delimiter buffer * @param output handler that will receive the output */ public static RecordParser newDelimited(Buffer delim, Handler output) { RecordParserImpl ls = new RecordParserImpl(output); ls.delimitedMode(delim); return ls; } /** * Create a new {@code RecordParser} instance, initially in fixed size mode, and where the record size is specified * by the {@code size} parameter. *

* {@code output} Will receive whole records which have been parsed. * * @param size the initial record size * @param output handler that will receive the output */ public static RecordParser newFixed(int size, Handler output) { Arguments.require(size > 0, "Size must be > 0"); RecordParserImpl ls = new RecordParserImpl(output); ls.fixedSizeMode(size); return ls; } /** * Flip the parser into delimited mode, and where the delimiter can be represented * by the String {@code delim} encoded in latin-1 . Don't use this if your String contains other than latin-1 characters. *

* This method can be called multiple times with different values of delim while data is being parsed. * * @param delim the new delimeter */ public void delimitedMode(String delim) { delimitedMode(latin1StringToBytes(delim)); } /** * Flip the parser into delimited mode, and where the delimiter can be represented * by the delimiter {@code delim}. *

* This method can be called multiple times with different values of delim while data is being parsed. * * @param delim the new delimiter */ public void delimitedMode(Buffer delim) { Objects.requireNonNull(delim, "delim"); delimited = true; this.delim = delim.getBytes(); delimPos = 0; reset = true; } /** * Flip the parser into fixed size mode, where the record size is specified by {@code size} in bytes. *

* This method can be called multiple times with different values of size while data is being parsed. * * @param size the new record size */ public void fixedSizeMode(int size) { Arguments.require(size > 0, "Size must be > 0"); delimited = false; recordSize = size; reset = true; } private void handleParsing() { int len = buff.length(); do { reset = false; if (delimited) { parseDelimited(); } else { parseFixed(); } } while (reset); if (start == len) { //Nothing left buff = null; pos = 0; } else { buff = buff.getBuffer(start, len); pos = buff.length(); } start = 0; } private void parseDelimited() { int len = buff.length(); for (; pos < len && !reset; pos++) { if (buff.getByte(pos) == delim[delimPos]) { delimPos++; if (delimPos == delim.length) { Buffer ret = buff.getBuffer(start, pos - delim.length + 1); start = pos + 1; delimPos = 0; output.handle(ret); } } else { if (delimPos > 0) { pos -= delimPos; delimPos = 0; } } } } private void parseFixed() { int len = buff.length(); while (len - start >= recordSize && !reset) { int end = start + recordSize; Buffer ret = buff.getBuffer(start, end); start = end; pos = start - 1; output.handle(ret); } } /** * This method is called to provide the parser with data. * * @param buffer a chunk of data */ public void handle(Buffer buffer) { if (buff == null) { buff = buffer; } else { buff.appendBuffer(buffer); } handleParsing(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy