Commit f0077949 authored by Achim Morschhauser's avatar Achim Morschhauser
Browse files

Add buffer to write binary files

- buffer_obs_file was introduced as base class
- buffer_obs_file_ascii for writing ascii files
- buffer_obs_binary for binary files
- At the moment, data type for binary is fixed:
  - POSIX time (from struct tm)
  - Vector data as float
  - No supplementary data
- Note that size of files depends on machine, i.e.
  size of datatype
parent e9e57601
/********************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, July 2019 *
* mors//gfz-potsdam.de *
* *
* This class provides a buffer of observatory data that uses file input and *
* output. It can be used in combination with the SHELL file operator (|). *
* *
* This class implements the abstract class buffer_obs. *
* *
********************************************************************************/
#ifndef _BUFFER_OBS_FILE_H
#define _BUFFER_OBS_FILE_H
#include <buffer_obs.hpp>
#include <data_obs.hpp>
#include <data_obs_vector.hpp>
#include <data_obs_scalar.hpp>
#include <fstream>
#include <String_Parser.hpp>
class buffer_obs_file : public buffer_obs
{
//
// Private class variables
//
protected:
// Path to output files
std::string path;
// Format of output file (strftime)
std::string format;
// Currently opened filename (no path)
std::string filename="";
// File stream
std::fstream file;
//
// Constructors
//
public:
//buffer_obs_file_ascii(int precision=2);
//buffer_obs_file_ascii(int precision,std::string path);
buffer_obs_file(std::string path="",
std::string file="TEST_%Y%m%d.txt");
//
// Public Methods
//
/** Add to buffer */
public: virtual int put(data_obs* data)=0;
/** Get last element and delete */
public: virtual int pop(data_obs* data)=0;
/** Get last element and delete */
public: virtual data_obs pop()=0;
//
// Private Methods
//
/** Initialize the buffer */
protected: int init();
/** Open file and create folder */
protected: int open(std::string filename);
/** Write string to file buffer */
protected: int check(data_obs* data);
};
#endif /* _BUFFER_OBS_FILE_H */
......@@ -8,10 +8,10 @@
* This class implements the abstract class buffer_obs. *
* *
********************************************************************************/
#ifndef _BUFFER_OBS_file_H
#define _BUFFER_OBS_file_H
#ifndef _BUFFER_OBS_FILE_ASCII_H
#define _BUFFER_OBS_FILE_ASCII_H
#include <buffer_obs.hpp>
#include <buffer_obs_file.hpp>
#include <data_obs.hpp>
#include <data_obs_vector.hpp>
#include <data_obs_scalar.hpp>
......@@ -20,7 +20,7 @@
#include <String_Parser.hpp>
class buffer_obs_file : public buffer_obs
class buffer_obs_file_ascii : public buffer_obs_file
{
//
......@@ -29,14 +29,6 @@ class buffer_obs_file : public buffer_obs
private:
// Path to output files
std::string path;
// Format of output file (strftime)
std::string format;
// Currently opened filename (no path)
std::string filename="";
// File stream
std::fstream file;
// String Parser for data format in file
String_Parser parser;
......@@ -49,20 +41,20 @@ public:
//buffer_obs_file(int precision=2);
//buffer_obs_file(int precision,std::string path);
buffer_obs_file(std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file_ascii(std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file(int precision,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file_ascii(int precision,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file(std::string& formatstr,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file_ascii(std::string& formatstr,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file(const String_Parser& parser,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
buffer_obs_file_ascii(const String_Parser& parser,
std::string path="",
std::string file="TEST_%Y%m%d.txt");
//
// Public Methods
......@@ -79,13 +71,7 @@ public: data_obs pop();
// Private Methods
//
/** Initialize the buffer */
private: int init();
/** Open file and create folder */
private: int open(std::string filename);
/** Write string to file buffer */
private: int check(data_obs* data);
};
#endif /* _BUFFER_OBS_file_H */
#endif /* _BUFFER_OBS_FILE_ASCII_H */
/********************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, July 2019 *
* mors//gfz-potsdam.de *
* *
* This class provides a buffer of observatory data that uses file input and *
* output. It can be used in combination with the SHELL file operator (|). *
* *
* This class implements the abstract class buffer_obs. *
* *
********************************************************************************/
#ifndef _BUFFER_OBS_FILE_BINARY_H
#define _BUFFER_OBS_FILE_BINARY_H
#include <buffer_obs_file.hpp>
#include <data_obs.hpp>
#include <data_obs_vector.hpp>
#include <data_obs_scalar.hpp>
#include <fstream>
class buffer_obs_file_binary : public buffer_obs_file
{
//
// Private class variables
//
private:
bool info_written=false;
//
// Constructors
//
public:
//buffer_obs_file_binary(int precision=2);
//buffer_obs_file_binary(int precision,std::string path);
buffer_obs_file_binary(std::string path="",
std::string file="TEST_%Y%m%d.bin");
//
// Public Methods
//
/** Add to buffer */
public: int put(data_obs* data);
/** Get last element and delete */
public: int pop(data_obs* data);
/** Get last element and delete */
public: data_obs pop();
//
// Private Methods
//
private:
int info(data_obs* data);
};
#endif /* _BUFFER_OBS_FILE_BINARY_H */
......@@ -91,6 +91,8 @@ public: int set_time(data_obs* data);
/** Get the time of the data */
public: int get_time(int* year, int* mon, int* day, int* hour, int* min, int* sec,
long* msec);
/** Get the time as std::vector */
public: int get_time(std::vector<int> &time);
/** Get time as tm */
public: int get_time(struct tm* time) const;
/** Get time as timespec */
......
/*******************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, July 2019 *
* mors//gfz-potsdam.de *
* *
* This class provides a buffer of observatory data that uses file input *
* and output. *
* *
* This class implements the abstract class buffer_obs. *
* *
********************************************************************************/
// C++ Headers
#include <iostream> // Standard I/O
#include <fstream>
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h> // for close
// C headers
#include <time.h>
// Custom C++ Headers
#include <buffer_obs_file.hpp> // Buffer using File I/O
/********************************************************************************
*********************************************************************************
* *
* Constructors. *
* *
*********************************************************************************
********************************************************************************/
buffer_obs_file::buffer_obs_file(std::string path,
std::string format) {
// Set path
this->path = path;
// Set format
this->format = format;
}
/********************************************************************************
*********************************************************************************
* *
* Public Methods. *
* *
*********************************************************************************
********************************************************************************/
/********************************************************************************
*********************************************************************************
* *
* Private Methods. *
* *
*********************************************************************************
********************************************************************************/
/********************************************************************************
* *
* Method dummy for initialization: No initialization is needed. *
* *
********************************************************************************/
int buffer_obs_file::init() {
return(0);
}
/********************************************************************************
* *
* Create directories and open file *
* *
********************************************************************************/
int buffer_obs_file::open(std::string filename) {
std::string filename_full;
// Create full path
filename_full = path+'/'+filename;
// Create directory
int pos = filename_full.find('/',1);
while (pos != std::string::npos){
mkdir(filename_full.substr(0,pos).c_str(),0777);
pos = filename_full.find('/',pos+1);
}
// Close old file, if necessary
if (file.is_open()) {
file.close();
}
// Open new file
file.open(filename_full,std::ios::out | std::ios::app);
if (!file.is_open()){
std::cerr << "Opening file failed: "
<< filename_full
<< std::endl;
}
// Set filename
this->filename = filename;
return(0);
}
int buffer_obs_file::check(data_obs* data){
struct tm time;
size_t smax=40;
char filename[smax];
// Create filename
data->get_time(&time);
mktime(&time); // Set yday
strftime(filename,smax,format.c_str(),&time);
// Check if file is already opened
if (this->filename.compare(filename)){
open(filename);
}
return(0);
}
......@@ -21,7 +21,7 @@
#include <time.h>
// Custom C++ Headers
#include <buffer_obs_file.hpp> // Buffer using File I/O
#include <buffer_obs_file_ascii.hpp> // Buffer using File I/O
#include <String_Parser.hpp>
/********************************************************************************
......@@ -32,24 +32,20 @@
*********************************************************************************
********************************************************************************/
buffer_obs_file::buffer_obs_file(std::string path,
std::string format) {
buffer_obs_file_ascii::buffer_obs_file_ascii(std::string path,
std::string format)
: buffer_obs_file(path, format) {
std::string formatstr = "%T(%Y %m %d %H %M) %t(%S) %V(%6.2f )";
// Create parser
parser = String_Parser(formatstr);
// Set path
this->path = path;
// Set format
this->format = format;
}
buffer_obs_file::buffer_obs_file(int precision, std::string path,
std::string format) {
buffer_obs_file_ascii::buffer_obs_file_ascii(int precision, std::string path,
std::string format)
: buffer_obs_file(path, format) {
std::string formatstr;
......@@ -65,41 +61,24 @@ buffer_obs_file::buffer_obs_file(int precision, std::string path,
// Create parser
parser = String_Parser(formatstr);
// Set path
this->path = path;
// Set format
this->format = format;
}
buffer_obs_file::buffer_obs_file(std::string& formatstr, std::string path,
std::string format) {
buffer_obs_file_ascii::buffer_obs_file_ascii(std::string& formatstr, std::string path,
std::string format)
: buffer_obs_file(path, format) {
// Create parser
parser = String_Parser(formatstr);
// Set path
this->path = path;
// Set format
this->format = format;
}
buffer_obs_file::buffer_obs_file(const String_Parser& parser, std::string path,
std::string format) {
buffer_obs_file_ascii::buffer_obs_file_ascii(const String_Parser& parser, std::string path,
std::string format)
: buffer_obs_file(path, format) {
this->parser = parser;
// Set path
this->path = path;
// Set format
this->format = format;
}
/********************************************************************************
......@@ -117,7 +96,7 @@ buffer_obs_file::buffer_obs_file(const String_Parser& parser, std::string path,
* Take care to name files according to date *
* *
********************************************************************************/
int buffer_obs_file::put(data_obs* data) {
int buffer_obs_file_ascii::put(data_obs* data) {
std::string datastr;
......@@ -142,13 +121,13 @@ int buffer_obs_file::put(data_obs* data) {
* parsing the string. *
* *
********************************************************************************/
int buffer_obs_file::pop(data_obs* data) {
int buffer_obs_file_ascii::pop(data_obs* data) {
return(-1);
}
data_obs buffer_obs_file::pop(){
data_obs buffer_obs_file_ascii::pop(){
data_obs data;
......@@ -166,72 +145,3 @@ data_obs buffer_obs_file::pop(){
*********************************************************************************
********************************************************************************/
/********************************************************************************
* *
* Method dummy for initialization: No initialization is needed. *
* *
********************************************************************************/
int buffer_obs_file::init() {
return(0);
}
/********************************************************************************
* *
* Create directories and open file *
* *
********************************************************************************/
int buffer_obs_file::open(std::string filename) {
std::string filename_full;
// Create full path
filename_full = path+'/'+filename;
// Create directory
int pos = filename_full.find('/',1);
while (pos != std::string::npos){
mkdir(filename_full.substr(0,pos).c_str(),0777);
pos = filename_full.find('/',pos+1);
}
// Close old file, if necessary
if (file.is_open()) {
file.close();
}
// Open new file
file.open(filename_full,std::ios::out | std::ios::app);
// Set filename
this->filename = filename;
return(0);
}
int buffer_obs_file::check(data_obs* data){
struct tm time;
size_t smax=40;
char filename[smax];
// Create filename
data->get_time(&time);
mktime(&time); // Set yday
strftime(filename,smax,format.c_str(),&time);
// Check if file is already opened
if (this->filename.compare(filename)){
open(filename);
}
if (file.bad()) {
std::cerr << "Opening file " << filename
<< " failed!" << std::endl;
}
return(0);
}
/*******************************************************************************
* WRITTEN BY ACHIM MORSCHHAUSER, GFZ POTSDAM, July 2019 *
* mors//gfz-potsdam.de *
* *
* This class provides a buffer of observatory data that uses file input *
* and output. *
* *
* This class implements the abstract class buffer_obs. *
* *
********************************************************************************/
// C++ Headers
#include <iostream> // Standard I/O
#include <fstream>
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h> // for close
// C headers
#include <time.h>
#include <typeinfo>
// Custom C++ Headers
#include <buffer_obs_file_binary.hpp> // Buffer using File I/O
/********************************************************************************
*********************************************************************************
* *
* Constructors. *
* *
*********************************************************************************
********************************************************************************/
buffer_obs_file_binary::buffer_obs_file_binary(std::string path,
std::string format)
: buffer_obs_file(path,format) {
}
/********************************************************************************
*********************************************************************************
* *
* Public Methods. *
* *
*********************************************************************************
********************************************************************************/
/********************************************************************************
* *
* Add data of type data_obs to the buffer. This is done by converting the *
* data to its string representation and writing to File Output. *
* Take care to name files according to date *
* *
********************************************************************************/
int buffer_obs_file_binary::put(data_obs* data) {
struct timespec time;
std::vector<double> values_orig;
std::vector<float> values;
// Write data info to stderr
if (!info_written){
info(data);
}
// Open new file if necessary
check(data);
// Write time to file
data->get_time(&time);
file.write((char*) &time, sizeof(time));
// Write data to file
data->get_data(values_orig);