Compare commits

...

17 Commits

Author SHA1 Message Date
Maarten L. Hekkelman
791ab245ca Fix makefile for renamed script 2020-12-15 19:15:00 +01:00
Maarten L. Hekkelman
43287736bb Revert renaming update script 2020-12-15 16:46:09 +01:00
Maarten L. Hekkelman
34ee3321d8 update makefile, to match debian 2020-12-15 16:37:53 +01:00
Maarten L. Hekkelman
6e433ae784 fix makefile for new configure script 2020-12-15 16:16:04 +01:00
Maarten L. Hekkelman
cd370275da Fix for 32-bit architectures 2020-12-15 15:47:41 +01:00
Maarten L. Hekkelman
7ed0f4c8ae clean up configure script 2020-12-02 15:21:17 +01:00
Maarten L. Hekkelman
ea7d8ce766 do not install the cron job by default 2020-11-19 16:27:21 +01:00
Maarten L. Hekkelman
f12e877251 for travis 2020-11-19 14:19:47 +01:00
Maarten L. Hekkelman
57ce90ce7c for travis 2020-11-19 14:18:54 +01:00
Maarten L. Hekkelman
b61321e360 for travis 2020-11-19 14:11:13 +01:00
Maarten L. Hekkelman
6416056958 disable resources on macOS 2020-11-19 13:39:14 +01:00
Maarten L. Hekkelman
4fdfd03c04 update clean target 2020-11-19 12:35:17 +01:00
Maarten L. Hekkelman
a1d2438341 and this one too 2020-11-19 12:27:53 +01:00
Maarten L. Hekkelman
952aa15d6e Fixed the --enable-revision argument for configure 2020-11-19 12:15:52 +01:00
Maarten L. Hekkelman
b3e45eb0b6 typo 2020-11-19 12:06:49 +01:00
Maarten L. Hekkelman
a548b39677 revision writing 2020-11-18 16:51:16 +01:00
Maarten L. Hekkelman
d5d96c58e4 resource loading 2020-11-18 08:35:23 +01:00
11 changed files with 538 additions and 247 deletions

View File

@@ -19,18 +19,15 @@ addons:
- libboost-all-dev
before_install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install make; fi
# - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install boost make; fi
script:
- ./configure
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake NO_REVISION=1 ; else make NO_REVISION=1 ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test NO_REVISION=1 ; else make test NO_REVISION=1 ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake NO_REVISION=1 install; else sudo make install NO_REVISION=1; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./configure --disable-shared ; else ./configure ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake ; else make ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test ; else make test ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake install ; else sudo make install; fi
jobs:
allow_failures:
- os: osx
# jobs:
# allow_failures:
# - os: osx

View File

