/src/logging-log4cxx/src/main/cpp/outputstreamwriter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #include <log4cxx/logstring.h> |
19 | | #include <log4cxx/helpers/outputstreamwriter.h> |
20 | | #include <log4cxx/helpers/exception.h> |
21 | | #include <log4cxx/helpers/charsetencoder.h> |
22 | | #include <log4cxx/helpers/bytebuffer.h> |
23 | | #include <log4cxx/helpers/stringhelper.h> |
24 | | |
25 | | using namespace LOG4CXX_NS; |
26 | | using namespace LOG4CXX_NS::helpers; |
27 | | |
28 | | IMPLEMENT_LOG4CXX_OBJECT(OutputStreamWriter) |
29 | | |
30 | | struct OutputStreamWriter::OutputStreamWriterPrivate |
31 | | { |
32 | | OutputStreamWriterPrivate |
33 | | ( const OutputStreamPtr& out1 |
34 | | , const CharsetEncoderPtr& enc1 = CharsetEncoder::getDefaultEncoder() |
35 | | ) |
36 | 0 | : out(out1) |
37 | 0 | , enc(enc1) |
38 | 0 | {} |
39 | | |
40 | | OutputStreamPtr out; |
41 | | CharsetEncoderPtr enc; |
42 | | }; |
43 | | |
44 | | OutputStreamWriter::OutputStreamWriter(LOG4CXX_16_CONST OutputStreamPtr& out) |
45 | 0 | : m_priv(std::make_unique<OutputStreamWriterPrivate>(out)) |
46 | 0 | { |
47 | 0 | if (!out) |
48 | 0 | { |
49 | 0 | throw NullPointerException(LOG4CXX_STR("OutputStream parameter may not be null.")); |
50 | 0 | } |
51 | 0 | } |
52 | | |
53 | | OutputStreamWriter::OutputStreamWriter |
54 | | ( LOG4CXX_16_CONST OutputStreamPtr& out |
55 | | , LOG4CXX_16_CONST CharsetEncoderPtr& enc |
56 | | ) |
57 | 0 | : m_priv(std::make_unique<OutputStreamWriterPrivate>(out, enc)) |
58 | 0 | { |
59 | 0 | if (!out) |
60 | 0 | { |
61 | 0 | throw NullPointerException(LOG4CXX_STR("OutputStream parameter may not be null.")); |
62 | 0 | } |
63 | | |
64 | 0 | if (!enc) |
65 | 0 | { |
66 | 0 | throw NullPointerException(LOG4CXX_STR("CharsetEncoder parameter may not be null.")); |
67 | 0 | } |
68 | 0 | } |
69 | | |
70 | | OutputStreamWriter::~OutputStreamWriter() |
71 | 0 | { |
72 | 0 | } |
73 | | |
74 | | void OutputStreamWriter::close(Pool& p) |
75 | 0 | { |
76 | 0 | m_priv->out->close(p); |
77 | 0 | } |
78 | | |
79 | | void OutputStreamWriter::flush(Pool& p) |
80 | 0 | { |
81 | 0 | m_priv->out->flush(p); |
82 | 0 | } |
83 | | |
84 | | void OutputStreamWriter::write(const LogString& str, Pool& p) |
85 | 0 | { |
86 | 0 | if (str.empty()) |
87 | 0 | return; |
88 | 0 | if (CharsetEncoder::isTriviallyCopyable(str, m_priv->enc)) |
89 | 0 | { |
90 | 0 | ByteBuffer buf((char*)str.data(), str.size() * sizeof (logchar)); |
91 | 0 | m_priv->out->write(buf, p); |
92 | 0 | } |
93 | 0 | else |
94 | 0 | { |
95 | 0 | enum { BUFSIZE = 1024 }; |
96 | 0 | char stackData[BUFSIZE]; |
97 | 0 | char* rawbuf = stackData; |
98 | 0 | size_t bufSize = BUFSIZE; |
99 | | #ifdef LOG4CXX_MULTI_PROCESS |
100 | | std::vector<char> heapData; |
101 | | // Ensure the logging event is a single write system call to keep events from each process separate |
102 | | if (bufSize < str.length() * 2) |
103 | | { |
104 | | heapData.resize(bufSize = str.length() * 2); |
105 | | rawbuf = heapData.data(); |
106 | | } |
107 | | #endif |
108 | 0 | ByteBuffer buf(rawbuf, bufSize); |
109 | 0 | m_priv->enc->reset(); |
110 | 0 | LogString::const_iterator iter = str.begin(); |
111 | |
|
112 | 0 | while (iter != str.end()) |
113 | 0 | { |
114 | 0 | CharsetEncoder::encode(m_priv->enc, str, iter, buf); |
115 | 0 | buf.flip(); |
116 | 0 | m_priv->out->write(buf, p); |
117 | 0 | buf.clear(); |
118 | 0 | } |
119 | |
|
120 | 0 | CharsetEncoder::encode(m_priv->enc, str, iter, buf); |
121 | 0 | m_priv->enc->flush(buf); |
122 | 0 | buf.flip(); |
123 | 0 | m_priv->out->write(buf, p); |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | OutputStreamPtr OutputStreamWriter::getOutputStreamPtr() const |
128 | 0 | { |
129 | 0 | return m_priv->out; |
130 | 0 | } |
131 | | |