emul/compact/src/main/java/java/io/Writer.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 07 Sep 2013 13:51:24 +0200
branchjdk7-b147
changeset 1258 724f3e1ea53e
permissions -rw-r--r--
Additional set of classes to make porting of lookup library more easier
jaroslav@1258
     1
/*
jaroslav@1258
     2
 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
jaroslav@1258
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@1258
     4
 *
jaroslav@1258
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@1258
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@1258
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@1258
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@1258
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@1258
    10
 *
jaroslav@1258
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@1258
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@1258
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@1258
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@1258
    15
 * accompanied this code).
jaroslav@1258
    16
 *
jaroslav@1258
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@1258
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@1258
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@1258
    20
 *
jaroslav@1258
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@1258
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@1258
    23
 * questions.
jaroslav@1258
    24
 */
jaroslav@1258
    25
jaroslav@1258
    26
package java.io;
jaroslav@1258
    27
jaroslav@1258
    28
jaroslav@1258
    29
/**
jaroslav@1258
    30
 * Abstract class for writing to character streams.  The only methods that a
jaroslav@1258
    31
 * subclass must implement are write(char[], int, int), flush(), and close().
jaroslav@1258
    32
 * Most subclasses, however, will override some of the methods defined here in
jaroslav@1258
    33
 * order to provide higher efficiency, additional functionality, or both.
jaroslav@1258
    34
 *
jaroslav@1258
    35
 * @see Writer
jaroslav@1258
    36
 * @see   BufferedWriter
jaroslav@1258
    37
 * @see   CharArrayWriter
jaroslav@1258
    38
 * @see   FilterWriter
jaroslav@1258
    39
 * @see   OutputStreamWriter
jaroslav@1258
    40
 * @see     FileWriter
jaroslav@1258
    41
 * @see   PipedWriter
jaroslav@1258
    42
 * @see   PrintWriter
jaroslav@1258
    43
 * @see   StringWriter
jaroslav@1258
    44
 * @see Reader
jaroslav@1258
    45
 *
jaroslav@1258
    46
 * @author      Mark Reinhold
jaroslav@1258
    47
 * @since       JDK1.1
jaroslav@1258
    48
 */
jaroslav@1258
    49
jaroslav@1258
    50
