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/cyclicbuffer.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
#include <log4cxx/logstring.h>
18
#include <log4cxx/helpers/cyclicbuffer.h>
19
#include <log4cxx/spi/loggingevent.h>
20
#include <log4cxx/helpers/exception.h>
21
#include <log4cxx/helpers/pool.h>
22
#include <log4cxx/helpers/stringhelper.h>
23
24
using namespace LOG4CXX_NS;
25
using namespace LOG4CXX_NS::helpers;
26
using namespace LOG4CXX_NS::spi;
27
28
namespace
29
{
30
int validateMaxSize(int maxSize)
31
0
{
32
0
  if (maxSize < 1)
33
0
  {
34
0
    LogString msg(LOG4CXX_STR("The maxSize argument ("));
35
0
    StringHelper::toString(maxSize, msg);
36
0
    msg.append(LOG4CXX_STR(") is not a positive integer."));
37
0
    throw IllegalArgumentException(msg);
38
0
  }
39
40
0
  return maxSize;
41
0
}
42
}
43
44
struct CyclicBuffer::CyclicBufferPriv
45
{
46
  CyclicBufferPriv(int maxSize1) :
47
0
    ea(maxSize1), first(0), last(0), numElems(0), maxSize(maxSize1) {}
48
49
  LOG4CXX_NS::spi::LoggingEventList ea;
50
  int first;
51
  int last;
52
  int numElems;
53
  int maxSize;
54
};
55
56
/**
57
Instantiate a new CyclicBuffer of at most <code>maxSize</code> events.
58
The <code>maxSize</code> argument must a positive integer.
59
@param maxSize The maximum number of elements in the buffer.
60
*/
61
CyclicBuffer::CyclicBuffer(int maxSize1)
62
0
  : m_priv(std::make_unique<CyclicBufferPriv>(validateMaxSize(maxSize1)))
63
0
{
64
0
}
65
66
CyclicBuffer::~CyclicBuffer()
67
0
{
68
0
}
69
70
/**
71
Add an <code>event</code> as the last event in the buffer.
72
*/
73
void CyclicBuffer::add(const spi::LoggingEventPtr& event)
74
0
{
75
0
  if (m_priv->ea.empty())
76
0
  {
77
0
    return;
78
0
  }
79
80
0
  m_priv->ea[m_priv->last] = event;
81
82
0
  if (++m_priv->last == m_priv->maxSize)
83
0
  {
84
0
    m_priv->last = 0;
85
0
  }
86
87
0
  if (m_priv->numElems < m_priv->maxSize)
88
0
  {
89
0
    m_priv->numElems++;
90
0
  }
91
0
  else if (++m_priv->first == m_priv->maxSize)
92
0
  {
93
0
    m_priv->first = 0;
94
0
  }
95
0
}
96
97
98
/**
99
Get the <i>i</i>th oldest event currently in the buffer. If
100
<em>i</em> is outside the range 0 to the number of elements
101
currently in the buffer, then <code>null</code> is returned.
102
*/
103
spi::LoggingEventPtr CyclicBuffer::get(int i)
104
0
{
105
0
  if (i < 0 || i >= m_priv->numElems)
106
0
  {
107
0
    return 0;
108
0
  }
109
110
0
  return m_priv->ea[(m_priv->first + i) % m_priv->maxSize];
111
0
}
112
113
/**
114
Get the oldest (first) element in the buffer. The oldest element
115
is removed from the buffer.
116
*/
117
spi::LoggingEventPtr CyclicBuffer::get()
118
0
{
119
0
  LoggingEventPtr r;
120
121
0
  if (m_priv->numElems > 0)
122
0
  {
123
0
    m_priv->numElems--;
124
0
    r = m_priv->ea[m_priv->first];
125
0
    m_priv->ea[m_priv->first] = 0;
126
127
0
    if (++m_priv->first == m_priv->maxSize)
128
0
    {
129
0
      m_priv->first = 0;
130
0
    }
131
0
  }
132
133
0
  return r;
134
0
}
135
136
/**
137
Resize the cyclic buffer to <code>newSize</code>.
138
@throws IllegalArgumentException if <code>newSize</code> is negative.
139
*/
140
void CyclicBuffer::resize(int newSize)
141
0
{
142
0
  if (newSize < 0)
143
0
  {
144
0
    LogString msg(LOG4CXX_STR("Negative array size ["));
145
0
    StringHelper::toString(newSize, msg);
146
0
    msg.append(LOG4CXX_STR("] not allowed."));
147
0
    throw IllegalArgumentException(msg);
148
0
  }
149
150
0
  if (newSize == m_priv->numElems)
151
0
  {
152
0
    return;    // nothing to do
153
0
  }
154
155
0
  LoggingEventList temp(newSize);
156
157
0
  int loopLen = newSize < m_priv->numElems ? newSize : m_priv->numElems;
158
0
  int i;
159
160
0
  for (i = 0; i < loopLen; i++)
161
0
  {
162
0
    temp[i] = m_priv->ea[m_priv->first];
163
0
    m_priv->ea[m_priv->first] = 0;
164
165
0
    if (++m_priv->first == m_priv->maxSize)
166
0
    {
167
0
      m_priv->first = 0;
168
0
    }
169
0
  }
170
171
0
  m_priv->ea = temp;
172
0
  m_priv->first = 0;
173
0
  m_priv->numElems = loopLen;
174
0
  m_priv->maxSize = newSize;
175
176
0
  if (loopLen == newSize)
177
0
  {
178
0
    m_priv->last = 0;
179
0
  }
180
0
  else
181
0
  {
182
0
    m_priv->last = loopLen;
183
0
  }
184
0
}
185
186
int CyclicBuffer::getMaxSize() const
187
0
{
188
0
  return m_priv->maxSize;
189
0
}
190
191
int CyclicBuffer::length() const
192
0
{
193
0
  return m_priv->numElems;
194
0
}