Refactored POSIX tools

This commit is contained in:
Pavel Kirienko
2015-05-18 15:14:37 +03:00
parent e4886606f0
commit 46afa99b27
4 changed files with 41 additions and 43 deletions
@@ -0,0 +1,85 @@
/****************************************************************************
*
* Copyright (c) 2015 PX4 Development Team. All rights reserved.
* Author: Pavel Kirienko <pavel.kirienko@gmail.com>
* David Sidrane <david_s5@usa.net>
*
****************************************************************************/
#ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED
#define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED
#include <uavcan/protocol/dynamic_node_id_server/event.hpp>
#include <time.h>
#include <fcntl.h>
namespace uavcan_posix
{
namespace dynamic_node_id_server
{
/**
* This interface implements a POSIX compliant file based IEventTracer interface
*/
class FileEventTracer : public uavcan::dynamic_node_id_server::IEventTracer
{
/**
* Maximum length of full path to log file
*/
enum { MaxPathLength = 128 };
/**
* This type is used for the path
*/
typedef uavcan::Array<uavcan::IntegerSpec<8, uavcan::SignednessUnsigned, uavcan::CastModeTruncate>,
uavcan::ArrayModeDynamic, MaxPathLength> PathString;
PathString path_;
virtual void onEvent(uavcan::dynamic_node_id_server::TraceCode code, uavcan::int64_t argument)
{
using namespace std;
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
int fd = open(path_.c_str(), O_WRONLY | O_CREAT | O_APPEND);
if (fd >= 0 )
{
const int FormatBufferLength = 64;
char buffer[FormatBufferLength + 1];
int n = snprintf(buffer, FormatBufferLength, "%d.%ld,%d,%lld\n", ts.tv_sec, ts.tv_nsec, code, argument);
write(fd, buffer, n);
close(fd);
}
}
public:
FileEventTracer() { }
/**
* Initializes the file based event tracer.
*/
int init(const PathString & path)
{
using namespace std;
int rv = -uavcan::ErrInvalidParam;
if (path.size() > 0)
{
rv = 0;
path_ = path.c_str();
int fd = open(path_.c_str(), O_RDWR | O_CREAT | O_TRUNC);
if ( fd >= 0)
{
close(fd);
}
}
return rv;
}
};
}
}
#endif // Include guard
@@ -0,0 +1,133 @@
/****************************************************************************
*
* Copyright (c) 2015 PX4 Development Team. All rights reserved.
* Author: Pavel Kirienko <pavel.kirienko@gmail.com>
* David Sidrane <david_s5@usa.net>
*
****************************************************************************/
#ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED
#define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED
#include <sys/stat.h>
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <fcntl.h>
#include <uavcan/protocol/dynamic_node_id_server/storage_backend.hpp>
namespace uavcan_posix
{
namespace dynamic_node_id_server
{
/**
* This interface implements a POSIX compliant IStorageBackend interface
*/
class FileStorageBackend : public uavcan::dynamic_node_id_server::IStorageBackend
{
/**
* Maximum length of full path including / and key max
*/
enum { MaxPathLength = 128 };
/**
* This type is used for the path
*/
typedef uavcan::Array<uavcan::IntegerSpec<8, uavcan::SignednessUnsigned, uavcan::CastModeTruncate>,
uavcan::ArrayModeDynamic, MaxPathLength> PathString;
PathString base_path;
virtual String get(const String& key) const
{
using namespace std;
PathString path = base_path.c_str();
path += key;
String value;
int fd = open(path.c_str(), O_RDONLY);
if (fd >= 0)
{
char buffer[MaxStringLength + 1];
memset(buffer, 0, sizeof(buffer));
int len = read(fd, buffer, MaxStringLength);
close(fd);
if (len > 0)
{
for (int i = 0; i < len; i++)
{
if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\r' )
{
buffer[i] = '\0';
break;
}
}
value = buffer;
}
}
return value;
}
virtual void set(const String& key, const String& value)
{
using namespace std;
PathString path = base_path.c_str();
path += key;
int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
if (fd >= 0)
{
write(fd, value.c_str(), value.size());
close(fd);
}
}
public:
FileStorageBackend() { }
/**
* Initializes the file based backend storage by passing a path to
* the directory where the key named files will be stored.
* The return value should be 0 on success.
* If it is -ErrInvalidConfiguration then the the path name is too long to
* accommodate the trailing slash and max key length.
*/
int init(const PathString& path)
{
using namespace std;
int rv = -uavcan::ErrInvalidParam;
if (path.size() > 0)
{
base_path = path.c_str();
if (base_path.back() == '/')
{
base_path.pop_back();
}
rv = 0;
struct stat sb;
if (stat(base_path.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode))
{
rv = mkdir(base_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
}
if (rv >= 0 )
{
base_path.push_back('/');
if ((base_path.size() + MaxStringLength) > MaxPathLength)
{
rv = -uavcan::ErrInvalidConfiguration;
}
}
}
return rv;
}
};
}
}
#endif // Include guard