@@ -28,24 +28,27 @@
firstTarget: all
CXX = @CXX@
CXXFLAGS = @CXXFLAGS@ @BOOST_CPPFLAGS@ @LIBBZ2_CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@ @LIBBZ2_LDFLAGS@
CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ @BOOST_CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@
LIBS = @LIBS@ \
-latomic \
@BOOST_IOSTREAMS_LIB@ \
@BOOST_DATE_TIME_LIB@
prefix = @prefix@
prefix = $(DESTDIR)@prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
includedir = @includedir@
datarootdir = @datarootdir@
datadir = @datadir@
docdir = @docdir@
pkgconfigdir = $(libdir)/pkgconfig
CCP4DIR = @CCP4@
CLIBD = $(CCP4DIR:%=%/lib/data)
CACHE_DIR = /var/cache/libcifpp
CACHE_DIR = $(DESTDIR)/var/cache/libcifpp
CRON_DIR = $(DESTDIR)/etc/cron.weekly
DEFINES += CACHE_DIR='"$(CACHE_DIR)"'
@@ -159,6 +162,7 @@ else
src/revision.hpp:
@ echo 'const char kRevision[] = R"(' > $@
@ echo libcifpp-version: $(VERSION) >> $@
@ echo Date: $$(date --iso-8601) >> $@
@ echo ')";' >> $@
endif
@@ -190,6 +194,7 @@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR)
.PHONY: clean
clean:
rm -rf .libs $(OBJDIR)/* $(LIB_TARGET)
rm -f $(TESTS:%=test/%-test)
.PHONY: distclean
distclean: clean
@@ -207,7 +212,7 @@ $(1)_OBJECTS = $$(OBJDIR)/$(1)-test.o
test/$(1)-test: $(LIB_TARGET) $$($(1)_OBJECTS)
@ echo ">>> building $(1)-test"
$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp $(LIBS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp $(LIBS)
.PHONY: $(1)-test
$(1)-test: test/$(1)-test
@@ -243,13 +248,13 @@ HEADERS = \
install: lib
install -d $(libdir)
$(LIBTOOL) --mode=install install $(LIB_TARGET) $(libdir)
install -d $(CACHE_DIR)
install -d $(datadir)/libcifpp
for d in isomers.txt dictionaries/mmcif_ddl.dic dictionaries/mmcif_pdbx_v50.dic; do \
install -m644 rsrc/$$d $(CACHE_DIR)/; \
install -m644 rsrc/$$d $(datadir)/libcifpp; \
done
if [ -d /etc/cron.weekly ]; then \
install -m755 tools/update-dictionaries-script /etc/cron.weekly/libcifpp; \
fi
gzip -f $(datadir)/libcifpp/*
install -d $(CRON_DIR)
install -m755 tools/update-dictionary-script $(CRON_DIR)/libcifpp
install -d $(includedir)/cif++
for f in $(HEADERS); do install include/cif++/$$f $(includedir)/cif++/$$f; done
install -d $(pkgconfigdir)

6
changelog Normal file
View File

@@ -0,0 +1,6 @@
Version 1.0.1
- Changed the way resources are looked up, local dir first,
then /var/cache and finally compiled in resources (with mrc).
Version 1.0.0
- First public release

209
configure vendored
View File

@@ -635,10 +635,6 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
LIBBZ2_LDFLAGS
LIBBZ2_CPPFLAGS
LIBZ_LDFLAGS
LIBZ_CPPFLAGS
BOOST_DATE_TIME_LIB
BOOST_IOSTREAMS_LIB
BOOST_LDFLAGS
@@ -647,6 +643,7 @@ SET_MAKE
PKG_CONFIG
CCP4
UPDATE_REVISION
USE_RSRC
DEBUG
LIBCIF_SEMANTIC_VERSION
LIBCIF_LT_VERSION
@@ -749,6 +746,7 @@ with_aix_soname
with_gnu_ld
with_sysroot
enable_libtool_lock
enable_revision
with_boost
with_boost_libdir
with_boost_iostreams
@@ -768,12 +766,7 @@ CC
CFLAGS
LT_SYS_LIBRARY_PATH
DEBUG
UPDATE_REVISION
CCP4
LIBZ_CPPFLAGS
LIBZ_LDFLAGS
LIBBZ2_CPPFLAGS
LIBBZ2_LDFLAGS'
CCP4'
# Initialize some variables set by options.
@@ -1403,6 +1396,7 @@ Optional Features:
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-revision Create a build number as revision
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1449,17 +1443,7 @@ Some influential environment variables:
LT_SYS_LIBRARY_PATH
User-defined run-time library search path.
DEBUG Build a debug version of the library
UPDATE_REVISION
Update the revision.hpp file
CCP4 The location where CCP4 is installed
LIBZ_CPPFLAGS
C preprocessor flags for LIBZ headers
LIBZ_LDFLAGS
linker flags for LIBZ libraries
LIBBZ2_CPPFLAGS
C preprocessor flags for LIBBZ2 headers
LIBBZ2_LDFLAGS
linker flags for LIBBZ2 libraries
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -16091,6 +16075,28 @@ LIBCIF_SEMANTIC_VERSION=1.0.0
# Check whether --enable-revision was given.
if test "${enable_revision+set}" = set; then :
enableval=$enable_revision;
fi
if test "x$enable_revision" != "xyes" ; then :
UPDATE_REVISION=1
fi
case $host in #(
*-apple-*) :
USE_RSRC=0 ;; #(
*) :
USE_RSRC=1
;;
esac
UPDATE_REVISION=$UPDATE_REVISION
@@ -17097,169 +17103,6 @@ fi
fi
if ${ax_cv_have_LIBZ+:} false; then :
$as_echo_n "(cached) " >&6
else
save_CPPFLAGS="$CPPFLAGS"
save_LDFLAGS="$LDFLAGS"
save_LIBS="$LIBS"
if test "x$LIBZ_CPPFLAGS" != "x"; then :
CPPFLAGS="$CPPFLAGS $LIBZ_CPPFLAGS"
fi
if test "x$LIBZ_LDFLAGS" != "x"; then :
LDFLAGS="$LDFLAGS $LIBZ_LDFLAGS"
fi
ac_fn_cxx_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
if test "x$ac_cv_header_zlib_h" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lz" >&5
$as_echo_n "checking for main in -lz... " >&6; }
if ${ac_cv_lib_z_main+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lz $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
return main ();
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
ac_cv_lib_z_main=yes
else
ac_cv_lib_z_main=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_main" >&5
$as_echo "$ac_cv_lib_z_main" >&6; }
if test "x$ac_cv_lib_z_main" = xyes; then :
ax_cv_have_LIBZ=yes
else
ax_cv_have_LIBZ=no
fi
else
ax_cv_have_LIBZ=no
fi
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
fi
if test "$ax_cv_have_LIBZ" = "yes"; then :
$as_echo "#define HAVE_LIBZ 1" >>confdefs.h
else
as_fn_error $? "libz not found - compressed files not supported" "$LINENO" 5
fi
if ${ax_cv_have_LIBBZ2+:} false; then :
$as_echo_n "(cached) " >&6
else
save_CPPFLAGS="$CPPFLAGS"
save_LDFLAGS="$LDFLAGS"
save_LIBS="$LIBS"
if test "x$LIBBZ2_CPPFLAGS" != "x"; then :
CPPFLAGS="$CPPFLAGS $LIBBZ2_CPPFLAGS"
fi
if test "x$LIBBZ2_LDFLAGS" != "x"; then :
LDFLAGS="$LDFLAGS $LIBBZ2_LDFLAGS"
fi
ac_fn_cxx_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default"
if test "x$ac_cv_header_bzlib_h" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lbz2" >&5
$as_echo_n "checking for main in -lbz2... " >&6; }
if ${ac_cv_lib_bz2_main+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lbz2 $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
return main ();
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
ac_cv_lib_bz2_main=yes
else
ac_cv_lib_bz2_main=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_main" >&5
$as_echo "$ac_cv_lib_bz2_main" >&6; }
if test "x$ac_cv_lib_bz2_main" = xyes; then :
ax_cv_have_LIBBZ2=yes
else
ax_cv_have_LIBBZ2=no
fi
else
ax_cv_have_LIBBZ2=no
fi
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
fi
if test "$ax_cv_have_LIBBZ2" = "yes"; then :
$as_echo "#define HAVE_LIBBZ2 1" >>confdefs.h
else
as_fn_error $? "libbz2 not found - compressed files not supported" "$LINENO" 5
fi
ac_config_files="$ac_config_files GNUmakefile libcifpp.pc"
cat >confcache <<\_ACEOF

View File

@@ -74,7 +74,23 @@ AC_SUBST(LIBCIF_SEMANTIC_VERSION)
AC_ARG_VAR([DEBUG], [Build a debug version of the library])
AC_ARG_VAR([UPDATE_REVISION], [Update the revision.hpp file])
dnl revision numbering is something used internally at the NKI
AC_ARG_ENABLE(
revision,
[AS_HELP_STRING([--enable-revision], [Create a build number as revision])])
AS_IF([test "x$enable_revision" != "xyes" ], [
UPDATE_REVISION=1
])
dnl disable resources on macOS
AS_CASE([$host],
[*-apple-*], [USE_RSRC=0],
[USE_RSRC=1]
)
AC_SUBST([USE_RSRC])
AC_SUBST([UPDATE_REVISION], [$UPDATE_REVISION])
AC_ARG_VAR([CCP4], [The location where CCP4 is installed])
@@ -93,10 +109,5 @@ AX_BOOST_BASE([1.71], [], [
AX_BOOST_IOSTREAMS
AX_BOOST_DATE_TIME
AX_CHECK_LIBRARY([LIBZ], [zlib.h], [z], [],
[AC_MSG_ERROR([libz not found - compressed files not supported])])
AX_CHECK_LIBRARY([LIBBZ2], [bzlib.h], [bz2], [],
[AC_MSG_ERROR([libbz2 not found - compressed files not supported])])
AC_OUTPUT([GNUmakefile
libcifpp.pc])

View File

@@ -33,6 +33,8 @@
#include <cassert>
#include <memory>
#include <list>
#include <iostream>
#include <filesystem>
#include <unistd.h>
@@ -190,6 +192,11 @@ class Progress
struct ProgressImpl* mImpl;
};
// --------------------------------------------------------------------
// Resources
std::unique_ptr<std::istream> loadResource(std::filesystem::path name);
}

View File

@@ -21,12 +21,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if LIBBZ2 is found */
#undef HAVE_LIBBZ2
/* Define to 1 if LIBZ is found */
#undef HAVE_LIBZ
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

