/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.logging.log4j.io; import java.nio.CharBuffer; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.spi.ExtendedLogger; /** * * @since 2.1 */ public class CharStreamLogger { private final ExtendedLogger logger; private final Level level; private final Marker marker; private final StringBuilder msg = new StringBuilder(); private boolean closed = false; public CharStreamLogger(final ExtendedLogger logger, final Level level, final Marker marker) { this.logger = logger; this.level = level == null ? logger.getLevel() : level; this.marker = marker; } public void close(final String fqcn) { synchronized (this.msg) { this.closed = true; logEnd(fqcn); } } private void log(final String fqcn) { // convert to string now so async loggers work this.logger.logIfEnabled(fqcn, this.level, this.marker, this.msg.toString()); this.msg.setLength(0); } private void logEnd(final String fqcn) { if (this.msg.length() > 0) { log(fqcn); } } public void put(final String fqcn, final char[] cbuf, final int off, final int len) { put(fqcn, CharBuffer.wrap(cbuf), off, len); } public void put(final String fqcn, final CharSequence str, final int off, final int len) { if (len >= 0) { synchronized (this.msg) { if (this.closed) { return; } int start = off; final int end = off + len; for (int pos = off; pos < end; pos++) { final char c = str.charAt(pos); switch (c) { case '\r': case '\n': this.msg.append(str, start, pos); start = pos + 1; if (c == '\n') { log(fqcn); } break; } } this.msg.append(str, start, end); } } else { logEnd(fqcn); } } public void put(final String fqcn, final int c) { if (c >= 0) { synchronized (this.msg) { if (this.closed) { return; } switch (c) { case '\n': log(fqcn); break; case '\r': break; default: this.msg.append((char) c); } } } else { logEnd(fqcn); } } }