001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.io.unsync;
016    
017    import java.io.IOException;
018    import java.io.Writer;
019    
020    /**
021     * <p>
022     * See http://issues.liferay.com/browse/LPS-6648.
023     * </p>
024     *
025     * @author Shuyang Zhou
026     */
027    public class UnsyncBufferedWriter extends Writer {
028    
029            public UnsyncBufferedWriter(Writer writer) {
030                    this(writer, _DEFAULT_BUFFER_SIZE);
031            }
032    
033            public UnsyncBufferedWriter(Writer writer, int size) {
034                    if (size <= 0) {
035                            throw new IllegalArgumentException("Size is less than 0");
036                    }
037    
038                    this.writer = writer;
039                    this.size = size;
040    
041                    buffer = new char[size];
042            }
043    
044            @Override
045            public void close() throws IOException {
046                    if (writer == null) {
047                            return;
048                    }
049    
050                    if (count > 0) {
051                            writer.write(buffer, 0, count);
052    
053                            count = 0;
054                    }
055    
056                    writer.flush();
057                    writer.close();
058    
059                    writer = null;
060                    buffer = null;
061            }
062    
063            @Override
064            public void flush() throws IOException {
065                    if (writer == null) {
066                            throw new IOException("Writer is null");
067                    }
068    
069                    if (count > 0) {
070                            writer.write(buffer, 0, count);
071    
072                            count = 0;
073                    }
074    
075                    writer.flush();
076            }
077    
078            public void newLine() throws IOException {
079                    write(_LINE_SEPARATOR);
080            }
081    
082            @Override
083            public void write(char[] chars, int offset, int length) throws IOException {
084                    if (writer == null) {
085                            throw new IOException("Writer is null");
086                    }
087    
088                    if (length >= size) {
089                            if (count > 0) {
090                                    writer.write(buffer, 0, count);
091    
092                                    count = 0;
093                            }
094    
095                            writer.write(chars, offset, length);
096    
097                            return;
098                    }
099    
100                    if ((count > 0) && (length > (size - count))) {
101                            writer.write(buffer, 0, count);
102    
103                            count = 0;
104                    }
105    
106                    System.arraycopy(chars, offset, buffer, count, length);
107    
108                    count += length;
109            }
110    
111            @Override
112            public void write(int c) throws IOException {
113                    if (writer == null) {
114                            throw new IOException("Writer is null");
115                    }
116    
117                    if (count >= size) {
118                            writer.write(buffer);
119    
120                            count = 0;
121                    }
122    
123                    buffer[count++] = (char)c;
124            }
125    
126            @Override
127            public void write(String string, int offset, int length)
128                    throws IOException {
129    
130                    if (writer == null) {
131                            throw new IOException("Writer is null");
132                    }
133    
134                    int x = offset;
135                    int y = offset + length;
136    
137                    while (x < y) {
138                            if (count >= size) {
139                                    writer.write(buffer);
140    
141                                    count = 0;
142                            }
143    
144                            int leftFreeSpace = size - count;
145                            int leftDataSize = y - x;
146    
147                            if (leftFreeSpace > leftDataSize) {
148                                    string.getChars(x, y, buffer, count);
149    
150                                    count += leftDataSize;
151    
152                                    break;
153                            }
154                            else {
155                                    int copyEnd = x + leftFreeSpace;
156    
157                                    string.getChars(x, copyEnd, buffer, count);
158    
159                                    count += leftFreeSpace;
160    
161                                    x = copyEnd;
162                            }
163                    }
164            }
165    
166            protected char[] buffer;
167            protected int count;
168            protected int size;
169            protected Writer writer;
170    
171            private static final int _DEFAULT_BUFFER_SIZE = 8192;
172    
173            private static final String _LINE_SEPARATOR = System.getProperty(
174                    "line.separator");
175    
176    }