View File

@@ -77,7 +77,7 @@ struct SymopData
friend struct SymopDataBlock;
const uint64_t kPackMask = (~0UL >> (64-36));
const uint64_t kPackMask = (~0ULL >> (64-36));
SymopData(uint64_t v)
: m_packed(v bitand kPackMask) {}

View File

@@ -3093,39 +3093,16 @@ void File::loadDictionary()
void File::loadDictionary(const char* dict)
{
for (;;)
{
fs::path name(dict);
try
{
if (fs::exists(name))
{
std::ifstream is(name);
loadDictionary(is);
break;
}
}
catch (...) {}
fs::path dict_name(dict);
fs::path datadir = CACHE_DIR;
if (not fs::is_directory(datadir))
throw std::runtime_error("Could not find dictionary " + name.string() + " and " CACHE_DIR " also does not exist");
auto data = loadResource(dict);
if (not data and dict_name.extension().string() != ".dic")
data = loadResource(dict_name.parent_path() / (dict_name.filename().string() + ".dic"));
name = datadir / name;
if (not fs::exists(name) and name.extension().string() != ".dic")
name = datadir / (name.string() + ".dic");
if (fs::exists(name))
{
std::ifstream is(name);
loadDictionary(is);
break;
}
throw std::runtime_error("Dictionary not found or defined (" + name.string() + ")");
}
if (not data)
throw std::runtime_error("Dictionary not found or defined (" + dict_name.string() + ")");
loadDictionary(*data);
}
void File::loadDictionary(std::istream& is)

