Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 144BF200B12 for ; Sun, 29 May 2016 04:49:21 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 12DAD160A1A; Sun, 29 May 2016 02:49:21 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 9872E160A3D for ; Sun, 29 May 2016 04:49:18 +0200 (CEST) Received: (qmail 35640 invoked by uid 500); 29 May 2016 02:49:17 -0000 Mailing-List: contact notifications-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list notifications@commons.apache.org Received: (qmail 35631 invoked by uid 99); 29 May 2016 02:49:17 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 29 May 2016 02:49:17 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 36B551A02D7 for ; Sun, 29 May 2016 02:49:17 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -0.426 X-Spam-Level: X-Spam-Status: No, score=-0.426 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx2-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id pES0PZXkC4bz for ; Sun, 29 May 2016 02:48:49 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx2-lw-us.apache.org (ASF Mail Server at mx2-lw-us.apache.org) with ESMTP id AB2F25F307 for ; Sun, 29 May 2016 02:48:48 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 66C83E1046 for ; Sun, 29 May 2016 02:48:46 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 5AEDD3A17FD for ; Sun, 29 May 2016 02:48:46 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r989467 [8/43] - in /websites/production/commons/content/proper/commons-csv/archives/1.4: ./ apidocs/ apidocs/org/ apidocs/org/apache/ apidocs/org/apache/commons/ apidocs/org/apache/commons/csv/ apidocs/org/apache/commons/csv/class-use/ api... Date: Sun, 29 May 2016 02:48:45 -0000 To: notifications@commons.apache.org From: ggregory@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20160529024846.5AEDD3A17FD@svn01-us-west.apache.org> archived-at: Sun, 29 May 2016 02:49:21 -0000 Added: websites/production/commons/content/proper/commons-csv/archives/1.4/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html ============================================================================== --- websites/production/commons/content/proper/commons-csv/archives/1.4/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html (added) +++ websites/production/commons/content/proper/commons-csv/archives/1.4/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html Sun May 29 02:48:43 2016 @@ -0,0 +1,1839 @@ + + + +Source code + + + +
+
001/*
+002 * Licensed to the Apache Software Foundation (ASF) under one or more
+003 * contributor license agreements.  See the NOTICE file distributed with
+004 * this work for additional information regarding copyright ownership.
+005 * The ASF licenses this file to You under the Apache License, Version 2.0
+006 * (the "License"); you may not use this file except in compliance with
+007 * the License.  You may obtain a copy of the License at
+008 *
+009 *      http://www.apache.org/licenses/LICENSE-2.0
+010 *
+011 * Unless required by applicable law or agreed to in writing, software
+012 * distributed under the License is distributed on an "AS IS" BASIS,
+013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+014 * See the License for the specific language governing permissions and
+015 * limitations under the License.
+016 */
+017
+018package org.apache.commons.csv;
+019
+020import static org.apache.commons.csv.Constants.BACKSLASH;
+021import static org.apache.commons.csv.Constants.COMMA;
+022import static org.apache.commons.csv.Constants.COMMENT;
+023import static org.apache.commons.csv.Constants.CR;
+024import static org.apache.commons.csv.Constants.CRLF;
+025import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
+026import static org.apache.commons.csv.Constants.LF;
+027import static org.apache.commons.csv.Constants.PIPE;
+028import static org.apache.commons.csv.Constants.SP;
+029import static org.apache.commons.csv.Constants.TAB;
+030
+031import java.io.IOException;
+032import java.io.Reader;
+033import java.io.Serializable;
+034import java.io.StringWriter;
+035import java.sql.ResultSet;
+036import java.sql.ResultSetMetaData;
+037import java.sql.SQLException;
+038import java.util.Arrays;
+039import java.util.HashSet;
+040import java.util.Set;
+041
+042/**
+043 * Specifies the format of a CSV file and parses input.
+044 *
+045 * <h2>Using predefined formats</h2>
+046 *
+047 * <p>
+048 * You can use one of the predefined formats:
+049 * </p>
+050 *
+051 * <ul>
+052 * <li>{@link #DEFAULT}</li>
+053 * <li>{@link #EXCEL}</li>
+054 * <li>{@link #MYSQL}</li>
+055 * <li>{@link #RFC4180}</li>
+056 * <li>{@link #TDF}</li>
+057 * </ul>
+058 *
+059 * <p>
+060 * For example:
+061 * </p>
+062 *
+063 * <pre>
+064 * CSVParser parser = CSVFormat.EXCEL.parse(reader);
+065 * </pre>
+066 *
+067 * <p>
+068 * The {@link CSVParser} provides static methods to parse other input types, for example:
+069 * </p>
+070 *
+071 * <pre>
+072 * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);
+073 * </pre>
+074 *
+075 * <h2>Defining formats</h2>
+076 *
+077 * <p>
+078 * You can extend a format by calling the {@code with} methods. For example:
+079 * </p>
+080 *
+081 * <pre>
+082 * CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
+083 * </pre>
+084 *
+085 * <h2>Defining column names</h2>
+086 *
+087 * <p>
+088 * To define the column names you want to use to access records, write:
+089 * </p>
+090 *
+091 * <pre>
+092 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;);
+093 * </pre>
+094 *
+095 * <p>
+096 * Calling {@link #withHeader(String...)} let's you use the given names to address values in a {@link CSVRecord}, and
+097 * assumes that your CSV source does not contain a first record that also defines column names.
+098 *
+099 * If it does, then you are overriding this metadata with your names and you should skip the first record by calling
+100 * {@link #withSkipHeaderRecord(boolean)} with {@code true}.
+101 * </p>
+102 *
+103 * <h2>Parsing</h2>
+104 *
+105 * <p>
+106 * You can use a format directly to parse a reader. For example, to parse an Excel file with columns header, write:
+107 * </p>
+108 *
+109 * <pre>
+110 * Reader in = ...;
+111 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;).parse(in);
+112 * </pre>
+113 *
+114 * <p>
+115 * For other input types, like resources, files, and URLs, use the static methods on {@link CSVParser}.
+116 * </p>
+117 *
+118 * <h2>Referencing columns safely</h2>
+119 *
+120 * <p>
+121 * If your source contains a header record, you can simplify your code and safely reference columns, by using
+122 * {@link #withHeader(String...)} with no arguments:
+123 * </p>
+124 *
+125 * <pre>
+126 * CSVFormat.EXCEL.withHeader();
+127 * </pre>
+128 *
+129 * <p>
+130 * This causes the parser to read the first record and use its values as column names.
+131 *
+132 * Then, call one of the {@link CSVRecord} get method that takes a String column name argument:
+133 * </p>
+134 *
+135 * <pre>
+136 * String value = record.get(&quot;Col1&quot;);
+137 * </pre>
+138 *
+139 * <p>
+140 * This makes your code impervious to changes in column order in the CSV file.
+141 * </p>
+142 *
+143 * <h2>Notes</h2>
+144 *
+145 * <p>
+146 * This class is immutable.
+147 * </p>
+148 *
+149 * @version $Id: CSVFormat.java 1745258 2016-05-23 20:24:33Z ggregory $
+150 */
+151public final class CSVFormat implements Serializable {
+152
+153    /**
+154     * Predefines formats.
+155     *
+156     * @since 1.2
+157     */
+158    public enum Predefined {
+159
+160        /**
+161         * @see CSVFormat#DEFAULT
+162         */
+163        Default(CSVFormat.DEFAULT),
+164
+165        /**
+166         * @see CSVFormat#EXCEL
+167         */
+168        Excel(CSVFormat.EXCEL),
+169
+170        /**
+171         * @see CSVFormat#INFORMIX_UNLOAD
+172         * @since 1.3
+173         */
+174        InformixUnload(CSVFormat.INFORMIX_UNLOAD),
+175
+176        /**
+177         * @see CSVFormat#INFORMIX_UNLOAD_CSV
+178         * @since 1.3
+179         */
+180        InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),
+181
+182        /**
+183         * @see CSVFormat#MYSQL
+184         */
+185        MySQL(CSVFormat.MYSQL),
+186
+187        /**
+188         * @see CSVFormat#RFC4180
+189         */
+190        RFC4180(CSVFormat.RFC4180),
+191
+192        /**
+193         * @see CSVFormat#TDF
+194         */
+195        TDF(CSVFormat.TDF);
+196
+197        private final CSVFormat format;
+198
+199        Predefined(final CSVFormat format) {
+200            this.format = format;
+201        }
+202
+203        /**
+204         * Gets the format.
+205         *
+206         * @return the format.
+207         */
+208        public CSVFormat getFormat() {
+209            return format;
+210        }
+211    }
+212
+213    /**
+214     * Standard comma separated format, as for {@link #RFC4180} but allowing empty lines.
+215     *
+216     * <p>
+217     * Settings are:
+218     * </p>
+219     * <ul>
+220     * <li>withDelimiter(',')</li>
+221     * <li>withQuote('"')</li>
+222     * <li>withRecordSeparator("\r\n")</li>
+223     * <li>withIgnoreEmptyLines(true)</li>
+224     * </ul>
+225     *
+226     * @see Predefined#Default
+227     */
+228    public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
+229            null, null, null, false, false, false, false, false);
+230
+231    /**
+232     * Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
+233     * locale dependent, it might be necessary to customize this format to accommodate to your regional settings.
+234     *
+235     * <p>
+236     * For example for parsing or generating a CSV file on a French system the following format will be used:
+237     * </p>
+238     *
+239     * <pre>
+240     * CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');
+241     * </pre>
+242     *
+243     * <p>
+244     * Settings are:
+245     * </p>
+246     * <ul>
+247     * <li>{@link #withDelimiter(char) withDelimiter(',')}</li>
+248     * <li>{@link #withQuote(char) withQuote('"')}</li>
+249     * <li>{@link #withRecordSeparator(String) withRecordSeparator("\r\n")}</li>
+250     * <li>{@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}</li>
+251     * <li>{@link #withAllowMissingColumnNames(boolean) withAllowMissingColumnNames(true)}</li>
+252     * </ul>
+253     * <p>
+254     * Note: this is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
+255     * withAllowMissingColumnNames(true)}.
+256     * </p>
+257     *
+258     * @see Predefined#Excel
+259     */
+260    public static final CSVFormat EXCEL = DEFAULT.withIgnoreEmptyLines(false).withAllowMissingColumnNames();
+261
+262    /**
+263     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
+264     *
+265     * <p>
+266     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
+267     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+268     * </p>
+269     *
+270     * <p>
+271     * Settings are:
+272     * </p>
+273     * <ul>
+274     * <li>withDelimiter(',')</li>
+275     * <li>withQuote("\"")</li>
+276     * <li>withRecordSeparator('\n')</li>
+277     * <li>withEscape('\\')</li>
+278     * </ul>
+279     *
+280     * @see Predefined#MySQL
+281     * @see <a href=
+282     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
+283     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
+284     * @since 1.3
+285     */
+286    public static final CSVFormat INFORMIX_UNLOAD = DEFAULT.withDelimiter(PIPE).withEscape(BACKSLASH)
+287            .withQuote(DOUBLE_QUOTE_CHAR).withRecordSeparator(LF);
+288
+289    /**
+290     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation (escaping is disabled.)
+291     *
+292     * <p>
+293     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
+294     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+295     * </p>
+296     *
+297     * <p>
+298     * Settings are:
+299     * </p>
+300     * <ul>
+301     * <li>withDelimiter(',')</li>
+302     * <li>withQuote("\"")</li>
+303     * <li>withRecordSeparator('\n')</li>
+304     * </ul>
+305     *
+306     * @see Predefined#MySQL
+307     * @see <a href=
+308     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
+309     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
+310     * @since 1.3
+311     */
+312    public static final CSVFormat INFORMIX_UNLOAD_CSV = DEFAULT.withDelimiter(COMMA).withQuote(DOUBLE_QUOTE_CHAR)
+313            .withRecordSeparator(LF);
+314
+315    /**
+316     * Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
+317     *
+318     * <p>
+319     * This is a tab-delimited format with a LF character as the line separator. Values are not quoted and special
+320     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+321     * </p>
+322     *
+323     * <p>
+324     * Settings are:
+325     * </p>
+326     * <ul>
+327     * <li>withDelimiter('\t')</li>
+328     * <li>withQuote(null)</li>
+329     * <li>withRecordSeparator('\n')</li>
+330     * <li>withIgnoreEmptyLines(false)</li>
+331     * <li>withEscape('\\')</li>
+332     * <li>withNullString("\\N")</li>
+333     * </ul>
+334     *
+335     * @see Predefined#MySQL
+336     * @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html"> http://dev.mysql.com/doc/refman/5.1/en/load
+337     *      -data.html</a>
+338     */
+339    public static final CSVFormat MYSQL = DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
+340            .withQuote(null).withRecordSeparator(LF).withNullString("\\N");
+341
+342    /**
+343     * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
+344     *
+345     * <p>
+346     * Settings are:
+347     * </p>
+348     * <ul>
+349     * <li>withDelimiter(',')</li>
+350     * <li>withQuote('"')</li>
+351     * <li>withRecordSeparator("\r\n")</li>
+352     * <li>withIgnoreEmptyLines(false)</li>
+353     * </ul>
+354     *
+355     * @see Predefined#RFC4180
+356     */
+357    public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
+358
+359    private static final long serialVersionUID = 1L;
+360
+361    /**
+362     * Tab-delimited format.
+363     *
+364     * <p>
+365     * Settings are:
+366     * </p>
+367     * <ul>
+368     * <li>withDelimiter('\t')</li>
+369     * <li>withQuote('"')</li>
+370     * <li>withRecordSeparator("\r\n")</li>
+371     * <li>withIgnoreSurroundingSpaces(true)</li>
+372     * </ul>
+373     *
+374     * @see Predefined#TDF
+375     */
+376    public static final CSVFormat TDF = DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
+377
+378    /**
+379     * Returns true if the given character is a line break character.
+380     *
+381     * @param c
+382     *            the character to check
+383     *
+384     * @return true if <code>c</code> is a line break character
+385     */
+386    private static boolean isLineBreak(final char c) {
+387        return c == LF || c == CR;
+388    }
+389
+390    /**
+391     * Returns true if the given character is a line break character.
+392     *
+393     * @param c
+394     *            the character to check, may be null
+395     *
+396     * @return true if <code>c</code> is a line break character (and not null)
+397     */
+398    private static boolean isLineBreak(final Character c) {
+399        return c != null && isLineBreak(c.charValue());
+400    }
+401
+402    /**
+403     * Creates a new CSV format with the specified delimiter.
+404     *
+405     * <p>
+406     * Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be initialized
+407     * with null/false.
+408     * </p>
+409     *
+410     * @param delimiter
+411     *            the char used for value separation, must not be a line break character
+412     * @return a new CSV format.
+413     * @throws IllegalArgumentException
+414     *             if the delimiter is a line break character
+415     *
+416     * @see #DEFAULT
+417     * @see #RFC4180
+418     * @see #MYSQL
+419     * @see #EXCEL
+420     * @see #TDF
+421     */
+422    public static CSVFormat newFormat(final char delimiter) {
+423        return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false,
+424                false, false, false);
+425    }
+426
+427    /**
+428     * Gets one of the predefined formats from {@link CSVFormat.Predefined}.
+429     *
+430     * @param format
+431     *            name
+432     * @return one of the predefined formats
+433     * @since 1.2
+434     */
+435    public static CSVFormat valueOf(final String format) {
+436        return CSVFormat.Predefined.valueOf(format).getFormat();
+437    }
+438
+439    private final boolean allowMissingColumnNames;
+440
+441    private final Character commentMarker; // null if commenting is disabled
+442
+443    private final char delimiter;
+444
+445    private final Character escapeCharacter; // null if escaping is disabled
+446
+447    private final String[] header; // array of header column names
+448
+449    private final String[] headerComments; // array of header comment lines
+450
+451    private final boolean ignoreEmptyLines;
+452
+453    private final boolean ignoreHeaderCase; // should ignore header names case
+454
+455    private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
+456
+457    private final String nullString; // the string to be used for null values
+458
+459    private final Character quoteCharacter; // null if quoting is disabled
+460
+461    private final QuoteMode quoteMode;
+462
+463    private final String recordSeparator; // for outputs
+464
+465    private final boolean skipHeaderRecord;
+466
+467    private final boolean trailingDelimiter;
+468
+469    private final boolean trim;
+470
+471    /**
+472     * Creates a customized CSV format.
+473     *
+474     * @param delimiter
+475     *            the char used for value separation, must not be a line break character
+476     * @param quoteChar
+477     *            the Character used as value encapsulation marker, may be {@code null} to disable
+478     * @param quoteMode
+479     *            the quote mode
+480     * @param commentStart
+481     *            the Character used for comment identification, may be {@code null} to disable
+482     * @param escape
+483     *            the Character used to escape special characters in values, may be {@code null} to disable
+484     * @param ignoreSurroundingSpaces
+485     *            {@code true} when whitespaces enclosing values should be ignored
+486     * @param ignoreEmptyLines
+487     *            {@code true} when the parser should skip empty lines
+488     * @param recordSeparator
+489     *            the line separator to use for output
+490     * @param nullString
+491     *            the line separator to use for output
+492     * @param headerComments
+493     *            the comments to be printed by the Printer before the actual CSV data
+494     * @param header
+495     *            the header
+496     * @param skipHeaderRecord
+497     *            TODO
+498     * @param allowMissingColumnNames
+499     *            TODO
+500     * @param ignoreHeaderCase
+501     *            TODO
+502     * @param trim
+503     *            TODO
+504     * @param trailingDelimiter
+505     *            TODO
+506     * @throws IllegalArgumentException
+507     *             if the delimiter is a line break character
+508     */
+509    private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMode quoteMode,
+510            final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
+511            final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
+512            final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
+513            final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, final boolean trim,
+514            final boolean trailingDelimiter) {
+515        this.delimiter = delimiter;
+516        this.quoteCharacter = quoteChar;
+517        this.quoteMode = quoteMode;
+518        this.commentMarker = commentStart;
+519        this.escapeCharacter = escape;
+520        this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
+521        this.allowMissingColumnNames = allowMissingColumnNames;
+522        this.ignoreEmptyLines = ignoreEmptyLines;
+523        this.recordSeparator = recordSeparator;
+524        this.nullString = nullString;
+525        this.headerComments = toStringArray(headerComments);
+526        this.header = header == null ? null : header.clone();
+527        this.skipHeaderRecord = skipHeaderRecord;
+528        this.ignoreHeaderCase = ignoreHeaderCase;
+529        this.trailingDelimiter = trailingDelimiter;
+530        this.trim = trim;
+531        validate();
+532    }
+533
+534    @Override
+535    public boolean equals(final Object obj) {
+536        if (this == obj) {
+537            return true;
+538        }
+539        if (obj == null) {
+540            return false;
+541        }
+542        if (getClass() != obj.getClass()) {
+543            return false;
+544        }
+545
+546        final CSVFormat other = (CSVFormat) obj;
+547        if (delimiter != other.delimiter) {
+548            return false;
+549        }
+550        if (quoteMode != other.quoteMode) {
+551            return false;
+552        }
+553        if (quoteCharacter == null) {
+554            if (other.quoteCharacter != null) {
+555                return false;
+556            }
+557        } else if (!quoteCharacter.equals(other.quoteCharacter)) {
+558            return false;
+559        }
+560        if (commentMarker == null) {
+561            if (other.commentMarker != null) {
+562                return false;
+563            }
+564        } else if (!commentMarker.equals(other.commentMarker)) {
+565            return false;
+566        }
+567        if (escapeCharacter == null) {
+568            if (other.escapeCharacter != null) {
+569                return false;
+570            }
+571        } else if (!escapeCharacter.equals(other.escapeCharacter)) {
+572            return false;
+573        }
+574        if (nullString == null) {
+575            if (other.nullString != null) {
+576                return false;
+577            }
+578        } else if (!nullString.equals(other.nullString)) {
+579            return false;
+580        }
+581        if (!Arrays.equals(header, other.header)) {
+582            return false;
+583        }
+584        if (ignoreSurroundingSpaces != other.ignoreSurroundingSpaces) {
+585            return false;
+586        }
+587        if (ignoreEmptyLines != other.ignoreEmptyLines) {
+588            return false;
+589        }
+590        if (skipHeaderRecord != other.skipHeaderRecord) {
+591            return false;
+592        }
+593        if (recordSeparator == null) {
+594            if (other.recordSeparator != null) {
+595                return false;
+596            }
+597        } else if (!recordSeparator.equals(other.recordSeparator)) {
+598            return false;
+599        }
+600        return true;
+601    }
+602
+603    /**
+604     * Formats the specified values.
+605     *
+606     * @param values
+607     *            the values to format
+608     * @return the formatted values
+609     */
+610    public String format(final Object... values) {
+611        final StringWriter out = new StringWriter();
+612        try {
+613            new CSVPrinter(out, this).printRecord(values);
+614            return out.toString().trim();
+615        } catch (final IOException e) {
+616            // should not happen because a StringWriter does not do IO.
+617            throw new IllegalStateException(e);
+618        }
+619    }
+620
+621    /**
+622     * Specifies whether missing column names are allowed when parsing the header line.
+623     *
+624     * @return {@code true} if missing column names are allowed when parsing the header line, {@code false} to throw an
+625     *         {@link IllegalArgumentException}.
+626     */
+627    public boolean getAllowMissingColumnNames() {
+628        return allowMissingColumnNames;
+629    }
+630
+631    /**
+632     * Returns the character marking the start of a line comment.
+633     *
+634     * @return the comment start marker, may be {@code null}
+635     */
+636    public Character getCommentMarker() {
+637        return commentMarker;
+638    }
+639
+640    /**
+641     * Returns the character delimiting the values (typically ';', ',' or '\t').
+642     *
+643     * @return the delimiter character
+644     */
+645    public char getDelimiter() {
+646        return delimiter;
+647    }
+648
+649    /**
+650     * Returns the escape character.
+651     *
+652     * @return the escape character, may be {@code null}
+653     */
+654    public Character getEscapeCharacter() {
+655        return escapeCharacter;
+656    }
+657
+658    /**
+659     * Returns a copy of the header array.
+660     *
+661     * @return a copy of the header array; {@code null} if disabled, the empty array if to be read from the file
+662     */
+663    public String[] getHeader() {
+664        return header != null ? header.clone() : null;
+665    }
+666
+667    /**
+668     * Returns a copy of the header comment array.
+669     *
+670     * @return a copy of the header comment array; {@code null} if disabled.
+671     */
+672    public String[] getHeaderComments() {
+673        return headerComments != null ? headerComments.clone() : null;
+674    }
+675
+676    /**
+677     * Specifies whether empty lines between records are ignored when parsing input.
+678     *
+679     * @return {@code true} if empty lines between records are ignored, {@code false} if they are turned into empty
+680     *         records.
+681     */
+682    public boolean getIgnoreEmptyLines() {
+683        return ignoreEmptyLines;
+684    }
+685
+686    /**
+687     * Specifies whether header names will be accessed ignoring case.
+688     *
+689     * @return {@code true} if header names cases are ignored, {@code false} if they are case sensitive.
+690     * @since 1.3
+691     */
+692    public boolean getIgnoreHeaderCase() {
+693        return ignoreHeaderCase;
+694    }
+695
+696    /**
+697     * Specifies whether spaces around values are ignored when parsing input.
+698     *
+699     * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the value.
+700     */
+701    public boolean getIgnoreSurroundingSpaces() {
+702        return ignoreSurroundingSpaces;
+703    }
+704
+705    /**
+706     * Gets the String to convert to and from {@code null}.
+707     * <ul>
+708     * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
+709     * records.</li>
+710     * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
+711     * </ul>
+712     *
+713     * @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
+714     */
+715    public String getNullString() {
+716        return nullString;
+717    }
+718
+719    /**
+720     * Returns the character used to encapsulate values containing special characters.
+721     *
+722     * @return the quoteChar character, may be {@code null}
+723     */
+724    public Character getQuoteCharacter() {
+725        return quoteCharacter;
+726    }
+727
+728    /**
+729     * Returns the quote policy output fields.
+730     *
+731     * @return the quote policy
+732     */
+733    public QuoteMode getQuoteMode() {
+734        return quoteMode;
+735    }
+736
+737    /**
+738     * Returns the record separator delimiting output records.
+739     *
+740     * @return the record separator
+741     */
+742    public String getRecordSeparator() {
+743        return recordSeparator;
+744    }
+745
+746    /**
+747     * Returns whether to skip the header record.
+748     *
+749     * @return whether to skip the header record.
+750     */
+751    public boolean getSkipHeaderRecord() {
+752        return skipHeaderRecord;
+753    }
+754
+755    /**
+756     * Returns whether to add a trailing delimiter.
+757     *
+758     * @return whether to add a trailing delimiter.
+759     * @since 1.3
+760     */
+761    public boolean getTrailingDelimiter() {
+762        return trailingDelimiter;
+763    }
+764
+765    /**
+766     * Returns whether to trim leading and trailing blanks.
+767     *
+768     * @return whether to trim leading and trailing blanks.
+769     */
+770    public boolean getTrim() {
+771        return trim;
+772    }
+773
+774    @Override
+775    public int hashCode() {
+776        final int prime = 31;
+777        int result = 1;
+778
+779        result = prime * result + delimiter;
+780        result = prime * result + ((quoteMode == null) ? 0 : quoteMode.hashCode());
+781        result = prime * result + ((quoteCharacter == null) ? 0 : quoteCharacter.hashCode());
+782        result = prime * result + ((commentMarker == null) ? 0 : commentMarker.hashCode());
+783        result = prime * result + ((escapeCharacter == null) ? 0 : escapeCharacter.hashCode());
+784        result = prime * result + ((nullString == null) ? 0 : nullString.hashCode());
+785        result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
+786        result = prime * result + (ignoreHeaderCase ? 1231 : 1237);
+787        result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
+788        result = prime * result + (skipHeaderRecord ? 1231 : 1237);
+789        result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
+790        result = prime * result + Arrays.hashCode(header);
+791        return result;
+792    }
+793
+794    /**
+795     * Specifies whether comments are supported by this format.
+796     *
+797     * Note that the comment introducer character is only recognized at the start of a line.
+798     *
+799     * @return {@code true} is comments are supported, {@code false} otherwise
+800     */
+801    public boolean isCommentMarkerSet() {
+802        return commentMarker != null;
+803    }
+804
+805    /**
+806     * Returns whether escape are being processed.
+807     *
+808     * @return {@code true} if escapes are processed
+809     */
+810    public boolean isEscapeCharacterSet() {
+811        return escapeCharacter != null;
+812    }
+813
+814    /**
+815     * Returns whether a nullString has been defined.
+816     *
+817     * @return {@code true} if a nullString is defined
+818     */
+819    public boolean isNullStringSet() {
+820        return nullString != null;
+821    }
+822
+823    /**
+824     * Returns whether a quoteChar has been defined.
+825     *
+826     * @return {@code true} if a quoteChar is defined
+827     */
+828    public boolean isQuoteCharacterSet() {
+829        return quoteCharacter != null;
+830    }
+831
+832    /**
+833     * Parses the specified content.
+834     *
+835     * <p>
+836     * See also the various static parse methods on {@link CSVParser}.
+837     * </p>
+838     *
+839     * @param in
+840     *            the input stream
+841     * @return a parser over a stream of {@link CSVRecord}s.
+842     * @throws IOException
+843     *             If an I/O error occurs
+844     */
+845    public CSVParser parse(final Reader in) throws IOException {
+846        return new CSVParser(in, this);
+847    }
+848
+849    /**
+850     * Prints to the specified output.
+851     *
+852     * <p>
+853     * See also {@link CSVPrinter}.
+854     * </p>
+855     *
+856     * @param out
+857     *            the output
+858     * @return a printer to an output
+859     * @throws IOException
+860     *             thrown if the optional header cannot be printed.
+861     */
+862    public CSVPrinter print(final Appendable out) throws IOException {
+863        return new CSVPrinter(out, this);
+864    }
+865
+866    /**
+867     * Prints the {@code value} as the next value on the line to {@code out}. The value will be escaped or encapsulated
+868     * as needed. Useful when one wants to avoid creating CSVPrinters.
+869     *
+870     * @param value
+871     *            value to output.
+872     * @param out
+873     *            where to print the value
+874     * @param newRecord
+875     *            if this a new record
+876     * @throws IOException
+877     *             If an I/O error occurs
+878     * @since 1.4
+879     */
+880    public void print(final Object value, final Appendable out, final boolean newRecord) throws IOException {
+881        // null values are considered empty
+882        // Only call CharSequence.toString() if you have to, helps GC-free use cases.
+883        CharSequence charSequence;
+884        if (value == null) {
+885            charSequence = nullString == null ? Constants.EMPTY : nullString;
+886        } else {
+887            charSequence = value instanceof CharSequence ? (CharSequence) value : value.toString();
+888        }
+889        charSequence = getTrim() ? trim(charSequence) : charSequence;
+890        this.print(value, charSequence, 0, charSequence.length(), out, newRecord);
+891    }
+892
+893    private void print(final Object object, final CharSequence value, final int offset, final int len,
+894            final Appendable out, final boolean newRecord) throws IOException {
+895        if (!newRecord) {
+896            out.append(getDelimiter());
+897        }
+898        if (object == null) {
+899            out.append(value);
+900        } else if (isQuoteCharacterSet()) {
+901            // the original object is needed so can check for Number
+902            printAndQuote(object, value, offset, len, out, newRecord);
+903        } else if (isEscapeCharacterSet()) {
+904            printAndEscape(value, offset, len, out);
+905        } else {
+906            out.append(value, offset, offset + len);
+907        }
+908    }
+909
+910    /*
+911     * Note: must only be called if escaping is enabled, otherwise will generate NPE
+912     */
+913    private void printAndEscape(final CharSequence value, final int offset, final int len, final Appendable out)
+914            throws IOException {
+915        int start = offset;
+916        int pos = offset;
+917        final int end = offset + len;
+918
+919        final char delim = getDelimiter();
+920        final char escape = getEscapeCharacter().charValue();
+921
+922        while (pos < end) {
+923            char c = value.charAt(pos);
+924            if (c == CR || c == LF || c == delim || c == escape) {
+925                // write out segment up until this char
+926                if (pos > start) {
+927                    out.append(value, start, pos);
+928                }
+929                if (c == LF) {
+930                    c = 'n';
+931                } else if (c == CR) {
+932                    c = 'r';
+933                }
+934
+935                out.append(escape);
+936                out.append(c);
+937

[... 896 lines stripped ...]