From 947c78887e791596d4a5ec2d1079f8b1a049628b Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Tue, 27 Oct 2020 11:16:21 +0900 Subject: basesystem 0.1 --- .../server/src/ns_npp_binary_accesser.cpp | 649 +++++++++++++++++++++ 1 file changed, 649 insertions(+) create mode 100644 nsframework/notification_persistent_service/server/src/ns_npp_binary_accesser.cpp (limited to 'nsframework/notification_persistent_service/server/src/ns_npp_binary_accesser.cpp') diff --git a/nsframework/notification_persistent_service/server/src/ns_npp_binary_accesser.cpp b/nsframework/notification_persistent_service/server/src/ns_npp_binary_accesser.cpp new file mode 100644 index 00000000..e0a749f7 --- /dev/null +++ b/nsframework/notification_persistent_service/server/src/ns_npp_binary_accesser.cpp @@ -0,0 +1,649 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_NPPService +/// \brief The file contains definition of CBinaryAccesser class. +/// This class stores data in a file in binary format. +/// +/// +//////////////////////////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#ifdef AGL_STUB +#include +#endif +#include +#include +#include "ns_npp_notificationpersistentservicelog.h" +#include "ns_npp_fs_directory.h" +#include "ns_npp_binary_accesser.h" +#include "ns_npp_persistent_data.h" +#include "ns_npp_persistent_accesser.h" + +struct PersistFileHeder { + char check_code[4]; + unsigned int crc; +}; +#define NPP_CHECK_CODE "NPPD" + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// CBinaryAccesser +/// Constructor of CBinaryAccesser class +//////////////////////////////////////////////////////////////////////////////////////////////// +CBinaryAccesser::CBinaryAccesser() { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + m_uiCurStrOffset = 0; + m_uiCurStrSize = 0; + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// ~CBinaryAccesser +/// Destructor of CBinaryAccesser class +//////////////////////////////////////////////////////////////////////////////////////////////// +CBinaryAccesser::~CBinaryAccesser() { // LCOV_EXCL_START 14: Resident process, global instance not released + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} +// LCOV_EXCL_STOP + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// PersistData +/// Persist data in persistent memory in a file in binary format. +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::PersistData(std::string f_cmemfilepath, + Persistent_Notification_List_Type *f_vdata, + EFrameworkunifiedNotificationType f_epersistenttype, + EFrameworkunifiedPersistCategory f_epersistcategory) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK; + + int l_OutFd; + + if (NULL != f_vdata) { // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL + // Open global file in write mode. + if ((eFrameworkunifiedStatusOK == OpenFileForWriting(&l_OutFd, f_cmemfilepath))) { + Persistent_Notification_List_Iterator l_itNotificationList = f_vdata->begin(); + + // Iterate through a vector f_vdata + for (; l_itNotificationList != f_vdata->end(); l_itNotificationList++) { + if (eFrameworkunifiedPersistedStateVar == (*l_itNotificationList)->m_ePersistentType) { + if (f_epersistcategory == (*l_itNotificationList)->m_ePersistCategory) { + // write header and data + if (eFrameworkunifiedStatusOK != WriteHeaderAndData((*l_itNotificationList), + (*l_itNotificationList)->m_pPersistentData->m_pMessage, + l_OutFd)) { + l_estatus = eFrameworkunifiedStatusFail; + break; + } + } + } else { + // write header and data + if (eFrameworkunifiedStatusOK != WriteHeaderAndData((*l_itNotificationList), + (*l_itNotificationList)->m_pPersistentData->m_pMessage, + l_OutFd)) { + l_estatus = eFrameworkunifiedStatusFail; + break; + } + } + } + + if (eFrameworkunifiedStatusOK != WriteFileHeaderAndDuplicate(l_OutFd, f_cmemfilepath)) { + l_estatus = eFrameworkunifiedStatusFail; + } else { + FRAMEWORKUNIFIEDLOG(ZONE_PRD_INFO3, __FUNCTION__, "Bytes written in NAND memory, %ld, file=%s", + static_cast(m_uiCurStrOffset - sizeof(PersistFileHeder)), f_cmemfilepath.c_str()); // NOLINT (runtime/int) + } + close(l_OutFd); + } else { + l_estatus = eFrameworkunifiedStatusFail; + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to open file %s", f_cmemfilepath.c_str()); + } + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// RetrieveData +/// Retrieve data in persistent memory in a file in binary format. +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::RetrieveData(std::string f_cmemfilepath, + Persistent_Notification_List_Type *&f_vdata, + EFrameworkunifiedPersistCategory f_epersistcategory) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK; + + int l_InFd; + + if (NULL != f_vdata) { // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL + if ((eFrameworkunifiedStatusOK == (l_estatus = OpenFileForReading(&l_InFd, f_cmemfilepath)))) { + l_estatus = FillNotificationList(l_InFd, f_vdata, f_epersistcategory); + + close(l_InFd); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to open file %s, status=%d", f_cmemfilepath.c_str(), l_estatus); + } + } else { + // LCOV_EXCL_START 6: f_vdata can't be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL"); + l_estatus = eFrameworkunifiedStatusInvldParam; + // LCOV_EXCL_STOP + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// FillNotificationList +/// This function retrieve the notification data from file and fill it in map. +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::FillNotificationList(int f_infd, + Persistent_Notification_List_Type *&f_vdata, + EFrameworkunifiedPersistCategory f_epersistcategory) { + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + if (NULL == f_vdata) { // LCOV_EXCL_BR_LINE 6: f_vdata can't be NULL + // LCOV_EXCL_START 6: f_vdata can't be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL"); + l_estatus = eFrameworkunifiedStatusNullPointer; + // LCOV_EXCL_STOP + } else { + while (eFrameworkunifiedStatusOK == l_estatus) { + CPersistDataHeader l_objCPersistDataHeader; + CHAR *l_pData = NULL; + + // Read header and data. + l_estatus = ReadHeaderAndData(l_objCPersistDataHeader, l_pData, f_infd); + if (eFrameworkunifiedStatusOK == l_estatus) { + CNotificationsToPersist *l_objCNotificationsToPersist = new(std::nothrow) CNotificationsToPersist(); + CPersistentData *l_objCPersistentData = new(std::nothrow) CPersistentData(); + + // fill the appropriate values in l_objCNotificationsToPersist + if ((NULL != l_objCPersistentData) && (NULL != l_objCNotificationsToPersist)) { // LCOV_EXCL_BR_LINE 5: new's error case // NOLINT[whitespace/line_length] + l_objCPersistentData->m_pMessage = new(std::nothrow) CHAR[l_objCPersistDataHeader.m_uiSize]; + if (NULL != l_objCPersistentData->m_pMessage) { // LCOV_EXCL_BR_LINE 5: new's error case + std::memcpy(l_objCPersistentData->m_pMessage, l_pData, l_objCPersistDataHeader.m_uiSize); + l_objCPersistentData->m_uiMsgSize = l_objCPersistDataHeader.m_uiSize; + l_objCNotificationsToPersist->m_ePersistentType = l_objCPersistDataHeader.m_ePersistentType; + l_objCNotificationsToPersist->m_ePersistCategory = f_epersistcategory; + + l_objCNotificationsToPersist->m_cNotificationName = l_objCPersistDataHeader.m_cNotificationName; + l_objCNotificationsToPersist->m_cPublisherName = l_objCPersistDataHeader.m_cPublisherName; + + l_objCNotificationsToPersist->m_pPersistentData = l_objCPersistentData; + + l_objCNotificationsToPersist->m_uiMaxMsgLength = l_objCPersistDataHeader.m_uiMaxMsgLength; + f_vdata->push_back(l_objCNotificationsToPersist); + } else { + // LCOV_EXCL_START 5: new's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader)); + l_estatus = eFrameworkunifiedStatusNullPointer; + break; + // LCOV_EXCL_STOP + } + } else { + // LCOV_EXCL_START 5: new's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader)); + l_estatus = eFrameworkunifiedStatusNullPointer; + break; + // LCOV_EXCL_STOP + } + } else if (eFrameworkunifiedStatusErrOther == l_estatus) { + // EOF + l_estatus = eFrameworkunifiedStatusOK; + break; + } else { + std::memset(&l_objCPersistDataHeader, 0, sizeof(CPersistDataHeader)); + break; + } + } + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// +/// +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::OpenFileForReading(int *f_infd, + std::string f_cfilepath) { + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + // raw & raw.bak file unlink + std::string l_cUnlinkPath(f_cfilepath); + unlink(l_cUnlinkPath.c_str()); + l_cUnlinkPath.append(".bak"); + unlink(l_cUnlinkPath.c_str()); + + // add .valid + std::string l_cValidPath(f_cfilepath); + l_cValidPath.append(".valid"); + + if ((*f_infd = open(l_cValidPath.c_str(), O_RDONLY)) >= 0) { + if (eFrameworkunifiedStatusOK == CheckFileHeader(*f_infd)) { + struct stat st; + if (fstat(*f_infd, &st) == 0) { // LCOV_EXCL_BR_LINE 5: fstat's error case + if (st.st_size == 0) { + // If original file is 0byte, to confirm bak file + int bak_fd; + if (eFrameworkunifiedStatusOK == OpenBakFileForReading(&bak_fd, l_cValidPath)) { + close(*f_infd); + *f_infd = bak_fd; + } + } + } + l_estatus = eFrameworkunifiedStatusOK; + } else { + close(*f_infd); + l_estatus = OpenBakFileForReading(f_infd, l_cValidPath); + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open(%s) fail: %s", l_cValidPath.c_str(), strerror(errno)); + l_estatus = OpenBakFileForReading(f_infd, l_cValidPath); + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// OpenFileForWriting +/// +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::OpenFileForWriting(int *f_outfd, + std::string f_cfilepath) { + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + + std::string l_cPath(f_cfilepath); + size_t l_ifound = l_cPath.rfind("/"); + std::string l_cOutDirPath = l_cPath.substr(0, l_ifound); + + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Path for persistence %s ", l_cOutDirPath.c_str()); + + // if parent directory path doesn't exists, create it + if (!CFSDirectory::DoesDirecotryExist(l_cOutDirPath)) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s DOESN'T exist, Creating...", l_cOutDirPath.c_str()); + if (eFrameworkunifiedStatusOK != (l_estatus = CFSDirectory::CreateDirectory(l_cOutDirPath))) { // LCOV_EXCL_BR_LINE 6: CreateDirectory always return ok // NOLINT[whitespace/line_length] + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Failed to create %s ", l_cOutDirPath.c_str()); // LCOV_EXCL_LINE 6: CreateDirectory always return ok // NOLINT[whitespace/line_length] + } + } + + // add .valid + std::string l_cValidPath(f_cfilepath); + l_cValidPath.append(".valid"); + + if ((*f_outfd = open(l_cValidPath.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0660)) >= 0) { + if (lseek(*f_outfd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) { // LCOV_EXCL_BR_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + l_estatus = eFrameworkunifiedStatusOK; + m_uiCurStrOffset = sizeof(PersistFileHeder); + } else { + // LCOV_EXCL_START 5: lseek's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno)); + close(*f_outfd); + *f_outfd = -1; + // LCOV_EXCL_STOP + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open(%s) fail: %s", l_cValidPath.c_str(), strerror(errno)); + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// WriteHeaderAndData +/// Write header and data in a file. +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::WriteHeaderAndData(CNotificationsToPersist *f_pnotificationstopersist, + PVOID f_pdata, + int f_outfd) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusFail; + + if ((NULL == f_pdata) || (NULL == f_pnotificationstopersist)) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "f_pdata is NULL"); + l_estatus = eFrameworkunifiedStatusNullPointer; + } else { + CPersistDataHeader l_objCPersistDataHeader; + +#ifdef AGL_PosixBasedOS001LEGACY_USED + strlcpy(l_objCPersistDataHeader.m_cNotificationName, f_pnotificationstopersist->m_cNotificationName.c_str(), + sizeof(l_objCPersistDataHeader.m_cNotificationName)); + strlcpy(l_objCPersistDataHeader.m_cPublisherName, f_pnotificationstopersist->m_cPublisherName.c_str(), + sizeof(l_objCPersistDataHeader.m_cPublisherName)); +#endif + + // size check + if (UINT32_MAX >= static_cast(sizeof(CPersistDataHeader) + l_objCPersistDataHeader.m_uiSize)) { // LCOV_EXCL_BR_LINE 5: the size is not bigger than UINT32_MAX // NOLINT[whitespace/line_length] + l_objCPersistDataHeader.m_uiOffset = static_cast(m_uiCurStrOffset + sizeof(CPersistDataHeader)); + l_objCPersistDataHeader.m_uiSize = f_pnotificationstopersist->m_pPersistentData->m_uiMsgSize; + l_objCPersistDataHeader.m_ePersistentType = f_pnotificationstopersist->m_ePersistentType; + l_objCPersistDataHeader.m_uiMaxMsgLength = f_pnotificationstopersist->m_uiMaxMsgLength; + + // write header + if (write(f_outfd, (PCHAR)&l_objCPersistDataHeader, sizeof(CPersistDataHeader)) == sizeof(CPersistDataHeader)) { // LCOV_EXCL_BR_LINE 5: write's error case // NOLINT[whitespace/line_length] + // write data + if (write(f_outfd, (PCHAR)f_pdata, // LCOV_EXCL_BR_LINE 5: write's error case + l_objCPersistDataHeader.m_uiSize) == (ssize_t)l_objCPersistDataHeader.m_uiSize) { + // save offset of end of current record's data + m_uiCurStrOffset += static_cast(sizeof(CPersistDataHeader) + l_objCPersistDataHeader.m_uiSize); + l_estatus = eFrameworkunifiedStatusOK; + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while writing data: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while writing header: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + } + } + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_estatus; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +/// +/// +//////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus CBinaryAccesser::ReadHeaderAndData(CPersistDataHeader &f_objcpersistdataheader, + CHAR *&f_pdata, int f_infd) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK; + static UI_32 l_uisPrevAllocSz = 0; + ssize_t l_iRet; + + // read header + l_iRet = read(f_infd, (PCHAR)&f_objcpersistdataheader, sizeof(f_objcpersistdataheader)); + if (l_iRet != sizeof(f_objcpersistdataheader)) { + if (l_iRet < 0) { // LCOV_EXCL_BR_LINE 5: read's error case + // LCOV_EXCL_START 5: read's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while reading header: %s", strerror(errno)); + l_estatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_STOP + } else { + l_estatus = eFrameworkunifiedStatusErrOther; // TODO(my_username): set specific error as eNotificationpersistentserviceStatusEOFReadched + } + std::memset(&f_objcpersistdataheader, 0, sizeof(CPersistDataHeader)); + } else { // read data + m_uiCurStrOffset += static_cast(sizeof(CPersistDataHeader)); + if (static_cast(f_objcpersistdataheader.m_uiSize) > 0 && + m_uiCurStrOffset + f_objcpersistdataheader.m_uiSize <= m_uiCurStrSize) { + // if f_pdata has space allocated and if the allocated size less than new size, + // free and reallocate + if ((NULL != f_pdata) && (l_uisPrevAllocSz < f_objcpersistdataheader.m_uiSize)) { // LCOV_EXCL_BR_LINE 6: f_pdata must be null // NOLINT[whitespace/line_length] + // LCOV_EXCL_START 6: f_pdata must be null + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + delete[] f_pdata; + f_pdata = NULL; + // LCOV_EXCL_STOP + } + + if (NULL == f_pdata) { // LCOV_EXCL_BR_LINE 200: f_pdata must be null + f_pdata = new(std::nothrow) CHAR[f_objcpersistdataheader.m_uiSize]; + } else { + // memory already allcoated. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + } + + if (NULL != f_pdata) { // LCOV_EXCL_BR_LINE 6: f_pdata can't be null + l_uisPrevAllocSz = f_objcpersistdataheader.m_uiSize; + l_iRet = read(f_infd, (PCHAR)f_pdata, f_objcpersistdataheader.m_uiSize); + if (l_iRet == (ssize_t)f_objcpersistdataheader.m_uiSize) { // LCOV_EXCL_BR_LINE 5: read's error case + m_uiCurStrOffset += f_objcpersistdataheader.m_uiSize; + l_estatus = eFrameworkunifiedStatusOK; + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error while reading data: %s", strerror(errno)); // LCOV_EXCL_LINE 5: read's error case // NOLINT[whitespace/line_length] + } + } else { + // LCOV_EXCL_START 6: f_pdata can't be null + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure"); + l_estatus = eFrameworkunifiedStatusNullPointer; + // LCOV_EXCL_STOP + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Invlide data size: %u", f_objcpersistdataheader.m_uiSize); + std::memset(&f_objcpersistdataheader, 0, sizeof(CPersistDataHeader)); + l_estatus = eFrameworkunifiedStatusFail; + } + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_estatus; +} + +EFrameworkunifiedStatus CBinaryAccesser::WriteFileHeaderAndDuplicate(int f_outfd, std::string f_cfilepath) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail; + struct stat st; + + if (fstat(f_outfd, &st) == 0) { // LCOV_EXCL_BR_LINE 5: fstat's error case + if (st.st_size > static_cast(sizeof(PersistFileHeder))) { // NOLINT (runtime/int) + size_t body_size = static_cast(st.st_size - sizeof(PersistFileHeder)); + char *buf = new(std::nothrow) char[body_size]; + if (buf != NULL) { // LCOV_EXCL_BR_LINE 5: new's error case + if (lseek(f_outfd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) { // LCOV_EXCL_BR_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + if (read(f_outfd, buf, body_size) == static_cast(body_size)) { // LCOV_EXCL_BR_LINE 5: read's error case // NOLINT[whitespace/line_length] + PersistFileHeder f_header; + std::memcpy(&f_header.check_code, NPP_CHECK_CODE, sizeof(f_header.check_code)); + f_header.crc = static_cast(CalcCRC(buf, static_cast(body_size))); + if (lseek(f_outfd, 0, SEEK_SET) == 0) { // LCOV_EXCL_BR_LINE 5: lseek's error case + 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] + eStatus = eFrameworkunifiedStatusOK; + + // file duplicate + std::string bak_file_path = f_cfilepath; + bak_file_path.append(".valid.bak"); + int bak_fd = open(bak_file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0660); + if (bak_fd >= 0) { // LCOV_EXCL_BR_LINE 5: open's error case + 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] + if (write(bak_fd, buf, body_size) != static_cast(body_size)) { // LCOV_EXCL_BR_LINE 5: write's error case // NOLINT[whitespace/line_length] + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: write's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: write's error case // NOLINT[whitespace/line_length] + } + close(bak_fd); + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "open fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: open's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "write fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: write's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: read's error case + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case + } + delete[] buf; + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure"); // LCOV_EXCL_LINE 5: new's error case + } + } else { + // 0byte file through + eStatus = eFrameworkunifiedStatusOK; + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: fstat's error case + } + + return eStatus; +} + +EFrameworkunifiedStatus CBinaryAccesser::CheckFileHeader(int f_infd) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail; + struct stat st; + + if (fstat(f_infd, &st) == 0) { // LCOV_EXCL_BR_LINE 5: fstat's error case + if (st.st_size > static_cast(sizeof(PersistFileHeder))) { // NOLINT (runtime/int) + size_t body_size = static_cast(st.st_size - sizeof(PersistFileHeder)); + char *buf = new(std::nothrow) char[body_size]; + if (buf != NULL) { // LCOV_EXCL_BR_LINE 5: new's error case + if (lseek(f_infd, sizeof(PersistFileHeder), SEEK_SET) == sizeof(PersistFileHeder)) { // LCOV_EXCL_BR_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + if (read(f_infd, buf, body_size) == static_cast(body_size)) { + UI_32 crc32 = static_cast(CalcCRC(buf, static_cast(body_size))); + PersistFileHeder f_header; + if (lseek(f_infd, 0, SEEK_SET) == 0) { // LCOV_EXCL_BR_LINE 5: lseek's error case + 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] + if (std::memcmp(&f_header.check_code, NPP_CHECK_CODE, sizeof(f_header.check_code)) == 0 + && f_header.crc == crc32) { + m_uiCurStrOffset = sizeof(f_header); + m_uiCurStrSize = static_cast(st.st_size); + eStatus = eFrameworkunifiedStatusOK; + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "file header fail: %02x %02x %02x %02x %#x:%#x", + f_header.check_code[0], f_header.check_code[1], + f_header.check_code[2], f_header.check_code[3], crc32, f_header.crc); + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: read's error case // NOLINT[whitespace/line_length] + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case // NOLINT[whitespace/line_length] + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "read fail: %s", strerror(errno)); + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lseek fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: lseek's error case + } + delete[] buf; + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Mem Allocation failure"); // LCOV_EXCL_LINE 5: new's error case + } + } else { + // 0byte file through + eStatus = eFrameworkunifiedStatusOK; + } + } else { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno)); // LCOV_EXCL_LINE 5: fstat's error case + } + + return eStatus; +} + +EFrameworkunifiedStatus CBinaryAccesser::OpenBakFileForReading(int *f_infd, std::string f_cfilepath) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail; + std::string bak_file_path = f_cfilepath; + bak_file_path.append(".bak"); + + *f_infd = open(bak_file_path.c_str(), O_RDONLY); + if (*f_infd >= 0) { + struct stat st; + if (fstat(*f_infd, &st) == 0) { + // Error if bak file is 0byte + if (st.st_size > 0) { + if (eFrameworkunifiedStatusOK == CheckFileHeader(*f_infd)) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s fail. bak file correct.", f_cfilepath.c_str()); + eStatus = eFrameworkunifiedStatusOK; + } else { + close(*f_infd); + *f_infd = -1; + } + } else { + close(*f_infd); + *f_infd = -1; + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "fstat fail: %s", strerror(errno)); + close(*f_infd); + *f_infd = -1; + } + } + + return eStatus; +} + +/* + * CRC-32C lookup table + * + * Polynomial 0x1EDC6F41 + */ +static const UI_32 crc32_lookup[4][256] = { // NOLINT (readability/naming) + { + }, + { + }, + { + }, + { + } +}; + +UI_32 CBinaryAccesser::CalcCRC(PVOID f_pdata, UI_32 f_size) { + UI_32 crc = 0xFFFFFFFF; + const UI_32 *current = (const UI_32 *)f_pdata; + + while (f_size >= 4) { + UI_32 one = *current++ ^ crc; + crc = crc32_lookup[0][(one >> 24) & 0xFF] ^ + crc32_lookup[1][(one >> 16) & 0xFF] ^ + crc32_lookup[2][(one >> 8) & 0xFF] ^ + crc32_lookup[3][one & 0xFF]; + f_size -= 4; + } + + const UI_8 *current_char = (const UI_8 *)current; + while (f_size-- > 0) { + crc = (crc >> 8) ^ crc32_lookup[0][(crc & 0xFF) ^ *current_char++]; + } + + return ~crc; +} -- cgit 1.2.3-korg