giuliomoro@153: /*
giuliomoro@153:  * WriteMFile.h
giuliomoro@153:  *
giuliomoro@153:  *  Created on: 5 Oct 2015
giuliomoro@153:  *      Author: giulio
giuliomoro@153:  */
giuliomoro@153: 
giuliomoro@153: #ifndef WRITEMFILE_H_
giuliomoro@153: #define WRITEMFILE_H_
giuliomoro@301: #include <Bela.h>
giuliomoro@153: #include <vector>
giuliomoro@153: #include <stdio.h>
giuliomoro@153: #include <stdlib.h>
giuliomoro@153: #include <string.h>
giuliomoro@153: #include <unistd.h>
giuliomoro@153: 
giuliomoro@157: typedef enum {
giuliomoro@157: 	kBinary,
giuliomoro@157: 	kText
giuliomoro@157: } WriteFileType;
giuliomoro@157: 
giuliomoro@153: class WriteFile {
giuliomoro@153: private:
giuliomoro@153: 	static AuxiliaryTask writeAllFilesTask;
giuliomoro@153: 	bool echo;
giuliomoro@157: 	int echoedLines;
giuliomoro@157: 	int echoPeriod;
giuliomoro@153: 	char *header;
giuliomoro@153: 	char *footer;
giuliomoro@153: 	char *stringBuffer;
giuliomoro@153: 	int stringBufferLength;
giuliomoro@153: 	int bufferLength;
giuliomoro@153: 	float* buffer;
giuliomoro@157: 	int textReadPointer;
giuliomoro@157: 	int binaryReadPointer;
giuliomoro@153: 	int writePointer;
giuliomoro@153: 	bool variableOpen;
giuliomoro@153: 	char* format;
giuliomoro@153: 	int lineLength;
giuliomoro@157: 	WriteFileType fileType;
giuliomoro@153: 	static int sleepTimeMs;
giuliomoro@153: 	FILE *file;
giuliomoro@153: 	void writeLine();
giuliomoro@153: 	void writeHeader();
giuliomoro@153: 	void writeFooter();
giuliomoro@153: 	void allocateAndCopyString(const char* source, char** destination);
giuliomoro@153: 	void print(const char* string);
giuliomoro@157: 	void printBinary(const char* string);
giuliomoro@153: 	void setLineLength(int newLineLength);
giuliomoro@157: 	int getOffsetFromPointer(int aPointer);
giuliomoro@153: 	std::vector<char *> formatTokens;
giuliomoro@153: 	static void sanitizeString(char* string);
giuliomoro@153: 	static void sanitizeString(char* string, int numberOfArguments);
giuliomoro@153:     static bool isThreadRunning();
giuliomoro@153: 	static bool auxiliaryTaskRunning;
giuliomoro@153:     static bool threadShouldExit();
giuliomoro@153:     static bool threadIsExiting;
giuliomoro@153:     static bool threadRunning;
giuliomoro@153:     static bool staticConstructed;
giuliomoro@153: 	static void staticConstructor();
giuliomoro@153: 	static std::vector<WriteFile *> objAddrs;
giuliomoro@159: 	void writeOutput(bool flush);
giuliomoro@153: public:
giuliomoro@153: 	WriteFile();
giuliomoro@157: 	/**
giuliomoro@157: 	 * Set the type of file to write, can be either kText or kBinary.
giuliomoro@157: 	 * Binary files can be imported e.g. in Matlab:
giuliomoro@157: 	 *   fid=fopen('out','r');
giuliomoro@157: 	 *   A = fread(fid, 'float');
giuliomoro@157: 	 * */
giuliomoro@157: 	void setFileType(WriteFileType newFileType);
giuliomoro@153: 	void setEcho(bool newEcho);
giuliomoro@157: 	void setEchoInterval(int newPeriod);
giuliomoro@157: 	/**
giuliomoro@157: 	 *  Set the format that you want to use for your output.
giuliomoro@157: 	 *
giuliomoro@157: 	 * Only %f is allowed (with modifiers). When in binary mode,
giuliomoro@157: 	 * the specified format is used only for echoing to console.
giuliomoro@157: 	 */
giuliomoro@153: 	void setFormat(const char* newFormat);
giuliomoro@157: 	/**
giuliomoro@157: 	 * Set one or more lines to be printed at the beginning of the file.
giuliomoro@157: 	 *
giuliomoro@157: 	 * This is ignored in binary mode.
giuliomoro@157: 	 */
giuliomoro@153: 	void setHeader(const char* newHeader);
giuliomoro@157: 	/**
giuliomoro@157: 	 * Set one or more lines to be printed at the end of the file.
giuliomoro@157: 	 *
giuliomoro@157: 	 * This is ignored in binary mode.
giuliomoro@157: 	 */
giuliomoro@153: 	void setFooter(const char* newFooter);
giuliomoro@153: 	void log(float* array, int length);
giuliomoro@153: 	void log(float value);
giuliomoro@153: 	void init(const char* filename);
giuliomoro@153: 
giuliomoro@153: 	/**
giuliomoro@153: 	 * Gets the distance between the write and read pointers of
giuliomoro@153: 	 * the buffer that holds data to be written to disk.
giuliomoro@153: 	 */
giuliomoro@153: 	int getOffset();
giuliomoro@153: 
giuliomoro@153: 	/**
giuliomoro@153: 	 * Inquiries the status of the buffer that holds data to be written to disk.
giuliomoro@153: 	 *
giuliomoro@153: 	 * @return a value between 0 and 1, with 0 being buffer full (writing to disk not fast enough)
giuliomoro@153: 	 * and 1 being buffer empty (writing to disk is fast enough).
giuliomoro@153: 	 */
giuliomoro@153: 	float getBufferStatus();
giuliomoro@153: 	~WriteFile();
giuliomoro@153:     static int getNumInstances();
giuliomoro@153:     static void writeAllHeaders();
giuliomoro@153:     static void writeAllFooters();
giuliomoro@159:     static void writeAllOutputs(bool flush);
giuliomoro@153:     static void startThread();
giuliomoro@153:     static void stopThread();
giuliomoro@153:     static void run();
giuliomoro@153: };
giuliomoro@153: 
giuliomoro@153: #endif /* WRITEMFILE_H_ */