文字列を「,」(半角カンマ)または「\t」(タブ)で分割しListに格納して返します。分割後の1要素の文字列が「
"」(半角ダブルクオーテーション)で開始かつ終了していた場合は、 前後の「"」を除きます。
分割後の要素数が下限値に満たない場合でも、空文字をList末尾に追加して下限値となるようにします。

@param line
分割対象の文字列
@param minCnt
分割後の要素数の下限値
@return 「,」(半角カンマ)または「\t」(タブ)で分割した文字を格納するList
437559
public static List<String> splitToCells(String line, int minCnt) {

        LOG.trace("split line : {}", line);

        List<String> newCells = new ArrayList<String>();

        for (Iterator<String> cellItr = Arrays.asList(line.split(",")).iterator(); cellItr
                .hasNext();) {

            String cell = cellItr.next();
            StringBuilder builder = new StringBuilder(cell);

            // セル内のダブルクオーテーションが奇数個の場合はセル内分割があるとみなし、
            // 次のダブルクオーテーションが奇数個のセルまで連結して1セルとする。
            if (StringUtils.countMatches(cell, '"') % 2 != 0) {

                do {
                    cell = cellItr.next();
                    // splitで除外された「,」をappend
                    builder.append(",");
                    builder.append(cell);

                } while (StringUtils.countMatches(cell, '"') % 2 == 0 && cellItr.hasNext());

            }

            newCells.add(modifyStr(builder.toString()));

        }

        while (newCells.size() < minCnt) {
            newCells.add("");
        }

        LOG.trace("new cells : {}", newCells);

        return newCells;
    }
650364
private int readCustomLine(Text str, int maxLineLength, int maxBytesToConsume)
            throws IOException
    {
        /* We're reading data from inputStream, but the head of the stream may be
         *  already captured in the previous buffer, so we have several cases:
         *
         * 1. The buffer tail does not contain any character sequence which
         *    matches with the head of delimiter. We count it as a
         *    ambiguous byte count = 0
         *
         * 2. The buffer tail contains a X number of characters,
         *    that forms a sequence, which matches with the
         *    head of delimiter. We count ambiguous byte count = X
         *
         *    // ***  eg: A segment of input file is as follows
         *
         *    " record 1792: I found this bug very interesting and
         *     I have completely read about it. record 1793: This bug
         *     can be solved easily record 1794: This ."
         *
         *    delimiter = "record";
         *
         *    supposing:- String at the end of buffer =
         *    "I found this bug very interesting and I have completely re"
         *    There for next buffer = "ad about it. record 179       ...."
         *
         *     The matching characters in the input
         *     buffer tail and delimiter head = "re"
         *     Therefore, ambiguous byte count = 2 ****   //
         *
         *     2.1 If the following bytes are the remaining characters of
         *         the delimiter, then we have to capture only up to the starting
         *         position of delimiter. That means, we need not include the
         *         ambiguous characters in str.
         *
         *     2.2 If the following bytes are not the remaining characters of
         *         the delimiter ( as mentioned in the example ),
         *         then we have to include the ambiguous characters in str.
         */
        str.clear();
        int txtLength = 0; // tracks str.getLength(), as an optimization
        long bytesConsumed = 0;
        int delPosn = 0;
        int ambiguousByteCount = 0; // To capture the ambiguous characters count
        do {
            int startPosn = bufferPosn; // Start from previous end position
            if (bufferPosn >= bufferLength) {
                startPosn = bufferPosn = 0;
                bufferLength = fillBuffer(in, buffer, ambiguousByteCount > 0);
                if (bufferLength <= 0) {
                    if (ambiguousByteCount > 0) {
                        str.append(recordDelimiterBytes, 0, ambiguousByteCount);
                        bytesConsumed += ambiguousByteCount;
                    }
                    break; // EOF
                }
            }
            for (; bufferPosn < bufferLength; ++bufferPosn) {
                if (buffer[bufferPosn] == recordDelimiterBytes[delPosn]) {
                    delPosn++;
                    if (delPosn >= recordDelimiterBytes.length) {
                        bufferPosn++;
                        break;
                    }
                }
                else if (delPosn != 0) {
                    bufferPosn -= delPosn;
                    if (bufferPosn < -1) {
                        bufferPosn = -1;
                    }
                    delPosn = 0;
                }
            }
            int readLength = bufferPosn - startPosn;
            bytesConsumed += readLength;
            int appendLength = readLength - delPosn;
            if (appendLength > maxLineLength - txtLength) {
                appendLength = maxLineLength - txtLength;
                if (appendLength > 0) {
                    // We want to fail the read when the line length is over the limit.
                    throw new TextLineLengthLimitExceededException("Too many bytes before delimiter: " + maxLineLength);
                }
            }
            bytesConsumed += ambiguousByteCount;
            if (appendLength >= 0 && ambiguousByteCount > 0) {
                //appending the ambiguous characters (refer case 2.2)
                str.append(recordDelimiterBytes, 0, ambiguousByteCount);
                ambiguousByteCount = 0;
                // since it is now certain that the split did not split a delimiter we
                // should not read the next record: clear the flag otherwise duplicate
                // records could be generated
                unsetNeedAdditionalRecordAfterSplit();
            }
            if (appendLength > 0) {
                int newTxtLength = txtLength + appendLength;
                if (str.getBytes().length < newTxtLength && Math.max(newTxtLength, txtLength << 1) > MAX_ARRAY_SIZE) {
                    // If str need to be resized but the target capacity is over VM limit, it will trigger OOM.
                    // In such case we will throw an IOException so the caller can deal with it.
                    throw new TextLineLengthLimitExceededException("Too many bytes before delimiter: " + newTxtLength);
                }
                str.append(buffer, startPosn, appendLength);
                txtLength = newTxtLength;
            }
            if (bufferPosn >= bufferLength) {
                if (delPosn > 0 && delPosn < recordDelimiterBytes.length) {
                    ambiguousByteCount = delPosn;
                    bytesConsumed -= ambiguousByteCount; //to be consumed in next
                }
            }
        }
        while (delPosn < recordDelimiterBytes.length
                && bytesConsumed < maxBytesToConsume);
        if (delPosn < recordDelimiterBytes.length
                && bytesConsumed >= maxBytesToConsume) {
            // It is possible that bytesConsumed is over the maxBytesToConsume but we
            // didn't append anything to str.bytes. If we have consumed over maxBytesToConsume
            // bytes but still haven't seen a line terminator, we will fail the read.
            throw new TextLineLengthLimitExceededException("Too many bytes before delimiter: " + bytesConsumed);
        }
        return (int) bytesConsumed;
    }
