/*
 * tools.h: Various tools
 *
 * See the main source file 'vdr.c' for copyright information and
 * how to reach the author.
 *
 * $Id: tools.h 1.83 2005/11/05 10:54:39 kls Exp $
 */

#ifndef __TOOLS_H
#define __TOOLS_H

#define uint64 unsigned long long

#include <stdio.h>

#define index(s,c) (strchr((s),(c)))

#define get_unaligned(ptr) (*(ptr))
#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))

#define MALLOC(type, size)  (type *)malloc(sizeof(type) * (size))

class cString {
private:
	char *s;
public:
	cString(const char *S = NULL, bool TakePointer = false);
	virtual ~cString();
	operator const char * () const { return s; } // for use in (const char *) context
	const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.) 
	cString &operator=(const cString &String);
	static cString sprintf(const char *fmt, ...);
};

char *skipspace(const char *s);
char *stripspace(char *s);
cString AddDirectory(const char *DirName, const char *FileName);
int readlink (const char * name, char * buf, int size);
char *ReadLink(const char *FileName); ///< returns a new string allocated on the heap, which the caller must delete (or NULL in case of an error)

int gettimeofday (struct timeval *tv, void *tz);

class cTimeMs {
private:
	uint64 begin;
public:
	cTimeMs(void);
	static uint64 Now(void);
	void Set(int Ms = 0);
	bool TimedOut(void);
	uint64 Elapsed(void);
};

class cSafeFile {
private:
	FILE *f;
	char *fileName;
	char *tempName;
public:
	cSafeFile(const char *FileName);
	~cSafeFile();
	operator FILE* () { return f; }
	bool Open(void);
	bool Close(void);
};

class cListObject {
private:
	cListObject *prev, *next;
public:
	cListObject(void);
	virtual ~cListObject();
	void Append(cListObject *Object);
	void Insert(cListObject *Object);
	void Unlink(void);
	int Index(void) const;
	cListObject *Prev(void) const { return prev; }
	cListObject *Next(void) const { return next; }
};

class cListBase {
protected:
	cListObject *objects, *lastObject;
	cListBase(void);
	int count;
public:
	virtual ~cListBase();
	void Add(cListObject *Object, cListObject *After = NULL);
	void Del(cListObject *Object, bool DeleteObject = true);
	virtual void Clear(void);
	cListObject *Get(int Index) const;
	int Count(void) const { return count; }
};

template<class T> class cList : public cListBase {
public:
	T *Get(int Index) const { return (T *)cListBase::Get(Index); }
	T *First(void) const { return (T *)objects; }
	T *Next(const T *object) const { return (T *)object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
};

#endif //__TOOLS_H
