From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/hdb/filemap.h | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/hdb/filemap.h (limited to 'src/hdb/filemap.h') diff --git a/src/hdb/filemap.h b/src/hdb/filemap.h new file mode 100644 index 0000000..d6af7eb --- /dev/null +++ b/src/hdb/filemap.h @@ -0,0 +1,196 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FILEMAPH +#define FILEMAPH + +#include +#include +#include +#include +#include + +////////////////////////////////////////////// +// +// NOTE that filemap is MT unsafe: +// it needs to be called from dbmap +// +// The exception is when filelocking; +// that's MT safe per filemap, and hence +// should not be locked further +// + +#define HEADLOCK(fm) headlock_t headlock(fm) + +////////////////////////////////////////////////////// + +// network byteorder +class byte4 { +public: + byte4() {} // must be uninitialized + explicit byte4(int h): n(htonl(h)) {} + void set(int h) { n=htonl(h); } + void add(int h) { n=htonl(ntohl(n)+h); } + int get() const { return ntohl(n); } +private: + long n; +}; + +////////////////////////////////////////////////////// + +class filemap { +public: + typedef char char32[32]; + static const int maxtabs=32; + + //////////////////////////////////////////////////// + + struct head_t { + char32 ident; + byte4 lock; + byte4 minor; + byte4 major; + byte4 fatal; + byte4 filesize; + byte4 filetop; + byte4 tables; + byte4 index; + char32 compname; + char32 tabs[maxtabs]; + byte4 frame; + + head_t(); + head_t(const head_t* hd,int mem); + + void setcomp(int idx, const sref& cp); + + sref get(int col) const { return sref(tabs[col]); } + void set(int col,const sref& s); + void insert(int col,const sref& s); + void remove(int col); + }; + + head_t* head() { return hd; } + const head_t* head() const { return hd; } + + /////////////////////////////////////////////////////// + + struct rec_t { + byte4 mem; + byte4 caps; + }; + + rec_t* at(int off) { + for(chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); return 0; + } + const rec_t* at(int off) const { + for(const chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); + return 0; + } + + int recs() const { return hd->frame.get(); } + int size(int off) const { + if(offfiletop.get()) { + for(const chunk_t* p=mem;p;p=p->next) + if(p->own(off)) return p->at(off)->mem.get(); + } + return 0; + } + + /////////////////////////////////////////////////////// + + void remap(); + + rec_t* add(int n); + void rem(rec_t* rec); + + /////////////////////////////////////////////////////// + + filemap(filemap* p); + filemap(filemap* p,const mstring& path,int update=0,int prot=0600); + ~filemap(); + + filemap* next; + + /////////////////////////////////////////////////////// + + void open(const mstring& path,int update=0,int prot=0600) throw(merror_t); + void save(const mstring& path,int prot=0600) throw(merror_t); + void check() throw(merror_t); + void close(); + void sync(); + + const mstring& Pathname() const { return pathname; } + time_t Lastmod() const; + + int reference() const { return refs; } + int writable() const { return wok; } + + void pushref() { refs++; } + void popref() { refs--; } + + /////////////////////////////////////////////////////// + + void lock(); + void unlock(); + + /////////////////////////////////////////////////////// + +protected: + struct chunk_t { + chunk_t* next; + long begin; + long end; + char* map; + + int size() const { return end-begin; } + + chunk_t(chunk_t* p,int fd,int wok,int off,int size); + ~chunk_t(); + + int own(int off) const { return off>=begin&&offlock(); } + ~headlock_t() { if(fm) fm->unlock(); } +}; + +#endif + -- cgit v1.2.3