240332
function (line) {
    /**
     * Background line : 0,0,"bg.jpg"
     * TODO: confirm that the second member is always zero
     *
     * Breaktimes lines : 2,1000,2000
     * second integer is start offset
     * third integer is end offset
     */
    members = line.split(',');

    if (members[0] == '0' && members[1] == '0' && members[2]) {
      var bgName = members[2].trim();

      if (bgName.charAt(0) == '"' && bgName.charAt(bgName.length - 1) == '"') {
        beatmap.bgFilename = bgName.substring(1, bgName.length - 1);
      } else {
        beatmap.bgFilename = bgName;
      }
    } else if (members[0] == '2' && /^[0-9]+$/.test(members[1]) && /^[0-9]+$/.test(members[2])) {
      beatmap.breakTimes.push({
        startTime: parseInt(members[1]),
        endTime: parseInt(members[2])
      });
    }
  }
487057
function getLineInfo(bRet,bNum,code) {
    var numCount = 0, hintCount = 0;
    var bLn = code.split(ln_re_), len = bLn.length;
    var iLastLn = -1, sLastNum = '0';
    for (var i=0; i < len; i++) {
      var item = bLn[i], hasHint = false;
      var sNew = item.replace(hint_re_, function(sMatch) {
        hasHint = true; hintCount += 1;
        var iTmp = sMatch.length;
        if (iLastLn + 1 == i) {
          iLastLn = i; sLastNum = (parseInt(sLastNum) + 1) + '';
          iTmp -= 1;
          sLastNum = sLastNum.slice(-iTmp);  // trim to same width: ~~
          if (sLastNum.length < iTmp) sLastNum = (new Array(iTmp-sLastNum.length+1)).join('0') + sLastNum;
          bRet[i] = sLastNum + '!';
        }
        else bRet[i] = (new Array(iTmp)).join(' ') + '!';
        return '';
      });
      
      if (hasHint)
        bLn[i] = sNew;
      else {
        var hasNum = false;
        var sNew2 = item.replace(num_re_, function(sMatch) {
          hasNum = true; numCount += 1;
          sLastNum = bRet[i] = sMatch.slice(0,-1);
          iLastLn = i;
          return '';
        });
        if (hasNum) bLn[i] = sNew2;
      }
    }
    
    if (!bRet.length)   // no changing
      return code;
    else {
      if (!hintCount && numCount <= 1) {  // avoid accident preceed-number
        bRet.splice(0);
        return code;    // no changing
      }
      else {
        if (numCount) bNum.push(numCount);
        return bLn.join('\n');
      }
    }
  }
