Path: blob/master/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/CSV.java
41161 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.jdeprscan;2627import java.io.PrintStream;28import java.util.ArrayList;29import java.util.Arrays;30import java.util.List;31import java.util.stream.Collectors;3233/**34* Utility class for manipulating comma-separated-value (CSV) data.35*/36public class CSV {37static String quote(String input) {38String result;39boolean needQuote = input.contains(",");4041if (input.contains("\"")) {42needQuote = true;43result = input.replace("\"", "\"\"");44} else {45result = input;46}4748if (needQuote) {49return "\"" + result + "\"";50} else {51return result;52}53}5455/**56* Writes the objects' string representations to the output as a line of CSV.57* The objects are converted to String, quoted if necessary, joined with commas,58* and are written to the output followed by the line separator string.59*60* @param out the output destination61* @param objs the objects to write62*/63public static void write(PrintStream out, Object... objs) {64out.println(Arrays.stream(objs)65.map(Object::toString)66.map(CSV::quote)67.collect(Collectors.joining(",")));68}6970/**71* The CSV parser state.72*/73enum State {74START_FIELD, // the start of a field75IN_FIELD, // within an unquoted field76IN_QFIELD, // within a quoted field77END_QFIELD // after the end of a quoted field78}7980/**81* Splits an input line into a list of strings, handling quoting.82*83* @param input the input line84* @return the resulting list of strings85*/86public static List<String> split(String input) {87List<String> result = new ArrayList<>();88StringBuilder cur = new StringBuilder();89State state = State.START_FIELD;9091for (int i = 0; i < input.length(); i++) {92char ch = input.charAt(i);93switch (ch) {94case ',':95switch (state) {96case IN_QFIELD:97cur.append(',');98break;99default:100result.add(cur.toString());101cur.setLength(0);102state = State.START_FIELD;103break;104}105break;106case '"':107switch (state) {108case START_FIELD:109state = State.IN_QFIELD;110break;111case IN_QFIELD:112state = State.END_QFIELD;113break;114case IN_FIELD:115throw new CSVParseException("unexpected quote", input, i);116case END_QFIELD:117cur.append('"');118state = State.IN_QFIELD;119break;120}121break;122default:123switch (state) {124case START_FIELD:125state = State.IN_FIELD;126break;127case IN_FIELD:128case IN_QFIELD:129break;130case END_QFIELD:131throw new CSVParseException("extra character after quoted string",132input, i);133}134cur.append(ch);135break;136}137}138139if (state == State.IN_QFIELD) {140throw new CSVParseException("unclosed quote", input, input.length());141}142143result.add(cur.toString());144return result;145}146}147148149