microsoft-azure-storage/src/com/microsoft/azure/storage/analytics/LogRecordStreamReader.java
private String readField(boolean isQuotedString) throws IOException {
        if (!this.isFirstFieldInRecord) {
            this.readDelimiter(LogRecordStreamReader.FIELD_DELIMITER);
        }
        else {
            this.isFirstFieldInRecord = false;
        }

        // Read a field, handling field/record delimiters in quotes and not counting them,
        // and also check that there are no record delimiters since they are only expected
        // outside of a field.
        // Note: We only need to handle strings that are quoted once from the beginning,
        // (e.g. "mystring"). We do not need to handle nested quotes or anything because
        // we control the string format. 
        StringBuilder fieldBuilder = new StringBuilder();
        boolean hasSeenQuoteForQuotedString = false;
        boolean isExpectingDelimiterForNextCharacterForQuotedString = false;
        while (true) {
            // If EOF when we haven't read the delimiter; unexpected.
            if (this.isEndOfFile()) {
                throw new EOFException(SR.LOG_STREAM_END_ERROR);
            }

            // Since we just checked isEndOfFile above, we know this is a char.
            char c = (char) this.peek();

            // If we hit a delimiter that is not quoted or we hit the delimiter for
            // a quoted string or we hit the empty value string and hit a delimiter,
            // then we have finished reading the field.
            // Note: The empty value string is the only string that we don't require
            // quotes for for a quoted string.
            if ((!isQuotedString || isExpectingDelimiterForNextCharacterForQuotedString || fieldBuilder.length() == 0)
                    && (c == LogRecordStreamReader.FIELD_DELIMITER || c == LogRecordStreamReader.RECORD_DELIMITER)) {
                // The delimiter character was peeked but not read -- they'll be consumed 
                // on either the next call to readField or to EndCurrentRecord.
                break;
            }

            if (isExpectingDelimiterForNextCharacterForQuotedString) {
                // We finished reading a quoted string but found no delimiter following it.
                throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
            }

            // The character was not a delimiter, so consume and add to builder.
            this.read();
            fieldBuilder.append(c);

            // We need to handle quotes specially since quoted delimiters
            // do not count since they are considered to be part of the
            // quoted string and not actually a delimiter.
            // Note: We use a specific quote character since we control the format
            // and we only allow non-encoded quote characters at the beginning/end
            // of the string.
            if (c == LogRecordStreamReader.QUOTE_CHAR) {
                if (!isQuotedString) {
                    // Non-encoded quote character only allowed for quoted strings.
                    throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
                }
                else if (fieldBuilder.length() == 1) {
                    // Opening quote for a quoted string.
                    hasSeenQuoteForQuotedString = true;
                }
                else if (hasSeenQuoteForQuotedString) {
                    // Closing quote for a quoted string.
                    isExpectingDelimiterForNextCharacterForQuotedString = true;
                }
                else {
                    // Unexpected non-encoded quote.
                    throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
                }
            }
        }

        String field;

        // Note: For quoted strings we remove the quotes.
        // We do not do this for the empty value string since it represents empty
        // and we don't write that out in quotes even for quoted strings.
        if (isQuotedString && fieldBuilder.length() != 0) {
            field = fieldBuilder.substring(1, fieldBuilder.length() - 1);
        }
        else {
            field = fieldBuilder.toString();
        }

        return field;
    }
private String readField(boolean isQuotedString) throws IOException {
        if (!this.isFirstFieldInRecord) {
            this.readDelimiter(LogRecordStreamReader.FIELD_DELIMITER);
        }
        else {
            this.isFirstFieldInRecord = false;
        }

        // Read a field, handling field/record delimiters in quotes and not counting them,
        // and also check that there are no record delimiters since they are only expected
        // outside of a field.
        // Note: We only need to handle strings that are quoted once from the beginning,
        // (e.g. "mystring"). We do not need to handle nested quotes or anything because
        // we control the string format. 
        StringBuilder fieldBuilder = new StringBuilder();
        boolean hasSeenQuoteForQuotedString = false;
        boolean isExpectingDelimiterForNextCharacterForQuotedString = false;
        while (true) {
            // If EOF when we haven't read the delimiter; unexpected.
            if (this.isEndOfFile()) {
                throw new EOFException(SR.LOG_STREAM_END_ERROR);
            }

            // Since we just checked isEndOfFile above, we know this is a char.
            char c = (char) this.peek();

            // If we hit a delimiter that is not quoted or we hit the delimiter for
            // a quoted string or we hit the empty value string and hit a delimiter,
            // then we have finished reading the field.
            // Note: The empty value string is the only string that we don't require
            // quotes for for a quoted string.
            if ((!isQuotedString || isExpectingDelimiterForNextCharacterForQuotedString || fieldBuilder.length() == 0)
                    && (c == LogRecordStreamReader.FIELD_DELIMITER || c == LogRecordStreamReader.RECORD_DELIMITER)) {
                // The delimiter character was peeked but not read -- they'll be consumed 
                // on either the next call to readField or to EndCurrentRecord.
                break;
            }

            if (isExpectingDelimiterForNextCharacterForQuotedString) {
                // We finished reading a quoted string but found no delimiter following it.
                throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
            }

            // The character was not a delimiter, so consume and add to builder.
            this.read();
            fieldBuilder.append(c);

            // We need to handle quotes specially since quoted delimiters
            // do not count since they are considered to be part of the
            // quoted string and not actually a delimiter.
            // Note: We use a specific quote character since we control the format
            // and we only allow non-encoded quote characters at the beginning/end
            // of the string.
            if (c == LogRecordStreamReader.QUOTE_CHAR) {
                if (!isQuotedString) {
                    // Non-encoded quote character only allowed for quoted strings.
                    throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
                }
                else if (fieldBuilder.length() == 1) {
                    // Opening quote for a quoted string.
                    hasSeenQuoteForQuotedString = true;
                }
                else if (hasSeenQuoteForQuotedString) {
                    // Closing quote for a quoted string.
                    isExpectingDelimiterForNextCharacterForQuotedString = true;
                }
                else {
                    // Unexpected non-encoded quote.
                    throw new IllegalStateException(SR.LOG_STREAM_QUOTE_ERROR);
                }
            }
        }

        String field;

        // Note: For quoted strings we remove the quotes.
        // We do not do this for the empty value string since it represents empty
        // and we don't write that out in quotes even for quoted strings.
        if (isQuotedString && fieldBuilder.length() != 0) {
            field = fieldBuilder.substring(1, fieldBuilder.length() - 1);
        }
        else {
            field = fieldBuilder.toString();
        }

        return field;
    }
Read a field from the stream.

@param isQuotedString
whether the field is encased in quotes and escaped.
@return
the field read.
@throws IOException