vdr/tools.h
Klaus Schmidinger d5c85f5ff8 Version 1.3.32
- Added some missing braces in remux.c (thanks to Wayne Keer for reporting this one).
- Removed unused MAINMENUENTRY from svdrpdemo.c (thanks to Udo Richter for reporting
  this one).
- Fixed appending sequence end code in cDvbPlayer::Goto() (thanks to Reinhard Nissl).
- Fixed syncing in cRepacker (thanks to Reinhard Nissl).
- Now always using stream id 0xE0 for the video stream, to avoid problems with
  post processing tools that choke on different ids (suggested by Reinhard Nissl).
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Fixed cDvbPlayer::SkipFrames() to properly handle radio recordings (thanks to
  Reinhard Nissl).
- Updated the Swedish OSD texts (thanks to Tomas Prybil).
- Updated the Slovenian OSD texts (thanks to Matjaz Thaler).
- Updated the Danish OSD texts (thanks to Mogens Elneff).
- Made LIRC command parsing more robust (thanks to Ville Skyttä).
- Introduced a separate 'plugins-install' target in the Makefile (thanks to Daniel
  Thompson).
- Re-introduced the code that waits for a tuner lock in VDR/device.c, since
  apparently some users actually need it. It's not active by default, you'll have
  to define the WAIT_FOR_TUNER_LOCK macro in that file if you need it (suggested
  by Malcolm Caldwell).
- Adjusted the Makefile to the dvb-kernel driver on kernel 2.6 and up (thanks to
  Lauri Tischler).
- Repeat keys are now ignored when waiting for a keypress to cancel an operation
  (thanks to Marko Mäkelä).
- The main menu function of a plugin can now be activated through a key macro of
  the form "@plugin" even if that plugin doesn't have a main menu entry (using
  part of a patch by Hardy Flor, which originally implemented calling plugins from
  SVDRP).
- The menu timeout handling is now done centrally in the main program loop.
- Added missing help for the 'help' keyword in the SVDRP command PLUG.
- The main menu function of a plugin can now be called programmatically through
  the static function cRemote::CallPlugin().
- The SVDRP command PLUG now has a new option 'main' which can be used to initiate
  a call to the main menu function of a plugin (using part of a patch by Hardy Flor).
- The new command line option '--vfat' can be used to make VDR encode special
  characters in recording file names, even if it wasn't compiled with VFAT=1
  (suggested by Peter Bieringer). The compile time option VFAT still exists and
  creates a VDR that always behaves as if it were called with '--vfat'.
- Replaced the ':' delimiter between hour and minute in recording file names with
  a '.' under Linux, too. Existing recordings with ':' as delimiter will still work.
- Implemented the SVDRP command MOVC (thanks to Andreas Brachold).
- Added support for multiple audio language codes in ISO639LanguageDescriptors to
  'libsi' (thanks to Marcel Wiesweg).
- Changed the audio PID language codes to hold up to two 3 letter codes, separated
  by '+', to store separate languages broadcast in two channel audio mode.
- If the preferred audio language is broadcast on a PID that has two different
  languages in the two stereo channels, the audio channel is now properly set when
  switching to such a channel (thanks to Mogens Elneff for his help in testing this).
- Fixed some typos in MANUAL (thanks to Ville Skyttä).
- Fixed the default value for "Setup/EPG bugfix level" (thanks to Ville Skyttä for
  reporting this one).
- Fixed defining timers that only differ in the day of week (thanks to Patrick
  Rother for reporting this one).
- Fixed converting summary.vdr files that would result in a very long 'short text'
  (thanks to Carsten Koch).
- Implemented a hash for the channels to reduce the system load in the EIT scanning
  thread (based on a patch by Georg Acher).
2005-09-11 18:00:00 +02:00

290 lines
8.5 KiB
C++