89533
private static State nextNormal(final State state,
        final ByteArrayOutputStream line, final int next) {
        final State result;
        switch (next) {
            case '\r':
                result = State.R;
                break;
            case '\"':
                result = State.QUOTED_STRING;
                break;
            default:
                result = state;
                line.write(next);
                break;
        }
        return result;
    }
638344
public static List<String> splitStringCommaSpace(String line) {
		List<String> words=new ArrayList<>();
		int len=line.length();
		int pos=0;
		while(pos<len) {
			// Skip past blank space
			char ch;
			while(pos<len && ((ch=line.charAt(pos))<=' ' || ch==',')) pos++;
			int start=pos;
			// Skip to the next blank space
			while(pos<len && (ch=line.charAt(pos))>' ' && ch!=',') pos++;
			if(pos>start) words.add(line.substring(start,pos));
		}
		return words;
	}
729916
protected String[] getLineParts(final String line) {
		String[] parts = line.split(" ");
		List<String> ans = new ArrayList<>();
		int idx = 0;
		int len = parts.length;
		while (idx < len) {
			if (parts[idx].contains("='") && !parts[idx].endsWith("'")) {
				StringBuilder builder = new StringBuilder(parts[idx++]);
				while (idx < len) {
					builder.append(" ").append(parts[idx]);
					if (parts[idx++].endsWith("'")) {
						break;
					}
				}
				ans.add(builder.toString());
			} else if (parts[idx].contains("=[") && !parts[idx].endsWith("]")) {
				StringBuilder builder = new StringBuilder(parts[idx++]);
				while (idx < len) {
					builder.append(" ").append(parts[idx]);
					if (parts[idx++].endsWith("]")) {
						break;
					}
				}
				ans.add(builder.toString());
			} else {
				String part = parts[idx++];
				if (StringUtils.isNotEmpty(part)) {
					ans.add(part);
				}
			}
		}
		return ans.toArray(new String[ans.size()]);
	}
20802
def _line_2_pair(line):
    '''
    '''
    key, val = line.split('=')
    return key.lower(), val.strip('"')
395640
private void convertError(CharBuffer buf, int line)
  {
    String srcFilename = null;
    int destLine = 0;
    int srcLine = 0;
    int srcTailLine = Integer.MAX_VALUE;
    
    for (int i = 0; i < _lines.size(); i++) {
      Line map = (Line) _lines.get(i);

      if (map._dstLine <= line && line <= map.getLastDestinationLine()) {
        srcFilename = map._srcFilename;
        destLine = map._dstLine;
        srcLine = map.getSourceLine(line);
        break;
      }
    }

    if (srcFilename != null) {
    }
    else if (_lines.size() > 0)
      srcFilename = ((Line) _lines.get(0))._srcFilename;
    else
      srcFilename = "";

    buf.append(srcFilename);
    if (line >= 0) {
      buf.append(":");
      buf.append(srcLine + (line - destLine));
    }
  }
