Coverage Report

Created: 2025-08-29 06:29

/src/logging-log4cxx/src/main/cpp/file.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/file.h>
20
#include <apr_file_io.h>
21
#include <apr_file_info.h>
22
#include <log4cxx/helpers/transcoder.h>
23
#include <log4cxx/helpers/pool.h>
24
#include <assert.h>
25
#include <log4cxx/helpers/exception.h>
26
27
using namespace LOG4CXX_NS;
28
using namespace LOG4CXX_NS::helpers;
29
30
struct File::FilePrivate{
31
  FilePrivate() :
32
2.56k
    autoDelete(false)
33
2.56k
  {}
34
35
  FilePrivate(LogString path) :
36
3.06k
    path(path),
37
3.06k
    autoDelete(false)
38
3.06k
  {}
39
40
  FilePrivate(LogString path, bool autoDelete) :
41
8
    path(path),
42
8
    autoDelete(autoDelete)
43
8
  {}
44
45
  LogString path;
46
  bool autoDelete;
47
};
48
49
File::File() :
50
2.56k
  m_priv(std::make_unique<FilePrivate>())
51
2.56k
{
52
2.56k
}
53
54
template<class S>
55
static LogString decodeLS(const S* src)
56
0
{
57
0
  LogString dst;
58
59
0
  if (src != 0)
60
0
  {
61
0
    Transcoder::decode(src, dst);
62
0
  }
63
64
0
  return dst;
65
0
}
Unexecuted instantiation: file.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > decodeLS<char>(char const*)
Unexecuted instantiation: file.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > decodeLS<wchar_t>(wchar_t const*)
66
67
template<class S>
68
static LogString decodeLS(const std::basic_string<S>& src)
69
3.06k
{
70
3.06k
  LogString dst;
71
3.06k
  Transcoder::decode(src, dst);
72
3.06k
  return dst;
73
3.06k
}
file.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > decodeLS<char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
69
3.06k
{
70
3.06k
  LogString dst;
71
3.06k
  Transcoder::decode(src, dst);
72
3.06k
  return dst;
73
3.06k
}
Unexecuted instantiation: file.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > decodeLS<wchar_t>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
74
75
76
File::File(const std::string& name1)
77
3.06k
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
78
3.06k
{
79
3.06k
}
80
81
File::File(const char* name1)
82
0
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
83
0
{
84
0
}
85
86
#if LOG4CXX_WCHAR_T_API
87
File::File(const std::wstring& name1)
88
0
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
89
0
{
90
0
}
91
92
File::File(const wchar_t* name1)
93
0
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
94
0
{
95
0
}
96
#endif
97
98
#if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR
99
File::File(const std::basic_string<UniChar>& name1)
100
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
101
{
102
}
103
104
File::File(const UniChar* name1)
105
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
106
{
107
}
108
#endif
109
110
#if LOG4CXX_CFSTRING_API
111
File::File(const CFStringRef& name1)
112
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
113
{
114
}
115
#endif
116
117
File::File(const File& src)
118
8
  : m_priv(std::make_unique<FilePrivate>(src.m_priv->path, src.m_priv->autoDelete))
119
8
{
120
8
}
121
122
File& File::operator=(const File& src)
123
0
{
124
0
  if (this == &src)
125
0
  {
126
0
    return *this;
127
0
  }
128
129
0
  m_priv->path.assign(src.m_priv->path);
130
0
  m_priv->autoDelete = src.m_priv->autoDelete;
131
132
0
  return *this;
133
0
}
134
135
136
File::~File()
137
5.63k
{
138
5.63k
  if(m_priv->autoDelete){
139
0
    Pool p;
140
0
    deleteFile(p);
141
0
  }
142
5.63k
}
143
144
145
LogString File::getPath() const
146
3
{
147
3
  return m_priv->path;
148
3
}
149
150
File& File::setPath(const LogString& newName)
151
2.05k
{
152
2.05k
  m_priv->path.assign(newName);
153
2.05k
  return *this;
154
2.05k
}
155
156
LogString File::getName() const
157
0
{
158
0
  const logchar slashes[] = { 0x2F, 0x5C, 0 };
159
0
  size_t lastSlash = m_priv->path.find_last_of(slashes);
160
161
0
  if (lastSlash != LogString::npos)
162
0
  {
163
0
    return m_priv->path.substr(lastSlash + 1);
164
0
  }
165
166
0
  return m_priv->path;
167
0
}
168
169
char* File::getPath(Pool& p) const
170
5.64k
{
171
5.64k
  int style = APR_FILEPATH_ENCODING_UNKNOWN;
172
5.64k
  apr_filepath_encoding(&style, p.getAPRPool());
173
5.64k
  char* retval = NULL;
174
175
5.64k
  if (style == APR_FILEPATH_ENCODING_UTF8)
176
0
  {
177
0
    retval = Transcoder::encodeUTF8(m_priv->path, p);
178
0
  }
179
5.64k
  else
180
5.64k
  {
181
5.64k
    retval = Transcoder::encode(m_priv->path, p);
182
5.64k
  }
183
184
5.64k
  return retval;
185
5.64k
}
186
187
log4cxx_status_t File::open(apr_file_t** file, int flags,
188
  int perm, Pool& p) const