/*
* tools.h: Various tools
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 1.76 2005/09/11 13:04:03 kls Exp $
*/
#ifndef __TOOLS_H
#define __TOOLS_H
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <sys/types.h>
typedef unsigned char uchar;
typedef unsigned long long int uint64;
extern int SysLogLevel;
#define esyslog(a...) void( (SysLogLevel > 0) ? syslog(LOG_ERR, a) : void() )
#define isyslog(a...) void( (SysLogLevel > 1) ? syslog(LOG_INFO, a) : void() )
#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog(LOG_DEBUG, a) : void() )
#define LOG_ERROR esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__)
#define LOG_ERROR_STR(s) esyslog("ERROR: %s: %m", s)
#define SECSINDAY 86400
#define KILOBYTE(n) ((n) * 1024)
#define MEGABYTE(n) ((n) * 1024 * 1024)
#define MAXPARSEBUFFER KILOBYTE(10)
#define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
#define DELETENULL(p) (delete (p), p = NULL)
#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
#define FATALERRNO (errno != EAGAIN && errno != EINTR)
#ifndef __STL_CONFIG_H // in case some plugin needs to use the STL
template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
#endif
#define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
int BCD2INT(int x);
// Unfortunately there are no platform independent macros for unaligned
// access. so we do it this way:
template<class T> inline T get_unaligned(T *p)
{
struct s { T v; } __attribute__((packed));
return ((s *)p)->v;
}
template<class T> inline void put_unaligned(unsigned int v, T* p)
{
struct s { T v; } __attribute__((packed));
((s *)p)->v = v;
}
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, ...);
};
ssize_t safe_read(int filedes, void *buffer, size_t size);
ssize_t safe_write(int filedes, const void *buffer, size_t size);
void writechar(int filedes, char c);
int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0);
///< Writes either all Data to the given file descriptor, or nothing at all.
///< If TimeoutMs is greater than 0, it will only retry for that long, otherwise
///< it will retry forever. RetryMs defines the time between two retries.
char *strcpyrealloc(char *dest, const char *src);
char *strn0cpy(char *dest, const char *src, size_t n);
char *strreplace(char *s, char c1, char c2);
char *strreplace(char *s, const char *s1, const char *s2); ///< re-allocates 's' and deletes the original string if necessary!
char *skipspace(const char *s);
char *stripspace(char *s);
char *compactspace(char *s);
cString strescape(const char *s, const char *chars);
bool startswith(const char *s, const char *p);
bool endswith(const char *s, const char *p);
bool isempty(const char *s);
int numdigits(int n);
bool isnumber(const char *s);
cString itoa(int n);
cString AddDirectory(const char *DirName, const char *FileName);
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
bool DirectoryOk(const char *DirName, bool LogErrors = false);
bool MakeDirs(const char *FileName, bool IsDirectory = false);
bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false);
char *ReadLink(const char *FileName); ///< returns a new strings allocated on the heap, which the caller must delete (or NULL in case of an error)
bool SpinUpDisk(const char *FileName);
time_t LastModifiedTime(const char *FileName);
cString WeekDayName(int WeekDay);
cString WeekDayName(time_t t);
cString DayDateTime(time_t t = 0);
cString TimeToString(time_t t);
cString DateString(time_t t);
cString TimeString(time_t t);
class cTimeMs {
private:
uint64 begin;
public:
cTimeMs(void);
static uint64 Now(void);
void Set(int Ms = 0);
bool TimedOut(void);
uint64 Elapsed(void);
};
class cReadLine {
private:
char buffer[MAXPARSEBUFFER];
public:
char *Read(FILE *f);
};
class cPoller {
private:
enum { MaxPollFiles = 16 };
pollfd pfd[MaxPollFiles];
int numFileHandles;
public:
cPoller(int FileHandle = -1, bool Out = false);
bool Add(int FileHandle, bool Out);
bool Poll(int TimeoutMs = 0);
};
class cReadDir {
private:
DIR *directory;
struct dirent *result;
union { // according to "The GNU C Library Reference Manual"
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} u;
public:
cReadDir(const char *Directory);
~cReadDir();
bool Ok(void) { return directory != NULL; }
struct dirent *Next(void);
};
class cFile {
private:
static bool files[];
static int maxFiles;
int f;
public:
cFile(void);
~cFile();
operator int () { return f; }
bool Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
bool Open(int FileDes);
void Close(void);
bool IsOpen(void) { return f >= 0; }
bool Ready(bool Wait = true);
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
static bool FileReady(int FileDes, int TimeoutMs = 1000);
static bool FileReadyForWriting(int FileDes, int TimeoutMs = 1000);
};
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 cLockFile {
private:
char *fileName;
int f;
public:
cLockFile(const char *Directory);
~cLockFile();
bool Lock(int WaitSeconds = 0);
void Unlock(void);
};
class cListObject {
private:
cListObject *prev, *next;
public:
cListObject(void);
virtual ~cListObject();
virtual int Compare(const cListObject &ListObject) const { return 0; }
///< Must return 0 if this object is equal to ListObject, a positive value
///< if it is "greater", and a negative value if it is "smaller".
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 Ins(cListObject *Object, cListObject *Before = NULL);
void Del(cListObject *Object, bool DeleteObject = true);
virtual void Move(int From, int To);
void Move(cListObject *From, cListObject *To);
virtual void Clear(void);
cListObject *Get(int Index) const;
int Count(void) const { return count; }
void Sort(void);
};
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 *Last(void) const { return (T *)lastObject; }
T *Prev(const T *object) const { return (T *)object->cListObject::Prev(); } // need to call cListObject's members to
T *Next(const T *object) const { return (T *)object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
};
class cHashObject : public cListObject {
friend class cHashBase;
private:
unsigned int id;
cListObject *object;
public:
cHashObject(cListObject *Object, unsigned int Id) { object = Object; id = Id; }
cListObject *Object(void) { return object; }
};
class cHashBase {
private:
cList<cHashObject> **hashTable;
int size;
unsigned int hashfn(unsigned int Id) const { return Id % size; }
protected:
cHashBase(int Size);
public:
virtual ~cHashBase();
void Add(cListObject *Object, unsigned int Id);
void Del(cListObject *Object, unsigned int Id);
void Clear(void);
cListObject *Get(unsigned int Id) const;
cList<cHashObject> *GetList(unsigned int Id) const;
};
#define HASHSIZE 512
template<class T> class cHash : public cHashBase {
public:
cHash(int Size = HASHSIZE) : cHashBase(Size) {}
T *Get(unsigned int Id) const { return (T *)cHashBase::Get(Id); }
};
#endif //__TOOLS_H