Coverage Report

Created: 2026-05-30 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/inputstreamreader.cpp
Line
Count
Source
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/inputstreamreader.h>
20
#include <log4cxx/helpers/exception.h>
21
#include <log4cxx/helpers/pool.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(InputStreamReader)
29
30
struct InputStreamReader::InputStreamReaderPrivate{
31
  InputStreamReaderPrivate(const InputStreamPtr& in1) :
32
0
    in(in1), dec(CharsetDecoder::getDefaultDecoder()){}
33
34
  InputStreamReaderPrivate(const InputStreamPtr& in1, const CharsetDecoderPtr& dec1) :
35
2
    in(in1), dec(dec1) {}
36
37
  InputStreamPtr in;
38
  CharsetDecoderPtr dec;
39
};
40
41
InputStreamReader::InputStreamReader(const InputStreamPtr& in1)
42
0
  : m_priv(std::make_unique<InputStreamReaderPrivate>(in1))
43
0
{
44
0
  if (!in1)
45
0
  {
46
0
    throw NullPointerException(LOG4CXX_STR("InputStream parameter"));
47
0
  }
48
0
}
49
50
InputStreamReader::InputStreamReader(const InputStreamPtr& in1, const CharsetDecoderPtr& dec1)
51
2
  : m_priv(std::make_unique<InputStreamReaderPrivate>(in1, dec1))
52
2
{
53
2
  if (!in1)
54
0
  {
55
0
    throw NullPointerException(LOG4CXX_STR("InputStream parameter"));
56
0
  }
57
58
2
  if (!dec1)
59
0
  {
60
0
    throw NullPointerException(LOG4CXX_STR("CharsetDecoder parameter"));
61
0
  }
62
2
}
63
64
InputStreamReader::~InputStreamReader()
65
2
{
66
2
}
67
68
void InputStreamReader::close( LOG4CXX_CLOSE_READER_FORMAL_PARAMETERS )
69
0
{
70
0
  m_priv->in->close();
71
0
}
72
73
LogString InputStreamReader::read( LOG4CXX_READ_READER_FORMAL_PARAMETERS )
74
2
{
75
2
  const size_t BUFSIZE = 4096;
76
2
  char stackStorage[BUFSIZE];
77
2
  ByteBuffer buf(stackStorage, BUFSIZE);
78
2
  LogString output;
79
2
  log4cxx_status_t stat{ 0 };
80
81
  // read whole file
82
4
  while (m_priv->in->read(buf) >= 0)
83
2
  {
84
2
    buf.flip();
85
2
    auto lastAvailableCount = buf.remaining();
86
2
    stat = m_priv->dec->decode(buf, output);
87
2
    if (buf.remaining() == lastAvailableCount)
88
0
    {
89
0
      if (stat == 0)
90
0
        stat = -1;
91
0
      break;
92
0
    }
93
2
    buf.carry();
94
2
  }
95
2
  if (stat != 0 && 0 < buf.remaining())
96
0
  {
97
0
    auto toHexDigit = [](int ch) -> int
98
0
    {
99
0
      return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
100
0
    };
101
0
    LogString msg(LOG4CXX_STR("Unable to decode character 0x"));
102
0
    auto ch = static_cast<unsigned int>(*buf.current());
103
0
    msg.push_back(toHexDigit((ch & 0xF0) >> 4));
104
0
    msg.push_back(toHexDigit((ch & 0xF)));
105
0
    msg += LOG4CXX_STR(" at offset ");
106
0
    StringHelper::toString(output.size(), msg);
107
0
    throw RuntimeException(msg);
108
0
  }
109
110
2
  return output;
111
2
}