├── hiredis
├── TODO
├── fmacros.h
├── COPYING
├── util.h
├── net.h
├── sds.h
├── async.h
├── net.c
└── hiredis.h
├── sample-images
├── screenshot-interlaced.png
└── screenshot-noninterlaced.png
├── .gitignore
├── png-db.xcodeproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── DbDefBackend.h
├── kyotocabinet
├── kyotocabinet.pc.in
├── README
├── kcdbext.cc
├── kcplantdb.cc
├── kcstashdb.cc
├── kccachedb.cc
├── kcdirdb.cc
├── kchashdb.cc
├── kcmap.cc
├── kcpolydb.cc
├── kcprotodb.cc
├── kcdb.cc
├── kyotocabinet.def
├── kccompare.cc
├── kcregex.h
├── kccommon.h
├── kcregex.cc
├── myconf.h
├── kccompare.h
├── kcutil.cc
├── kyotocabinet.idl
├── cmdcommon.h
└── kccompress.cc
├── Crc.h
├── DbFsBackend.h
├── StaticAssert.h
├── stats.sh
├── Sha1.h
├── Return.h
├── test-png-dumpchunks.cpp
├── StringUtils.h
├── DbRedisBackend.h
├── DbKyotoBackend.h
├── StringUtils.cpp
├── Mutex.h
├── DbFileBackend.h
├── Endianess.h
├── DbPng.h
├── db-extract-file.cpp
├── db-push.cpp
├── test-png-reader.cpp
├── db-list-dir.cpp
├── pnginfo.cpp
├── Utils.h
├── FileUtils.cpp
├── db-push-dir.cpp
├── compile.sh
├── FileUtils.h
├── Png.h
├── Db.cpp
├── Db.h
├── Crc.cpp
├── DbFsBackend.cpp
├── SmartPointer.h
├── DbKyotoBackend.cpp
├── README.md
├── DbRedisBackend.cpp
├── DbPng.cpp
├── db-fuse.cpp
└── Sha1.cpp
/hiredis/TODO:
--------------------------------------------------------------------------------
1 | - add redisCommandVector()
2 | - add support for pipelining
3 |
--------------------------------------------------------------------------------
/sample-images/screenshot-interlaced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/albertz/png-db/HEAD/sample-images/screenshot-interlaced.png
--------------------------------------------------------------------------------
/sample-images/screenshot-noninterlaced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/albertz/png-db/HEAD/sample-images/screenshot-noninterlaced.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.bin
3 | *.dSYM
4 | *.deps
5 | *.o
6 | bin
7 | build
8 | db
9 | db.kch
10 | db.pngdb
11 | xcuserdata
12 |
--------------------------------------------------------------------------------
/png-db.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DbDefBackend.h:
--------------------------------------------------------------------------------
1 | /* DB default backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ_DBDEFBACKEND_H__
7 | #define __AZ_DBDEFBACKEND_H__
8 |
9 | #include "DbKyotoBackend.h"
10 |
11 | typedef DbKyotoBackend DbDefBackend;
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/hiredis/fmacros.h:
--------------------------------------------------------------------------------
1 | #ifndef _REDIS_FMACRO_H
2 | #define _REDIS_FMACRO_H
3 |
4 | #define _BSD_SOURCE
5 |
6 | #ifdef __linux__
7 | #define _XOPEN_SOURCE 700
8 | #else
9 | #define _XOPEN_SOURCE
10 | #endif
11 |
12 | #define _LARGEFILE_SOURCE
13 | #define _FILE_OFFSET_BITS 64
14 |
15 | #endif
16 |
--------------------------------------------------------------------------------
/kyotocabinet/kyotocabinet.pc.in:
--------------------------------------------------------------------------------
1 | prefix=@prefix@
2 | exec_prefix=@exec_prefix@
3 | datarootdir = @datarootdir@
4 | bindir=@bindir@
5 | libdir=@libdir@
6 | libexecdir=@libexecdir@
7 | includedir=@includedir@
8 | datadir=@datadir@
9 |
10 | Name: Kyoto Cabinet
11 | Description: a straightforward implementation of DBM
12 | Version: @PACKAGE_VERSION@
13 | Libs: -L${libdir} -lkyotocabinet
14 | Libs.private: @LIBS@
15 | Cflags: -I${includedir}
16 |
--------------------------------------------------------------------------------
/Crc.h:
--------------------------------------------------------------------------------
1 | /* calculate CRC
2 | * based on http://www.w3.org/TR/PNG/#D-CRCAppendix
3 | * by Albert Zeyer, 2011
4 | * code public domain
5 | */
6 |
7 | #ifndef __AZ__CRC_H__
8 | #define __AZ__CRC_H__
9 |
10 | #include
11 |
12 | uint32_t update_crc(uint32_t crc, const char *buf, size_t len);
13 | uint32_t calc_crc(const char *buf, size_t len);
14 | uint32_t calc_crc(const std::string& s);
15 | uint32_t calc_crc(const std::string& s1, const std::string& s2);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/DbFsBackend.h:
--------------------------------------------------------------------------------
1 | /* filesystem DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DBFSBACKEND_H__
7 | #define __AZ__DBFSBACKEND_H__
8 |
9 | #include "Db.h"
10 |
11 | struct DbFsBackend : DbIntf {
12 | std::string baseDir;
13 |
14 | DbFsBackend(const std::string& d = "db") : baseDir(d) {}
15 | Return init() { return true; }
16 | Return push(/*out*/ DbEntryId& id, const DbEntry& entry);
17 | Return get(/*out*/ DbEntry& entry, const DbEntryId& id);
18 | };
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/StaticAssert.h:
--------------------------------------------------------------------------------
1 | /*
2 | * StaticAssert.h
3 | * OpenLieroX
4 | *
5 | * Created by Albert Zeyer on 30.03.09.
6 | * code under LGPL
7 | *
8 | */
9 |
10 | #ifndef __OLX__STATICASSERT_H__
11 | #define __OLX__STATICASSERT_H__
12 |
13 | template class static_assert_failure;
14 | template <> class static_assert_failure { char foo; };
15 | template class static_assert_test{};
16 |
17 | #define static_assert(X, desc) \
18 | typedef static_assert_test< (int)sizeof(static_assert_failure< (bool)(X) >) > static_assert_typedef_##desc;
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/stats.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | DBFILE=db.kch
4 | SRCDIR="$HOME/screenies"
5 | [ "$1" != "" ] && SCRDIR="$1"
6 |
7 | zmodload zsh/stat
8 | sizesum=0
9 | numfiles=0
10 |
11 | ./bin/db-list-dir | while read l; do
12 | [[ "$l" =~ "^file: /(.*), .*, .*$" ]] && {
13 | fn="$match"
14 | size="$(stat -L +size $SRCDIR/$fn)"
15 | sizesum=$(($sizesum + $size))
16 | numfiles=$(($numfiles + 1))
17 | }
18 | done
19 |
20 | dbsize="$(stat -L +size $DBFILE)"
21 |
22 | echo "num files: $numfiles"
23 | echo "fs size: $(($sizesum / 1024 / 1024.0)) MB"
24 | echo "db size: $(($dbsize / 1024 / 1024.0)) MB"
25 |
--------------------------------------------------------------------------------
/Sha1.h:
--------------------------------------------------------------------------------
1 | /* public api for steve reid's public domain SHA-1 implementation */
2 | /* this file is in the public domain */
3 |
4 | #ifndef __SHA1_H
5 | #define __SHA1_H
6 |
7 | #include
8 | #include
9 |
10 | #define SHA1_DIGEST_SIZE 20
11 |
12 | struct Sha1Context {
13 | uint32_t state[5];
14 | uint32_t count[2];
15 | uint8_t buffer[64];
16 |
17 | Sha1Context();
18 | void update(const char* data, size_t len);
19 | std::string final();
20 | };
21 |
22 | std::string calc_sha1(const char* data, size_t s);
23 |
24 | inline std::string calc_sha1(const std::string& data) {
25 | return calc_sha1(&data[0], data.size());
26 | }
27 |
28 | #endif /* __SHA1_H */
29 |
--------------------------------------------------------------------------------
/Return.h:
--------------------------------------------------------------------------------
1 | /* Return value class
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__RETURN_H__
7 | #define __AZ__RETURN_H__
8 |
9 | #include
10 |
11 | struct Return {
12 | bool success;
13 | std::string errmsg;
14 |
15 | Return(bool s = true) : success(s) {}
16 | Return(const char* errm) : success(false), errmsg(errm) {}
17 | Return(const std::string& errm) : success(false), errmsg(errm) {}
18 | Return(const Return& r, const std::string& extmsg) : success(false) {
19 | if(r) errmsg = extmsg;
20 | else errmsg = extmsg + ": " + r.errmsg;
21 | }
22 | operator bool() const { return success; }
23 | };
24 |
25 | #define ASSERT(x) { Return ___r = (x); if(!___r) return ___r; }
26 | #define ASSERT_EXT(x, msg) { Return ___r = (x); if(!___r) return Return(___r, msg); }
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/test-png-dumpchunks.cpp:
--------------------------------------------------------------------------------
1 | /* demo for PNG chunk reading
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 |
8 | #include
9 | #include
10 | using namespace std;
11 |
12 | int main(int argc, char** argv) {
13 | if(argc <= 1) {
14 | cout << "please give me a filename" << endl;
15 | return 1;
16 | }
17 |
18 | FILE* f = fopen(argv[1], "rb");
19 | if(Return r = png_read_sig(f))
20 | cout << "* signature: OK" << endl;
21 | else {
22 | cout << "* signature: " << r.errmsg << endl;
23 | return 1;
24 | }
25 |
26 | while(!feof(f) && !ferror(f)) {
27 | PngChunk chunk;
28 | Return r = png_read_chunk(f, chunk);
29 | if(!r) {
30 | cout << "* chunk: " << r.errmsg << endl;
31 | return 1;
32 | }
33 | cout << "* chunk: " << chunk.type << ", len=" << chunk.data.size() << endl;
34 | }
35 |
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/StringUtils.h:
--------------------------------------------------------------------------------
1 | /* String utils
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__STRINGUTILS_H__
7 | #define __AZ__STRINGUTILS_H__
8 |
9 | #include
10 | #include
11 | #include "Endianess.h"
12 |
13 | std::string hexString(char c);
14 | std::string hexString(const std::string& rawData);
15 | inline static std::string hexString(const char* s) { return hexString(std::string(s)); }
16 |
17 | template
18 | std::string rawString(T val) {
19 | BEndianSwap(val);
20 | return std::string((char*)&val, sizeof(T));
21 | }
22 |
23 | template
24 | std::string hexString(T val) {
25 | return hexString(rawString(val));
26 | }
27 |
28 | template
29 | T valueFromRaw(const char* s) {
30 | T val = *(const T*)s;
31 | BEndianSwap(val);
32 | return val;
33 | }
34 |
35 | size_t findLastPathSep(const std::string& path);
36 | std::string baseFilename(const std::string& filename);
37 | std::string dirName(const std::string& filename);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/DbRedisBackend.h:
--------------------------------------------------------------------------------
1 | /* Redis DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DBREDISBACKEND_H__
7 | #define __AZ__DBREDISBACKEND_H__
8 |
9 | #include "Db.h"
10 | #include "hiredis/hiredis.h"
11 |
12 | struct DbRedisBackend : DbIntf {
13 | std::string prefix;
14 | std::string host;
15 | int port;
16 | redisContext* redis;
17 |
18 | DbRedisBackend(const std::string& _prefix = "db.", const std::string& _host = "127.0.0.1", int _port = 6379)
19 | : prefix(_prefix), host(_host), port(_port), redis(NULL) {}
20 | ~DbRedisBackend();
21 | Return init();
22 | Return push(/*out*/ DbEntryId& id, const DbEntry& entry);
23 | Return get(/*out*/ DbEntry& entry, const DbEntryId& id);
24 | Return pushToDir(const std::string& path, const DbDirEntry& dirEntry);
25 | Return getDir(/*out*/ std::list& dirList, const std::string& path);
26 | Return setFileRef(/*can be empty*/ const DbEntryId& id, const std::string& path);
27 | Return getFileRef(/*out (can be empty)*/ DbEntryId& id, const std::string& path);
28 | };
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/DbKyotoBackend.h:
--------------------------------------------------------------------------------
1 | /* KyotoCabinet DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DBKYOTOBACKEND_H__
7 | #define __AZ__DBKYOTOBACKEND_H__
8 |
9 | #include "Db.h"
10 | #include "kyotocabinet/kcpolydb.h"
11 |
12 | struct DbKyotoBackend : DbIntf {
13 | kyotocabinet::PolyDB db;
14 | std::string filename;
15 | bool readonly;
16 |
17 | DbKyotoBackend(const std::string& dbfilename = "db.kch", bool ro = false) : filename(dbfilename), readonly(ro) {}
18 | ~DbKyotoBackend();
19 | Return setReadOnly(bool ro) { readonly = ro; return true; }
20 | Return init();
21 | Return push(/*out*/ DbEntryId& id, const DbEntry& entry);
22 | Return get(/*out*/ DbEntry& entry, const DbEntryId& id);
23 | Return pushToDir(const std::string& path, const DbDirEntry& dirEntry);
24 | Return getDir(/*out*/ std::list& dirList, const std::string& path);
25 | Return setFileRef(/*can be empty*/ const DbEntryId& id, const std::string& path);
26 | Return getFileRef(/*out (can be empty)*/ DbEntryId& id, const std::string& path);
27 | };
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/kyotocabinet/README:
--------------------------------------------------------------------------------
1 | ================================================================
2 | Kyoto Cabinet: a straightforward implementation of DBM
3 | Copyright (C) 2009-2011 FAL Labs
4 | ================================================================
5 |
6 |
7 | Please read the following documents with a WWW browser.
8 | How to install Kyoto Cabinet is explained in the specification.
9 |
10 | README - this file
11 | COPYING - license
12 | ChangeLog - history of enhancement
13 | doc/index.html - index of documents
14 |
15 |
16 | Contents of the directory tree is below.
17 |
18 | ./ - sources of Kyoto Cabinet
19 | ./doc/ - manuals and specifications
20 | ./man/ - manuals for nroff
21 | ./example/ - sample code for tutorial
22 | ./lab/ - for test and experiment
23 |
24 |
25 | Kyoto Cabinet is released under the terms of the GNU General Public
26 | License version 3. See the file `COPYING' for details.
27 |
28 | Kyoto Cabinet was written by FAL Labs. You can contact the author
29 | by e-mail to `info@fallabs.com'.
30 |
31 |
32 | Thanks.
33 |
34 |
35 |
36 | == END OF FILE ==
37 |
--------------------------------------------------------------------------------
/StringUtils.cpp:
--------------------------------------------------------------------------------
1 | /* String utils
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "StringUtils.h"
7 | #include
8 |
9 | std::string hexString(char c) {
10 | char buf[3];
11 | sprintf(buf, "%02X", (int)(unsigned char)c);
12 | return buf;
13 | }
14 |
15 | std::string hexString(const std::string& rawData) {
16 | std::string ret;
17 | for(size_t i = 0; i < rawData.size(); ++i)
18 | ret += hexString(rawData[i]);
19 | return ret;
20 | }
21 |
22 | size_t findLastPathSep(const std::string& path) {
23 | size_t slash = path.rfind('\\');
24 | size_t slash2 = path.rfind('/');
25 | if(slash == std::string::npos)
26 | slash = slash2;
27 | else if(slash2 != std::string::npos)
28 | slash = std::max(slash, slash2);
29 | return slash;
30 | }
31 |
32 | std::string baseFilename(const std::string& filename) {
33 | size_t p = findLastPathSep(filename);
34 | if(p == std::string::npos) return filename;
35 | return filename.substr(p+1);
36 | }
37 |
38 | std::string dirName(const std::string& filename) {
39 | size_t p = findLastPathSep(filename);
40 | if(p == std::string::npos) return "";
41 | return filename.substr(0, p);
42 | }
43 |
--------------------------------------------------------------------------------
/Mutex.h:
--------------------------------------------------------------------------------
1 | /* Mutex class - small wrapper around pthread
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__MUTEX_H__
7 | #define __AZ__MUTEX_H__
8 |
9 | #include "Utils.h"
10 | #include
11 |
12 | struct Mutex {
13 | pthread_mutex_t m;
14 | Mutex() { pthread_mutex_init(&m, NULL); }
15 | Mutex(const Mutex&) { pthread_mutex_init(&m, NULL); } // ignore copy constr
16 | Mutex& operator=(const Mutex&) {} // ignore assign
17 | ~Mutex() { pthread_mutex_destroy(&m); }
18 | void lock() { pthread_mutex_lock(&m); }
19 | bool trylock() { if(pthread_mutex_trylock(&m) == 0) return true; return false; }
20 | void unlock() { pthread_mutex_unlock(&m); }
21 | };
22 |
23 | struct ScopedLock : DontCopyTag {
24 | Mutex& mutex;
25 | ScopedLock(Mutex& m) : mutex(m) { mutex.lock(); }
26 | ~ScopedLock() { mutex.unlock(); }
27 | };
28 |
29 | struct ScopedTryLock : DontCopyTag {
30 | Mutex& mutex;
31 | bool islocked;
32 | ScopedTryLock(Mutex& m) : mutex(m), islocked(false) { islocked = mutex.trylock(); }
33 | ~ScopedTryLock() { if(islocked) { mutex.unlock(); islocked = false; } }
34 | operator bool() const { return islocked; }
35 | };
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/DbFileBackend.h:
--------------------------------------------------------------------------------
1 | /* single raw file DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DBFILEBACKEND_H__
7 | #define __AZ__DBFILEBACKEND_H__
8 |
9 | #include "Db.h"
10 | #include "Mutex.h"
11 |
12 | struct DbFile_TreeChunk;
13 |
14 | struct DbFileBackend : DbIntf {
15 | Mutex mutex;
16 | FILE* file;
17 | DbFile_TreeChunk* rootChunk;
18 | size_t fileSize;
19 | std::string filename;
20 | bool readonly;
21 |
22 | DbFileBackend(const std::string& dbfilename = "db.pngdb", bool ro = false)
23 | : file(NULL), rootChunk(NULL), fileSize(0), filename(dbfilename), readonly(ro) {}
24 | ~DbFileBackend() { reset(); }
25 | void reset();
26 | Return setReadOnly(bool ro) { readonly = ro; return true; }
27 | Return init();
28 | Return push(/*out*/ DbEntryId& id, const DbEntry& entry);
29 | Return get(/*out*/ DbEntry& entry, const DbEntryId& id);
30 | Return pushToDir(const std::string& path, const DbDirEntry& dirEntry);
31 | Return getDir(/*out*/ std::list& dirList, const std::string& path);
32 | Return setFileRef(/*can be empty*/ const DbEntryId& id, const std::string& path);
33 | Return getFileRef(/*out (can be empty)*/ DbEntryId& id, const std::string& path);
34 | };
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/Endianess.h:
--------------------------------------------------------------------------------
1 | /*
2 | (from OpenLieroX)
3 |
4 | makros for endianess / swapping / conversions
5 |
6 | Code under LGPL
7 | by Albert Zeyer, Dark Charlie, 23-06-2007
8 | */
9 |
10 | #ifndef __ENDIANSWAP_H__
11 | #define __ENDIANSWAP_H__
12 |
13 | #include
14 |
15 | #if !defined(BYTE_ORDER)
16 | # error BYTE_ORDER not defined
17 | #endif
18 | #if BYTE_ORDER == LITTLE_ENDIAN
19 | # define EndianSwap(x) ;
20 | # define BEndianSwap(x) ByteSwap5(x);
21 | # define GetEndianSwapped(x) (x)
22 | #elif BYTEORDER == BIG_ENDIAN
23 | # define EndianSwap(x) ByteSwap5(x);
24 | # define BEndianSwap(x) ;
25 | # define GetEndianSwapped(x) (GetByteSwapped(x))
26 | #else
27 | # error unknown ENDIAN type
28 | #endif
29 |
30 | #include
31 | #include "StaticAssert.h"
32 |
33 | template
34 | void ByteSwap(unsigned char * b) {
35 | static_assert(n == 1 || n % 2 == 0, n_must_be_equal);
36 | for(int i = 0; i < n/2; ++i) {
37 | std::swap(b[i], b[n - i - 1]);
38 | }
39 | }
40 |
41 | template
42 | T GetByteSwapped(T b) {
43 | ByteSwap(&b);
44 | return b;
45 | }
46 |
47 | template
48 | void ByteSwap5(T& x) {
49 | ByteSwap((unsigned char*) &x);
50 | }
51 |
52 | #endif
53 |
54 |
--------------------------------------------------------------------------------
/kyotocabinet/kcdbext.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Database extension
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcdbext.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcplantdb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Plant database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcplantdb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcstashdb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Stash database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcstashdb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kccachedb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Cache hash database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kccachedb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcdirdb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Directory hash database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcdirdb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kchashdb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * File hash database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kchashdb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcmap.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Data mapping structures
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcmap.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcpolydb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Polymorphic database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcpolydb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/kyotocabinet/kcprotodb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Prototype database
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcprotodb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | // There is no implementation now.
23 |
24 |
25 | } // common namespace
26 |
27 | // END OF FILE
28 |
--------------------------------------------------------------------------------
/DbPng.h:
--------------------------------------------------------------------------------
1 | /* PNG data <-> DB interface
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DBPNG_H__
7 | #define __AZ__DBPNG_H__
8 |
9 | #include "Png.h"
10 | #include "Db.h"
11 | #include "Utils.h"
12 | #include
13 | #include
14 | #include
15 |
16 | struct DbPngEntryWriter {
17 | PngReader reader;
18 | DbIntf* db;
19 | std::list contentChunkEntries;
20 | std::list contentDataEntries;
21 | DbEntryId contentId;
22 |
23 | DbPngEntryWriter(FILE* f, DbIntf* _db) : reader(f), db(_db) {}
24 | Return next();
25 | operator bool() const { return !reader.hasFinishedReading; }
26 | };
27 |
28 | struct DbPngEntryBlockList {
29 | uint8_t blockHeight;
30 | size_t scanlineWidth;
31 | std::list blocks;
32 | DbPngEntryBlockList() : scanlineWidth(0), blockHeight(0) {}
33 | };
34 |
35 | struct DbPngEntryReader {
36 | PngWriter writer;
37 | DbIntf* db;
38 | DbEntryId contentId;
39 | std::list contentEntries;
40 | bool haveContentEntries;
41 | DbPngEntryBlockList blockList;
42 |
43 | DbPngEntryReader(WriteCallbackIntf* w, DbIntf* _db, const DbEntryId& _contentId)
44 | : writer(w), db(_db), contentId(_contentId), haveContentEntries(false) {}
45 | Return next();
46 | operator bool() const { return !writer.hasFinishedWriting; }
47 | };
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/kyotocabinet/kcdb.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Database interface
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kcdb.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | /** Special pointer for no operation. */
23 | const char* const DB::Visitor::NOP = (const char*)0;
24 |
25 | /** Special pointer to remove the record. */
26 | const char* const DB::Visitor::REMOVE = (const char*)1;
27 |
28 |
29 | } // common namespace
30 |
31 | // END OF FILE
32 |
--------------------------------------------------------------------------------
/hiredis/COPYING:
--------------------------------------------------------------------------------
1 | Copyright (c) 2006-2009, Salvatore Sanfilippo
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9 |
10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11 |
--------------------------------------------------------------------------------
/db-extract-file.cpp:
--------------------------------------------------------------------------------
1 | /* simple tool to extract a single file from the DB
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 | #include "DbDefBackend.h"
8 | #include "DbPng.h"
9 | #include "StringUtils.h"
10 | #include "FileUtils.h"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | using namespace std;
17 |
18 | Return _main(const std::string& filename) {
19 | DbDefBackend db;
20 | db.setReadOnly(true);
21 | ASSERT( db.init() );
22 |
23 | DbEntryId fileEntryId;
24 | ASSERT( db.getFileRef(fileEntryId, filename) );
25 | cout << "entry id: " << hexString(fileEntryId) << endl;
26 |
27 | std::string extract_fn = baseFilename(filename);
28 | FILE* f = fopen(extract_fn.c_str(), "wb");
29 | if(f == NULL)
30 | return "cannot open " + extract_fn;
31 |
32 | if(!fileEntryId.empty()) {
33 | FileWriteCallback writer(f);
34 | DbPngEntryReader dbPngReader(&writer, &db, fileEntryId);
35 | while(dbPngReader)
36 | ASSERT( dbPngReader.next() );
37 | }
38 |
39 | cout << "wrote " << ftell(f) << " bytes" << endl;
40 | fclose(f);
41 |
42 | return true;
43 | }
44 |
45 | int main(int argc, char** argv) {
46 | if(argc <= 1) {
47 | cerr << "please give me a filename" << endl;
48 | return 1;
49 | }
50 |
51 | std::string filename = argv[1];
52 | srandom(time(NULL));
53 | Return r = _main(filename);
54 | if(!r) {
55 | cerr << "error: " << r.errmsg << endl;
56 | return 1;
57 | }
58 |
59 | cout << "success" << endl;
60 | return 0;
61 | }
62 |
--------------------------------------------------------------------------------
/db-push.cpp:
--------------------------------------------------------------------------------
1 | /* tool to push some entry to the DB
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 | #include "DbDefBackend.h"
8 | #include "DbPng.h"
9 | #include "StringUtils.h"
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | using namespace std;
16 |
17 | Return _main(const std::string& filename) {
18 | FILE* f = fopen(filename.c_str(), "rb");
19 | if(f == NULL)
20 | return "cannot open " + filename;
21 |
22 | DbDefBackend db;
23 | ASSERT( db.init() );
24 | DbPngEntryWriter dbPngWriter(f, &db);
25 | while(dbPngWriter)
26 | ASSERT( dbPngWriter.next() );
27 |
28 | ASSERT( db.pushToDir("", DbDirEntry::File(baseFilename(filename), ftell(f))) );
29 | ASSERT( db.setFileRef(dbPngWriter.contentId, "/" + baseFilename(filename)) );
30 | fclose(f);
31 |
32 | cout << "content id: " << hexString(dbPngWriter.contentId) << endl;
33 | cout << "num content entries: " << dbPngWriter.contentChunkEntries.size() + dbPngWriter.contentDataEntries.size() << endl;
34 | cout << "db stats: push new: " << db.stats.pushNew << endl;
35 | cout << "db stats: push reuse: " << db.stats.pushReuse << endl;
36 |
37 | return true;
38 | }
39 |
40 | int main(int argc, char** argv) {
41 | if(argc <= 1) {
42 | cerr << "please give me a filename" << endl;
43 | return 1;
44 | }
45 |
46 | std::string filename = argv[1];
47 | srandom(time(NULL));
48 | Return r = _main(filename);
49 | if(!r) {
50 | cerr << "error: " << r.errmsg << endl;
51 | return 1;
52 | }
53 |
54 | cout << "success" << endl;
55 | return 0;
56 | }
57 |
--------------------------------------------------------------------------------
/test-png-reader.cpp:
--------------------------------------------------------------------------------
1 | /* demo for PNG reader
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 |
8 | #include
9 | #include
10 | using namespace std;
11 |
12 | int main(int argc, char** argv) {
13 | if(argc <= 1) {
14 | cout << "please give me a filename" << endl;
15 | return 1;
16 | }
17 |
18 | FILE* f = fopen(argv[1], "rb");
19 | PngReader reader(f);
20 | bool haveSeenHeader = false;
21 | while(!reader.hasFinishedReading) {
22 | Return r = reader.read();
23 | if(!r) {
24 | cout << "error: " << r.errmsg << endl;
25 | return 1;
26 | }
27 |
28 | if(!haveSeenHeader && reader.gotHeader) {
29 | cout << "header: width=" << reader.header.width << ", height=" << reader.header.height << endl;
30 | cout << "header: bitDepth=" << (int)reader.header.bitDepth << endl;
31 | cout << "header: colorType=" << (int)reader.header.colourType << endl;
32 | cout << "header: bytesPerPixel=" << (int)reader.header.bytesPerPixel() << endl;
33 | cout << "header: compressionMethod=" << (int)reader.header.compressionMethod << endl;
34 | cout << "header: filterMethod=" << (int)reader.header.filterMethod << endl;
35 | cout << "header: interlaceMethod=" << (int)reader.header.interlaceMethod << endl;
36 | haveSeenHeader = true;
37 | }
38 |
39 | size_t s = 0;
40 | for(std::list::iterator i = reader.scanlines.begin(); i != reader.scanlines.end(); ++i)
41 | s += i->size();
42 | cout << "at " << ftell(f) << ": got " << s << " uncompressed" << endl;
43 | }
44 |
45 | cout << "success" << endl;
46 | return 0;
47 | }
48 |
--------------------------------------------------------------------------------
/db-list-dir.cpp:
--------------------------------------------------------------------------------
1 | /* tool to list a dir from the DB
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 | #include "DbDefBackend.h"
8 | #include "DbPng.h"
9 | #include "StringUtils.h"
10 | #include "FileUtils.h"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | using namespace std;
17 |
18 | DbDefBackend* db = NULL;
19 |
20 | static Return listDir(const std::string& path) {
21 | std::list dirList;
22 | ASSERT( db->getDir(dirList, path) );
23 |
24 | for(std::list::iterator i = dirList.begin(); i != dirList.end(); ++i) {
25 | if(i->mode & S_IFREG)
26 | cout << "file: ";
27 | else if(i->mode & S_IFDIR)
28 | cout << "dir: ";
29 | else
30 | cout << hexString(i->mode) << ": ";
31 | cout << path << "/" << i->name;
32 | if(i->mode & S_IFREG) {
33 | cout << ", " << i->size << " bytes";
34 | DbEntryId id;
35 | ASSERT( db->getFileRef(id, path + "/" + i->name) );
36 | if(id.size() > 0)
37 | cout << ", ref=" << hexString(id);
38 | else
39 | cout << ", empty";
40 | }
41 | else if(i->mode & S_IFDIR)
42 | cout << "/";
43 | cout << endl;
44 | if(i->mode & S_IFDIR)
45 | ASSERT( listDir(path + "/" + i->name) );
46 | }
47 |
48 | return true;
49 | }
50 |
51 | static Return _main() {
52 | DbDefBackend dbInst;
53 | db = &dbInst;
54 | db->setReadOnly(true);
55 | ASSERT( db->init() );
56 | ASSERT( listDir("") );
57 | return true;
58 | }
59 |
60 | int main(int argc, char** argv) {
61 | srandom(time(NULL));
62 |
63 | Return r = _main();
64 | if(!r) {
65 | cerr << "error: " << r.errmsg << endl;
66 | return 1;
67 | }
68 |
69 | cout << "success" << endl;
70 | return 0;
71 | }
72 |
--------------------------------------------------------------------------------
/pnginfo.cpp:
--------------------------------------------------------------------------------
1 | /* print some PNG info/stats
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 |
8 | #include
9 | #include
10 | using namespace std;
11 |
12 | int main(int argc, char** argv) {
13 | if(argc <= 1) {
14 | cerr << "please give me a filename" << endl;
15 | return 1;
16 | }
17 |
18 | FILE* f = fopen(argv[1], "rb");
19 | if(f == NULL) {
20 | cerr << "error: cannot open " << argv[1] << endl;
21 | return 1;
22 | }
23 | PngReader reader(f);
24 | bool haveSeenHeader = false;
25 | while(!reader.hasFinishedReading) {
26 | Return r = reader.read();
27 | if(!r) {
28 | cerr << "error: " << r.errmsg << endl;
29 | return 1;
30 | }
31 |
32 | if(!haveSeenHeader && reader.gotHeader) {
33 | cout << "header: width=" << reader.header.width << ", height=" << reader.header.height << endl;
34 | cout << "header: bitDepth=" << (int)reader.header.bitDepth << endl;
35 | cout << "header: colorType=" << (int)reader.header.colourType << endl;
36 | cout << "header: bytesPerPixel=" << (int)reader.header.bytesPerPixel() << endl;
37 | cout << "header: compressionMethod=" << (int)reader.header.compressionMethod << endl;
38 | cout << "header: filterMethod=" << (int)reader.header.filterMethod << endl;
39 | cout << "header: interlaceMethod=" << (int)reader.header.interlaceMethod << endl;
40 | haveSeenHeader = true;
41 | }
42 | }
43 |
44 | size_t s = 0;
45 | for(std::list::iterator i = reader.scanlines.begin(); i != reader.scanlines.end(); ++i)
46 | s += i->size();
47 | cout << "uncompressed data stream size: " << s << endl;
48 | cout << "number scanlines: " << reader.scanlines.size() << endl;
49 |
50 | cout << "success" << endl;
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/Utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | OpenLieroX
3 |
4 | various utilities
5 |
6 | code under LGPL
7 | created 01-05-2007
8 | by Albert Zeyer and Dark Charlie
9 | */
10 |
11 | #ifndef __UTILS_H__
12 | #define __UTILS_H__
13 |
14 | #include // for size_t
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include "Return.h"
20 |
21 | template
22 | bool isSameType(const _src& obj1, const _dst& obj2) {
23 | if(sizeof(_dst) < sizeof(_src)) return isSameType(obj2, obj1);
24 | return dynamic_cast(&obj1) != NULL;
25 | }
26 |
27 |
28 |
29 | template void SafeAdvance(Iter& it, size_t count, const Iter& end) {
30 | for (size_t i=0; i < count && it != end; i++, it++) {}
31 | }
32 |
33 |
34 | template
35 | int highestBit(T d) {
36 | for(int i = sizeof(T) * 8 - 1; i >= 0; --i)
37 | if((1 << i) <= d) return i + 1;
38 | return 0;
39 | }
40 |
41 |
42 | class DontCopyTag {
43 | public:
44 | DontCopyTag() {}
45 | private:
46 | DontCopyTag(const DontCopyTag&) { assert(false); }
47 | DontCopyTag& operator=(const DontCopyTag&) { assert(false); return *this; }
48 | };
49 |
50 |
51 | template
52 | std::vector ListAsVector(const std::list& l) {
53 | return std::vector(l.begin(), l.end());
54 | }
55 |
56 | template std::set Set(T v1) { std::set ret; ret.insert(v1); return ret; }
57 | template std::set Set(T v1, T v2) { std::set ret; ret.insert(v1); ret.insert(v2); return ret; }
58 | template std::set Set(T v1, T v2, T v3) { std::set ret; ret.insert(v1); ret.insert(v2); ret.insert(v3); return ret; }
59 |
60 |
61 | struct WriteCallbackIntf {
62 | virtual Return write(const char* data, size_t s) = 0;
63 | Return write(const std::string& data) { return write(&data[0], data.size()); }
64 | };
65 |
66 |
67 |
68 | #endif
69 |
70 |
--------------------------------------------------------------------------------
/hiredis/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009-2010, Salvatore Sanfilippo
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of Redis nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef __UTIL_H
31 | #define __UTIL_H
32 | #include
33 |
34 | /* Abort on out of memory */
35 | static void redisOOM(void) {
36 | fprintf(stderr,"Out of memory in hiredis");
37 | exit(1);
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/kyotocabinet/kyotocabinet.def:
--------------------------------------------------------------------------------
1 | EXPORTS
2 | KCVERSION = KCVERSION CONSTANT
3 | KCVISNOP = KCVISNOP CONSTANT
4 | KCVISREMOVE = KCVISREMOVE CONSTANT
5 | kcatof = kcatof
6 | kcatoi = kcatoi
7 | kcatoix = kcatoix
8 | kcchkinf = kcchkinf
9 | kcchknan = kcchknan
10 | kccuraccept = kccuraccept
11 | kccurdb = kccurdb
12 | kccurdel = kccurdel
13 | kccurecode = kccurecode
14 | kccuremsg = kccuremsg
15 | kccurget = kccurget
16 | kccurgetkey = kccurgetkey
17 | kccurgetvalue = kccurgetvalue
18 | kccurjump = kccurjump
19 | kccurjumpback = kccurjumpback
20 | kccurjumpbackkey = kccurjumpbackkey
21 | kccurjumpkey = kccurjumpkey
22 | kccurremove = kccurremove
23 | kccursetvalue = kccursetvalue
24 | kccurstep = kccurstep
25 | kccurstepback = kccurstepback
26 | kcdbaccept = kcdbaccept
27 | kcdbadd = kcdbadd
28 | kcdbappend = kcdbappend
29 | kcdbbegintran = kcdbbegintran
30 | kcdbbegintrantry = kcdbbegintrantry
31 | kcdbcas = kcdbcas
32 | kcdbclear = kcdbclear
33 | kcdbclose = kcdbclose
34 | kcdbcopy = kcdbcopy
35 | kcdbcount = kcdbcount
36 | kcdbcursor = kcdbcursor
37 | kcdbdel = kcdbdel
38 | kcdbdumpsnap = kcdbdumpsnap
39 | kcdbecode = kcdbecode
40 | kcdbemsg = kcdbemsg
41 | kcdbendtran = kcdbendtran
42 | kcdbget = kcdbget
43 | kcdbgetbuf = kcdbgetbuf
44 | kcdbincrdouble = kcdbincrdouble
45 | kcdbincrint = kcdbincrint
46 | kcdbiterate = kcdbiterate
47 | kcdbloadsnap = kcdbloadsnap
48 | kcdbmatchprefix = kcdbmatchprefix
49 | kcdbmatchregex = kcdbmatchregex
50 | kcdbmerge = kcdbmerge
51 | kcdbnew = kcdbnew
52 | kcdbopen = kcdbopen
53 | kcdbpath = kcdbpath
54 | kcdbremove = kcdbremove
55 | kcdbreplace = kcdbreplace
56 | kcdbset = kcdbset
57 | kcdbsize = kcdbsize
58 | kcdbstatus = kcdbstatus
59 | kcdbsync = kcdbsync
60 | kcecodename = kcecodename
61 | kcfree = kcfree
62 | kchashfnv = kchashfnv
63 | kchashmurmur = kchashmurmur
64 | kcinf = kcinf
65 | kcmalloc = kcmalloc
66 | kcnan = kcnan
67 | kctime = kctime
68 |
--------------------------------------------------------------------------------
/kyotocabinet/kccompare.cc:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Comparator functions
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #include "kccompare.h"
17 | #include "myconf.h"
18 |
19 | namespace kyotocabinet { // common namespace
20 |
21 |
22 | /**
23 | * Prepared pointer of the comparator in the lexical order.
24 | */
25 | LexicalComparator lexicalfunc;
26 | LexicalComparator* const LEXICALCOMP = &lexicalfunc;
27 |
28 |
29 | /**
30 | * Prepared pointer of the comparator in the lexical descending order.
31 | */
32 | LexicalDescendingComparator lexicaldescfunc;
33 | LexicalDescendingComparator* const LEXICALDESCCOMP = &lexicaldescfunc;
34 |
35 |
36 | /**
37 | * Prepared pointer of the comparator in the decimal order.
38 | */
39 | DecimalComparator decimalfunc;
40 | DecimalComparator* const DECIMALCOMP = &decimalfunc;
41 |
42 |
43 | /**
44 | * Prepared pointer of the comparator in the decimal descending order.
45 | */
46 | DecimalDescendingComparator decimaldescfunc;
47 | DecimalDescendingComparator* const DECIMALDESCCOMP = &decimaldescfunc;
48 |
49 |
50 | } // common namespace
51 |
52 | // END OF FILE
53 |
--------------------------------------------------------------------------------
/hiredis/net.h:
--------------------------------------------------------------------------------
1 | /* Extracted from anet.c to work properly with Hiredis error reporting.
2 | *
3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright notice,
10 | * this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Redis nor the names of its contributors may be used
15 | * to endorse or promote products derived from this software without
16 | * specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #ifndef __NET_H
32 | #define __NET_H
33 |
34 | #include "hiredis.h"
35 |
36 | #if defined(__sun)
37 | #define AF_LOCAL AF_UNIX
38 | #endif
39 |
40 | int redisContextConnectTcp(redisContext *c, const char *addr, int port);
41 | int redisContextConnectUnix(redisContext *c, const char *path);
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/FileUtils.cpp:
--------------------------------------------------------------------------------
1 | /* File utils
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "FileUtils.h"
7 | #include // mkdir
8 | #include
9 | #include
10 |
11 | #include
12 | using namespace std;
13 |
14 | Return fread_all(FILE* fp, std::string& out) {
15 | fseek(fp, 0, SEEK_END);
16 | size_t size = ftell(fp);
17 | fseek(fp, 0, SEEK_SET);
18 |
19 | out = std::string(size, '\0');
20 | char* outP = &out[0];
21 | size_t remaining = size;
22 |
23 | while(remaining > 0) {
24 | if(feof(fp))
25 | return "end-of-file";
26 | if(ferror(fp))
27 | return "file-read-error";
28 | size_t n = fread(outP, 1, remaining, fp);
29 | remaining -= n;
30 | outP += n;
31 | }
32 |
33 | return true;
34 | }
35 |
36 | Return fwrite_bytes(FILE* fp, const char* d, size_t size) {
37 | while(size > 0) {
38 | if(ferror(fp))
39 | return "file-write-error";
40 | size_t n = fwrite(d, 1, size, fp);
41 | d += n;
42 | size -= n;
43 | }
44 |
45 | return true;
46 | }
47 |
48 | Return fwrite_all(FILE* fp, const std::string& in) {
49 | return fwrite_bytes(fp, &in[0], in.size());
50 | }
51 |
52 | DirIter::~DirIter() {
53 | if(dir != NULL) {
54 | closedir(dir);
55 | dir = NULL;
56 | }
57 | }
58 |
59 | void DirIter::next() {
60 | filename = "";
61 | if(dir == NULL) return;
62 | dirent* entry = readdir(dir);
63 | if(entry == NULL) return;
64 | filename = std::string(entry->d_name, entry->d_namlen);
65 | }
66 |
67 | static Return __createDir(const std::string& dir, mode_t mode = 0777) {
68 | if(mkdir(dir.c_str(), mode) != 0) {
69 | if(errno == EEXIST) return true; // no error
70 | return std::string() + "cannot create dir '" + dir + "': " + strerror(errno);
71 | }
72 | return true;
73 | }
74 |
75 | Return createRecDir(const std::string& abs_filename, bool last_is_dir) {
76 | std::string tmp;
77 | std::string::const_iterator f = abs_filename.begin();
78 | for(tmp = ""; f != abs_filename.end(); f++) {
79 | if(*f == '\\' || *f == '/')
80 | ASSERT( __createDir(tmp) );
81 | tmp += *f;
82 | }
83 | if(last_is_dir)
84 | ASSERT( __createDir(tmp) );
85 | return true;
86 | }
87 |
--------------------------------------------------------------------------------
/db-push-dir.cpp:
--------------------------------------------------------------------------------
1 | /* tool to push a dir to the DB
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "Png.h"
7 | #include "DbDefBackend.h"
8 | #include "DbPng.h"
9 | #include "StringUtils.h"
10 | #include "FileUtils.h"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | using namespace std;
17 |
18 | Return _main(const std::string& dirname) {
19 | DbDefBackend db;
20 | ASSERT( db.init() );
21 |
22 | DirIter dir(dirname);
23 | if(dir.dir == NULL)
24 | return "cannot open directory " + dirname;
25 |
26 | for(; dir; dir.next()) {
27 | if(dir.filename.size() <= 4) continue;
28 | if(dir.filename.substr(dir.filename.size()-4) != ".png") continue;
29 | std::string filename = dirname + "/" + dir.filename;
30 |
31 | DbEntryId ref;
32 | if(db.getFileRef(ref, "/" + baseFilename(filename)))
33 | // skip files we already have in DB
34 | continue;
35 |
36 | FILE* f = fopen(filename.c_str(), "rb");
37 | if(f == NULL) {
38 | cerr << "error: " << dir.filename << ": cannot open file" << endl;
39 | continue;
40 | }
41 |
42 | DbPngEntryWriter dbPngWriter(f, &db);
43 | while(dbPngWriter) {
44 | Return r = dbPngWriter.next();
45 | if(!r) {
46 | cerr << "error: " << dir.filename << ": " << r.errmsg << endl;
47 | break;
48 | }
49 | }
50 | db.pushToDir("", DbDirEntry::File(baseFilename(filename), ftell(f)));
51 | db.setFileRef(dbPngWriter.contentId, "/" + baseFilename(filename));
52 | fclose(f);
53 |
54 | cout << dir.filename << ": "
55 | << (100.0f * float(db.stats.pushReuse) / (db.stats.pushNew + db.stats.pushReuse)) << "%, "
56 | << db.stats.pushReuse << " / " << db.stats.pushNew
57 | << endl;
58 | }
59 |
60 | return true;
61 | }
62 |
63 | int main(int argc, char** argv) {
64 | if(argc <= 1) {
65 | cerr << "please give me a dirname" << endl;
66 | return 1;
67 | }
68 |
69 | srandom(time(NULL));
70 |
71 | std::string dirname = argv[1];
72 | Return r = _main(dirname);
73 | if(!r) {
74 | cerr << "error: " << r.errmsg << endl;
75 | return 1;
76 | }
77 |
78 | cout << "success" << endl;
79 | return 0;
80 | }
81 |
--------------------------------------------------------------------------------
/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | # simple compile.sh script
4 | # by Albert Zeyer, 2010 or so
5 | # code under zlib
6 |
7 | cd "$(dirname $0)"
8 | ROOTDIR="$(pwd)"
9 | BUILDDIR="build"
10 |
11 | # $1 - target
12 | # $... - deps
13 | function checkdeps() {
14 | local t="$1"
15 | [ ! -e "$t" ] && return -1
16 | for arg in $*; do
17 | [ "$arg" != "" ] && [ ! -e "$arg" ] && return -1
18 | [ "$arg" != "" ] && [ "$arg" -nt "$t" ] && return -1
19 | done
20 | return 0
21 | }
22 |
23 | # $1 - dep-file
24 | function listdeps() {
25 | sed -e "s/\\\\$//g" -e "s/.*\\.o://g" \
26 | -e "s/^ *//g" -e "s/ *$//g" \
27 | "$1"
28 | #-e "s/^/\\\"/g" -e "s/$/\\\"/g"
29 | }
30 |
31 | typeset -A C
32 | C[cpp]=g++
33 | C[cc]=g++
34 | C[c]=gcc
35 |
36 | typeset -A Cflags
37 | Cflags[.]="-I kyotocabinet"
38 |
39 | # $1 - c/cpp-file
40 | # will compile the o-file
41 | function srccompile() {
42 | local f="$1"
43 | local fext="${f##*.}"
44 | local o="$BUILDDIR/${f/.${fext}/.o}"
45 | local deps="$BUILDDIR/$f.deps"
46 | mkdir -p "$(dirname "$o")"
47 | [ -e $deps ] && checkdeps $o $f $(listdeps $deps) && echo "uptodate: $o" && return 0
48 | echo "compiling $o"
49 | $C[$fext] -c -MMD -MF $deps -o $o -iquote $(dirname $f) ${(z)Cflags[$f]} ${(z)Cflags[.]} -g $f || exit -1
50 | }
51 |
52 | typeset -A Lflags
53 | Lflags[.]="-lz"
54 | Lflags[db-fuse.cpp]="-lfuse"
55 | [ "$(uname)" = "Darwin" ] && Lflags[db-fuse.cpp]="-lfuse_ino64"
56 |
57 | # $1 - c/cpp-file
58 | # will link all the $OBJS together
59 | function srclink() {
60 | local f="$1"
61 | local fext="${f##*.}"
62 | local o="$BUILDDIR/${f/.${fext}/.o}"
63 | local b="bin/${f/.${fext}/}"
64 | checkdeps $b $OBJS $o && echo "uptodate: $b" && return 0
65 | echo "linking $b"
66 | $C[$fext] $OBJS $o -o $b ${(z)Lflags[$f]} ${(z)Lflags[.]} || exit -1
67 | }
68 |
69 | BINS=("test-png-dumpchunks.cpp" "test-png-reader.cpp"
70 | "pnginfo.cpp"
71 | "db-push.cpp" "db-push-dir.cpp"
72 | "db-list-dir.cpp" "db-extract-file.cpp"
73 | "db-fuse.cpp")
74 |
75 | # compile all sources
76 | OBJS=()
77 | for f in *.cpp; do
78 | srccompile "$f"
79 | [[ ${BINS[(i)$f]} -gt ${#BINS} ]] && \
80 | OBJS=($OBJS "$BUILDDIR/${f/.cpp/.o}")
81 | done
82 | for f in hiredis/*.c; do
83 | srccompile "$f"
84 | OBJS=($OBJS "$BUILDDIR/${f/.c/.o}")
85 | done
86 | for f in kyotocabinet/*.cc; do
87 | srccompile "$f"
88 | OBJS=($OBJS "$BUILDDIR/${f/.cc/.o}")
89 | done
90 |
91 | mkdir -p bin
92 | for b in $BINS; do
93 | srclink $b
94 | done
95 |
--------------------------------------------------------------------------------
/FileUtils.h:
--------------------------------------------------------------------------------
1 | /* File utils
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__FILEUTILS_H__
7 | #define __AZ__FILEUTILS_H__
8 |
9 | #include "Return.h"
10 | #include "Endianess.h"
11 | #include "Utils.h"
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | static inline Return fread_bytes(FILE* f, char* d, size_t s) {
20 | if(fread(d, s, 1, f) > 0) return true;
21 | while(s > 0) {
22 | while(fread(d, 1, 1, f) == 0) {
23 | if(feof(f))
24 | return "end-of-file";
25 | if(ferror(f))
26 | return "file-read-error";
27 | }
28 | ++d; --s;
29 | }
30 | return true;
31 | }
32 |
33 | Return fwrite_bytes(FILE* f, const char* d, size_t s);
34 |
35 | template
36 | static inline Return fread_bytes(FILE* f, T& d) {
37 | ASSERT( fread_bytes(f, &d[0], sizeof(T)/sizeof(d[0])) );
38 | return true;
39 | }
40 |
41 | template
42 | static Return fread_litendian(FILE* stream, _D& d) {
43 | T data;
44 | ASSERT( fread_bytes(stream, (char*) &data, sizeof(T)) );
45 | EndianSwap(data);
46 | d = (_D)data;
47 | return true;
48 | }
49 |
50 | template
51 | static Return fread_bigendian(FILE* stream, _D& d) {
52 | T data;
53 | ASSERT( fread_bytes(stream, (char*) &data, sizeof(T)) );
54 | BEndianSwap(data);
55 | d = (_D)data;
56 | return true;
57 | }
58 |
59 | template
60 | static Return fwrite_litendian(FILE* stream, T data) {
61 | EndianSwap(data);
62 | ASSERT( fwrite_bytes(stream, (const char*) &data, sizeof(T)) );
63 | return true;
64 | }
65 |
66 | template
67 | static Return fwrite_bigendian(FILE* stream, T data) {
68 | BEndianSwap(data);
69 | ASSERT( fwrite_bytes(stream, (const char*) &data, sizeof(T)) );
70 | return true;
71 | }
72 |
73 | Return fread_all(FILE* fp, std::string& out);
74 | Return fwrite_all(FILE* fp, const std::string& in);
75 |
76 | struct DirIter : DontCopyTag {
77 | DIR* dir;
78 | std::string filename;
79 |
80 | DirIter(const std::string& dirname) : dir(opendir(dirname.c_str())) { next(); /* set first filename */ }
81 | ~DirIter();
82 | void next();
83 | operator bool() const { return dir != NULL && !filename.empty(); }
84 | };
85 |
86 | Return createRecDir(const std::string& abs_filename, bool last_is_dir = true);
87 |
88 | struct FileWriteCallback : WriteCallbackIntf {
89 | FILE* file;
90 | FileWriteCallback(FILE* f) : file(f) {}
91 | Return write(const char* data, size_t s) { return fwrite_bytes(file, data, s); }
92 | };
93 |
94 | #endif
95 |
--------------------------------------------------------------------------------
/Png.h:
--------------------------------------------------------------------------------
1 | /* PNG parser
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__PNG_H__
7 | #define __AZ__PNG_H__
8 |
9 | #include "Return.h"
10 | #include "Utils.h"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | struct PngChunk {
19 | std::string type;
20 | std::string data;
21 | };
22 |
23 | Return png_read_sig(FILE* f);
24 | Return png_read_chunk(FILE* f, PngChunk& chunk);
25 | Return png_write_sig(WriteCallbackIntf* w);
26 | Return png_write_chunk(WriteCallbackIntf* w, const PngChunk& chunk);
27 |
28 | struct PngHeader {
29 | static const size_t SIZE = 13;
30 | uint32_t width, height;
31 | uint8_t bitDepth;
32 | uint8_t colourType;
33 | uint8_t compressionMethod;
34 | uint8_t filterMethod;
35 | uint8_t interlaceMethod;
36 |
37 | uint8_t samplesPerPixel() {
38 | switch(colourType) {
39 | case 0: return 1; // greyscale
40 | case 2: return 3; // truecolour
41 | case 3: return 1; // indexed
42 | case 4: return 2; // greyscale+alpha
43 | case 6: return 4; // truecolour+alpha
44 | }
45 | return 1; // error anyway; return 1 to avoid infinite loops
46 | }
47 |
48 | uint8_t bytesPerPixel() {
49 | return (samplesPerPixel() * bitDepth + 7) / 8;
50 | }
51 |
52 | uint32_t scanlineSize(uint32_t width) {
53 | return (width * samplesPerPixel() * bitDepth + 7) / 8 + /* filter type byte */ 1;
54 | }
55 | };
56 |
57 | struct PngInterlacedPos {
58 | short pass;
59 | uint32_t row;
60 | PngInterlacedPos() : pass(0), row(0) {}
61 | void inc(uint32_t height);
62 | size_t scanlineWidth(uint32_t width);
63 | };
64 |
65 | struct PngReader : DontCopyTag {
66 | FILE* file;
67 | z_stream stream;
68 | PngHeader header;
69 | bool hasInitialized, gotHeader, gotStreamEnd, gotEndChunk, hasFinishedReading;
70 | std::list chunks;
71 |
72 | PngInterlacedPos interlacedPos;
73 | std::string incompleteScanline;
74 | size_t incompleteScanlineOffset;
75 | std::list scanlines;
76 |
77 | PngReader(FILE* f = NULL);
78 | ~PngReader();
79 | Return read();
80 | };
81 |
82 | struct PngWriter : DontCopyTag {
83 | WriteCallbackIntf* writer;
84 | z_stream stream;
85 | std::list chunks;
86 | std::list scanlines;
87 | std::list dataChunks;
88 | bool hasInitialized, hasFinishedWriting; // these are set from write()
89 | bool hasAllChunks, hasAllScanlines; // these are expected to be set from outside
90 |
91 | PngWriter(WriteCallbackIntf* w = NULL);
92 | ~PngWriter();
93 | Return write();
94 | };
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/Db.cpp:
--------------------------------------------------------------------------------
1 | /* simple DB interface
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef Z_CompressionLevel
7 | #define Z_CompressionLevel 9
8 | #endif
9 |
10 | #ifndef Z_BufSize
11 | #define Z_BufSize 1024*128
12 | #endif
13 |
14 | #include "Db.h"
15 | #include "Sha1.h"
16 | #include "StringUtils.h"
17 | #include "FileUtils.h"
18 | #include
19 | #include
20 | #include
21 |
22 | #include
23 | using namespace std;
24 |
25 | void DbEntry::calcSha1() {
26 | sha1 = calc_sha1(data);
27 | }
28 |
29 | void DbEntry::compress() {
30 | compressed = "";
31 |
32 | z_stream stream;
33 | stream.zalloc = Z_NULL;
34 | stream.zfree = Z_NULL;
35 | stream.opaque = Z_NULL;
36 | deflateInit(&stream, Z_CompressionLevel);
37 |
38 | stream.avail_in = data.size();
39 | stream.next_in = (unsigned char*) &data[0];
40 | while(true) {
41 | char outputData[Z_BufSize];
42 | stream.avail_out = sizeof(outputData);
43 | stream.next_out = (unsigned char*) outputData;
44 | int ret = deflate(&stream, Z_FINISH);
45 | switch(ret) {
46 | case Z_OK: break;
47 | case Z_STREAM_END: break;
48 | // these cases should not happen. but check anyway
49 | case Z_STREAM_ERROR:
50 | default:
51 | cerr << "error to deflate " << data.size() << " bytes" << endl;
52 | cerr << "remaining: " << stream.avail_in << " bytes" << endl;
53 | cerr << "deflate ret: " << ret << endl;
54 | assert(false);
55 | return;
56 | }
57 | size_t out_size = sizeof(outputData) - stream.avail_out;
58 | compressed += std::string(outputData, out_size);
59 | if(ret == Z_STREAM_END) break;
60 | }
61 | deflateEnd(&stream);
62 | }
63 |
64 | Return DbEntry::uncompress() {
65 | data = "";
66 |
67 | z_stream stream;
68 | stream.zalloc = Z_NULL;
69 | stream.zfree = Z_NULL;
70 | stream.opaque = Z_NULL;
71 | inflateInit(&stream);
72 |
73 | bool gotStreamEnd = false;
74 | stream.avail_in = compressed.size();
75 | stream.next_in = (unsigned char*) &compressed[0];
76 | while(true) {
77 | char outputData[Z_BufSize];
78 | stream.avail_out = sizeof(outputData);
79 | stream.next_out = (unsigned char*) outputData;
80 | int ret = inflate(&stream, Z_NO_FLUSH);
81 | switch(ret) {
82 | case Z_STREAM_ERROR: inflateEnd(&stream); return "zlib stream error / invalid compression level";
83 | case Z_NEED_DICT: inflateEnd(&stream); return "zlib need dict error";
84 | case Z_DATA_ERROR: inflateEnd(&stream); return "zlib data error";
85 | case Z_MEM_ERROR: inflateEnd(&stream); return "zlib out-of-memory error";
86 | case Z_STREAM_END: gotStreamEnd = true;
87 | }
88 | size_t out_size = sizeof(outputData) - stream.avail_out;
89 | if(out_size == 0) break;
90 | data += std::string(outputData, out_size);
91 | }
92 | inflateEnd(&stream);
93 |
94 | if(!gotStreamEnd)
95 | return "zlib stream incomplete";
96 | return true;
97 | }
98 |
--------------------------------------------------------------------------------
/hiredis/sds.h:
--------------------------------------------------------------------------------
1 | /* SDSLib, A C dynamic strings library
2 | *
3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright notice,
10 | * this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of Redis nor the names of its contributors may be used
15 | * to endorse or promote products derived from this software without
16 | * specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #ifndef __SDS_H
32 | #define __SDS_H
33 |
34 | #include
35 | #include
36 |
37 | typedef char *sds;
38 |
39 | struct sdshdr {
40 | int len;
41 | int free;
42 | char buf[];
43 | };
44 |
45 | sds sdsnewlen(const void *init, size_t initlen);
46 | sds sdsnew(const char *init);
47 | sds sdsempty();
48 | size_t sdslen(const sds s);
49 | sds sdsdup(const sds s);
50 | void sdsfree(sds s);
51 | size_t sdsavail(sds s);
52 | sds sdscatlen(sds s, const void *t, size_t len);
53 | sds sdscat(sds s, const char *t);
54 | sds sdscpylen(sds s, char *t, size_t len);
55 | sds sdscpy(sds s, char *t);
56 |
57 | sds sdscatvprintf(sds s, const char *fmt, va_list ap);
58 | #ifdef __GNUC__
59 | sds sdscatprintf(sds s, const char *fmt, ...)
60 | __attribute__((format(printf, 2, 3)));
61 | #else
62 | sds sdscatprintf(sds s, const char *fmt, ...);
63 | #endif
64 |
65 | sds sdstrim(sds s, const char *cset);
66 | sds sdsrange(sds s, int start, int end);
67 | void sdsupdatelen(sds s);
68 | int sdscmp(sds s1, sds s2);
69 | sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
70 | void sdsfreesplitres(sds *tokens, int count);
71 | void sdstolower(sds s);
72 | void sdstoupper(sds s);
73 | sds sdsfromlonglong(long long value);
74 | sds sdscatrepr(sds s, char *p, size_t len);
75 | sds *sdssplitargs(char *line, int *argc);
76 |
77 | #endif
78 |
--------------------------------------------------------------------------------
/Db.h:
--------------------------------------------------------------------------------
1 | /* simple DB interface
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #ifndef __AZ__DB_H__
7 | #define __AZ__DB_H__
8 |
9 | #include "Return.h"
10 | #include "StringUtils.h"
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #define DbEntryType_PngContentList 1
17 | #define DbEntryType_PngChunk 2
18 | #define DbEntryType_PngBlock 3
19 |
20 | struct DbEntry {
21 | std::string data;
22 | std::string sha1;
23 | std::string compressed;
24 |
25 | DbEntry() {}
26 | DbEntry(const std::string& d) : data(d) { prepare(); }
27 | bool haveSha1() const { return !sha1.empty(); }
28 | void calcSha1();
29 | bool haveCompressed() const { return !compressed.empty(); }
30 | void compress();
31 | Return uncompress();
32 | void prepare() { calcSha1(); compress(); }
33 |
34 | bool operator==(const DbEntry& other) const {
35 | assert(haveSha1());
36 | assert(haveCompressed());
37 | assert(other.haveSha1());
38 | assert(other.haveCompressed());
39 | if(sha1 != other.sha1) return false;
40 | // Note: If we would ensure that the compression algorithm always works exactly
41 | // the same way, we could just restrict the check on the compressed data.
42 | // But as we don't want to restrict ourself to this, we can't.
43 | if(compressed == other.compressed) return true;
44 | return data == other.data;
45 | }
46 | };
47 |
48 | typedef std::string DbEntryId; /* guaranteed to not contain \0 and to be not empty */
49 |
50 | struct DbStats {
51 | size_t pushNew;
52 | size_t pushReuse;
53 | DbStats() : pushNew(0), pushReuse(0) {}
54 | };
55 |
56 | struct DbDirEntry {
57 | mode_t mode;
58 | std::string name;
59 | size_t size;
60 | DbDirEntry(mode_t m = 0, const std::string& fn = "", size_t s = 0) : mode(m), name(fn), size(s) {}
61 | std::string serialized() const { return rawString(mode) + rawString(size) + name; }
62 | static DbDirEntry FromSerialized(const std::string& raw) {
63 | if(raw.size() <= 6) return DbDirEntry();
64 | return DbDirEntry(valueFromRaw(&raw[0]), raw.substr(6), valueFromRaw(&raw[2]));
65 | }
66 | static DbDirEntry File(const std::string& fn, size_t s) { return DbDirEntry(S_IFREG | 0444, fn, s); }
67 | static DbDirEntry Dir(const std::string& fn) { return DbDirEntry(S_IFDIR | 0755, fn); }
68 | };
69 |
70 | struct DbIntf {
71 | DbStats stats;
72 | virtual Return setReadOnly(bool ro) { return "Db::setReadOnly: not implemented"; }
73 | virtual Return init() = 0;
74 | virtual Return push(/*out*/ DbEntryId& id, const DbEntry& entry) = 0;
75 | virtual Return get(/*out*/ DbEntry& entry, const DbEntryId& id) = 0;
76 | virtual Return pushToDir(const std::string& path, const DbDirEntry& dirEntry) {
77 | return "Db::pushToDir: not implemented";
78 | }
79 | virtual Return getDir(/*out*/ std::list& dirList, const std::string& path) {
80 | return "Db::getDir: not implemented";
81 | }
82 | virtual Return setFileRef(/*can be empty*/ const DbEntryId& id, const std::string& path) {
83 | return "Db::setFileRef: not implemented";
84 | }
85 | virtual Return getFileRef(/*out (can be empty)*/ DbEntryId& id, const std::string& path) {
86 | return "Db::getFileRef: not implemented";
87 | }
88 | };
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/Crc.cpp:
--------------------------------------------------------------------------------
1 | /* calculate CRC
2 | * based on http://www.w3.org/TR/PNG/#D-CRCAppendix
3 | * by Albert Zeyer, 2011
4 | * code public domain
5 | */
6 |
7 | #include "Crc.h"
8 |
9 | /* Table of CRCs of all 8-bit messages. */
10 | static const uint32_t crc_table[256] = {
11 | 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546,
12 | 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538,
13 | 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355,
14 | 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
15 | 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456,
16 | 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117 };
17 |
18 | /* Update a running CRC with the bytes buf[0..len-1]--the CRC
19 | should be initialized to all 1's, and the transmitted value
20 | is the 1's complement of the final running CRC (see the
21 | crc() routine below). */
22 | uint32_t update_crc(uint32_t crc, const char *buf, size_t len) {
23 | uint32_t c = crc;
24 | for (size_t n = 0; n < len; n++)
25 | c = crc_table[(c ^ (unsigned char)buf[n]) & 0xff] ^ (c >> 8);
26 | return c;
27 | }
28 |
29 | /* Return the CRC of the bytes buf[0..len-1]. */
30 | uint32_t calc_crc(const char *buf, size_t len) {
31 | return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
32 | }
33 |
34 | uint32_t calc_crc(const std::string& s) {
35 | return calc_crc(&s[0], s.size());
36 | }
37 |
38 | uint32_t calc_crc(const std::string& s1, const std::string& s2) {
39 | uint32_t c = 0xffffffffL;
40 | c = update_crc(c, &s1[0], s1.size());
41 | c = update_crc(c, &s2[0], s2.size());
42 | return c ^ 0xffffffffL;
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/DbFsBackend.cpp:
--------------------------------------------------------------------------------
1 | /* filesystem DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "DbFsBackend.h"
7 | #include "Sha1.h"
8 | #include "StringUtils.h"
9 | #include "FileUtils.h"
10 | #include
11 | #include
12 | #include
13 |
14 | #include
15 | using namespace std;
16 |
17 | static std::string __filenameForDbEntryId(const DbEntryId& id) {
18 | assert(!id.empty());
19 |
20 | std::string ret = "data/";
21 | for(size_t i = 0; i < id.size() - 1; ++i)
22 | ret += hexString(id[i]) + "/";
23 | ret += hexString(id[id.size()-1]) + ".dat";
24 | return ret;
25 | }
26 |
27 | static std::string __dirnameForSha1Ref(const std::string& sha1) {
28 | assert(sha1.size() == SHA1_DIGEST_SIZE);
29 |
30 | std::string ret = "sha1refs/";
31 | for(size_t i = 0; i < sha1.size(); ++i) {
32 | if(i % 5 == 0 && i > 0) ret += "/";
33 | ret += hexString(sha1[i]);
34 | }
35 | return ret;
36 | }
37 |
38 | static int __hexnumFromChar(char c) {
39 | if(c >= '0' && c <= '9') return c - '0';
40 | if(c >= 'A' && c <= 'F') return 10 + c - 'A';
41 | if(c >= 'a' && c <= 'f') return 10 + c - 'a';
42 | return -1;
43 | }
44 |
45 | static DbEntryId __entryIdFromSha1RefFilename(const std::string& fn) {
46 | DbEntryId id;
47 | size_t i = 0;
48 | for(; i + 1 < fn.size(); i += 2) {
49 | if(fn.substr(i) == ".ref") return id;
50 | int n1 = __hexnumFromChar(fn[i]);
51 | int n2 = __hexnumFromChar(fn[i+1]);
52 | if(n1 < 0 || n2 < 0) return "";
53 | id += (char)(unsigned char)(n1 * 16 + n2);
54 | }
55 | return "";
56 | }
57 |
58 | static Return __openNewDbEntry(const std::string& baseDir, DbEntryId& id, FILE*& f) {
59 | bool createdDir = false;
60 | unsigned short triesNum = (id.size() <= 4) ? (2 << id.size()) : 64;
61 | for(unsigned short i = 0; i < triesNum; ++i) {
62 | DbEntryId newId = id;
63 | newId += (char)random();
64 | std::string filename = baseDir + "/" + __filenameForDbEntryId(newId);
65 | if(!createdDir) {
66 | ASSERT( createRecDir(filename, false) );
67 | createdDir = true;
68 | }
69 | f = fopen(filename.c_str(), "wbx");
70 | if(f) {
71 | id = newId;
72 | return true;
73 | }
74 | }
75 |
76 | id += (char)random();
77 | return __openNewDbEntry(baseDir, id, f);
78 | }
79 |
80 | Return DbFsBackend::push(/*out*/ DbEntryId& id, const DbEntry& entry) {
81 | if(!entry.haveSha1())
82 | return "DB push: entry SHA1 not calculated";
83 | if(!entry.haveCompressed())
84 | return "DB push: entry compression not calculated";
85 |
86 | // search for existing entry
87 | std::string sha1refdir = __dirnameForSha1Ref(entry.sha1);
88 | for(DirIter dir(baseDir + "/" + sha1refdir); dir; dir.next()) {
89 | DbEntryId otherId = __entryIdFromSha1RefFilename(dir.filename);
90 | if(otherId != "") {
91 | DbEntry otherEntry;
92 | if(get(otherEntry, otherId)) {
93 | if(entry == otherEntry) {
94 | // found
95 | id = otherId;
96 | stats.pushReuse++;
97 | return true;
98 | }
99 | }
100 | }
101 | }
102 |
103 | // write DB entry
104 | id = "";
105 | FILE* f = NULL;
106 | ASSERT( __openNewDbEntry(baseDir, id, f) );
107 | {
108 | Return r = fwrite_all(f, entry.compressed);
109 | fclose(f);
110 | if(!r) return r;
111 | }
112 |
113 | // create sha1 ref
114 | std::string sha1reffn = baseDir + "/" + sha1refdir + "/" + hexString(id) + ".ref";
115 | ASSERT( createRecDir(sha1reffn, false) );
116 | f = fopen(sha1reffn.c_str(), "w");
117 | if(f == NULL)
118 | return "DB push: cannot create SHA1 ref: cannot create file '" + sha1reffn + "'";
119 | fclose(f);
120 |
121 | stats.pushNew++;
122 | return true;
123 | }
124 |
125 | Return DbFsBackend::get(/*out*/ DbEntry& entry, const DbEntryId& id) {
126 | std::string filename = baseDir + "/" + __filenameForDbEntryId(id);
127 | FILE* f = fopen(filename.c_str(), "rb");
128 | if(f == NULL)
129 | return "Db::get: cannot open file '" + filename + "'";
130 |
131 | {
132 | Return r = fread_all(f, entry.compressed);
133 | fclose(f);
134 | if(!r) return r;
135 | }
136 |
137 | ASSERT( entry.uncompress() );
138 | entry.calcSha1();
139 |
140 | return true;
141 | }
142 |
--------------------------------------------------------------------------------
/SmartPointer.h:
--------------------------------------------------------------------------------
1 | /*
2 | OpenLieroX
3 | code under LGPL
4 | 27-12-2007 Albert Zeyer
5 | */
6 |
7 | #ifndef __SMARTPOINTER_H__
8 | #define __SMARTPOINTER_H__
9 |
10 | #include
11 | #include
12 | #include "Mutex.h"
13 |
14 | // Default de-initialization action is to call operator delete, for each object type.
15 | template < typename _Type >
16 | void SmartPointer_ObjectDeinit( _Type * obj ) {
17 | delete obj;
18 | }
19 |
20 |
21 | /*
22 | standard smartpointer based on simple refcounting
23 |
24 | The refcounting is multithreading safe in this class,
25 | you can have copies of this object in different threads.
26 | Though it's not designed to operate with the same
27 | object in different threads. Also there is absolutly no
28 | thread safty on the pointer itself, you have to care
29 | about this yourself.
30 | */
31 |
32 |
33 | template < typename _Type >
34 | class SmartPointer {
35 | public:
36 | typedef _Type value_type;
37 | private:
38 | _Type* obj;
39 | int* refCount;
40 | Mutex* mutex;
41 |
42 | void init(_Type* newObj) {
43 | if( newObj == NULL )
44 | return;
45 | if(!mutex) {
46 | mutex = new Mutex();
47 | obj = newObj;
48 | refCount = new int(1);
49 | }
50 | }
51 |
52 | void reset() {
53 | if(mutex) {
54 | lock();
55 | (*refCount)--;
56 | if(*refCount == 0) {
57 | SmartPointer_ObjectDeinit( obj );
58 | delete refCount; // safe, because there is no other ref anymore
59 | obj = NULL;
60 | refCount = NULL;
61 | unlock();
62 | delete mutex; // safe because there is no other ref anymore
63 | mutex = NULL;
64 | } else
65 | unlock();
66 | }
67 | obj = NULL;
68 | refCount = NULL;
69 | mutex = NULL;
70 | }
71 |
72 | void incCounter() {
73 | assert(*refCount > 0 && *refCount < INT_MAX);
74 | (*refCount)++;
75 | }
76 |
77 | void lock() { mutex->lock(); }
78 | void unlock() { mutex->unlock(); }
79 |
80 | public:
81 | SmartPointer() : obj(NULL), refCount(NULL), mutex(NULL) {}
82 | ~SmartPointer() { reset(); }
83 |
84 | // Default copy constructor and operator=
85 | // If you specify any template<> params here these funcs will be silently ignored by compiler
86 | SmartPointer(const SmartPointer& pt) : obj(NULL), refCount(NULL), mutex(NULL) { operator=(pt); }
87 | SmartPointer& operator=(const SmartPointer& pt) {
88 | if(mutex == pt.mutex) return *this; // ignore this case
89 | reset();
90 | mutex = pt.mutex;
91 | if(mutex) {
92 | lock();
93 | obj = pt.obj; refCount = pt.refCount;
94 | incCounter();
95 | unlock();
96 | } else { obj = NULL; refCount = NULL; }
97 | return *this;
98 | }
99 |
100 | // WARNING: Be carefull, don't assing a pointer to different SmartPointer objects,
101 | // else they will get freed twice in the end. Always copy the SmartPointer itself.
102 | // In short: SmartPointer ptr(SomeObj); SmartPointer ptr1( ptr.get() ); // It's wrong, don't do that.
103 | SmartPointer(_Type* pt): obj(NULL), refCount(NULL), mutex(NULL) { operator=(pt); }
104 | SmartPointer& operator=(_Type* pt) {
105 | if(obj == pt) return *this; // ignore this case
106 | reset();
107 | init(pt);
108 | return *this;
109 | }
110 |
111 | _Type* get() const { return obj; } // The smartpointer itself won't change when returning address of obj, so it's const.
112 |
113 | // HINT: no convenient cast functions in this class to avoid error-prone automatic casts
114 | // (which would lead to collisions!)
115 | // This operator is safe though.
116 | _Type * operator -> () const { return obj; };
117 |
118 | // refcount may be changed from another thread, though if refcount==1 or 0 it won't change
119 | int getRefCount() {
120 | int ret = 0;
121 | if(mutex) {
122 | lock();
123 | ret = *refCount;
124 | unlock(); // Here the other thread may change refcount, that's why it's approximate
125 | }
126 | return ret;
127 | }
128 |
129 | // Returns true only if the data is deleted (no other smartpointer used it), sets pointer to NULL then
130 | bool tryDeleteData() {
131 | if(mutex) {
132 | lock();
133 | if( *refCount == 1 )
134 | {
135 | unlock(); // Locks mutex again inside reset(), since we're only ones using data refcount cannot change from other thread
136 | reset();
137 | return true; // Data deleted
138 | }
139 | unlock();
140 | return false; // Data not deleted
141 | }
142 | return true; // Data was already deleted
143 | }
144 |
145 | };
146 |
147 | #endif
148 |
149 |
--------------------------------------------------------------------------------
/DbKyotoBackend.cpp:
--------------------------------------------------------------------------------
1 | /* KyotoCabinet DB backend
2 | * by Albert Zeyer, 2011
3 | * code under LGPL
4 | */
5 |
6 | #include "DbKyotoBackend.h"
7 | #include "StringUtils.h"
8 | #include "Utils.h"
9 | #include
10 |
11 | #include
12 | using namespace std;
13 | using namespace kyotocabinet;
14 |
15 | DbKyotoBackend::~DbKyotoBackend() {
16 | db.close();
17 | }
18 |
19 | Return DbKyotoBackend::init() {
20 | if(!db.open(filename, readonly ? PolyDB::OREADER : (PolyDB::OWRITER | PolyDB::OCREATE)))
21 | return std::string() + "failed to open KyotoCabinet DB: " + db.error().name();
22 | return true;
23 | }
24 |
25 | typedef PolyDB KyotoDB;
26 |
27 | static Return __addEntryToList(KyotoDB& db, const std::string& key, const std::string& entry) {
28 | if(entry.size() > 255)
29 | return "cannot add entries with size>255 to list";
30 | if(!db.append(key, rawString(entry.size()) + entry))
31 | return std::string() + "error adding entry to list: " + db.error().name();
32 | return true;
33 | }
34 |
35 | static Return __getEntryList(KyotoDB& db, const std::string& key, std::list& entries) {
36 | std::string value;
37 | if(!db.get(key, &value))
38 | return std::string() + "error getting entry list: " + db.error().name();
39 |
40 | size_t i = 0;
41 | while(i < value.size()) {
42 | uint8_t size = value[i];
43 | ++i;
44 | if(i + size > value.size())
45 | return "entry list data is inconsistent";
46 | entries.push_back( value.substr(i, size) );
47 | i += size;
48 | }
49 |
50 | return true;
51 | }
52 |
53 | static Return __saveNewDbEntry(KyotoDB& db, DbEntryId& id, const std::string& content) {
54 | unsigned short triesNum = (id.size() <= 4) ? (2 << id.size()) : 64;
55 | for(unsigned short i = 0; i < triesNum; ++i) {
56 | DbEntryId newId = id;
57 | newId += (char)random();
58 | std::string key = "data." + newId;
59 | if(db.add(key, content)) {
60 | id = newId;
61 | return true;
62 | }
63 | }
64 |
65 | id += (char)random();
66 | return __saveNewDbEntry(db, id, content);
67 | }
68 |
69 | Return DbKyotoBackend::push(/*out*/ DbEntryId& id, const DbEntry& entry) {
70 | if(!entry.haveSha1())
71 | return "DB push: entry SHA1 not calculated";
72 | if(!entry.haveCompressed())
73 | return "DB push: entry compression not calculated";
74 |
75 | // search for existing entry
76 | std::string sha1refkey = "sha1ref." + entry.sha1;
77 | std::list sha1refs;
78 | if(__getEntryList(db, sha1refkey, sha1refs))
79 | for(std::list::iterator i = sha1refs.begin(); i != sha1refs.end(); ++i) {
80 | DbEntryId otherId = *i;
81 | DbEntry otherEntry;
82 | if(get(otherEntry, otherId)) {
83 | if(entry == otherEntry) {
84 | // found
85 | id = otherId;
86 | stats.pushReuse++;
87 | return true;
88 | }
89 | }
90 | }
91 |
92 | // write DB entry
93 | id = "";
94 | ASSERT( __saveNewDbEntry(db, id, entry.compressed) );
95 |
96 | // create sha1 ref
97 | ASSERT( __addEntryToList(db, sha1refkey, id) );
98 |
99 | stats.pushNew++;
100 | return true;
101 | }
102 |
103 | Return DbKyotoBackend::get(/*out*/ DbEntry& entry, const DbEntryId& id) {
104 | std::string key = "data." + id;
105 | if(!db.get(key, &entry.compressed))
106 | return std::string() + "DB get: error getting entry: " + db.error().name();
107 |
108 | ASSERT( entry.uncompress() );
109 | entry.calcSha1();
110 |
111 | return true;
112 | }
113 |
114 | Return DbKyotoBackend::pushToDir(const std::string& path, const DbDirEntry& dirEntry) {
115 | std::string key = "fs." + path;
116 | std::string dirEntryRaw = dirEntry.serialized();
117 | ASSERT( __addEntryToList(db, key, dirEntryRaw) );
118 | return true;
119 | }
120 |
121 | Return DbKyotoBackend::getDir(/*out*/ std::list& dirList, const std::string& path) {
122 | std::string key = "fs." + path;
123 | std::list entries;
124 | ASSERT( __getEntryList(db, key, entries) );
125 | for(std::list::iterator i = entries.begin(); i != entries.end(); ++i)
126 | dirList.push_back( DbDirEntry::FromSerialized(*i) );
127 |
128 | return true;
129 | }
130 |
131 | Return DbKyotoBackend::setFileRef(/*can be empty*/ const DbEntryId& id, const std::string& path) {
132 | std::string key = "fs." + path;
133 | if(!db.set(key, id))
134 | return std::string() + "DB setFileRef: error setting entry: " + db.error().name();
135 | return true;
136 | }
137 |
138 | Return DbKyotoBackend::getFileRef(/*out (can be empty)*/ DbEntryId& id, const std::string& path) {
139 | std::string key = "fs." + path;
140 | if(!db.get(key, &id))
141 | return std::string() + "DB getFileRef: error getting entry: " + db.error().name();
142 | return true;
143 | }
144 |
145 |
--------------------------------------------------------------------------------
/kyotocabinet/kcregex.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Regular expression
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #ifndef _KCREGEX_H // duplication check
17 | #define _KCREGEX_H
18 |
19 | #include
20 | #include
21 |
22 | namespace kyotocabinet { // common namespace
23 |
24 |
25 | /**
26 | * Regular expression.
27 | */
28 | class Regex {
29 | public:
30 | /**
31 | * Options.
32 | */
33 | enum Option {
34 | IGNCASE = 1 << 0, ///< case-insensitive
35 | MATCHONLY = 1 << 1, ///< matching only
36 | };
37 | /**
38 | * Default constructor.
39 | */
40 | explicit Regex();
41 | /**
42 | * Destructor.
43 | */
44 | ~Regex();
45 | /**
46 | * Compile a string of regular expression.
47 | * @param regex the string of regular expression.
48 | * @param opts the optional features by bitwise-or: Regex::IGNCASE for case-insensitive
49 | * matching, Regex::MATCHONLY for matching only usage.
50 | */
51 | bool compile(const std::string& regex, uint32_t opts = 0);
52 | /**
53 | * Check whether a string matches the regular expression.
54 | * @param str the string.
55 | * @return true if the string matches, or false if not.
56 | */
57 | bool match(const std::string& str);
58 | /**
59 | * Check whether a string matches the regular expression.
60 | * @param str the string.
61 | * @param alt the alternative string with which each substring is replaced. Each "$" in the
62 | * string escapes the following character. Special escapes "$1" through "$9" refer to partial
63 | * substrings corresponding to sub-expressions in the regular expression. "$0" and "$&" refer
64 | * to the whole matching substring.
65 | * @return the result string.
66 | */
67 | std::string replace(const std::string& str, const std::string& alt);
68 | /**
69 | * Check whether a string matches a regular expression.
70 | * @param str the string.
71 | * @param pattern the matching pattern.
72 | * @param opts the optional features by bitwise-or: Regex::IGNCASE for case-insensitive
73 | * matching, Regex::MATCHONLY for matching only usage.
74 | * @return true if the string matches, or false if not.
75 | */
76 | static bool match(const std::string& str, const std::string& pattern, uint32_t opts = 0) {
77 | Regex regex;
78 | if (!regex.compile(pattern, opts)) return false;
79 | return regex.match(str);
80 | }
81 | /**
82 | * Check whether a string matches the regular expression.
83 | * @param str the string.
84 | * @param pattern the matching pattern.
85 | * @param alt the alternative string with which each substring is replaced. Each "$" in the
86 | * string escapes the following character. Special escapes "$1" through "$9" refer to partial
87 | * substrings corresponding to sub-expressions in the regular expression. "$0" and "$&" refer
88 | * to the whole matching substring.
89 | * @param opts the optional features by bitwise-or: Regex::IGNCASE for case-insensitive
90 | * matching, Regex::MATCHONLY for matching only usage.
91 | * @return the result string.
92 | */
93 | static std::string replace(const std::string& str, const std::string& pattern,
94 | const std::string& alt, uint32_t opts = 0) {
95 | Regex regex;
96 | if (!regex.compile(pattern, opts)) return str;
97 | return regex.replace(str, alt);
98 | }
99 | private:
100 | /** Dummy constructor to forbid the use. */
101 | Regex(const Regex&);
102 | /** Dummy Operator to forbid the use. */
103 | Regex& operator =(const Regex&);
104 | /** Opaque pointer. */
105 | void* opq_;
106 | };
107 |
108 |
109 | } // common namespace
110 |
111 | #endif // duplication check
112 |
113 | // END OF FILE
114 |
--------------------------------------------------------------------------------
/hiredis/async.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009-2010, Salvatore Sanfilippo
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of Redis nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef __HIREDIS_ASYNC_H
31 | #define __HIREDIS_ASYNC_H
32 | #include "hiredis.h"
33 |
34 | #ifdef __cplusplus
35 | extern "C" {
36 | #endif
37 |
38 | struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
39 |
40 | /* Reply callback prototype and container */
41 | typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
42 | typedef struct redisCallback {
43 | struct redisCallback *next; /* simple singly linked list */
44 | redisCallbackFn *fn;
45 | void *privdata;
46 | } redisCallback;
47 |
48 | /* List of callbacks for either regular replies or pub/sub */
49 | typedef struct redisCallbackList {
50 | redisCallback *head, *tail;
51 | } redisCallbackList;
52 |
53 | /* Connection callback prototypes */
54 | typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
55 | typedef void (redisConnectCallback)(const struct redisAsyncContext*);
56 |
57 | /* Context for an async connection to Redis */
58 | typedef struct redisAsyncContext {
59 | /* Hold the regular context, so it can be realloc'ed. */
60 | redisContext c;
61 |
62 | /* Setup error flags so they can be used directly. */
63 | int err;
64 | char *errstr;
65 |
66 | /* Not used by hiredis */
67 | void *data;
68 |
69 | /* Used by the different event lib adapters to store their private data */
70 | void *_adapter_data;
71 |
72 | /* Called when the library expects to start reading/writing.
73 | * The supplied functions should be idempotent. */
74 | void (*evAddRead)(void *privdata);
75 | void (*evDelRead)(void *privdata);
76 | void (*evAddWrite)(void *privdata);
77 | void (*evDelWrite)(void *privdata);
78 | void (*evCleanup)(void *privdata);
79 |
80 | /* Called when either the connection is terminated due to an error or per
81 | * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
82 | redisDisconnectCallback *onDisconnect;
83 |
84 | /* Called when the first write event was received. */
85 | redisConnectCallback *onConnect;
86 |
87 | /* Reply callbacks */
88 | redisCallbackList replies;
89 | } redisAsyncContext;
90 |
91 | /* Functions that proxy to hiredis */
92 | redisAsyncContext *redisAsyncConnect(const char *ip, int port);
93 | int redisAsyncSetReplyObjectFunctions(redisAsyncContext *ac, redisReplyObjectFunctions *fn);
94 | int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
95 | int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
96 | void redisAsyncDisconnect(redisAsyncContext *ac);
97 |
98 | /* Handle read/write events */
99 | void redisAsyncHandleRead(redisAsyncContext *ac);
100 | void redisAsyncHandleWrite(redisAsyncContext *ac);
101 |
102 | /* Command functions for an async context. Write the command to the
103 | * output buffer and register the provided callback. */
104 | int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
105 | int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
106 | int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
107 |
108 | #ifdef __cplusplus
109 | }
110 | #endif
111 |
112 | #endif
113 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DB optimized for a bunch of PNG images.
2 |
3 | Idea
4 | ====
5 |
6 | The idea is to split PNG images into many blocks and have each block stored in a DB.
7 | If there are several equal blocks, it is only stored once.
8 | Via a hash table, the lookup for such blocks is made fast.
9 |
10 | Use case
11 | ========
12 |
13 | I am collecting screenshots (for several reasons; one is to play around with machine learning / computer vision;
14 | one example is here: ). A lot of them. :)
15 |
16 | Right now, I have about 88k screenshots with about 77GB. And as many of them have a lot of repetitive areas
17 | (on some days, I were making a screenshot every 10 seconds, even when not using the computer at all,
18 | so the only changing part was the time display), I didn't wanted to waste so much space on so much repetitive data.
19 |
20 | With this PNG DB, I have a compression rate of about 400-500%
21 | (for the first 1k screenshots or so; probably the rate will even be higher for all of them).
22 |
23 | This example with the screenshots is probably an extreme case (where this applies extremely well).
24 | But I guess in many other cases where you are collecting a huge amount of PNG images
25 | (with computer-generated content; real-world images would not work that well), you can safe some space by it.
26 |
27 | And if this gets optimized as far as possible, it may be even faster than normal filesystem access
28 | (because of less disk IO).
29 |
30 | Technical details
31 | =================
32 |
33 | To make things easier on the PNG side, it just parses down until it gets a scanline serialization.
34 | Multiple directly following scanline (of same width) serializations parts build up a block
35 | (so it actually really matches a block in the real picture). But I don't do any of the PNG filtering.
36 | PNG spec:
37 |
38 | The general DB layout is as follows:
39 |
40 | - ("data." unique id -> zlib compressed data) data pairs
41 | - ("sha1refs." SHA1 -> set of ids) data pairs
42 | - ("fs." filename -> id) data pairs
43 |
44 | Such data value (uncompressed) starts with a data-type-byte. Only 3 types are there currently:
45 |
46 | - PNG file summary
47 | - PNG chunk (all non-data PNG chunks)
48 | - PNG block
49 |
50 | There are multiple DB backend implementations:
51 |
52 | - The filesystem itself. But creates a lot of files!
53 | - [Redis](http://redis.io/). Via [hiredis](https://github.com/antirez/hiredis). As everything is in memory, you are a bit limited.
54 | - [KyotoCabinet](http://fallabs.com/kyotocabinet/). (Currently the default.)
55 |
56 | Comparison with other compression methods / deduplicators
57 | =========================================================
58 |
59 | In the beginning, I thought about using some generic image library to be able to handle just any
60 | image type and then operate just on the raw data. This would even give me some slight better compression rate
61 | because now, I am operating on PNGs scanline serializations and there are 5 different ways (filters) in PNG
62 | to represent a scanline.
63 |
64 | However, because I am storing all the data as PNG raw data in the DB, the reconstruction of the PNG should
65 | be much faster. In the more generic case, I would have to recompress/reencode the PNG. Now I only have
66 | to (roughly) collect and glew the parts together and run the PNG zlib over it.
67 |
68 | Using a general deduplicator / compressor on the raw data (uncompressed PNG, TGA or BMP):
69 | It would be based on connected chunks of data; i.e., in the image, it would mean one or many following scanlines.
70 | But what I am doing is based on rectangular blocks in the image. So I am able to get much bigger
71 | chunks of data which is repetitive.
72 |
73 | Something like what is done in video compressions methods like H264: This might actually be a very good idea.
74 | And it should be possible to just add it now to my current method.
75 |
76 | Tools
77 | =====
78 |
79 | It comes with several tools. Some of them:
80 |
81 | - db-push: Pushes a single PNG into the DB.
82 | - db-push-dir: Pushes all PNGs in a given directory into the DB.
83 | - db-extract-file: Extracts a single PNG from the DB.
84 | - db-fuse: Simple FUSE interface to the DB. (Slow though because it is not very optimized!)
85 |
86 | Compilation
87 | ===========
88 |
89 | Just run `./compile.sh`.
90 |
91 | For Mac: If you haven't MacFUSE installed, install it from here:
92 |
93 | TODOs
94 | =====
95 |
96 | - Many parts could be optimized a lot.
97 | - Try with other DB backend implementations.
98 | Maybe [mongoDB](http://www.mongodb.org/) or [Basho Riak](http://www.basho.com/products_riak_overview.php).
99 | Or improve the filesystem implementation (which is incomplete anyway currently).
100 | - To make the FUSE interface faster, the caching must be improved.
101 | Also, there should be a way to get the filesize in advance and maybe also to seek in constant time.
102 | Probably, to make this possible, we need to have a fixed compression algorithm and
103 | the file summary must contain some offset information.
104 | - We could also store other image formats in a similar way. And also general files.
105 | There should be also a standard fallback.
106 | - The FUSE interface could also support writing.
107 |
108 |
109 | -Albert Zeyer,
110 |
--------------------------------------------------------------------------------
/kyotocabinet/kccommon.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************************************
2 | * Common symbols for the library
3 | * Copyright (C) 2009-2011 FAL Labs
4 | * This file is part of Kyoto Cabinet.
5 | * This program is free software: you can redistribute it and/or modify it under the terms of
6 | * the GNU General Public License as published by the Free Software Foundation, either version
7 | * 3 of the License, or any later version.
8 | * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 | * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 | * See the GNU General Public License for more details.
11 | * You should have received a copy of the GNU General Public License along with this program.
12 | * If not, see .
13 | *************************************************************************************************/
14 |
15 |
16 | #ifndef _KCCOMMON_H // duplication check
17 | #define _KCCOMMON_H
18 |
19 | extern "C" {
20 | #include
21 | }
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 |
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 |
53 | #include
54 | #include
55 | #include
56 | #include