init
This commit is contained in:
+1759
File diff suppressed because it is too large
Load Diff
+355
@@ -0,0 +1,355 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ovICSV.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace CSV {
|
||||
class CCSVHandler final : public ICSVHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Set lib value to default
|
||||
*/
|
||||
CCSVHandler() : m_inputTypeID(EStreamType::StreamedMatrix), m_dimSizes({}) {}
|
||||
|
||||
/**
|
||||
* \brief Close the file if it is open.
|
||||
*/
|
||||
~CCSVHandler() override { this->closeFile(); }
|
||||
|
||||
/**
|
||||
* \brief Get the floating point precision used to write float values.
|
||||
*
|
||||
* \return the Floating point precision.
|
||||
*/
|
||||
size_t getOutputFloatPrecision() override { return m_oPrecision; }
|
||||
|
||||
/**
|
||||
* \brief Set the floating point precision used to write float values.
|
||||
*
|
||||
* \param precision the floating point precision.
|
||||
*/
|
||||
void setOutputFloatPrecision(const size_t precision) override { m_oPrecision = precision; }
|
||||
|
||||
void setFormatType(const EStreamType typeID) override;
|
||||
EStreamType getFormatType() override { return m_inputTypeID; }
|
||||
|
||||
void setLastMatrixOnlyMode(const bool isActivated) override { m_lastMatrixOnly = isActivated; }
|
||||
bool getLastMatrixOnlyMode() override { return m_lastMatrixOnly; }
|
||||
|
||||
bool setSignalInformation(const std::vector<std::string>& channelNames, size_t sampling, size_t nSamplePerBuffer) override;
|
||||
bool getSignalInformation(std::vector<std::string>& channelNames, size_t& sampling, size_t& nSamplePerBuffer) override;
|
||||
|
||||
bool setSpectrumInformation(const std::vector<std::string>& channelNames, const std::vector<double>& frequencyAbscissa, size_t sampling) override;
|
||||
bool getSpectrumInformation(std::vector<std::string>& channelNames, std::vector<double>& frequencyAbscissa, size_t& sampling) override;
|
||||
|
||||
bool setFeatureVectorInformation(const std::vector<std::string>& channelNames) override;
|
||||
bool getFeatureVectorInformation(std::vector<std::string>& channelNames) override;
|
||||
|
||||
bool setStreamedMatrixInformation(const std::vector<size_t>& dimSizes, const std::vector<std::string>& labels) override;
|
||||
bool getStreamedMatrixInformation(std::vector<size_t>& dimSizes, std::vector<std::string>& labels) override;
|
||||
|
||||
/**
|
||||
* \brief Write the header to the file
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool writeHeaderToFile() override;
|
||||
|
||||
/**
|
||||
* \brief Write current available data to the file until the last stimulation or if you set that it will not have new event before a date.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*
|
||||
* \sa noEventsUntilDate
|
||||
*/
|
||||
bool writeDataToFile() override;
|
||||
|
||||
/**
|
||||
* \brief Write current available data to the file.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool writeAllDataToFile() override;
|
||||
|
||||
/**
|
||||
* \brief Read samples and stimulations.
|
||||
*
|
||||
* \param lineNb Maximum number of lines to read. If there is no more data in the file, the number of lines read can be lower.
|
||||
* \param chunks[out] Valid chunks read.
|
||||
* \param stimulations[out] Valid stimulations read.
|
||||
*
|
||||
* \retval True in case of success, even if the number of lines is different than the lineNb parameter.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool readSamplesAndEventsFromFile(size_t lineNb, std::vector<SMatrixChunk>& chunks, std::vector<SStimulationChunk>& stimulations) override;
|
||||
|
||||
/**
|
||||
* \brief Open a OV CSV file.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool openFile(const std::string& fileName, EFileAccessMode mode) override;
|
||||
|
||||
/**
|
||||
* \brief Close the opened file.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool closeFile() override;
|
||||
|
||||
/**
|
||||
* \brief Add a single sample.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool addSample(const SMatrixChunk& sample) override;
|
||||
|
||||
/**
|
||||
* \brief Add several samples.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool addBuffer(const std::vector<SMatrixChunk>& samples) override;
|
||||
|
||||
/**
|
||||
* \brief Add a single stimulation.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool addEvent(uint64_t code, double date, double duration) override;
|
||||
|
||||
/**
|
||||
* \brief Add several stimulations.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*/
|
||||
bool addEvent(const SStimulationChunk& event) override;
|
||||
|
||||
/**
|
||||
* \brief Guarantee that will not have new event before a date.
|
||||
* This information is used to allow the library to write all the chunks available, before this date, to a file.
|
||||
*
|
||||
* \retval True in case of success.
|
||||
* \retval False in case of error.
|
||||
*
|
||||
* \sa writeDataToFile
|
||||
*/
|
||||
bool noEventsUntilDate(double date) override;
|
||||
|
||||
ELogErrorCodes getLastLogError() override { return m_logError; }
|
||||
|
||||
std::string getLastErrorString() override { return m_lastStringError; }
|
||||
|
||||
/**
|
||||
* \brief Check if there is still data to read in the file.
|
||||
*
|
||||
* \retval True if there is still data to read in the file.
|
||||
* \retval False if there is no more data to read in the file.
|
||||
*/
|
||||
bool hasDataToRead() const override { return m_hasDataToRead; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Split a string into a vector of strings.
|
||||
*
|
||||
* \param in String to split.
|
||||
* \param delimiter Delimitor.
|
||||
* \param out[out] Vector of string.
|
||||
*/
|
||||
void split(const std::string& in, char delimiter, std::vector<std::string>& out) const;
|
||||
|
||||
/**
|
||||
* \brief Create a string with stimulations to add in the buffer.
|
||||
*
|
||||
* \param stimulationsToPrint stimulations to put into the buffer
|
||||
*
|
||||
* \return string with stimulations to write
|
||||
*/
|
||||
std::string stimulationsToString(const std::vector<SStimulationChunk>& stimulationsToPrint) const;
|
||||
|
||||
/**
|
||||
* \brief Create a string representation of the header data.
|
||||
*
|
||||
* \retval true Header data as it should be written in the file
|
||||
* \retval "" in case of error
|
||||
*/
|
||||
std::string createHeaderString();
|
||||
|
||||
/**
|
||||
* \brief Set the buffer in function of data saved.
|
||||
*
|
||||
* \param canWriteAll true if it must write all lines, false if it write only the next buffer
|
||||
* \param csv The CSV string.
|
||||
*
|
||||
* \retval true in case of success
|
||||
* \retval false in case of wrong data sent
|
||||
*/
|
||||
bool createCSVStringFromData(bool canWriteAll, std::string& csv);
|
||||
|
||||
/**
|
||||
* \brief Parsing header to read data.
|
||||
*
|
||||
* \retval true in case of correct header
|
||||
* \retval false in case of incorrect header
|
||||
*/
|
||||
bool parseHeader();
|
||||
|
||||
/**
|
||||
* \brief Parsing header to read signal data.
|
||||
*
|
||||
* \param header[out]
|
||||
*
|
||||
* \retval true in case of correct header
|
||||
* \retval false in case of incorrect header
|
||||
*/
|
||||
bool parseSignalHeader(const std::vector<std::string>& header);
|
||||
|
||||
/**
|
||||
* \brief Parsing header to read Spectrum data.
|
||||
*
|
||||
* \param header[out]
|
||||
*
|
||||
* \retval true in case of correct header
|
||||
* \retval false in case of incorrect header
|
||||
*/
|
||||
bool parseSpectrumHeader(const std::vector<std::string>& header);
|
||||
|
||||
/**
|
||||
* \brief Parsing header to read matrix data (Streamed Matrix, Covariance matrix and Feature Vector).
|
||||
*
|
||||
* \param header[out]
|
||||
*
|
||||
* \retval true in case of correct header
|
||||
* \retval false in case of incorrect header
|
||||
*/
|
||||
bool parseMatrixHeader(const std::vector<std::string>& header);
|
||||
|
||||
/**
|
||||
* \brief Read line data concerning time, epoch and matrix.
|
||||
*
|
||||
* \param line line to read
|
||||
* \param sample[out] reference to stock data in
|
||||
* \param lineNb index of the read line
|
||||
*
|
||||
* \retval true in case of success
|
||||
* \retval false in case of error (as letters instead of numbers)
|
||||
*/
|
||||
bool readSampleChunk(const std::string& line, SMatrixChunk& sample, size_t lineNb);
|
||||
|
||||
/**
|
||||
* \brief Read line data conerning stimulations.
|
||||
*
|
||||
* \param line the line to read
|
||||
* \param stimulations[out] vector to stock stimulations in (identifier, date and duration)
|
||||
* \param lineNb the line actually reading
|
||||
*
|
||||
* \retval true in case of success
|
||||
* \retval false in case of error (as letters instead of numbers)
|
||||
*/
|
||||
bool readStimulationChunk(const std::string& line, std::vector<SStimulationChunk>& stimulations, size_t lineNb);
|
||||
|
||||
/**
|
||||
* \brief Update position into the matrix while reading or writing.
|
||||
*
|
||||
* \param position[out] is the position into the matrix
|
||||
*
|
||||
* \retval true in case of success
|
||||
* \retval false in case of browse matrix
|
||||
*/
|
||||
bool increasePositionIndexes(std::vector<size_t>& position);
|
||||
|
||||
/**
|
||||
* \brief Read lines of the first epoch to found sample count per buffer.
|
||||
*
|
||||
* \retval true in case of success
|
||||
* \retval false in case of error
|
||||
*/
|
||||
bool calculateSampleCountPerBuffer();
|
||||
|
||||
/**
|
||||
* \brief Read a stream until a delimiter and provide the string before the delimiter.
|
||||
*
|
||||
* \param in The stream to read.
|
||||
* \param out The string before the next delimitor.
|
||||
* \param delimiter The delimiter .
|
||||
* \param bufferHistory
|
||||
*/
|
||||
bool streamReader(std::istream& in, std::string& out, char delimiter, std::string& bufferHistory) const;
|
||||
|
||||
std::fstream m_fs;
|
||||
std::string m_filename;
|
||||
std::deque<SMatrixChunk> m_chunks;
|
||||
std::deque<SStimulationChunk> m_stimulations;
|
||||
ELogErrorCodes m_logError = LogErrorCodes_NoError;
|
||||
std::string m_lastStringError = "";
|
||||
|
||||
EStreamType m_inputTypeID;
|
||||
|
||||
typedef std::istream& GetLine(std::istream& in, std::string& out, char delimiter);
|
||||
size_t m_nDim = 0;
|
||||
std::vector<size_t> m_dimSizes;
|
||||
std::vector<std::string> m_dimLabels;
|
||||
size_t m_nSamplePerBuffer = 0;
|
||||
double m_noEventSince = 0;
|
||||
|
||||
std::vector<double> m_frequencyAbscissa;
|
||||
|
||||
size_t m_sampling = 0;
|
||||
size_t m_nCol = 0;
|
||||
|
||||
bool m_hasInputType = false;
|
||||
bool m_isFirstLineWritten = false;
|
||||
bool m_isHeaderRead = false;
|
||||
bool m_isSetInfoCalled = false;
|
||||
bool m_hasEpoch = false;
|
||||
|
||||
size_t m_nSampleOriginal = 0;
|
||||
size_t m_oPrecision = 10;
|
||||
|
||||
bool m_lastMatrixOnly = false;
|
||||
|
||||
std::string m_bufferReadFileLine; // Buffer used to store unused read chars.
|
||||
|
||||
bool m_hasDataToRead = true;
|
||||
|
||||
#if defined TARGET_OS_Linux || defined TARGET_OS_MacOS
|
||||
bool m_isCRLFEOL = false; // Is a CRLF end of line
|
||||
#endif
|
||||
};
|
||||
} // namespace CSV
|
||||
} // namespace OpenViBE
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <map>
|
||||
|
||||
#include <ovICSV.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace CSV {
|
||||
|
||||
static const std::map<ELogErrorCodes, std::string> ERROR_MAP =
|
||||
{
|
||||
{ LogErrorCodes_ErrorWhileClosing, "Error while closing the file" },
|
||||
{ LogErrorCodes_NoFileDefined, "No file defined yet" },
|
||||
{ LogErrorCodes_CantOpenFile, "Could not open the file" },
|
||||
{ LogErrorCodes_DurationError, "The duration can't be negative" },
|
||||
{ LogErrorCodes_DateError, "The date can't be negative" },
|
||||
{ LogErrorCodes_NoSample, "Their is no sample to add" },
|
||||
{ LogErrorCodes_NoMatrixLabels, "No matrix labels" },
|
||||
{ LogErrorCodes_WrongMatrixSize, "Matrix size is different from the initial size" },
|
||||
{ LogErrorCodes_MatrixEmpty, "A matrix of the buffer is empty" },
|
||||
{ LogErrorCodes_DimensionSizeZero, "Dimensions can not have size equal to 0" },
|
||||
{ LogErrorCodes_DimensionSizeEmpty, "Dimension sizes vector is empty" },
|
||||
{ LogErrorCodes_NoChannelsName, "No channel names in the vector" },
|
||||
{ LogErrorCodes_SetInfoOnce, "The setTypeInformation function should be called only once" },
|
||||
{ LogErrorCodes_WrongInputType, "Wrong input type" },
|
||||
{ LogErrorCodes_WrongHeader, "Error in the header of the file" },
|
||||
{ LogErrorCodes_WrongLineSize, "There is a difference between the current line size and the size that it should have" },
|
||||
{ LogErrorCodes_SampleNotEmpty, "Matrix must be empty to store in results of reading" },
|
||||
{ LogErrorCodes_NotEnoughLines, "Can't reach the line in parameter, not enough lines in the file" },
|
||||
{ LogErrorCodes_NegativeStimulation, "Stimulations cannot have negatives values" },
|
||||
{ LogErrorCodes_WrongSampleDate, "Sample dates must be correct (greater than or equal to zero, and start date less than end date)" },
|
||||
{ LogErrorCodes_InvalidStimulationArgument, "Wrong stimulation entry" },
|
||||
{ LogErrorCodes_StimulationSize, "Some stimulation(s) has/have incomplete parameter(s)" },
|
||||
{ LogErrorCodes_EmptyColumn, "A column of the file is empty" },
|
||||
{ LogErrorCodes_WrongDimensionSize, "Size of dimension sizes vector must be equal to the number of dimensions" },
|
||||
{ LogErrorCodes_DimensionCountZero, "Number of dimension must be at least 1" },
|
||||
{ LogErrorCodes_OutOfRangeException, "Convertion from string to number is impossible : string is out of range" },
|
||||
{ LogErrorCodes_InvalidArgumentException, "An invalid argument exeption have been thrown" },
|
||||
{ LogErrorCodes_CantWriteHeader, "Can not write header, data already began to be written or header already written" },
|
||||
{ LogErrorCodes_ErrorWhileWriting, "Error occured while trying to write" },
|
||||
{ LogErrorCodes_WrongParameters, "Error with (one of )the parameter(s)" },
|
||||
{ LogErrorCodes_MissingData, "Missing data in file, file may be corrupted" }
|
||||
};
|
||||
|
||||
std::string ICSVHandler::getLogError(const ELogErrorCodes code)
|
||||
{
|
||||
if (ERROR_MAP.count(code) != 0) { return ERROR_MAP.at(code); }
|
||||
return "Unknow error";
|
||||
}
|
||||
|
||||
} // namespace CSV
|
||||
} // namespace OpenViBE
|
||||
Reference in New Issue
Block a user