F´ Flight Software - C/C++ Documentation
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 
13 #include "Os/ValidateFile.hpp"
14 #include "Os/ValidatedFile.hpp"
16 
17 namespace Svc {
18 
19 // ----------------------------------------------------------------------
20 // Constructors and destructors
21 // ----------------------------------------------------------------------
22 
23 BufferLogger::File ::File(BufferLogger& bufferLogger)
24  : m_bufferLogger(bufferLogger),
25  m_prefix(""),
26  m_suffix(""),
27  m_baseName(""),
28  m_fileCounter(0),
29  m_maxSize(0),
30  m_sizeOfSize(0),
31  m_mode(Mode::CLOSED),
32  m_bytesWritten(0) {}
33 
34 BufferLogger::File ::~File() {
35  this->close();
36 }
37 
38 // ----------------------------------------------------------------------
39 // Public functions
40 // ----------------------------------------------------------------------
41 
42 void BufferLogger::File ::init(const char* const logFilePrefix,
43  const char* const logFileSuffix,
44  const FwSizeType maxFileSize,
45  const U8 sizeOfSize) {
46  // NOTE(mereweth) - only call this before opening the file
47  FW_ASSERT(this->m_mode == File::Mode::CLOSED);
48 
49  this->m_prefix = logFilePrefix;
50  this->m_suffix = logFileSuffix;
51  this->m_maxSize = maxFileSize;
52  this->m_sizeOfSize = sizeOfSize;
53 
54  FW_ASSERT(sizeOfSize <= sizeof(FwSizeType), static_cast<FwAssertArgType>(sizeOfSize));
55  FW_ASSERT(m_maxSize > sizeOfSize, static_cast<FwAssertArgType>(m_maxSize));
56 }
57 
58 void BufferLogger::File ::setBaseName(const Fw::StringBase& baseName) {
59  if (this->m_mode == File::Mode::OPEN) {
60  this->closeAndEmitEvent();
61  }
62  this->m_baseName = baseName;
63  this->m_fileCounter = 0;
64  this->open();
65 }
66 
67 void BufferLogger::File ::logBuffer(const U8* const data, const FwSizeType size) {
68  // Close the file if it will be too big
69  if (this->m_mode == File::Mode::OPEN) {
70  const FwSizeType projectedByteCount = this->m_bytesWritten + this->m_sizeOfSize + size;
71  if (projectedByteCount > this->m_maxSize) {
72  this->closeAndEmitEvent();
73  }
74  }
75  // Open a file if necessary
76  if (this->m_mode == File::Mode::CLOSED) {
77  this->open();
78  }
79  // Write to the file if it is open
80  if (this->m_mode == File::Mode::OPEN) {
81  (void)this->writeBuffer(data, size);
82  }
83 }
84 
85 void BufferLogger::File ::closeAndEmitEvent() {
86  if (this->m_mode == File::Mode::OPEN) {
87  this->close();
88  Fw::LogStringArg logStringArg(this->m_name.toChar());
89  this->m_bufferLogger.log_DIAGNOSTIC_BL_LogFileClosed(logStringArg);
90  }
91 }
92 
93 // ----------------------------------------------------------------------
94 // Private functions
95 // ----------------------------------------------------------------------
96 
97 void BufferLogger::File ::open() {
98  FW_ASSERT(this->m_mode == File::Mode::CLOSED);
99 
100  // NOTE(mereweth) - check that file path has been set and that initLog has been called
101  if ((this->m_baseName.toChar()[0] == '\0') || (this->m_sizeOfSize > sizeof(FwSizeType)) ||
102  (this->m_maxSize <= this->m_sizeOfSize)) {
103  this->m_bufferLogger.log_WARNING_HI_BL_NoLogFileOpenInitError();
104  return;
105  }
106 
107  if (this->m_fileCounter == 0) {
108  this->m_name.format("%s%s%s", this->m_prefix.toChar(), this->m_baseName.toChar(), this->m_suffix.toChar());
109  } else {
110  this->m_name.format("%s%s%" PRI_FwSizeType "%s", this->m_prefix.toChar(), this->m_baseName.toChar(),
111  this->m_fileCounter, this->m_suffix.toChar());
112  }
113 
114  const Os::File::Status status = this->m_osFile.open(this->m_name.toChar(), Os::File::OPEN_WRITE);
115  if (status == Os::File::OP_OK) {
116  this->m_fileCounter++;
117  // Reset bytes written
118  this->m_bytesWritten = 0;
119  // Set mode
120  this->m_mode = File::Mode::OPEN;
121  } else {
122  Fw::LogStringArg string(this->m_name.toChar());
123  this->m_bufferLogger.log_WARNING_HI_BL_LogFileOpenError(status, string);
124  }
125 }
126 
127 bool BufferLogger::File ::writeBuffer(const U8* const data, const FwSizeType size) {
128  bool status = this->writeSize(size);
129  if (status) {
130  status = this->writeBytes(data, size);
131  }
132  return status;
133 }
134 
135 bool BufferLogger::File ::writeSize(const FwSizeType size) {
136  FW_ASSERT(this->m_sizeOfSize <= sizeof(FwSizeType));
137  U8 sizeBuffer[sizeof(FwSizeType)];
138  FwSizeType sizeRegister = size;
139  for (U8 i = 0; i < this->m_sizeOfSize; ++i) {
140  sizeBuffer[this->m_sizeOfSize - i - 1] = sizeRegister & 0xFF;
141  sizeRegister >>= 8;
142  }
143  const bool status = this->writeBytes(sizeBuffer, this->m_sizeOfSize);
144  return status;
145 }
146 
147 bool BufferLogger::File ::writeBytes(const void* const data, const FwSizeType length) {
148  FwSizeType size = length;
149  const Os::File::Status fileStatus = this->m_osFile.write(reinterpret_cast<const U8*>(data), size);
150  bool status;
151  if (fileStatus == Os::File::OP_OK && static_cast<FwSizeType>(size) == length) {
152  this->m_bytesWritten += length;
153  status = true;
154  } else {
155  Fw::LogStringArg string(this->m_name.toChar());
156 
157  this->m_bufferLogger.log_WARNING_HI_BL_LogFileWriteError(fileStatus, static_cast<U32>(size),
158  static_cast<U32>(length), string);
159  status = false;
160  }
161  return status;
162 }
163 
164 void BufferLogger::File ::writeHashFile() {
165  Os::ValidatedFile validatedFile(this->m_name.toChar());
166  const Os::ValidateFile::Status status = validatedFile.createHashFile();
167  if (status != Os::ValidateFile::VALIDATION_OK) {
168  const Fw::StringBase& hashFileName = validatedFile.getHashFileName();
169  Fw::LogStringArg logStringArg(hashFileName.toChar());
170  this->m_bufferLogger.log_WARNING_HI_BL_LogFileValidationError(logStringArg, status);
171  }
172 }
173 
174 bool BufferLogger::File ::flush() {
175  return true;
176  // NOTE(if your fprime uses buffered file I/O, re-enable this)
177  /*bool status = true;
178  if(this->mode == File::Mode::OPEN)
179  {
180  const Os::File::Status fileStatus = this->osFile.flush();
181  if(fileStatus == Os::File::OP_OK)
182  {
183  status = true;
184  }
185  else
186  {
187  status = false;
188  }
189  }
190  return status;*/
191 }
192 
193 void BufferLogger::File ::close() {
194  if (this->m_mode == File::Mode::OPEN) {
195  // Close file
196  this->m_osFile.close();
197  // Write out the hash file to disk
198  this->writeHashFile();
199  // Update mode
200  this->m_mode = File::Mode::CLOSED;
201  }
202 }
203 
204 } // namespace Svc
PlatformSizeType FwSizeType
#define PRI_FwSizeType
Open file for writing.
Definition: File.hpp:33
A validated file.
The validation of the file passed.
Os::ValidateFile::Status createHashFile()
void init()
Initialize the OS Abstraction Layer (OSAL)
Definition: Os.cpp:15
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
Operation was successful.
Definition: File.hpp:40
Defines a file class to validate files or generate a file validator file.
RateGroupDivider component implementation.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
virtual const CHAR * toChar() const =0