public abstract class Writer implements Appendable, Closeable, Flushable {
jaroslav@1258
    51
jaroslav@1258
    52
    /**
jaroslav@1258
    53
     * Temporary buffer used to hold writes of strings and single characters
jaroslav@1258
    54
     */
jaroslav@1258
    55
    private char[] writeBuffer;
jaroslav@1258
    56
jaroslav@1258
    57
    /**
jaroslav@1258
    58
     * Size of writeBuffer, must be >= 1
jaroslav@1258
    59
     */
jaroslav@1258
    60
    private final int writeBufferSize = 1024;
jaroslav@1258
    61
jaroslav@1258
    62
    /**
jaroslav@1258
    63
     * The object used to synchronize operations on this stream.  For
jaroslav@1258
    64
     * efficiency, a character-stream object may use an object other than
jaroslav@1258
    65
     * itself to protect critical sections.  A subclass should therefore use
jaroslav@1258
    66
     * the object in this field rather than <tt>this</tt> or a synchronized
jaroslav@1258
    67
     * method.
jaroslav@1258
    68
     */
jaroslav@1258
    69
    protected Object lock;
jaroslav@1258
    70
jaroslav@1258
    71
    /**
jaroslav@1258
    72
     * Creates a new character-stream writer whose critical sections will
jaroslav@1258
    73
     * synchronize on the writer itself.
jaroslav@1258
    74
     */
jaroslav@1258
    75
    protected Writer() {
jaroslav@1258
    76
        this.lock = this;
jaroslav@1258
    77
    }
jaroslav@1258
    78
jaroslav@1258
    79
    /**
jaroslav@1258
    80
     * Creates a new character-stream writer whose critical sections will
jaroslav@1258
    81
     * synchronize on the given object.
jaroslav@1258
    82
     *
jaroslav@1258
    83
     * @param  lock
jaroslav@1258
    84
     *         Object to synchronize on
jaroslav@1258
    85
     */
jaroslav@1258
    86
    protected Writer(Object lock) {
jaroslav@1258
    87
        if (lock == null) {
jaroslav@1258
    88
            throw new NullPointerException();
jaroslav@1258
    89
        }
jaroslav@1258
    90
        this.lock = lock;
jaroslav@1258
    91
    }
jaroslav@1258
    92
jaroslav@1258
    93
    /**
jaroslav@1258
    94
     * Writes a single character.  The character to be written is contained in
jaroslav@1258
    95
     * the 16 low-order bits of the given integer value; the 16 high-order bits
jaroslav@1258
    96
     * are ignored.
jaroslav@1258
    97
     *
jaroslav@1258
    98
     * <p> Subclasses that intend to support efficient single-character output
jaroslav@1258
    99
     * should override this method.
jaroslav@1258
   100
     *
jaroslav@1258
   101
     * @param  c
jaroslav@1258
   102
     *         int specifying a character to be written
jaroslav@1258
   103
     *
jaroslav@1258
   104
     * @throws  IOException
jaroslav@1258
   105
     *          If an I/O error occurs
jaroslav@1258
   106
     */
jaroslav@1258
   107
    public void write(int c) throws IOException {
jaroslav@1258
   108
        synchronized (lock) {
jaroslav@1258
   109
            if (writeBuffer == null){
jaroslav@1258
   110
                writeBuffer = new char[writeBufferSize];
jaroslav@1258
   111
            }
jaroslav@1258
   112
            writeBuffer[0] = (char) c;
jaroslav@1258
   113
            write(writeBuffer, 0, 1);
jaroslav@1258
   114
        }
jaroslav@1258
   115
    }
jaroslav@1258
   116
jaroslav@1258
   117
    /**
jaroslav@1258
   118
     * Writes an array of characters.
jaroslav@1258
   119
     *
jaroslav@1258
   120
     * @param  cbuf
jaroslav@1258
   121
     *         Array of characters to be written
jaroslav@1258
   122
     *
jaroslav@1258
   123
     * @throws  IOException
jaroslav@1258
   124
     *          If an I/O error occurs
jaroslav@1258
   125
     */
jaroslav@1258
   126
    public void write(char cbuf[]) throws IOException {
jaroslav@1258
   127
        write(cbuf, 0, cbuf.length);
jaroslav@1258
   128
    }
jaroslav@1258
   129
jaroslav@1258
   130
    /**
jaroslav@1258
   131
     * Writes a portion of an array of characters.
jaroslav@1258
   132
     *
jaroslav@1258
   133
     * @param  cbuf
jaroslav@1258
   134
     *         Array of characters
jaroslav@1258
   135
     *
jaroslav@1258
   136
     * @param  off
jaroslav@1258
   137
     *         Offset from which to start writing characters
jaroslav@1258
   138
     *
jaroslav@1258
   139
     * @param  len
jaroslav@1258
   140
     *         Number of characters to write
jaroslav@1258
   141
     *
jaroslav@1258
   142
     * @throws  IOException
jaroslav@1258
   143
     *          If an I/O error occurs
jaroslav@1258
   144
     */
jaroslav@1258
   145
    abstract public void write(char cbuf[], int off, int len) throws IOException;
jaroslav@1258
   146
jaroslav@1258
   147
    /**
jaroslav@1258
   148
     * Writes a string.
jaroslav@1258
   149
     *
jaroslav@1258
   150
     * @param  str
jaroslav@1258
   151
     *         String to be written
jaroslav@1258
   152
     *
jaroslav@1258
   153
     * @throws  IOException
jaroslav@1258
   154
     *          If an I/O error occurs
jaroslav@1258
   155
     */
jaroslav@1258
   156
    public void write(String str) throws IOException {
jaroslav@1258
   157
        write(str, 0, str.length());
jaroslav@1258
   158
    }
jaroslav@1258
   159
jaroslav@1258
   160
    /**
jaroslav@1258
   161
     * Writes a portion of a string.
jaroslav@1258
   162
     *
jaroslav@1258
   163
     * @param  str
jaroslav@1258
   164
     *         A String
jaroslav@1258
   165
     *
jaroslav@1258
   166
     * @param  off
jaroslav@1258
   167
     *         Offset from which to start writing characters
jaroslav@1258
   168
     *
jaroslav@1258
   169
     * @param  len
jaroslav@1258
   170
     *         Number of characters to write
jaroslav@1258
   171
     *
jaroslav@1258
   172
     * @throws  IndexOutOfBoundsException
jaroslav@1258
   173
     *          If <tt>off</tt> is negative, or <tt>len</tt> is negative,
jaroslav@1258
   174
     *          or <tt>off+len</tt> is negative or greater than the length
jaroslav@1258
   175
     *          of the given string
jaroslav@1258
   176
     *
jaroslav@1258
   177
     * @throws  IOException
jaroslav@1258
   178
     *          If an I/O error occurs
jaroslav@1258
   179
     */
jaroslav@1258
   180
    public void write(String str, int off, int len) throws IOException {
jaroslav@1258
   181
        synchronized (lock) {
jaroslav@1258
   182
            char cbuf[];
jaroslav@1258
   183
            if (len <= writeBufferSize) {
jaroslav@1258
   184
                if (writeBuffer == null) {
jaroslav@1258
   185
                    writeBuffer = new char[writeBufferSize];
jaroslav@1258
   186
                }
jaroslav@1258
   187
                cbuf = writeBuffer;
jaroslav@1258
   188
            } else {    // Don't permanently allocate very large buffers.
jaroslav@1258
   189
                cbuf = new char[len];
jaroslav@1258
   190
            }
jaroslav@1258
   191
            str.getChars(off, (off + len), cbuf, 0);
jaroslav@1258
   192
            write(cbuf, 0, len);
jaroslav@1258
   193
        }
jaroslav@1258
   194
    }
jaroslav@1258
   195
jaroslav@1258
   196
    /**
jaroslav@1258
   197
     * Appends the specified character sequence to this writer.
jaroslav@1258
   198
     *
jaroslav@1258
   199
     * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
jaroslav@1258
   200
     * behaves in exactly the same way as the invocation
jaroslav@1258
   201
     *
jaroslav@1258
   202
     * <pre>
jaroslav@1258
   203
     *     out.write(csq.toString()) </pre>
jaroslav@1258
   204
     *
jaroslav@1258
   205
     * <p> Depending on the specification of <tt>toString</tt> for the
jaroslav@1258
   206
     * character sequence <tt>csq</tt>, the entire sequence may not be
jaroslav@1258
   207
     * appended. For instance, invoking the <tt>toString</tt> method of a
jaroslav@1258
   208
     * character buffer will return a subsequence whose content depends upon
jaroslav@1258
   209
     * the buffer's position and limit.
jaroslav@1258
   210
     *
jaroslav@1258
   211
     * @param  csq
jaroslav@1258
   212
     *         The character sequence to append.  If <tt>csq</tt> is
jaroslav@1258
   213
     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
jaroslav@1258
   214
     *         appended to this writer.
jaroslav@1258
   215
     *
jaroslav@1258
   216
     * @return  This writer
jaroslav@1258
   217
     *
jaroslav@1258
   218
     * @throws  IOException
jaroslav@1258
   219
     *          If an I/O error occurs
jaroslav@1258
   220
     *
jaroslav@1258
   221
     * @since  1.5
jaroslav@1258
   222
     */
jaroslav@1258
   223
    public Writer append(CharSequence csq) throws IOException {
jaroslav@1258
   224
        if (csq == null)
jaroslav@1258
   225
            write("null");
jaroslav@1258
   226
        else
jaroslav@1258
   227
            write(csq.toString());
jaroslav@1258
   228
        return this;
jaroslav@1258
   229
    }
jaroslav@1258
   230
jaroslav@1258
   231
    /**
jaroslav@1258
   232
     * Appends a subsequence of the specified character sequence to this writer.
jaroslav@1258
   233
     * <tt>Appendable</tt>.
jaroslav@1258
   234
     *
jaroslav@1258
   235
     * <p> An invocation of this method of the form <tt>out.append(csq, start,
jaroslav@1258
   236
     * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the
jaroslav@1258
   237
     * same way as the invocation
jaroslav@1258
   238
     *
jaroslav@1258
   239
     * <pre>
jaroslav@1258
   240
     *     out.write(csq.subSequence(start, end).toString()) </pre>
jaroslav@1258
   241
     *
jaroslav@1258
   242
     * @param  csq
jaroslav@1258
   243
     *         The character sequence from which a subsequence will be
jaroslav@1258
   244
     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
jaroslav@1258
   245
     *         will be appended as if <tt>csq</tt> contained the four
jaroslav@1258
   246
     *         characters <tt>"null"</tt>.
jaroslav@1258
   247
     *
jaroslav@1258
   248
     * @param  start
jaroslav@1258
   249
     *         The index of the first character in the subsequence
jaroslav@1258
   250
     *
jaroslav@1258
   251
     * @param  end
jaroslav@1258
   252
     *         The index of the character following the last character in the
jaroslav@1258
   253
     *         subsequence
jaroslav@1258
   254
     *
jaroslav@1258
   255
     * @return  This writer
jaroslav@1258
   256
     *
jaroslav@1258
   257
     * @throws  IndexOutOfBoundsException
jaroslav@1258
   258
     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
jaroslav@1258
   259
     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
jaroslav@1258
   260
     *          <tt>csq.length()</tt>
jaroslav@1258
   261
     *
jaroslav@1258
   262
     * @throws  IOException
jaroslav@1258
   263
     *          If an I/O error occurs
jaroslav@1258
   264
     *
jaroslav@1258
   265
     * @since  1.5
jaroslav@1258
   266
     */
jaroslav@1258
   267
    public Writer append(CharSequence csq, int start, int end) throws IOException {
jaroslav@1258
   268
        CharSequence cs = (csq == null ? "null" : csq);
jaroslav@1258
   269
        write(cs.subSequence(start, end).toString());
jaroslav@1258
   270
        return this;
jaroslav@1258
   271
    }
jaroslav@1258
   272
jaroslav@1258
   273
    /**
jaroslav@1258
   274
     * Appends the specified character to this writer.
jaroslav@1258
   275
     *
jaroslav@1258
   276
     * <p> An invocation of this method of the form <tt>out.append(c)</tt>
jaroslav@1258
   277
     * behaves in exactly the same way as the invocation
jaroslav@1258
   278
     *
jaroslav@1258
   279
     * <pre>
jaroslav@1258
   280
     *     out.write(c) </pre>
jaroslav@1258
   281
     *
jaroslav@1258
   282
     * @param  c
jaroslav@1258
   283
     *         The 16-bit character to append
jaroslav@1258
   284
     *
jaroslav@1258
   285
     * @return  This writer
jaroslav@1258
   286
     *
jaroslav@1258
   287
     * @throws  IOException
jaroslav@1258
   288
     *          If an I/O error occurs
jaroslav@1258
   289
     *
jaroslav@1258
   290
     * @since 1.5
jaroslav@1258
   291
     */
jaroslav@1258
   292
    public Writer append(char c) throws IOException {
jaroslav@1258
   293
        write(c);
jaroslav@1258
   294
        return this;
jaroslav@1258
   295
    }
jaroslav@1258
   296
jaroslav@1258
   297
    /**
jaroslav@1258
   298
     * Flushes the stream.  If the stream has saved any characters from the
jaroslav@1258
   299
     * various write() methods in a buffer, write them immediately to their
jaroslav@1258
   300
     * intended destination.  Then, if that destination is another character or
jaroslav@1258
   301
     * byte stream, flush it.  Thus one flush() invocation will flush all the
jaroslav@1258
   302
     * buffers in a chain of Writers and OutputStreams.
jaroslav@1258
   303
     *
jaroslav@1258
   304
     * <p> If the intended destination of this stream is an abstraction provided
jaroslav@1258
   305
     * by the underlying operating system, for example a file, then flushing the
jaroslav@1258
   306
     * stream guarantees only that bytes previously written to the stream are
jaroslav@1258
   307
     * passed to the operating system for writing; it does not guarantee that
jaroslav@1258
   308
     * they are actually written to a physical device such as a disk drive.
jaroslav@1258
   309
     *
jaroslav@1258
   310
     * @throws  IOException
jaroslav@1258
   311
     *          If an I/O error occurs
jaroslav@1258
   312
     */
jaroslav@1258
   313
    abstract public void flush() throws IOException;
jaroslav@1258
   314
jaroslav@1258
   315
    /**
jaroslav@1258
   316
     * Closes the stream, flushing it first. Once the stream has been closed,
jaroslav@1258
   317
     * further write() or flush() invocations will cause an IOException to be
jaroslav@1258
   318
     * thrown. Closing a previously closed stream has no effect.
jaroslav@1258
   319
     *
jaroslav@1258
   320
     * @throws  IOException
jaroslav@1258
   321
     *          If an I/O error occurs
jaroslav@1258
   322
     */
jaroslav@1258
   323
    abstract public void close() throws IOException;
jaroslav@1258
   324
jaroslav@1258
   325
}