F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
LogFile.cpp
Go to the documentation of this file.
1 // \copyright
2 // Copyright 2009-2015, by the California Institute of Technology.
3 // ALL RIGHTS RESERVED. United States Government Sponsorship
4 // acknowledged.
5 
6 #include <Fw/Types/Assert.hpp>
8 #include <Os/File.hpp>
9 #include <Os/FileSystem.hpp>
11 #include <cstdio>
12 #include <cstring>
13 #include <limits>
14 
15 namespace Svc {
16 
17 // ----------------------------------------------------------------------
18 // Initialization/Exiting
19 // ----------------------------------------------------------------------
20 
21 LogFile::LogFile() : m_fileName(), m_file(), m_maxFileSize(0), m_openFile(false), m_currentFileSize(0) {}
22 
24  // Close the file if needed:
25  if (this->m_openFile) {
26  this->m_file.close();
27  }
28 }
29 
30 // ----------------------------------------------------------------------
31 // Member Functions
32 // ----------------------------------------------------------------------
33 
34 bool LogFile::write_to_log(const char* const buf, const FwSizeType size) {
35  FW_ASSERT(buf != nullptr);
36 
37  bool status = true;
38 
39  // Print to file if there is one, and given a valid size:
40  if (this->m_openFile && size > 0) {
41  // Make sure we won't exceed the maximum size:
42  // Note: second condition in if statement is true if there is overflow
43  // in the addition below
44  FwSizeType projectedSize = this->m_currentFileSize + size;
45  if (projectedSize > this->m_maxFileSize ||
46  (this->m_currentFileSize > (std::numeric_limits<FwSizeType>::max() - size))) {
47  status = false;
48  this->m_openFile = false;
49  this->m_file.close();
50  }
51  // Won't exceed max size, so write to file:
52  else {
53  FwSizeType writeSize = size;
54  Os::File::Status stat = this->m_file.write(reinterpret_cast<const U8*>(buf), writeSize, Os::File::WAIT);
55 
56  // Assert that we are not trying to write to a file we never opened:
58 
59  // Only return a good status if the write was valid
60  status = (stat == Os::File::OP_OK) && (static_cast<FwSizeType>(writeSize) == size);
61 
62  this->m_currentFileSize += static_cast<FwSizeType>(writeSize);
63  }
64  }
65 
66  return status;
67 }
68 
69 bool LogFile::set_log_file(const char* fileName, const FwSizeType maxSize, const FwSizeType maxBackups) {
70  FW_ASSERT(fileName != nullptr);
71 
72  // If there is already a previously open file then close it:
73  if (this->m_openFile) {
74  this->m_openFile = false;
75  this->m_file.close();
76  }
77  Fw::FileNameString searchFilename;
78  Fw::FormatStatus formatStatus = searchFilename.format("%s", fileName);
79 
80  // If file name is too large, return failure:
81  if (formatStatus != Fw::FormatStatus::SUCCESS) {
82  return false;
83  }
84 
85  // Check if file already exists, and if it does try to tack on a suffix.
86  // Quit after maxBackups suffix addition tries (first try is w/ the original name).
87  U32 suffix = 0;
88  bool failedSuffix = false;
89  FwSizeType fileSize = 0;
90  while (Os::FileSystem::getFileSize(searchFilename.toChar(), fileSize) == Os::FileSystem::OP_OK) {
91  // Not able to create a new non-existing file in maxBackups tries, then mark that it failed:
92  if (suffix >= maxBackups) {
93  failedSuffix = true;
94  break;
95  }
96  // Format and check for error and overflows
97  formatStatus = searchFilename.format("%s%" PRIu32, fileName, suffix);
98  if (formatStatus != Fw::FormatStatus::SUCCESS) {
99  return false;
100  }
101  ++suffix;
102  }
103 
104  // If failed trying to make a new file, just use the original file
105  if (failedSuffix) {
106  searchFilename = fileName;
107  }
108 
109  // Open the file (using CREATE so that it truncates an already existing file):
110  Os::File::Status stat =
111  this->m_file.open(searchFilename.toChar(), Os::File::OPEN_CREATE, Os::File::OverwriteType::OVERWRITE);
112 
113  // Bad status when trying to open the file:
114  if (stat != Os::File::OP_OK) {
115  return false;
116  }
117 
118  this->m_currentFileSize = 0;
119  this->m_maxFileSize = maxSize;
120  this->m_fileName = searchFilename;
121  this->m_openFile = true;
122 
123  return true;
124 }
125 
126 } // namespace Svc
bool write_to_log(const char *const buf, const FwSizeType size)
Write the passed buf to the log if possible.
Definition: LogFile.cpp:34
LogFile()
Constructor.
Definition: LogFile.cpp:21
PlatformSizeType FwSizeType
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
bool m_openFile
Definition: LogFile.hpp:65
const char * toChar() const
Do wait for read/write operation to finish.
Definition: File.hpp:69
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:70
Status write(const U8 *buffer, FwSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:187
Os::File m_file
Definition: LogFile.hpp:59
bool set_log_file(const char *fileName, const FwSizeType maxSize, const FwSizeType maxBackups=10)
Set log file and max size.
Definition: LogFile.cpp:69
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:55
static Status getFileSize(const char *path, FwSizeType &size)
Get the size of the file (in bytes) at the specified path.
Definition: FileSystem.cpp:225
file hasn&#39;t been opened yet
Definition: File.hpp:45
Operation was successful.
Definition: File.hpp:40
FwSizeType m_maxFileSize
Definition: LogFile.hpp:62
RateGroupDivider component implementation.
FwSizeType m_currentFileSize
Definition: LogFile.hpp:68
Operation was successful.
Definition: FileSystem.hpp:24
~LogFile()
Destructor.
Definition: LogFile.cpp:23
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Fw::FileNameString m_fileName
Definition: LogFile.hpp:56
FormatStatus
status of string format calls
Definition: format.hpp:18
Open file for writing and truncates file if it exists, ie same flags as creat()
Definition: File.hpp:32