/** * 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; }
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]; (void)memset(buffer, 0, sizeof(buffer)); int len = read(fd, buffer, MaxStringLength); (void)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, FilePermissions); if (fd >= 0) { (void)write(fd, value.c_str(), value.size()); // TODO FIXME Write loop (void)fsync(fd); (void)close(fd); } }
virtual void onEvent(uavcan::dynamic_node_id_server::TraceCode code, uavcan::int64_t argument) { using namespace std; timespec ts = timespec(); // If clock_gettime() fails, zero time will be used (void)clock_gettime(CLOCK_REALTIME, &ts); int fd = open(path_.c_str(), O_WRONLY | O_CREAT | O_APPEND, FilePermissions); if (fd >= 0) { const int FormatBufferLength = 63; char buffer[FormatBufferLength + 1]; ssize_t remaining = snprintf(buffer, FormatBufferLength, "%ld.%06ld\t%d\t%lld\n", static_cast<long>(ts.tv_sec), static_cast<long>(ts.tv_nsec / 1000L), static_cast<int>(code), static_cast<long long>(argument)); ssize_t total_written = 0; ssize_t written = 0; do { written = write(fd, &buffer[total_written], remaining); if (written > 0) { total_written += written; remaining -= written; } } while (written > 0 && remaining > 0); (void)close(fd); } }
/** * 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, FilePermissions); if (fd >= 0) { (void)close(fd); } } return rv; }
/** * フルパス名を求めます。 */ PathString getFullPath(const PathString &s) { const DWORD bufferLen = MAX_PATH; TCHAR *filePart; TCHAR buffer[bufferLen + 1]; DWORD len = GetFullPathName(s.c_str(), bufferLen, buffer, &filePart); if(len == 0 || len >= bufferLen){ return PathString(); } return PathString(buffer); }
/** * フルパス名のファイル部分を除いた物を求めます。 * * chopLastFileName(getFullPath(s))とほぼ同じだと思います。 */ PathString getFullPathDir(const PathString &s) { const DWORD bufferLen = MAX_PATH; TCHAR *filePart; TCHAR buffer[bufferLen + 1]; DWORD len = GetFullPathName(s.c_str(), bufferLen, buffer, &filePart); if(len == 0 || len == bufferLen){ return PathString(); } if(filePart == NULL){ return PathString(buffer); // sがパス区切りで終わっていたり、//serverや//server/shareのようなUNC先頭。 } else{ return PathString(buffer, filePart); //ファイル部の直前までを返す。 } }
void DeleteFilePath(const PathString& log_name) { DeleteFileW(log_name.c_str()); }