2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netconf.nettyutil.handler;
10 import java.io.IOException;
11 import java.io.Writer;
14 * Custom BufferedWriter optimized for NETCONF pipeline implemented instead of default BufferedWriter provided by JDK..
17 * In versions up to and including Java 8, java.io.BufferedWriter initialized its lineSeparator field using
18 * AccessController and takes considerable amount of time especially if lots of BufferedWriters are created in the
19 * system. This has been rectified in <a href="https://bugs.openjdk.org/browse/JDK-8068498">Java 9</a>.
22 * Despite that issue having been fixed we retain this implementation because its methods are not synchronized, hence
23 * offer a tad better performance.
26 * This implementation should only be used if newLine method is not required such as NETCONF message to XML encoders.
28 public final class BufferedWriter extends Writer {
29 private static final int DEFAULT_CHAR_BUFFER_SIZE = 8192;
31 private final Writer writer;
32 private final char[] buffer;
33 private final int bufferSize;
35 private int nextChar = 0;
37 public BufferedWriter(final Writer writer) {
38 this(writer, DEFAULT_CHAR_BUFFER_SIZE);
41 public BufferedWriter(final Writer writer, final int bufferSize) {
43 if (bufferSize <= 0) {
44 throw new IllegalArgumentException("Buffer size <= 0");
47 this.bufferSize = bufferSize;
48 buffer = new char[bufferSize];
51 private void flushBuffer() throws IOException {
55 writer.write(buffer, 0, nextChar);
60 public void write(final int character) throws IOException {
61 if (nextChar >= bufferSize) {
64 buffer[nextChar++] = (char) character;
68 @SuppressWarnings("checkstyle:hiddenField")
69 public void write(final char[] buffer, final int offset, final int length) throws IOException {
70 if (offset < 0 || offset > buffer.length
71 || length < 0 || offset + length > buffer.length || offset + length < 0) {
72 throw new IndexOutOfBoundsException(
73 "Buffer size: %d, Offset: %d, Length: %d".formatted(buffer.length, offset, length));
74 } else if (length == 0) {
78 if (length >= bufferSize) {
80 writer.write(buffer, offset, length);
84 int bufferOffset = offset;
85 final int t = offset + length;
86 while (bufferOffset < t) {
87 final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
88 System.arraycopy(buffer, bufferOffset, this.buffer, nextChar, d);
91 if (nextChar >= bufferSize) {
98 public void write(final String string, final int offset, final int length) throws IOException {
99 int bufferOffset = offset;
100 final int t = offset + length;
101 while (bufferOffset < t) {
102 final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
103 string.getChars(bufferOffset, bufferOffset + d, buffer, nextChar);
106 if (nextChar >= bufferSize) {
113 public void flush() throws IOException {
119 public void close() throws IOException {