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 */
017package org.apache.commons.geometry.io.core.utils;
018
019import java.io.Closeable;
020import java.io.IOException;
021import java.io.Writer;
022import java.util.function.DoubleFunction;
023
024import org.apache.commons.geometry.io.core.internal.GeometryIOUtils;
025
026/** Base type for classes that write text-based data formats. This class
027 * provides a number of common configuration options and utility methods.
028 */
029public abstract class AbstractTextFormatWriter implements Closeable {
030
031    /** The default line separator value. */
032    private static final String DEFAULT_LINE_SEPARATOR = "\n";
033
034    /** Underlying writer instance. */
035    private final Writer writer;
036
037    /** Line separator string. */
038    private String lineSeparator = DEFAULT_LINE_SEPARATOR;
039
040    /** Double format function. */
041    private DoubleFunction<String> doubleFormat;
042
043    /** Construct a new instance that writes content to the given writer.
044     * @param writer writer instance
045     */
046    protected AbstractTextFormatWriter(final Writer writer) {
047        this(writer, Double::toString);
048    }
049
050    /** Construct a new instance that writes content to the given writer and uses the
051     * decimal format instance for creating floating-point string representations.
052     * @param writer writer instance
053     * @param doubleFormat double format function
054     */
055    protected AbstractTextFormatWriter(final Writer writer, final DoubleFunction<String> doubleFormat) {
056        this.writer = writer;
057        this.doubleFormat = doubleFormat;
058    }
059
060    /** Get the current line separator. This value defaults to {@value #DEFAULT_LINE_SEPARATOR}.
061     * @return the current line separator
062     */
063    public String getLineSeparator() {
064        return lineSeparator;
065    }
066
067    /** Set the line separator.
068     * @param lineSeparator the line separator to use
069     */
070    public void setLineSeparator(final String lineSeparator) {
071        this.lineSeparator = lineSeparator;
072    }
073
074    /** Get the function used to format floating point output.
075     * @return the double format function
076     */
077    public DoubleFunction<String> getDoubleFormat() {
078        return doubleFormat;
079    }
080
081    /** Set the function used to format floating point output.
082     * @param doubleFormat double format function
083     */
084    public void setDoubleFormat(final DoubleFunction<String> doubleFormat) {
085        this.doubleFormat = doubleFormat;
086    }
087
088    /** {@inheritDoc} */
089    @Override
090    public void close() {
091        GeometryIOUtils.closeUnchecked(writer);
092    }
093
094    /** Get the underlying writer instance.
095     * @return writer instance
096     */
097    protected Writer getWriter() {
098        return writer;
099    }
100
101    /** Write a double value formatted using the configured decimal format function.
102     * @param d value to write
103     * @throws java.io.UncheckedIOException if an I/O error occurs
104     */
105    protected void write(final double d) {
106        write(doubleFormat.apply(d));
107    }
108
109    /** Write an integer value.
110     * @param n value to write
111     * @throws java.io.UncheckedIOException if an I/O error occurs
112     */
113    protected void write(final int n) {
114        write(String.valueOf(n));
115    }
116
117    /** Write a char value.
118     * @param c character to write
119     * @throws java.io.UncheckedIOException if an I/O error occurs
120     */
121    protected void write(final char c) {
122        try {
123            writer.write(c);
124        } catch (IOException exc) {
125            throw GeometryIOUtils.createUnchecked(exc);
126        }
127    }
128
129    /** Write a string.
130     * @param str string to write
131     * @throws java.io.UncheckedIOException if an I/O error occurs
132     */
133    protected void write(final String str) {
134        try {
135            writer.write(str);
136        } catch (IOException exc) {
137            throw GeometryIOUtils.createUnchecked(exc);
138        }
139    }
140
141    /** Write the configured line separator to the output.
142     * @throws java.io.UncheckedIOException if an I/O error occurs
143     */
144    protected void writeNewLine() {
145        write(lineSeparator);
146    }
147}