F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
17namespace Svc {
18
19 // ----------------------------------------------------------------------
20 // Constructors and destructors
21 // ----------------------------------------------------------------------
22
23 BufferLogger::File ::
24 File(
25 BufferLogger& bufferLogger
26 ) :
27 bufferLogger(bufferLogger),
28 prefix(""),
29 suffix(""),
30 baseName(""),
31 fileCounter(0),
32 maxSize(0),
33 sizeOfSize(0),
34 mode(Mode::CLOSED),
35 bytesWritten(0)
36 {
37 }
38
39 BufferLogger::File ::
40 ~File()
41 {
42 this->close();
43 }
44
45 // ----------------------------------------------------------------------
46 // Public functions
47 // ----------------------------------------------------------------------
48
49 void BufferLogger::File ::
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->mode == File::Mode::CLOSED);
59
60 this->prefix = logFilePrefix;
61 this->suffix = logFileSuffix;
62 this->maxSize = maxFileSize;
63 this->sizeOfSize = sizeOfSize;
64
65 FW_ASSERT(sizeOfSize <= sizeof(U32), sizeOfSize);
66 FW_ASSERT(maxSize > sizeOfSize, maxSize);
67 }
68
69 void BufferLogger::File ::
70 setBaseName(
71 const Fw::StringBase& baseName
72 )
73 {
74 if (this->mode == File::Mode::OPEN) {
75 this->closeAndEmitEvent();
76 }
77 this->baseName = baseName;
78 this->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->mode == File::Mode::OPEN) {
90 const U32 projectedByteCount =
91 this->bytesWritten + this->sizeOfSize + size;
92 if (projectedByteCount > this->maxSize) {
93 this->closeAndEmitEvent();
94 }
95 }
96 // Open a file if necessary
97 if (this->mode == File::Mode::CLOSED) {
98 this->open();
99 }
100 // Write to the file if it is open
101 if (this->mode == File::Mode::OPEN) {
102 (void) this->writeBuffer(data, size);
103 }
104 }
105
106 void BufferLogger::File ::
107 closeAndEmitEvent()
108 {
109 if (this->mode == File::Mode::OPEN) {
110 this->close();
111 Fw::LogStringArg logStringArg(this->name.toChar());
112 this->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->mode == File::Mode::CLOSED);
124
125 // NOTE(mereweth) - check that file path has been set and that initLog has been called
126 if ((this->baseName.toChar()[0] == '\0') ||
127 (this->sizeOfSize > sizeof(U32)) ||
128 (this->maxSize <= this->sizeOfSize)) {
129 this->bufferLogger.log_WARNING_HI_BL_NoLogFileOpenInitError();
130 return;
131 }
132
133 if (this->fileCounter == 0) {
134 this->name.format(
135 "%s%s%s",
136 this->prefix.toChar(),
137 this->baseName.toChar(),
138 this->suffix.toChar()
139 );
140 }
141 else {
142 this->name.format(
143 "%s%s%d%s",
144 this->prefix.toChar(),
145 this->baseName.toChar(),
146 this->fileCounter,
147 this->suffix.toChar()
148 );
149 }
150
151 const Os::File::Status status = this->osFile.open(
152 this->name.toChar(),
154 );
155 if (status == Os::File::OP_OK) {
156 this->fileCounter++;
157 // Reset bytes written
158 this->bytesWritten = 0;
159 // Set mode
160 this->mode = File::Mode::OPEN;
161 }
162 else {
163 Fw::LogStringArg string(this->name.toChar());
164 this->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->sizeOfSize <= sizeof(U32));
185 U8 sizeBuffer[sizeof(U32)];
186 U32 sizeRegister = size;
187 for (U8 i = 0; i < this->sizeOfSize; ++i) {
188 sizeBuffer[this->sizeOfSize - i - 1] = sizeRegister & 0xFF;
189 sizeRegister >>= 8;
190 }
191 const bool status = this->writeBytes(
192 sizeBuffer,
193 this->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, length);
205 NATIVE_INT_TYPE size = length;
206 const Os::File::Status fileStatus = this->osFile.write(data, size);
207 bool status;
208 if (fileStatus == Os::File::OP_OK && size == static_cast<NATIVE_INT_TYPE>(length)) {
209 this->bytesWritten += length;
210 status = true;
211 }
212 else {
213 Fw::LogStringArg string(this->name.toChar());
214
215 this->bufferLogger.log_WARNING_HI_BL_LogFileWriteError(fileStatus, size, length, string);
216 status = false;
217 }
218 return status;
219 }
220
221 void BufferLogger::File ::
222 writeHashFile()
223 {
224 Os::ValidatedFile validatedFile(this->name.toChar());
225 const Os::ValidateFile::Status status =
226 validatedFile.createHashFile();
227 if (status != Os::ValidateFile::VALIDATION_OK) {
228 const Fw::String &hashFileName = validatedFile.getHashFileName();
229 Fw::LogStringArg logStringArg(hashFileName.toChar());
230 this->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->mode == File::Mode::OPEN) {
262 // Close file
263 this->osFile.close();
264 // Write out the hash file to disk
265 this->writeHashFile();
266 // Update mode
267 this->mode = File::Mode::CLOSED;
268 }
269 }
270
271}
#define FW_ASSERT(...)
Definition Assert.hpp:7
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
Defines a file class to validate files or generate a file validator file.
virtual const CHAR * toChar() const =0
const char * toChar() const
gets char buffer
Definition String.cpp:48
@ OP_OK
Operation was successful.
Definition File.hpp:24
@ OPEN_WRITE
Open file for writing.
Definition File.hpp:16
A validated file.
@ VALIDATION_OK
The validation of the file passed.