blob: 17cb065d50271198ae88b7084a51c0b7e2459b3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Herwig Eichler, www.conmeleon.org
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Herwig Eichler - initial API and implementation and initial documentation
*******************************************************************************/
#include "fileres.h"
#include <cstring>
#include <cstdlib>
#include <cstdarg>
CFileResource::CFileResource(const char* pszFileName, const char* pszOpenMode /*= "a+"*/) : m_pFileHandle(std::fopen(pszFileName, pszOpenMode)) {
m_ReadOnly = checkModeReadOnly(pszOpenMode);
}
CFileResource::~CFileResource() {
if (m_pFileHandle != nullptr) {
std::fclose(m_pFileHandle);
}
}
void CFileResource::writeLine(const char* pszData) const {
if (pszData == nullptr) {
return; // bad parameter, just return and do nothing
}
if (!m_ReadOnly && (m_pFileHandle != nullptr)) {
std::fputs(pszData, m_pFileHandle);
if (ferror(m_pFileHandle)) {
// TODO: add logging or trace function like "Error during write to file operation! Check file permissions!";
}
// flushing or repositioning is required if the file is opened in update mode ("a"), so we do this always
// following read operations on the same file will get the updated value for sure
std::fflush(m_pFileHandle);
}
}
void CFileResource::writeFormattedLine(const char* pszFormat, ...) const {
if (pszFormat == nullptr) {
return; // bad parameter, just return and do nothing
}
if (!m_ReadOnly && (m_pFileHandle != nullptr)) {
char buffer[256]; // buffer to hold formatted string including the arguments
va_list args;
// start to deal with the arguments
va_start (args, pszFormat);
if (vsprintf (buffer,pszFormat, args) > 0) {
// formatted string was assembled properly
std::fputs(buffer, m_pFileHandle);
if (ferror(m_pFileHandle)) {
// TODO: add logging or trace function like "Error during write to file operation! Check file permissions!";
}
// flushing or repositioning is required if the file is opened in update mode ("a"), so we do this always
// following read operations on the same file will get the updated value for sure
std::fflush(m_pFileHandle);
}
va_end(args);
}
}
void CFileResource::readLine(char* pszData, std::size_t nLength) const {
if ((pszData == nullptr) || (nLength < 1)) {
return; // bad parameters, just return and do nothing
}
if (m_pFileHandle != nullptr) {
char *pszLine = NULL;
std::size_t nLen = 0;
ssize_t nNrCharsRead;
// set file position to the beginning
std::rewind(m_pFileHandle);
nNrCharsRead = getline(&pszLine, &nLen, m_pFileHandle);
if (nNrCharsRead != -1) {
strncpy(pszData, pszLine, nLength);
}
else {
// TODO: add logging or trace function like "Error during write to file operation! Check file permissions!";
}
// getline allocates memory if needed, we need to release this memory again
free(pszLine);
}
}
bool checkModeReadOnly (const char* pszMode) {
bool bIsReadOnly;
if (pszMode == nullptr) {
return false;
}
// there needs to be a "r"
bIsReadOnly = (strstr(pszMode, "r") != nullptr);
// and we don't want to have a "+"
return (bIsReadOnly && (strstr(pszMode, "+") == nullptr));
}