189
1.02k
{
190
1.02k
  return apr_file_open(file, getPath(p), flags, perm, p.getAPRPool());
191
1.02k
}
192
193
194
195
bool File::exists(Pool& p) const
196
3.57k
{
197
3.57k
  apr_finfo_t finfo;
198
3.57k
  apr_status_t rv = apr_stat(&finfo, getPath(p),
199
3.57k
      0, p.getAPRPool());
200
3.57k
  return rv == APR_SUCCESS;
201
3.57k
}
202
203
char* File::convertBackSlashes(char* src)
204
8
{
205
120
  for (char* c = src; *c != 0; c++)
206
112
  {
207
112
    if (*c == '\\')
208
0
    {
209
0
      *c = '/';
210
0
    }
211
112
  }
212
213
8
  return src;
214
8
}
215
216
bool File::deleteFile(Pool& p) const
217
2
{
218
2
  apr_status_t rv = apr_file_remove(convertBackSlashes(getPath(p)),
219
2
      p.getAPRPool());
220
2
  return rv == APR_SUCCESS;
221
2
}
222
223
bool File::renameTo(const File& dest, Pool& p) const
224
2
{
225
2
  apr_status_t rv = apr_file_rename(convertBackSlashes(getPath(p)),
226
2
      convertBackSlashes(dest.getPath(p)),
227
2
      p.getAPRPool());
228
2
  return rv == APR_SUCCESS;
229
2
}
230
231
232
size_t File::length(Pool& pool) const
233
434
{
234
434
  apr_finfo_t finfo;
235
434
  apr_status_t rv = apr_stat(&finfo, getPath(pool),
236
434
      APR_FINFO_SIZE, pool.getAPRPool());
237
238
434
  if (rv == APR_SUCCESS)
239
262
  {
240
262
    return (size_t) finfo.size;
241
262
  }
242
243
172
  return 0;
244
434
}
245
246
247
log4cxx_time_t File::lastModified(Pool& pool) const
248
609
{
249
609
  apr_finfo_t finfo;
250
609
  apr_status_t rv = apr_stat(&finfo, getPath(pool),
251
609
      APR_FINFO_MTIME, pool.getAPRPool());
252
253
609
  if (rv == APR_SUCCESS)
254
608
  {
255
608
    return finfo.mtime;
256
608
  }
257
258
1
  return 0;
259
609
}
260
261
262
std::vector<LogString> File::list(Pool& p) const
263
0
{
264
0
  apr_dir_t* dir;
265
0
  apr_finfo_t entry;
266
0
  std::vector<LogString> filenames;
267
268
0
  apr_status_t stat = apr_dir_open(&dir,
269
0
      convertBackSlashes(getPath(p)),
270
0
      p.getAPRPool());
271
272
0
  if (stat == APR_SUCCESS)
273
0
  {
274
0
    int style = APR_FILEPATH_ENCODING_UNKNOWN;
275
0
    apr_filepath_encoding(&style, p.getAPRPool());
276
0
    stat = apr_dir_read(&entry, APR_FINFO_DIRENT, dir);
277
278
0
    while (stat == APR_SUCCESS)
279
0
    {
280
0
      if (entry.name != NULL)
281
0
      {
282
0
        LogString filename;
283
284
0
        if (style == APR_FILEPATH_ENCODING_UTF8)
285
0
        {
286
0
          Transcoder::decodeUTF8(entry.name, filename);
287
0
        }
288
0
        else
289
0
        {
290
0
          Transcoder::decode(entry.name, filename);
291
0
        }
292
293
0
        filenames.push_back(filename);
294
0
      }
295
296
0
      stat = apr_dir_read(&entry, APR_FINFO_DIRENT, dir);
297
0
    }
298
299
0
    stat = apr_dir_close(dir);
300
0
  }
301
302
0
  return filenames;
303
0
}
304
305
LogString File::getParent(Pool&) const
306
2
{
307
2
  LogString::size_type slashPos = m_priv->path.rfind(LOG4CXX_STR('/'));
308
2
  LogString::size_type backPos = m_priv->path.rfind(LOG4CXX_STR('\\'));
309
310
2
  if (slashPos == LogString::npos)
311
2
  {
312
2
    slashPos = backPos;
313
2
  }
314
0
  else
315
0
  {
316
0
    if (backPos != LogString::npos && backPos > slashPos)
317
0
    {
318
0
      slashPos = backPos;
319
0
    }
320
0
  }
321
322
2
  LogString parent;
323
324
2
  if (slashPos != LogString::npos && slashPos > 0)
325
0
  {
326
0
    parent.assign(m_priv->path, 0, slashPos);
327
0
  }
328
329
2
  return parent;
330
2
}
331
332
bool File::mkdirs(Pool& p) const
333
2
{
334
2
  apr_status_t stat = apr_dir_make_recursive(convertBackSlashes(getPath(p)),
335
2
      APR_OS_DEFAULT, p.getAPRPool());
336
2
  return stat == APR_SUCCESS;
337
2
}
338
339
2
void File::setAutoDelete(bool autoDelete){
340
2
  m_priv->autoDelete = autoDelete;
341
2
}
342
343
0
bool File::getAutoDelete() const{
344
0
  return m_priv->autoDelete;
345
0
}