View File

@@ -748,3 +748,449 @@ void Progress::message(const std::string& inMessage)
}
}
#if USE_RSRC
// --------------------------------------------------------------------
//
// Try to find a named resource. Can be either a local file with this name,
// a file located in our cache directory or a resource linked in with mrc.
//
// We have a special, private version of mrsrc here. To be able to create
// shared libraries and still be able to link when there's no mrc used.
namespace mrsrc
{
/// \brief Internal data structure as generated by mrc
struct rsrc_imp
{
unsigned int m_next;
unsigned int m_child;
unsigned int m_name;
unsigned int m_size;
unsigned int m_data;
};
}
extern const __attribute__((weak)) mrsrc::rsrc_imp gResourceIndex[];
extern const __attribute__((weak)) char gResourceData[];
extern const __attribute__((weak)) char gResourceName[];
namespace mrsrc
{
class rsrc_data
{
public:
static rsrc_data& instance()
{
static rsrc_data s_instance;
return s_instance;
}
const rsrc_imp* index() const { return m_index; }
const char* data(unsigned int offset) const
{
return m_data + offset;
}
const char* name(unsigned int offset) const
{
return m_name + offset;
}
private:
rsrc_data()
{
if (gResourceIndex and gResourceIndex and gResourceName)
{
m_index = gResourceIndex;
m_data = gResourceData;
m_name = gResourceName;
}
}
rsrc_imp m_dummy = {};
const rsrc_imp* m_index = &m_dummy;
const char* m_data = "";
const char* m_name = "";
};
/// \brief Class mrsrc::rsrc contains a pointer to the data in the
/// resource, as well as offering an iterator interface to its
/// children.
class rsrc
{
public:
rsrc() : m_impl(rsrc_data::instance().index()) {}
rsrc(const rsrc& other)
: m_impl(other.m_impl) {}
rsrc& operator=(const rsrc& other)
{
m_impl = other.m_impl;
return *this;
}
rsrc(std::filesystem::path path);
std::string name() const { return rsrc_data::instance().name(m_impl->m_name); }
const char* data() const { return rsrc_data::instance().data(m_impl->m_data); }
unsigned long size() const { return m_impl->m_size; }
explicit operator bool() const { return m_impl != NULL and m_impl->m_size > 0; }
template<typename RSRC>
class iterator_t
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = RSRC;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
iterator_t(const rsrc_imp* cur)
: m_cur(cur) {}
iterator_t(const iterator_t& i)
: m_cur(i.m_cur)
{
}
iterator_t& operator=(const iterator_t& i)
{
m_cur = i.m_cur;
return *this;
}
reference operator*() { return m_cur; }
pointer operator->() { return& m_cur; }
iterator_t& operator++()
{
if (m_cur.m_impl->m_next)
m_cur.m_impl = rsrc_data::instance().index() + m_cur.m_impl->m_next;
else
m_cur.m_impl = nullptr;
return *this;
}
iterator_t operator++(int)
{
auto tmp(*this);
this->operator++();
return tmp;
}
bool operator==(const iterator_t& rhs) const { return m_cur.m_impl == rhs.m_cur.m_impl; }
bool operator!=(const iterator_t& rhs) const { return m_cur.m_impl != rhs.m_cur.m_impl; }
private:
value_type m_cur;
};
using iterator = iterator_t<rsrc>;
iterator begin() const
{
const rsrc_imp* impl = nullptr;
if (m_impl and m_impl->m_child)
impl = rsrc_data::instance().index() + m_impl->m_child;
return iterator(impl);
}
iterator end() const
{
return iterator(nullptr);
}
private:
rsrc(const rsrc_imp* imp)
: m_impl(imp) {}
const rsrc_imp *m_impl;
};
inline rsrc::rsrc(std::filesystem::path p)
{
m_impl = rsrc_data::instance().index();
// using std::filesytem::path would have been natural here of course...
auto pb = p.begin();
auto pe = p.end();
while (m_impl != nullptr and pb != pe)
{
auto name = *pb++;
const rsrc_imp* impl = nullptr;
for (rsrc child: *this)
{
if (child.name() == name)
{
impl = child.m_impl;
break;
}
}
m_impl = impl;
}
if (pb != pe) // not found
m_impl = nullptr;
}
// --------------------------------------------------------------------
template<typename CharT, typename Traits>
class basic_streambuf : public std::basic_streambuf<CharT, Traits>
{
public:
typedef CharT char_type;
typedef Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
/// \brief constructor taking a \a path to the resource in memory
basic_streambuf(const std::string& path)
: m_rsrc(path)
{
init();
}
/// \brief constructor taking a \a rsrc
basic_streambuf(const rsrc& rsrc)
: m_rsrc(rsrc)
{
init();
}
basic_streambuf(const basic_streambuf&) = delete;
basic_streambuf(basic_streambuf&& rhs)
: basic_streambuf(rhs.m_rsrc)
{
}
basic_streambuf& operator=(const basic_streambuf&) = delete;
basic_streambuf& operator=(basic_streambuf&& rhs)
{
swap(rhs);
return *this;
}
void swap(basic_streambuf& rhs)
{
std::swap(m_begin, rhs.m_begin);
std::swap(m_end, rhs.m_end);
std::swap(m_current, rhs.m_current);
}
private:
void init()
{
m_begin = reinterpret_cast<const char_type*>(m_rsrc.data());
m_end = reinterpret_cast<const char_type*>(m_rsrc.data() + m_rsrc.size());
m_current = m_begin;
}
int_type underflow()
{
if (m_current == m_end)
return traits_type::eof();
return traits_type::to_int_type(*m_current);
}
int_type uflow()
{
if (m_current == m_end)
return traits_type::eof();
return traits_type::to_int_type(*m_current++);
}
int_type pbackfail(int_type ch)
{
if (m_current == m_begin or (ch != traits_type::eof() and ch != m_current[-1]))
return traits_type::eof();
return traits_type::to_int_type(*--m_current);
}
std::streamsize showmanyc()
{
assert(std::less_equal<const char*>()(m_current, m_end));
return m_end - m_current;
}
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
{
switch (dir)
{
case std::ios_base::beg:
m_current = m_begin + off;
break;
case std::ios_base::end:
m_current = m_end + off;
break;
case std::ios_base::cur:
m_current += off;
break;
default:
break;
}
if (m_current < m_begin)
m_current = m_begin;
if (m_current > m_end)
m_current = m_end;
return m_current - m_begin;
}
pos_type seekpos(pos_type pos, std::ios_base::openmode which)
{
m_current = m_begin + pos;
if (m_current < m_begin)
m_current = m_begin;
if (m_current > m_end)
m_current = m_end;
return m_current - m_begin;
}
private:
rsrc m_rsrc;
const char_type* m_begin;
const char_type* m_end;
const char_type* m_current;
};
using streambuf = basic_streambuf<char, std::char_traits<char>>;
// --------------------------------------------------------------------
// class mrsrc::istream
template<typename CharT, typename Traits>
class basic_istream : public std::basic_istream<CharT, Traits>
{
public:
typedef CharT char_type;
typedef Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
private:
using __streambuf_type = basic_streambuf<CharT, Traits>;
using __istream_type = std::basic_istream<CharT, Traits>;
__streambuf_type m_buffer;
public:
basic_istream(const std::string& path)
: __istream_type(&m_buffer)
, m_buffer(path)
{
this->init(&m_buffer);
}
basic_istream(rsrc& resource)
: __istream_type(&m_buffer)
, m_buffer(resource)\
{
this->init(&m_buffer);
}
basic_istream(const basic_istream&) = delete;
basic_istream(basic_istream&& rhs)
: __istream_type(std::move(rhs))
, m_buffer(std::move(rhs.m_buffer))
{
__istream_type::set_rdbuf(&m_buffer);
}
basic_istream& operator=(const basic_istream& ) = delete;
basic_istream& operator=(basic_istream&& rhs)
{
__istream_type::operator=(std::move(rhs));
m_buffer = std::move(rhs.m_buffer);
return *this;
}
void swap(basic_istream& rhs)
{
__istream_type::swap(rhs);
m_buffer.swap(rhs.m_buffer);
}
__streambuf_type* rdbuf() const
{
return const_cast<__streambuf_type*>(&m_buffer);
}
};
using istream = basic_istream<char, std::char_traits<char>>;
}
#endif
// --------------------------------------------------------------------
namespace cif
{
// --------------------------------------------------------------------
std::unique_ptr<std::istream> loadResource(std::filesystem::path name)
{
std::unique_ptr<std::istream> result;
fs::path p = name;
if (not fs::exists(p))
p = fs::path(CACHE_DIR) / p;
if (fs::exists(p))
{
std::unique_ptr<std::ifstream> file(new std::ifstream(p));
if (file->is_open())
result.reset(file.release());
}
#if USE_RSRC
if (not result)
{
mrsrc::rsrc rsrc(name);
if (rsrc)
result.reset(new mrsrc::istream(rsrc));
}
#endif
return result;
}
}

View File

@@ -2,6 +2,11 @@
set -e
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
# create cache directory if it doesn't exist
if ! [ -d /var/cache/libcifpp ]; then
install -d -m755 /var/cache/libcifpp