F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
BufferLoggerFile.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title BufferLoggerFile.cpp
3 // \author bocchino, dinkel, mereweth
4 // \brief Implementation for Svc::BufferLogger::BufferLoggerFile
5 //
6 // \copyright
7 // Copyright (C) 2015-2017 California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
14 #include "Os/ValidateFile.hpp"
15 #include "Os/ValidatedFile.hpp"
16 
17 namespace Svc {
18 
19  // ----------------------------------------------------------------------
20  // Constructors and destructors
21  // ----------------------------------------------------------------------
22 
23  BufferLogger::File ::
24  File(
25  BufferLogger& bufferLogger
26  ) :
27  m_bufferLogger(bufferLogger),
28  m_prefix(""),
29  m_suffix(""),
30  m_baseName(""),
31  m_fileCounter(0),
32  m_maxSize(0),
33  m_sizeOfSize(0),
34  m_mode(Mode::CLOSED),
35  m_bytesWritten(0)
36  {
37  }
38 
39  BufferLogger::File ::
40  ~File()
41  {
42  this->close();
43  }
44 
45  // ----------------------------------------------------------------------
46  // Public functions
47  // ----------------------------------------------------------------------
48 
50  init(
51  const char *const logFilePrefix,
52  const char *const logFileSuffix,
53  const U32 maxFileSize,
54  const U8 sizeOfSize
55  )
56  {
57  //NOTE(mereweth) - only call this before opening the file
58  FW_ASSERT(this->m_mode == File::Mode::CLOSED);
59 
60  this->m_prefix = logFilePrefix;
61  this->m_suffix = logFileSuffix;
62  this->m_maxSize = maxFileSize;
63  this->m_sizeOfSize = sizeOfSize;
64 
65  FW_ASSERT(sizeOfSize <= sizeof(U32), sizeOfSize);
66  FW_ASSERT(m_maxSize > sizeOfSize, static_cast<FwAssertArgType>(m_maxSize));
67  }
68 
69  void BufferLogger::File ::
70  setBaseName(
71  const Fw::StringBase& baseName
72  )
73  {
74  if (this->m_mode == File::Mode::OPEN) {
75  this->closeAndEmitEvent();
76  }
77  this->m_baseName = baseName;
78  this->m_fileCounter = 0;
79  this->open();
80  }
81 
82  void BufferLogger::File ::
83  logBuffer(
84  const U8 *const data,
85  const U32 size
86  )
87  {
88  // Close the file if it will be too big
89  if (this->m_mode == File::Mode::OPEN) {
90  const U32 projectedByteCount =
91  this->m_bytesWritten + this->m_sizeOfSize + size;
92  if (projectedByteCount > this->m_maxSize) {
93  this->closeAndEmitEvent();
94  }
95  }
96  // Open a file if necessary
97  if (this->m_mode == File::Mode::CLOSED) {
98  this->open();
99  }
100  // Write to the file if it is open
101  if (this->m_mode == File::Mode::OPEN) {
102  (void) this->writeBuffer(data, size);
103  }
104  }
105 
106  void BufferLogger::File ::
107  closeAndEmitEvent()
108  {
109  if (this->m_mode == File::Mode::OPEN) {
110  this->close();
111  Fw::LogStringArg logStringArg(this->m_name.toChar());
112  this->m_bufferLogger.log_DIAGNOSTIC_BL_LogFileClosed(logStringArg);
113  }
114  }
115 
116  // ----------------------------------------------------------------------
117  // Private functions
118  // ----------------------------------------------------------------------
119 
120  void BufferLogger::File ::
121  open()
122  {
123  FW_ASSERT(this->m_mode == File::Mode::CLOSED);
124 
125  // NOTE(mereweth) - check that file path has been set and that initLog has been called
126  if ((this->m_baseName.toChar()[0] == '\0') ||
127  (this->m_sizeOfSize > sizeof(U32)) ||
128  (this->m_maxSize <= this->m_sizeOfSize)) {
129  this->m_bufferLogger.log_WARNING_HI_BL_NoLogFileOpenInitError();
130  return;
131  }
132 
133  if (this->m_fileCounter == 0) {
134  this->m_name.format(
135  "%s%s%s",
136  this->m_prefix.toChar(),
137  this->m_baseName.toChar(),
138  this->m_suffix.toChar()
139  );
140  }
141  else {
142  this->m_name.format(
143  "%s%s%d%s",
144  this->m_prefix.toChar(),
145  this->m_baseName.toChar(),
146  this->m_fileCounter,
147  this->m_suffix.toChar()
148  );
149  }
150 
151  const Os::File::Status status = this->m_osFile.open(
152  this->m_name.toChar(),
154  );
155  if (status == Os::File::OP_OK) {
156  this->m_fileCounter++;
157  // Reset bytes written
158  this->m_bytesWritten = 0;
159  // Set mode
160  this->m_mode = File::Mode::OPEN;
161  }
162  else {
163  Fw::LogStringArg string(this->m_name.toChar());
164  this->m_bufferLogger.log_WARNING_HI_BL_LogFileOpenError(status, string);
165  }
166  }
167 
168  bool BufferLogger::File ::
169  writeBuffer(
170  const U8 *const data,
171  const U32 size
172  )
173  {
174  bool status = this->writeSize(size);
175  if (status) {
176  status = this->writeBytes(data, size);
177  }
178  return status;
179  }
180 
181  bool BufferLogger::File ::
182  writeSize(const U32 size)
183  {
184  FW_ASSERT(this->m_sizeOfSize <= sizeof(U32));
185  U8 sizeBuffer[sizeof(U32)];
186  U32 sizeRegister = size;
187  for (U8 i = 0; i < this->m_sizeOfSize; ++i) {
188  sizeBuffer[this->m_sizeOfSize - i - 1] = sizeRegister & 0xFF;
189  sizeRegister >>= 8;
190  }
191  const bool status = this->writeBytes(
192  sizeBuffer,
193  this->m_sizeOfSize
194  );
195  return status;
196  }
197 
198  bool BufferLogger::File ::
199  writeBytes(
200  const void *const data,
201  const U32 length
202  )
203  {
204  FW_ASSERT(length > 0, static_cast<FwAssertArgType>(length));
205  FwSignedSizeType size = length;
206  const Os::File::Status fileStatus = this->m_osFile.write(reinterpret_cast<const U8*>(data), size);
207  bool status;
208  if (fileStatus == Os::File::OP_OK && size == static_cast<NATIVE_INT_TYPE>(length)) {
209  this->m_bytesWritten += length;
210  status = true;
211  }
212  else {
213  Fw::LogStringArg string(this->m_name.toChar());
214 
215  this->m_bufferLogger.log_WARNING_HI_BL_LogFileWriteError(fileStatus, static_cast<U32>(size), length, string);
216  status = false;
217  }
218  return status;
219  }
220 
221  void BufferLogger::File ::
222  writeHashFile()
223  {
224  Os::ValidatedFile validatedFile(this->m_name.toChar());
225  const Os::ValidateFile::Status status =
226  validatedFile.createHashFile();
227  if (status != Os::ValidateFile::VALIDATION_OK) {
228  const Fw::StringBase &hashFileName = validatedFile.getHashFileName();
229  Fw::LogStringArg logStringArg(hashFileName.toChar());
230  this->m_bufferLogger.log_WARNING_HI_BL_LogFileValidationError(
231  logStringArg,
232  status
233  );
234  }
235  }
236 
237  bool BufferLogger::File ::
238  flush()
239  {
240  return true;
241  // NOTE(if your fprime uses buffered file I/O, re-enable this)
242  /*bool status = true;
243  if(this->mode == File::Mode::OPEN)
244  {
245  const Os::File::Status fileStatus = this->osFile.flush();
246  if(fileStatus == Os::File::OP_OK)
247  {
248  status = true;
249  }
250  else
251  {
252  status = false;
253  }
254  }
255  return status;*/
256  }
257 
258  void BufferLogger::File ::
259  close()
260  {
261  if (this->m_mode == File::Mode::OPEN) {
262  // Close file
263  this->m_osFile.close();
264  // Write out the hash file to disk
265  this->writeHashFile();
266  // Update mode
267  this->m_mode = File::Mode::CLOSED;
268  }
269  }
270 
271 }
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:55
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:30
PlatformAssertArgType FwAssertArgType
Definition: FpConfig.h:39
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:30
Defines a file class to validate files or generate a file validator file.
virtual const CHAR * toChar() const =0
@ OP_OK
Operation was successful.
Definition: File.hpp:30
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:23
A validated file.
@ VALIDATION_OK
The validation of the file passed.
void init()
Initialize the OS Abstraction Layer (OSAL)
Definition: Os.cpp:15