Coverage Report

Created: 2025-07-11 07:00

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