Init basesystem source codes.
[staging/basesystem.git] / video_in_hal / nsframework / notification_persistent_service / server / src / ns_npp_binary_accesser.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ////////////////////////////////////////////////////////////////////////////////////////////////////
18 /// \ingroup  tag_NPPService
19 /// \brief    The file contains definition of CBinaryAccesser class.
20 ///       This class stores data in a file in binary format.
21 ///
22 ///
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #ifdef AGL_STUB
29 #include <other_service/strlcpy.h>
30 #endif
31 #include <cerrno>
32 #include <string>
33 #include "ns_npp_notificationpersistentservicelog.h"
34 #include "ns_npp_fs_directory.h"
35 #include "ns_npp_binary_accesser.h"
36 #include "ns_npp_persistent_data.h"
37 #include "ns_npp_persistent_accesser.h"
38
39 struct PersistFileHeder {
40   char check_code[4];
41   unsigned int crc;
42 };
43 #define NPP_CHECK_CODE "NPPD"
44
45 ////////////////////////////////////////////////////////////////////////////////////////////////
46 /// CBinaryAccesser
47 /// Constructor of CBinaryAccesser class
48 ////////////////////////////////////////////////////////////////////////////////////////////////
49 CBinaryAccesser::CBinaryAccesser() {
50   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
51
52   m_uiCurStrOffset = 0;
53   m_uiCurStrSize = 0;
54
55   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
56 }
57
58 ////////////////////////////////////////////////////////////////////////////////////////////////
59 /// ~CBinaryAccesser
60 /// Destructor of CBinaryAccesser class
61 ////////////////////////////////////////////////////////////////////////////////////////////////
62 CBinaryAccesser::~CBinaryAccesser() {   // LCOV_EXCL_START 14: Resident process, global instance not released
63   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
64   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
65
66   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
67 }
68 // LCOV_EXCL_STOP
69
70 ////////////////////////////////////////////////////////////////////////////////////////////////
71 /// PersistData
72 /// Persist data in persistent memory in a file in binary format.
73 ////////////////////////////////////////////////////////////////////////////////////////////////
74 EFrameworkunifiedStatus CBinaryAccesser::PersistData(std::string f_cmemfilepath,
75                                         Persistent_Notification_List_Type *f_vdata,
76                                         EFrameworkunifiedNotificationType f_epersistenttype,
77                                         EFrameworkunifiedPersistCategory f_epersistcategory) {
78   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
79   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
80
81   int l_OutFd;
82
83   if (NULL != f_vdata) {  // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL
84     // Open global file in write mode.
85     if ((eFrameworkunifiedStatusOK == OpenFileForWriting(&l_OutFd, f_cmemfilepath))) {
86       Persistent_Notification_List_Iterator l_itNotificationList = f_vdata->begin();
87
88       // Iterate through a vector f_vdata
89       for (; l_itNotificationList != f_vdata->end(); l_itNotificationList++) {
90         if (eFrameworkunifiedPersistedStateVar == (*l_itNotificationList)->m_ePersistentType) {
91           if (f_epersistcategory == (*l_itNotificationList)->m_ePersistCategory) {
92             // write header and data
93             if (eFrameworkunifiedStatusOK != WriteHeaderAndData((*l_itNotificationList),
94                                                    (*l_itNotificationList)->m_pPersistentData->m_pMessage,
95                                                    l_OutFd)) {
96               l_estatus = eFrameworkunifiedStatusFail;
97               break;
98             }
99           }
100         } else {
101           // write header and data
102           if (eFrameworkunifiedStatusOK != WriteHeaderAndData((*l_itNotificationList),
103                                                  (*l_itNotificationList)->m_pPersistentData->m_pMessage,
104                                                  l_OutFd)) {
105             l_estatus = eFrameworkunifiedStatusFail;
106             break;
107           }
108         }
109       }
110
111       if (eFrameworkunifiedStatusOK != WriteFileHeaderAndDuplicate(l_OutFd, f_cmemfilepath)) {
112         l_estatus = eFrameworkunifiedStatusFail;
113       } else {
114         FRAMEWORKUNIFIEDLOG(ZONE_PRD_INFO3, __FUNCTION__, "Bytes written in NAND memory, %ld, file=%s",
115                static_cast<long int>(m_uiCurStrOffset - sizeof(PersistFileHeder)), f_cmemfilepath.c_str()); // NOLINT (runtime/int)
116       }
117       close(l_OutFd);
118     } else {
119       l_estatus = eFrameworkunifiedStatusFail;
120       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to open file %s", f_cmemfilepath.c_str());
121     }
122   }
123   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
124
125   return l_estatus;
126 }
127
128 ////////////////////////////////////////////////////////////////////////////////////////////////
129 /// RetrieveData
130 /// Retrieve data in persistent memory in a file in binary format.
131 ////////////////////////////////////////////////////////////////////////////////////////////////
132 EFrameworkunifiedStatus CBinaryAccesser::RetrieveData(std::string f_cmemfilepath,
133                                          Persistent_Notification_List_Type *&f_vdata,
134                                          EFrameworkunifiedPersistCategory f_epersistcategory) {
135   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
136   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
137
138   int l_InFd;
139
140   if (NULL != f_vdata) {  // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL
141     if ((eFrameworkunifiedStatusOK == (l_estatus = OpenFileForReading(&l_InFd, f_cmemfilepath)))) {
142       l_estatus = FillNotificationList(l_InFd, f_vdata, f_epersistcategory);
143
144       close(l_InFd);
145     } else {
146       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to open file %s, status=%d", f_cmemfilepath.c_str(), l_estatus);
147     }
148   } else {
149     // LCOV_EXCL_START 6: f_vdata can't be NULL
150     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
151     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL");
152     l_estatus = eFrameworkunifiedStatusInvldParam;
153     // LCOV_EXCL_STOP
154   }
155
156   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
157
158   return l_estatus;
159 }
160
161 ////////////////////////////////////////////////////////////////////////////////////////////////
162 /// FillNotificationList
163 /// This function retrieve the notification data from file and fill it in map.
164 ////////////////////////////////////////////////////////////////////////////////////////////////
165 EFrameworkunifiedStatus CBinaryAccesser::FillNotificationList(int f_infd,
166                                                  Persistent_Notification_List_Type *&f_vdata,
167                                                  EFrameworkunifiedPersistCategory f_epersistcategory) {
168   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
169   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
170
171   if (NULL == f_vdata) {  // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL
172     // LCOV_EXCL_START 6: f_vdata can't be NULL
173     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
174     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL");
175     l_estatus = eFrameworkunifiedStatusNullPointer;
176     // LCOV_EXCL_STOP
177   } else {
178     while (eFrameworkunifiedStatusOK == l_estatus) {
179       CPersistDataHeader l_objCPersistDataHeader;
180       CHAR *l_pData = NULL;
181
182       // Read header and data.
183       l_estatus = ReadHeaderAndData(l_objCPersistDataHeader, l_pData, f_infd);
184       if (eFrameworkunifiedStatusOK == l_estatus) {
185         CNotificationsToPersist *l_objCNotificationsToPersist = new(std::nothrow) CNotificationsToPersist();
186         CPersistentData *l_objCPersistentData = new(std::nothrow) CPersistentData();
187
188         // fill the appropriate values in  l_objCNotificationsToPersist
189         if ((NULL != l_objCPersistentData) && (NULL != l_objCNotificationsToPersist)) {  // LCOV_EXCL_BR_LINE 5: new's error case  // NOLINT[whitespace/line_length]
190           l_objCPersistentData->m_pMessage = new(std::nothrow) CHAR[l_objCPersistDataHeader.m_uiSize];
191           if (NULL != l_objCPersistentData->m_pMessage) {  // LCOV_EXCL_BR_LINE 5: new's error case
192             std::memcpy(l_objCPersistentData->m_pMessage, l_pData, l_objCPersistDataHeader.m_uiSize);
193             l_objCPersistentData->m_uiMsgSize = l_objCPersistDataHeader.m_uiSize;
194             l_objCNotificationsToPersist->m_ePersistentType = l_objCPersistDataHeader.m_ePersistentType;
195             l_objCNotificationsToPersist->m_ePersistCategory = f_epersistcategory;
196
197             l_objCNotificationsToPersist->m_cNotificationName = l_objCPersistDataHeader.m_cNotificationName;
198             l_objCNotificationsToPersist->m_cPublisherName = l_objCPersistDataHeader.m_cPublisherName;
199
200             l_objCNotificationsToPersist->m_pPersistentData = l_objCPersistentData;
201
202             l_objCNotificationsToPersist->m_uiMaxMsgLength = l_objCPersistDataHeader.m_uiMaxMsgLength;
203             f_vdata->push_back(l_objCNotificationsToPersist);
204           } else {
205             // LCOV_EXCL_START 5: new's error case
206             AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
207             std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader));
208             l_estatus = eFrameworkunifiedStatusNullPointer;
209             break;
210             // LCOV_EXCL_STOP
211           }
212         } else {
213           // LCOV_EXCL_START 5: new's error case
214           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
215           std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader));
216           l_estatus = eFrameworkunifiedStatusNullPointer;
217           break;
218           // LCOV_EXCL_STOP
219         }
220       } else if (eFrameworkunifiedStatusErrOther == l_estatus) {
221         // EOF
222         l_estatus = eFrameworkunifiedStatusOK;
223         break;
224       } else {
225         std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader));
226         break;
227       }
228     }
229   }
230
231   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
232   return l_estatus;
233 }
234
235 ////////////////////////////////////////////////////////////////////////////////////////////////
236 ///
237 ///
238 ////////////////////////////////////////////////////////////////////////////////////////////////
239 EFrameworkunifiedStatus CBinaryAccesser::OpenFileForReading(int *f_infd,
240                                                std::string f_cfilepath) {
241   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail;
242   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
243
244   // raw & raw.bak file unlink
245   std::string l_cUnlinkPath(f_cfilepath);
246   unlink(l_cUnlinkPath.c_str());
247   l_cUnlinkPath.append(".bak");
248   unlink(l_cUnlinkPath.c_str());
249
250   // add .valid
251   std::string l_cValidPath(f_cfilepath);
252   l_cValidPath.append(".valid");
253
254   if ((*f_infd = open(l_cValidPath.c_str(), O_RDONLY)) >= 0) {
255     if (eFrameworkunifiedStatusOK == CheckFileHeader(*f_infd)) {
256       struct stat st;
257       if (fstat(*f_infd, &st) == 0) {  // LCOV_EXCL_BR_LINE 5: fstat's error case
258         if (st.st_size == 0) {
259           // If original file is 0byte, to confirm bak file
260           int bak_fd;
261           if (eFrameworkunifiedStatusOK == OpenBakFileForReading(&bak_fd, l_cValidPath)) {
262             close(*f_infd);
263             *f_infd = bak_fd;
264           }
265         }
266       }
267       l_estatus = eFrameworkunifiedStatusOK;
268     } else {
269       close(*f_infd);
270       l_estatus = OpenBakFileForReading(f_infd, l_cValidPath);
271     }
272   } else {
273     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open(%s) fail: %s", l_cValidPath.c_str(), strerror(errno));
274     l_estatus = OpenBakFileForReading(f_infd, l_cValidPath);
275   }
276
277   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
278   return l_estatus;
279 }
280
281 ////////////////////////////////////////////////////////////////////////////////////////////////
282 /// OpenFileForWriting
283 ///
284 ////////////////////////////////////////////////////////////////////////////////////////////////
285 EFrameworkunifiedStatus CBinaryAccesser::OpenFileForWriting(int *f_outfd,
286                                                std::string f_cfilepath) {
287   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail;
288   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
289
290
291   std::string l_cPath(f_cfilepath);
292   size_t l_ifound = l_cPath.rfind("/");
293   std::string l_cOutDirPath = l_cPath.substr(0, l_ifound);
294
295   FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Path for persistence %s ", l_cOutDirPath.c_str());
296
297   // if parent directory path doesn't exists, create it
298   if (!CFSDirectory::DoesDirecotryExist(l_cOutDirPath)) {
299     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s DOESN'T exist, Creating...", l_cOutDirPath.c_str());
300     if (eFrameworkunifiedStatusOK != (l_estatus = CFSDirectory::CreateDirectory(l_cOutDirPath))) {  // LCOV_EXCL_BR_LINE 6: CreateDirectory always return ok  // NOLINT[whitespace/line_length]
301       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
302       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Failed to create %s ", l_cOutDirPath.c_str());  // LCOV_EXCL_LINE 6: CreateDirectory always return ok  // NOLINT[whitespace/line_length]
303     }
304   }
305
306   // add .valid
307   std::string l_cValidPath(f_cfilepath);
308   l_cValidPath.append(".valid");
309
310   if ((*f_outfd = open(l_cValidPath.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0660)) >= 0) {
311     if (lseek(*f_outfd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) {  // LCOV_EXCL_BR_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
312       l_estatus = eFrameworkunifiedStatusOK;
313       m_uiCurStrOffset = sizeof(PersistFileHeder);
314     } else {
315       // LCOV_EXCL_START 5: lseek's error case
316       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
317       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno));
318       close(*f_outfd);
319       *f_outfd = -1;
320       // LCOV_EXCL_STOP
321     }
322   } else {
323     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open(%s) fail: %s", l_cValidPath.c_str(), strerror(errno));
324   }
325
326   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
327   return l_estatus;
328 }
329
330 ////////////////////////////////////////////////////////////////////////////////////////////////
331 /// WriteHeaderAndData
332 /// Write header and data in a file.
333 ////////////////////////////////////////////////////////////////////////////////////////////////
334 EFrameworkunifiedStatus CBinaryAccesser::WriteHeaderAndData(CNotificationsToPersist *f_pnotificationstopersist,
335                                                PVOID f_pdata,
336                                                int f_outfd) {
337   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
338   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail;
339
340   if ((NULL == f_pdata) || (NULL == f_pnotificationstopersist)) {
341     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL");
342     l_estatus = eFrameworkunifiedStatusNullPointer;
343   } else {
344     CPersistDataHeader l_objCPersistDataHeader;
345
346 #ifdef AGL_PosixBasedOS001LEGACY_USED
347     strlcpy(l_objCPersistDataHeader.m_cNotificationName, f_pnotificationstopersist->m_cNotificationName.c_str(),
348             sizeof(l_objCPersistDataHeader.m_cNotificationName));
349     strlcpy(l_objCPersistDataHeader.m_cPublisherName, f_pnotificationstopersist->m_cPublisherName.c_str(),
350             sizeof(l_objCPersistDataHeader.m_cPublisherName));
351 #endif
352
353     //  size check
354     if (UINT32_MAX >= static_cast<size_t>(sizeof(CPersistDataHeader) + l_objCPersistDataHeader.m_uiSize)) {  // LCOV_EXCL_BR_LINE 5: the size is not bigger than UINT32_MAX  // NOLINT[whitespace/line_length]
355       l_objCPersistDataHeader.m_uiOffset      = static_cast<UI_32>(m_uiCurStrOffset + sizeof(CPersistDataHeader));
356       l_objCPersistDataHeader.m_uiSize      = f_pnotificationstopersist->m_pPersistentData->m_uiMsgSize;
357       l_objCPersistDataHeader.m_ePersistentType   = f_pnotificationstopersist->m_ePersistentType;
358       l_objCPersistDataHeader.m_uiMaxMsgLength  = f_pnotificationstopersist->m_uiMaxMsgLength;
359
360         // write header
361         if (write(f_outfd, (PCHAR)&l_objCPersistDataHeader, sizeof(CPersistDataHeader)) == sizeof(CPersistDataHeader)) {  // LCOV_EXCL_BR_LINE 5: write's error case  // NOLINT[whitespace/line_length]
362           // write data
363           if (write(f_outfd, (PCHAR)f_pdata,  // LCOV_EXCL_BR_LINE 5: write's error case
364                     l_objCPersistDataHeader.m_uiSize) == (ssize_t)l_objCPersistDataHeader.m_uiSize) {
365             // save offset of end of current record's data
366             m_uiCurStrOffset += static_cast<UI_32>(sizeof(CPersistDataHeader) + l_objCPersistDataHeader.m_uiSize);
367             l_estatus = eFrameworkunifiedStatusOK;
368           } else {
369             AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
370             FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while writing data: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
371           }
372         } else {
373           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
374           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while writing header: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
375         }
376       }
377   }
378
379   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
380   return l_estatus;
381 }
382
383 ////////////////////////////////////////////////////////////////////////////////////////////////
384 ///
385 ///
386 ////////////////////////////////////////////////////////////////////////////////////////////////
387 EFrameworkunifiedStatus CBinaryAccesser::ReadHeaderAndData(CPersistDataHeader &f_objcpersistdataheader,
388                                               CHAR *&f_pdata, int f_infd) {
389   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
390   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
391   static UI_32 l_uisPrevAllocSz = 0;
392   ssize_t l_iRet;
393
394   // read header
395   l_iRet = read(f_infd, (PCHAR)&f_objcpersistdataheader, sizeof(f_objcpersistdataheader));
396   if (l_iRet != sizeof(f_objcpersistdataheader)) {
397     if (l_iRet < 0) {  // LCOV_EXCL_BR_LINE 5: read's error case
398       // LCOV_EXCL_START 5: read's error case
399       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
400       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while reading header: %s", strerror(errno));
401       l_estatus = eFrameworkunifiedStatusFail;
402       // LCOV_EXCL_STOP
403     } else {
404       l_estatus = eFrameworkunifiedStatusErrOther;  // TODO(my_username): set specific error as eNotificationpersistentserviceStatusEOFReadched
405     }
406     std::memset(&f_objcpersistdataheader, 0, sizeof(CPersistDataHeader));
407   } else {  // read data
408     m_uiCurStrOffset += static_cast<UI_32>(sizeof(CPersistDataHeader));
409     if (static_cast<int>(f_objcpersistdataheader.m_uiSize) > 0 &&
410         m_uiCurStrOffset + f_objcpersistdataheader.m_uiSize <= m_uiCurStrSize) {
411       // if f_pdata has space allocated and if the allocated size less than new size,
412       // free and reallocate
413       if ((NULL != f_pdata) && (l_uisPrevAllocSz < f_objcpersistdataheader.m_uiSize)) {  // LCOV_EXCL_BR_LINE 6: f_pdata must be null  // NOLINT[whitespace/line_length]
414         // LCOV_EXCL_START 6: f_pdata must be null
415         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
416         delete[] f_pdata;
417         f_pdata = NULL;
418         // LCOV_EXCL_STOP
419       }
420
421       if (NULL == f_pdata) {  // LCOV_EXCL_BR_LINE 200: f_pdata must be null
422         f_pdata = new(std::nothrow) CHAR[f_objcpersistdataheader.m_uiSize];
423       } else {
424         // memory already allcoated.
425         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
426       }
427
428       if (NULL != f_pdata) {   // LCOV_EXCL_BR_LINE 6: f_pdata can't be null
429         l_uisPrevAllocSz = f_objcpersistdataheader.m_uiSize;
430         l_iRet = read(f_infd, (PCHAR)f_pdata, f_objcpersistdataheader.m_uiSize);
431         if (l_iRet == (ssize_t)f_objcpersistdataheader.m_uiSize) {  // LCOV_EXCL_BR_LINE 5: read's error case
432           m_uiCurStrOffset += f_objcpersistdataheader.m_uiSize;
433           l_estatus = eFrameworkunifiedStatusOK;
434         } else {
435           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
436           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while reading data: %s", strerror(errno));  // LCOV_EXCL_LINE 5: read's error case  // NOLINT[whitespace/line_length]
437         }
438       } else {
439         // LCOV_EXCL_START 6: f_pdata can't be null
440         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
441         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure");
442         l_estatus = eFrameworkunifiedStatusNullPointer;
443         // LCOV_EXCL_STOP
444       }
445     } else {
446       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Invlide data size: %u", f_objcpersistdataheader.m_uiSize);
447       std::memset(&f_objcpersistdataheader, 0, sizeof(CPersistDataHeader));
448       l_estatus = eFrameworkunifiedStatusFail;
449     }
450   }
451   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
452   return l_estatus;
453 }
454
455 EFrameworkunifiedStatus CBinaryAccesser::WriteFileHeaderAndDuplicate(int f_outfd, std::string f_cfilepath) {
456   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail;
457   struct stat st;
458
459   if (fstat(f_outfd, &st) == 0) {  // LCOV_EXCL_BR_LINE 5: fstat's error case
460     if (st.st_size > static_cast<long>(sizeof(PersistFileHeder))) { // NOLINT (runtime/int)
461       size_t body_size = static_cast<size_t>(st.st_size - sizeof(PersistFileHeder));
462       char *buf = new(std::nothrow) char[body_size];
463       if (buf != NULL) {  // LCOV_EXCL_BR_LINE 5: new's error case
464         if (lseek(f_outfd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) {  // LCOV_EXCL_BR_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
465           if (read(f_outfd, buf, body_size) == static_cast<ssize_t>(body_size)) {  // LCOV_EXCL_BR_LINE 5: read's error case  // NOLINT[whitespace/line_length]
466             PersistFileHeder f_header;
467             std::memcpy(&f_header.check_code, NPP_CHECK_CODE, sizeof(f_header.check_code));
468             f_header.crc = static_cast<UI_32>(CalcCRC(buf, static_cast<UI_32>(body_size)));
469             if (lseek(f_outfd, 0, SEEK_SET) == 0) {  // LCOV_EXCL_BR_LINE 5: lseek's error case
470               if (write(f_outfd, &f_header, sizeof(f_header)) == sizeof(f_header)) {  // LCOV_EXCL_BR_LINE 5: write's error case  // NOLINT[whitespace/line_length]
471                 eStatus = eFrameworkunifiedStatusOK;
472
473                 // file duplicate
474                 std::string bak_file_path = f_cfilepath;
475                 bak_file_path.append(".valid.bak");
476                 int bak_fd = open(bak_file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0660);
477                 if (bak_fd >= 0) {  // LCOV_EXCL_BR_LINE 5: open's error case
478                   if (write(bak_fd, &f_header, sizeof(f_header)) == sizeof(f_header)) {  // LCOV_EXCL_BR_LINE 5: write's error case  // NOLINT[whitespace/line_length]
479                     if (write(bak_fd, buf, body_size) != static_cast<ssize_t>(body_size)) {  // LCOV_EXCL_BR_LINE 5: write's error case  // NOLINT[whitespace/line_length]
480                       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
481                       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: write's error case  // NOLINT[whitespace/line_length]
482                     }
483                   } else {
484                     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
485                     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: write's error case  // NOLINT[whitespace/line_length]
486                   }
487                   close(bak_fd);
488                 } else {
489                   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
490                   FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: open's error case  // NOLINT[whitespace/line_length]
491                 }
492               } else {
493                 AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
494                 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: write's error case  // NOLINT[whitespace/line_length]
495               }
496             } else {
497               AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
498               FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
499             }
500           } else {
501             AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
502             FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: read's error case
503           }
504         } else {
505           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
506           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case
507         }
508         delete[] buf;
509       } else {
510         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
511         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure");  // LCOV_EXCL_LINE 5: new's error case
512       }
513     } else {
514       // 0byte file through
515       eStatus = eFrameworkunifiedStatusOK;
516     }
517   } else {
518     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
519     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: fstat's error case
520   }
521
522   return eStatus;
523 }
524
525 EFrameworkunifiedStatus CBinaryAccesser::CheckFileHeader(int f_infd) {
526   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail;
527   struct stat st;
528
529   if (fstat(f_infd, &st) == 0) {  // LCOV_EXCL_BR_LINE 5: fstat's error case
530     if (st.st_size > static_cast<long>(sizeof(PersistFileHeder))) { // NOLINT (runtime/int)
531       size_t body_size = static_cast<size_t>(st.st_size - sizeof(PersistFileHeder));
532       char *buf = new(std::nothrow) char[body_size];
533       if (buf != NULL) {  // LCOV_EXCL_BR_LINE 5: new's error case
534         if (lseek(f_infd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) {  // LCOV_EXCL_BR_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
535           if (read(f_infd, buf, body_size) == static_cast<ssize_t>(body_size)) {
536             UI_32 crc32 = static_cast<UI_32>(CalcCRC(buf, static_cast<UI_32>(body_size)));
537             PersistFileHeder f_header;
538             if (lseek(f_infd, 0, SEEK_SET) == 0) {  // LCOV_EXCL_BR_LINE 5: lseek's error case
539               if (read(f_infd, &f_header, sizeof(f_header)) == sizeof(f_header)) {  // LCOV_EXCL_BR_LINE 5: read's error case  // NOLINT[whitespace/line_length]
540                 if (std::memcmp(&f_header.check_code, NPP_CHECK_CODE, sizeof(f_header.check_code)) == 0
541                     && f_header.crc == crc32) {
542                   m_uiCurStrOffset = sizeof(f_header);
543                   m_uiCurStrSize = static_cast<UI_32>(st.st_size);
544                   eStatus = eFrameworkunifiedStatusOK;
545                 } else {
546                   FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "file header fail: %02x %02x %02x %02x %#x:%#x",
547                          f_header.check_code[0], f_header.check_code[1],
548                          f_header.check_code[2], f_header.check_code[3], crc32, f_header.crc);
549                 }
550               } else {
551                 AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
552                 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: read's error case  // NOLINT[whitespace/line_length]
553               }
554             } else {
555               AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
556               FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case  // NOLINT[whitespace/line_length]
557             }
558           } else {
559             FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno));
560           }
561         } else {
562           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
563           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: lseek's error case
564         }
565         delete[] buf;
566       } else {
567         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
568         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure");  // LCOV_EXCL_LINE 5: new's error case
569       }
570     } else {
571       // 0byte file through
572       eStatus = eFrameworkunifiedStatusOK;
573     }
574   } else {
575     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
576     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno));  // LCOV_EXCL_LINE 5: fstat's error case
577   }
578
579   return eStatus;
580 }
581
582 EFrameworkunifiedStatus CBinaryAccesser::OpenBakFileForReading(int *f_infd, std::string f_cfilepath) {
583   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail;
584   std::string bak_file_path = f_cfilepath;
585   bak_file_path.append(".bak");
586
587   *f_infd = open(bak_file_path.c_str(), O_RDONLY);
588   if (*f_infd >= 0) {
589     struct stat st;
590     if (fstat(*f_infd, &st) == 0) {
591       // Error if bak file is 0byte
592       if (st.st_size > 0) {
593         if (eFrameworkunifiedStatusOK == CheckFileHeader(*f_infd)) {
594           FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s fail. bak file correct.", f_cfilepath.c_str());
595           eStatus = eFrameworkunifiedStatusOK;
596         } else {
597           close(*f_infd);
598           *f_infd = -1;
599         }
600       } else {
601         close(*f_infd);
602         *f_infd = -1;
603       }
604     } else {
605       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno));
606       close(*f_infd);
607       *f_infd = -1;
608     }
609   }
610
611   return eStatus;
612 }
613
614 /*
615  * CRC-32C lookup table
616  *
617  * Polynomial 0x1EDC6F41
618  */
619 static const UI_32 crc32_lookup[4][256] = {  // NOLINT (readability/naming)
620   {
621   },
622   {
623   },
624   {
625   },
626   {
627   }
628 };
629
630 UI_32 CBinaryAccesser::CalcCRC(PVOID f_pdata, UI_32 f_size) {
631   UI_32 crc = 0xFFFFFFFF;
632   const UI_32 *current = (const UI_32 *)f_pdata;
633
634   while (f_size >= 4) {
635     UI_32 one = *current++ ^ crc;
636     crc = crc32_lookup[0][(one >> 24) & 0xFF] ^
637           crc32_lookup[1][(one >> 16) & 0xFF] ^
638           crc32_lookup[2][(one >> 8) & 0xFF] ^
639           crc32_lookup[3][one & 0xFF];
640     f_size -= 4;
641   }
642
643   const UI_8 *current_char = (const UI_8 *)current;
644   while (f_size-- > 0) {
645     crc = (crc >> 8) ^ crc32_lookup[0][(crc & 0xFF) ^ *current_char++];
646   }
647
648   return ~crc;
649 }