497767
private List<String> breakLines(List<LineNumberPosition> o_LineBrokenPositions) throws IOException
    {
        int numLinesRead = 0;
        int lineOffset = 0;
        List<String> brokenLines = new ArrayList<>();

        try (BufferedReader r = new BufferedReader(new FileReader(_file)))
        {
            for (int posIndex = 0; posIndex < _positions.size(); posIndex++)
            {
                LineNumberPosition pos = _positions.get(posIndex);
                o_LineBrokenPositions.add(new LineNumberPosition(
                            pos.getOriginalLine(), pos.getEmittedLine() + lineOffset, pos.getEmittedColumn()));

                // Copy the input file up to but not including the emitted line # in "pos".
                while (numLinesRead < pos.getEmittedLine() - 1)
                {
                    brokenLines.add(r.readLine());
                    numLinesRead++;
                }

                // Read the line that contains the next line number annotations, but don't write it yet.
                String line = r.readLine();
                numLinesRead++;

                // See if there are two original line annotations on the same emitted line.
                LineNumberPosition nextPos;
                int prevPartLen = 0;
                char[] indent = {};
                do
                {
                    nextPos = (posIndex < _positions.size() - 1) ? _positions.get(posIndex + 1) : null;
                    if (nextPos != null
                                && nextPos.getEmittedLine() == pos.getEmittedLine()
                                && nextPos.getOriginalLine() > pos.getOriginalLine())
                    {
                        // Two different source line numbers on the same emitted line!
                        posIndex++;
                        lineOffset++;
                        String firstPart = line.substring(0, nextPos.getEmittedColumn() - prevPartLen - 1);
                        brokenLines.add(new String(indent) + firstPart);
                        prevPartLen += firstPart.length();
                        indent = new char[prevPartLen];
                        Arrays.fill(indent, ' ');
                        line = line.substring(firstPart.length(), line.length());

                        // Alter the position while adding it.
                        o_LineBrokenPositions.add(new LineNumberPosition(
                                    nextPos.getOriginalLine(), nextPos.getEmittedLine() + lineOffset, nextPos
                                                .getEmittedColumn()));
                    }
                    else
                    {
                        nextPos = null;
                    }
                }
                while (nextPos != null);

                // Nothing special here-- just emit the line.
                brokenLines.add(new String(indent) + line);
            }

            // Copy out the remainder of the file.
            String line;
            while ((line = r.readLine()) != null)
            {
                brokenLines.add(line);
            }
        }
        return brokenLines;
    }
1277508
public static String encodeLines(final byte[] input, final int iOff, final int iLen, final int lineLen,
           final String lineSeparator) {
       final int blockLen = (lineLen * CONSTANT_3) / CONSTANT_4;
       if (blockLen <= 0) {
           throw new IllegalArgumentException();
       }
       final int lines = (iLen + blockLen - 1) / blockLen;
       final int bufLen = ((iLen + 2) / CONSTANT_3) * CONSTANT_4 + lines * lineSeparator.length();
       final StringBuilder buf = new StringBuilder(bufLen);
       int ipValue = 0;
       while (ipValue < iLen) {
           final int length = Math.min(iLen - ipValue, blockLen);
           buf.append(encode(input, iOff + ipValue, length));
           buf.append(lineSeparator);
           ipValue += length;
       }
       return buf.toString();
   }
