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