// -*- C++ -*- /*****************************************************************************\ * Copyright (c) 2004 Mark Aylett * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to permit * * persons to whom the Software is furnished to do so, subject to the * * following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN * * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * * USE OR OTHER DEALINGS IN THE SOFTWARE. * \*****************************************************************************/ /** * \file mar_archive_cpp.h * \brief TODO */ #ifndef INCLUDED_MAR_ARCHIVE_CPP #define INCLUDED_MAR_ARCHIVE_CPP #ifndef INCLUDED_MAR_KEY_CPP #include "mar_key_cpp.h" #endif // INCLUDED_MAR_KEY_CPP #ifndef INCLUDED_MAR_TYPES_CPP #include "mar_types_cpp.h" #endif // INCLUDED_MAR_TYPES_CPP #ifndef INCLUDED_MAR_C #include "mar_c.h" #endif // INCLUDED_MAR_C #ifndef INCLUDED_ALGORITHM #define INCLUDED_ALGORITHM #include #endif // INCLUDED_ALGORITHM #ifndef INCLUDED_CERRNO #define INCLUDED_CERRNO #include #endif // INCLUDED_CERRNO #ifndef INCLUDED_VECTOR #define INCLUDED_VECTOR #include #endif // INCLUDED_VECTOR #ifndef INCLUDED_STRING #define INCLUDED_STRING #include #endif // INCLUDED_STRING namespace mar { class pair { friend class archive; mar_pair_t value_; public: pair() { clear(); } explicit pair(const mar_pair_t& p) : value_(p) { } explicit pair(const char* k) { setkey(k); value_.data_ = 0; value_.size_ = 0; } pair(const char* k, const void* d, size_t s) { setkey(k); setdata(d, s); } pair(const char* k, const char* d) { setkey(k); setdata(d); } void clear() { value_.key_[0] = '\0'; value_.data_ = 0; value_.size_ = 0; } void setkey(const char* k) { mar_strncpy_(value_.key_, k, sizeof(value_.key_)); } void setdata(const void* d, size_t s) { value_.data_ = d; value_.size_ = s; } void setdata(const char* d) { value_.data_ = d; value_.size_ = strlen(d); } const char* key() const { return value_.key_; } const void* data() const { return value_.data_; } size_t size() const { return value_.size_; } }; class handle { friend class archive; mar_t mar_; int release() MAR_NOTHROW { if (!mar_) return 0; mar_t tmp(mar_); mar_ = 0; return mar_release(tmp); } explicit handle(mar_t m = 0) : mar_(m) { } handle(const handle& rhs) { if ((mar_ = rhs.mar_)) mar_retain(mar_); } handle& operator =(const handle& rhs) { handle tmp(rhs); std::swap(mar_, tmp.mar_); return *this; } public: ~handle() MAR_NOTHROW { if (mar_) mar_release(mar_); } operator bool() const { return 0 != mar_; } }; class archive { handle h_; explicit archive(mar_t m) : h_(m) { } public: archive() { } archive(const handle& rhs) : h_(rhs) { } archive(archive& rhs) : h_(rhs.h_) { } archive& operator =(const handle& rhs) { h_ = rhs; return *this; } archive& operator =(archive& rhs) { h_ = rhs.h_; return *this; } // Creational. static archive create() { return archive(handle(mar_create())); } static archive open(const char* path, int flags, mode_t mode) { return archive(handle(mar_open(path, flags, mode))); } static archive open(const char* path, int flags) { return archive(handle(mar_open(path, flags))); } static archive opencopy(const char* path, const char* master, int flags = rdwr | creat | excl, mode_t mode = 0664) { handle ret, dst(mar_open(path, flags, mode)); if (!dst.mar_) return archive(ret); handle src(mar_open(master, rdonly)); if (src.mar_) { if (-1 == mar_copy(dst.mar_, src.mar_)) return archive(ret); } else if (ENOENT != mar_errno()) return archive(ret); return archive(ret = dst); } int copy(const archive& src) { return mar_copy(h_.mar_, src.h_.mar_); } int release() { return h_.release(); } operator const handle&() { return h_; } // Meta Modifiers. int removepairs() { return mar_removepairs(h_.mar_); } int setmeta(size_t ord, const void* data, size_t size) { return mar_setmeta(h_.mar_, ord, data, size); } int setmeta(const pair& p, size_t& ord) { return mar_setpair(h_.mar_, &p.value_, &ord); } int setmeta(const pair& p) { return mar_setpair(h_.mar_, &p.value_, NULL); } int unsetmeta(const char* key, size_t& ord) { return mar_unsetbykey(h_.mar_, key, &ord); } int unsetmeta(const char* key) { return mar_unsetbykey(h_.mar_, key, NULL); } int unsetmeta(size_t ord) { return mar_unsetbyord(h_.mar_, ord); } // User Modifiers. int insert(const char* path) { return mar_insert(h_.mar_, path); } ssize_t read(void* buf, size_t size) { return mar_read(h_.mar_, buf, size); } off_t seek(off_t offset, int whence) { return mar_seek(h_.mar_, offset, whence); } int setuser(const void* data, size_t size) { return mar_setuser(h_.mar_, data, size); } int sync() { return mar_sync(h_.mar_); } int truncate(size_t size) { return mar_truncate(h_.mar_, size); } ssize_t write(const void* buf, size_t size) { return mar_write(h_.mar_, buf, size); } // Meta Accessors. const void* meta(const char* key, size_t& size) const { return mar_metabykey(h_.mar_, key, &size); } const void* meta(const char* key) const { return mar_metabykey(h_.mar_, key, NULL); } const void* meta(size_t ord, size_t& size) const { return mar_metabyord(h_.mar_, ord, &size); } const void* meta(size_t ord) const { return mar_metabyord(h_.mar_, ord, NULL); } int meta(pair& p, size_t ord) const { return mar_metapair(h_.mar_, &p.value_, ord); } int metapairs(size_t& size) const { return mar_metapairs(h_.mar_, &size); } int tokey(key& k, size_t ord) const { mar_key_t local; int ret(mar_tokey(h_.mar_, local, ord)); if (-1 != ret) k = local; return ret; } int toord(size_t& ord, const char* key) const { return mar_toord(h_.mar_, &ord, key); } // User Accessors. int extract(const char* path) const { return mar_extract(h_.mar_, path); } const void* user(size_t& size) const { return mar_user(h_.mar_, &size); } const void* user() const { return mar_user(h_.mar_, NULL); } int usersize(size_t& size) const { return mar_usersize(h_.mar_, &size); } bool isopen() const { return static_cast(h_); } // Operators. bool operator ==(const archive& rhs) const { return h_.mar_ == rhs.h_.mar_; } bool operator !=(const archive& rhs) const { return h_.mar_ != rhs.h_.mar_; } bool operator <(const archive& rhs) const { return h_.mar_ < rhs.h_.mar_; } operator bool() const { return isopen(); } }; } #endif // INCLUDED_MAR_ARCHIVE_CPP