1369907
function(ln, line_number) {

  var all_matched = true;
  var last_child;
  var first_nonspace;
  var offset = 0;
  var match;
  var data;
  var blank;
  var indent;
  var last_matched_container;
  var i;
  var CODE_INDENT = 4;

  var container = this.doc;
  var oldtip = this.tip;

  // Convert tabs to spaces:
  ln = detabLine(ln);

  // For each containing block, try to parse the associated line start.
  // Bail out on failure: container will point to the last matching block.
  // Set all_matched to false if not all containers match.
  while (container.children.length > 0) {
    last_child = container.children[container.children.length - 1];
    if (!last_child.open) {
      break;
    }
    container = last_child;

    match = matchAt(/[^ ]/, ln, offset);
    if (match === null) {
      first_nonspace = ln.length;
      blank = true;
    } else {
      first_nonspace = match;
      blank = false;
    }
    indent = first_nonspace - offset;

    switch (container.t) {
      case 'BlockQuote':
        var matched = indent <= 3 && ln.charAt(first_nonspace) === '>';
        if (matched) {
          offset = first_nonspace + 1;
          if (ln.charAt(offset) === ' ') {
            offset++;
          }
        } else {
          all_matched = false;
        }
        break;

      case 'ListItem':
        if (indent >= container.list_data.marker_offset +
                      container.list_data.padding) {
          offset += container.list_data.marker_offset +
                    container.list_data.padding;
        } else if (blank) {
          offset = first_nonspace;
        } else {
          all_matched = false;
        }
        break;

      case 'IndentedCode':
        if (indent >= CODE_INDENT) {
          offset += CODE_INDENT;
        } else if (blank) {
          offset = first_nonspace;
        } else {
          all_matched = false;
        }
        break;

      case 'ATXHeader':
      case 'SetextHeader':
      case 'HorizontalRule':
        // a header can never container > 1 line, so fail to match:
        all_matched = false;
        break;

      case 'FencedCode':
        // skip optional spaces of fence offset
        i = container.fence_offset;
        while (i > 0 && ln.charAt(offset) === ' ') {
          offset++;
          i--;
        }
        break;

      case 'HtmlBlock':
        if (blank) {
          all_matched = false;
        }
        break;

      case 'Paragraph':
        if (blank) {
          container.last_line_blank = true;
          all_matched = false;
        }
        break;

      default:
    }

    if (!all_matched) {
      container = container.parent; // back up to last matching block
      break;
    }
  }

  last_matched_container = container;

  // This function is used to finalize and close any unmatched
  // blocks.  We aren't ready to do this now, because we might
  // have a lazy paragraph continuation, in which case we don't
  // want to close unmatched blocks.  So we store this closure for
  // use later, when we have more information.
  var closeUnmatchedBlocks = function(mythis) {
    // finalize any blocks not matched
    while (!already_done && oldtip != last_matched_container) {
      mythis.finalize(oldtip, line_number);
      oldtip = oldtip.parent;
    }
    var already_done = true;
  };

  // Check to see if we've hit 2nd blank line; if so break out of list:
  if (blank && container.last_line_blank) {
    this.breakOutOfLists(container, line_number);
  }

  // Unless last matched container is a code block, try new container starts,
  // adding children to the last matched container:
  while (container.t != 'FencedCode' &&
         container.t != 'IndentedCode' &&
         container.t != 'HtmlBlock' &&
         // this is a little performance optimization:
         matchAt(/^[ #`~*+_=<>0-9-]/,ln,offset) !== null) {

    match = matchAt(/[^ ]/, ln, offset);
    if (match === null) {
      first_nonspace = ln.length;
      blank = true;
    } else {
      first_nonspace = match;
      blank = false;
    }
    indent = first_nonspace - offset;

    if (indent >= CODE_INDENT) {
      // indented code
      if (this.tip.t != 'Paragraph' && !blank) {
        offset += CODE_INDENT;
        closeUnmatchedBlocks(this);
        container = this.addChild('IndentedCode', line_number, offset);
      } else { // indent > 4 in a lazy paragraph continuation
        break;
      }

    } else if (ln.charAt(first_nonspace) === '>') {
      // blockquote
      offset = first_nonspace + 1;
      // optional following space
      if (ln.charAt(offset) === ' ') {
        offset++;
      }
      closeUnmatchedBlocks(this);
      container = this.addChild('BlockQuote', line_number, offset);

    } else if ((match = ln.slice(first_nonspace).match(/^#{1,6}(?: +|$)/))) {
      // ATX header
      offset = first_nonspace + match[0].length;
      closeUnmatchedBlocks(this);
      container = this.addChild('ATXHeader', line_number, first_nonspace);
      container.level = match[0].trim().length; // number of #s
      // remove trailing ###s:
      container.strings =
            [ln.slice(offset).replace(/(?:(\\#) *#*| *#+) *$/,'$1')];
      break;

    } else if ((match = ln.slice(first_nonspace).match(/^`{3,}(?!.*`)|^~{3,}(?!.*~)/))) {
      // fenced code block
      var fence_length = match[0].length;
      closeUnmatchedBlocks(this);
      container = this.addChild('FencedCode', line_number, first_nonspace);
      container.fence_length = fence_length;
      container.fence_char = match[0].charAt(0);
      container.fence_offset = first_nonspace - offset;
      offset = first_nonspace + fence_length;
      break;

    } else if (matchAt(reHtmlBlockOpen, ln, first_nonspace) !== null) {
      // html block
      closeUnmatchedBlocks(this);
      container = this.addChild('HtmlBlock', line_number, first_nonspace);
      // note, we don't adjust offset because the tag is part of the text
      break;

    } else if (container.t == 'Paragraph' &&
               container.strings.length === 1 &&
               ((match = ln.slice(first_nonspace).match(/^(?:=+|-+) *$/)))) {
      // setext header line
      closeUnmatchedBlocks(this);
      container.t = 'SetextHeader'; // convert Paragraph to SetextHeader
      container.level = match[0].charAt(0) === '=' ? 1 : 2;
      offset = ln.length;

    } else if (matchAt(reHrule, ln, first_nonspace) !== null) {
      // hrule
      closeUnmatchedBlocks(this);
      container = this.addChild('HorizontalRule', line_number, first_nonspace);
      offset = ln.length - 1;
      break;

    } else if ((data = parseListMarker(ln, first_nonspace))) {
      // list item
      closeUnmatchedBlocks(this);
      data.marker_offset = indent;
      offset = first_nonspace + data.padding;

      // add the list if needed
      if (container.t !== 'List' ||
          !(listsMatch(container.list_data, data))) {
           container = this.addChild('List', line_number, first_nonspace);
           container.list_data = data;
      }

      // add the list item
      container = this.addChild('ListItem', line_number, first_nonspace);
      container.list_data = data;

    } else {
      break;

    }

    if (acceptsLines(container.t)) {
      // if it's a line container, it can't contain other containers
      break;
    }
  }

  // What remains at the offset is a text line.  Add the text to the
  // appropriate container.

  match = matchAt(/[^ ]/, ln, offset);
  if (match === null) {
    first_nonspace = ln.length;
    blank = true;
  } else {
    first_nonspace = match;
    blank = false;
  }
  indent = first_nonspace - offset;

  // First check for a lazy paragraph continuation:
  if (this.tip !== last_matched_container &&
      !blank &&
      this.tip.t == 'Paragraph' &&
      this.tip.strings.length > 0) {
     // lazy paragraph continuation

    this.last_line_blank = false;
    this.addLine(ln, offset);

  } else { // not a lazy continuation

    // finalize any blocks not matched
    closeUnmatchedBlocks(this);

    // Block quote lines are never blank as they start with >
    // and we don't count blanks in fenced code for purposes of tight/loose
    // lists or breaking out of lists.  We also don't set last_line_blank
    // on an empty list item.
    container.last_line_blank = blank &&
      !(container.t == 'BlockQuote' ||
        container.t == 'FencedCode' ||
        (container.t == 'ListItem' &&
         container.children.length === 0 &&
         container.start_line == line_number));

    var cont = container;
    while (cont.parent) {
      cont.parent.last_line_blank = false;
      cont = cont.parent;
    }

    switch (container.t) {
    case 'IndentedCode':
    case 'HtmlBlock':
      this.addLine(ln, offset);
      break;

    case 'FencedCode':
      // check for closing code fence:
      match = (indent <= 3 &&
               ln.charAt(first_nonspace) == container.fence_char &&
               ln.slice(first_nonspace).match(/^(?:`{3,}|~{3,})(?= *$)/));
      if (match && match[0].length >= container.fence_length) {
        // don't add closing fence to container; instead, close it:
        this.finalize(container, line_number);
      } else {
        this.addLine(ln, offset);
      }
      break;

    case 'ATXHeader':
    case 'SetextHeader':
    case 'HorizontalRule':
      // nothing to do; we already added the contents.
      break;

    default:
      if (acceptsLines(container.t)) {
        this.addLine(ln, first_nonspace);
      } else if (blank) {
        // do nothing
      } else if (container.t != 'HorizontalRule' &&
                 container.t != 'SetextHeader') {
        // create paragraph container for line
        container = this.addChild('Paragraph', line_number, first_nonspace);
        this.addLine(ln, first_nonspace);
      } else {
        console.log("Line " + line_number.toString() +
                     " with container type " + container.t +
                     " did not match any condition.");

      }
    }
  }
}
1154230
def list_line(self, line):
        
        
        if len(line) == 0:
            return
        
        self.stream.write(str(line[0]))
        
        for item in line[1:]:
            self.stream.write("\t")
            self.stream.write(str(item))
        
        self.stream.write("\n")
498743
public static String[] disectCommandLine(String line) {
		return StringSupport.split(line, "() ,;", "\"", false, false, false).toArray(new String[0]);
	}
1311437
private ShellCommand getCommandForLine(final String line) {

		final int pos                             = line.indexOf(" ");
		final String commandString                = pos > 0 ? line.substring(0, pos) : line;
		final Class<? extends ShellCommand> clazz = commands.get(commandString);

		if (clazz != null) {

			try {

				return clazz.newInstance();

			} catch (Throwable t) {
				logger.warn("", t);
			}
		}

		return null;
	}
804374
synchronized void line(String line, long arrivalTime) {

		if (count.incrementAndGet() % logCountFrequency == 0)
			log.info("count=" + count.get() + ",buffer size=" + lines.size());

		NmeaMessage nmea;
		try {
			nmea = NmeaUtil.parseNmea(line);
		} catch (NmeaMessageParseException e) {
			listener.invalidNmea(line, arrivalTime, e.getMessage());
			return;
		}

		// if is multi line message then don't report to listener till last
		// message in sequence has been received.
		if (!nmea.isSingleSentence()) {
			Optional<List<NmeaMessage>> messages = nmeaBuffer.add(nmea);
			if (messages.isPresent()) {
				Optional<NmeaMessage> joined = AisNmeaBuffer
						.concatenateMessages(messages.get());
				if (joined.isPresent()) {
					if (joined.get().getUnixTimeMillis() != null)
						listener.message(joined.get().toLine(), joined.get()
								.getUnixTimeMillis());
					else
						listener.message(joined.get().toLine(), arrivalTime);
				}
				// TODO else report error, might need to change signature of
				// listener to handle problem with multi-line message
			}
			return;
		}

		if (nmea.getUnixTimeMillis() != null) {
			listener.message(line, nmea.getUnixTimeMillis());
			return;
		}

		if (!matchWithTimestampLine) {
			listener.message(line, arrivalTime);
			return;
		}

		if (!NmeaUtil.isValid(line))
			return;

		addLine(line, arrivalTime);
		log.debug("buffer lines=" + lines.size());
		Integer earliestTimestampLineIndex = getEarliestTimestampLineIndex(lines);
		Set<Integer> removeThese;
		if (earliestTimestampLineIndex != null) {
			removeThese = matchWithClosestAisMessageIfBufferLargeEnough(
					arrivalTime, earliestTimestampLineIndex);
		} else
			removeThese = findExpiredIndexesBeforeIndex(lastIndex());
		TreeSet<Integer> orderedIndexes = Sets.newTreeSet(removeThese);
		for (int index : orderedIndexes.descendingSet()) {
			removeLineWithIndex(index);
		}
	}
1313997
private int readCustomLine(Text str, int maxLineLength, int maxBytesToConsume)
    throws IOException {
    str.clear();
    int txtLength = 0; // tracks str.getLength(), as an optimization
    long bytesConsumed = 0;
    int delPosn = 0;
    do {
      int startPosn = bufferPosn; // starting from where we left off the last
      // time
      if (bufferPosn >= bufferLength) {
        startPosn = bufferPosn = 0;
        bufferLength = in.read(buffer);
        if (bufferLength <= 0)
          break; // EOF
      }
      for (; bufferPosn < bufferLength; ++bufferPosn) {
        if (buffer[bufferPosn] == recordDelimiterBytes[delPosn]) {
          delPosn++;
          if (delPosn >= recordDelimiterBytes.length) {
            bufferPosn++;
            break;
          }
        } else {
          delPosn = 0;
        }
      }
      int readLength = bufferPosn - startPosn;
      bytesConsumed += readLength;
      int appendLength = readLength - delPosn;
      if (appendLength > maxLineLength - txtLength) {
        appendLength = maxLineLength - txtLength;
      }
      if (appendLength > 0) {
        str.append(buffer, startPosn, appendLength);
        txtLength += appendLength;
      }
    } while (delPosn < recordDelimiterBytes.length
      && bytesConsumed < maxBytesToConsume);
    if (bytesConsumed > (long) Integer.MAX_VALUE)
      throw new IOException("Too many bytes before delimiter: " + bytesConsumed);
    return (int) bytesConsumed;
  }