Coverage Report

Created: 2025-07-01 06:08

/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
0
    autoDelete(false)
33
0
  {}
34
35
  FilePrivate(LogString path) :
36
1.72k
    path(path),
37
1.72k
    autoDelete(false)
38
1.72k
  {}
39
40
  FilePrivate(LogString path, bool autoDelete) :
41
0
    path(path),
42
0
    autoDelete(autoDelete)
43
0
  {}
44
45
  LogString path;
46
  bool autoDelete;
47
};
48
49
File::File() :
50
0
  m_priv(std::make_unique<FilePrivate>())
51
0
{
52
0
}
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
1.72k
{
70
1.72k
  LogString dst;
71
1.72k
  Transcoder::decode(src, dst);
72
1.72k
  return dst;
73
1.72k
}
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
1.72k
{
70
1.72k
  LogString dst;
71
1.72k
  Transcoder::decode(src, dst);
72
1.72k
  return dst;
73
1.72k
}
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
1.72k
  : m_priv(std::make_unique<FilePrivate>(decodeLS(name1)))
78
1.72k
{
79
1.72k
}
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
0
  : m_priv(std::make_unique<FilePrivate>(src.m_priv->path, src.m_priv->autoDelete))
119
0
{
120
0
}
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
1.72k
{
138
1.72k
  if(m_priv->autoDelete){
139
0
    Pool p;
140
0
    deleteFile(p);
141
0
  }
142
1.72k
}
143
144
145
LogString File::getPath() const
146
4.03k
{
147
4.03k
  return m_priv->path;
148
4.03k
}
149
150
File& File::setPath(const LogString& newName)
151
0
{
152
0
  m_priv->path.assign(newName);
153
0
  return *this;
154
0
}
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
1.72k
{
171
1.72k
  int style = APR_FILEPATH_ENCODING_UNKNOWN;
172
1.72k
  apr_filepath_encoding(&style, p.getAPRPool());
173
1.72k
  char* retval = NULL;
174
175
1.72k
  if (style == APR_FILEPATH_ENCODING_UTF8)
176
0
  {
177
0
    retval = Transcoder::encodeUTF8(m_priv->path, p);
178
0
  }
179
1.72k
  else
180
1.72k
  {
181
1.72k
    retval = Transcoder::encode(m_priv->path, p);
182
1.72k
  }
183
184
1.72k
  return retval;
185
1.72k
}
186
187
log4cxx_status_t File::open(apr_file_t** file, int flags,
188
  int perm, Pool& p) const
189
1.72k
{
190
1.72k
  return apr_file_open(file, getPath(p), flags, perm, p.getAPRPool());
191
1.72k
}
192
193
194
195
bool File::exists(Pool& p) const
196
0
{
197
0
  apr_finfo_t finfo;
198
0
  apr_status_t rv = apr_stat(&finfo, getPath(p),
199
0
      0, p.getAPRPool());
200
0
  return rv == APR_SUCCESS;
201
0
}
202
203
char* File::convertBackSlashes(char* src)
204
0
{
205
0
  for (char* c = src; *c != 0; c++)
206
0
  {
207
0
    if (*c == '\\')
208
0
    {
209
0
      *c = '/';
210
0
    }
211
0
  }
212
213
0
  return src;
214
0
}
215
216
bool File::deleteFile(Pool& p) const
217
0
{
218
0
  apr_status_t rv = apr_file_remove(convertBackSlashes(getPath(p)),
219
0
      p.getAPRPool());
220
0
  return rv == APR_SUCCESS;
221
0
}
222
223
bool File::renameTo(const File& dest, Pool& p) const
224
0
{
225
0
  apr_status_t rv = apr_file_rename(convertBackSlashes(getPath(p)),
226
0
      convertBackSlashes(dest.getPath(p)),
227
0
      p.getAPRPool());
228
0
  return rv == APR_SUCCESS;
229
0
}
230
231
232
size_t File::length(Pool& pool) const
233
0
{
234
0
  apr_finfo_t finfo;
235
0
  apr_status_t rv = apr_stat(&finfo, getPath(pool),
236
0
      APR_FINFO_SIZE, pool.getAPRPool());
237
238
0
  if (rv == APR_SUCCESS)
239
0
  {
240
0
    return (size_t) finfo.size;
241
0
  }
242
243
0
  return 0;
244
0
}
245
246
247
log4cxx_time_t File::lastModified(Pool& pool) const
248
0
{
249
0
  apr_finfo_t finfo;
250
0
  apr_status_t rv = apr_stat(&finfo, getPath(pool),
251
0
      APR_FINFO_MTIME, pool.getAPRPool());
252
253
0
  if (rv == APR_SUCCESS)
254
0
  {
255
0
    return finfo.mtime;
256
0
  }
257
258
0
  return 0;
259
0
}
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
0
{
307
0
  LogString::size_type slashPos = m_priv->path.rfind(LOG4CXX_STR('/'));
308
0
  LogString::size_type backPos = m_priv->path.rfind(LOG4CXX_STR('\\'));
309
310
0
  if (slashPos == LogString::npos)
311
0
  {
312
0
    slashPos = backPos;
313
0
  }
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
0
  LogString parent;
323
324
0
  if (slashPos != LogString::npos && slashPos > 0)
325
0
  {
326
0
    parent.assign(m_priv->path, 0, slashPos);
327
0
  }
328
329
0
  return parent;
330
0
}
331
332
bool File::mkdirs(Pool& p) const
333
0
{
334
0
  apr_status_t stat = apr_dir_make_recursive(convertBackSlashes(getPath(p)),
335
0
      APR_OS_DEFAULT, p.getAPRPool());
336
0
  return stat == APR_SUCCESS;
337
0
}
338
339
0
void File::setAutoDelete(bool autoDelete){
340
0
  m_priv->autoDelete = autoDelete;
341
0
}
342
343
0
bool File::getAutoDelete() const{
344
0
  return m_priv->autoDelete;
345
0
}