summaryrefslogtreecommitdiff
path: root/libsi/util.h
blob: a7f5d602b0799880a9012c30b557592b12a3c234 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/***************************************************************************
 *       Copyright (c) 2003 by Marcel Wiesweg                              *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   $Id: util.h 2.3 2012/02/26 13:58:26 kls Exp $
 *                                                                         *
 ***************************************************************************/

#ifndef LIBSI_UTIL_H
#define LIBSI_UTIL_H

#include <stdint.h>
#include <sys/types.h>
#include <pthread.h>
#include <time.h>

#define HILO(x) (x##_hi << 8 | x##_lo)
#define HILOHILO(x) (x##_hi_hi << 24 | x##_hi_lo << 16 | x##_lo_hi << 8 | x##_lo_lo)
#define BCD_TIME_TO_SECONDS(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \
                             (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \
                             ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF)))

namespace SI {

//Holds an array of unsigned char which is deleted
//when the last object pointing to it is deleted.
//Optimized for use in libsi.
class CharArray {
public:
   CharArray();

   CharArray(const CharArray &source);
   CharArray& operator=(const CharArray &source);
   ~CharArray();

   //can be called exactly once
   void assign(const unsigned char*data, int size, bool doCopy=true);
   //compares to a null-terminated string
   bool operator==(const char *string) const;
   //compares to another CharArray (data not necessarily null-terminated)
   bool operator==(const CharArray &other) const;

   //returns another CharArray with its offset incremented by offset
   CharArray operator+(const int offset) const;

   //access and convenience methods
   const unsigned char* getData() const { return data_->data+off; }
   const unsigned char* getData(int offset) const { return data_->data+offset+off; }
   template <typename T> const T* getData() const { return (T*)(data_->data+off); }
   template <typename T> const T* getData(int offset) const { return (T*)(data_->data+offset+off); }
      //sets p to point to data+offset, increments offset
   template <typename T> void setPointerAndOffset(const T* &p, int &offset) const { p=(T*)getData(offset); offset+=sizeof(T); }
   unsigned char operator[](const int index) const { return data_->data ? data_->data[off+index] : (unsigned char)0; }
   int getLength() const { return data_->size; }
   u_int16_t TwoBytes(const int index) const { return data_->data ? data_->TwoBytes(off+index) : u_int16_t(0); }
   u_int32_t FourBytes(const int index) const { return data_->data ? data_->FourBytes(off+index) : u_int32_t(0); }

   bool isValid() const { return data_->valid; }
   bool checkSize(int offset) { return (data_->valid && (data_->valid=(offset>=0 && off+offset < data_->size))); }

   void addOffset(int offset) { off+=offset; }
private:
   class Data {
   public:
      Data();
      virtual ~Data();

      virtual void assign(const unsigned char*data, int size) = 0;
      virtual void Delete() = 0;

      u_int16_t TwoBytes(const int index) const
         { return u_int16_t((data[index] << 8) | data[index+1]); }
      u_int32_t FourBytes(const int index) const
         { return u_int32_t((data[index] << 24) | (data[index+1] << 16) | (data[index+2] << 8) | data[index+3]); }
      /*#ifdef CHARARRAY_THREADSAFE
      void Lock();
      void Unlock();
      #else
      void Lock() {}
      void Unlock() {}
      #endif
      Data(const Data& d);
      void assign(int size);
      */

      const unsigned char*data;
      int size;

      // count_ is the number of CharArray objects that point at this
      // count_ must be initialized to 1 by all constructors
      // (it starts as 1 since it is pointed to by the CharArray object that created it)
      unsigned count_;

      bool valid;

      /*
      pthread_mutex_t mutex;
      pid_t lockingPid;
      pthread_t locked;
      */
   };
   class DataOwnData : public Data {
   public:
      DataOwnData() {}
      virtual ~DataOwnData();
      virtual void assign(const unsigned char*data, int size);
      virtual void Delete();
   };
   class DataForeignData : public Data {
   public:
      DataForeignData() {}
      virtual ~DataForeignData();
      virtual void assign(const unsigned char*data, int size);
      virtual void Delete();
   };
   Data* data_;
   int off;
};



//abstract base class
class Parsable {
public:
   void CheckParse();
protected:
   Parsable();
   virtual ~Parsable() {}
   //actually parses given data.
   virtual void Parse() = 0;
private:
   bool parsed;
};

//taken and adapted from libdtv, (c) Rolf Hakenes and VDR, (c) Klaus Schmidinger
namespace DVBTime {
time_t getTime(unsigned char date_hi, unsigned char date_lo, unsigned char timehr, unsigned char timemi, unsigned char timese);
time_t getDuration(unsigned char timehr, unsigned char timemi, unsigned char timese);
inline unsigned char bcdToDec(unsigned char b) { return (unsigned char)(((b >> 4) & 0x0F) * 10 + (b & 0x0F)); }
}

//taken and adapted from libdtv, (c) Rolf Hakenes
class CRC32 {
public:
   CRC32(const char *d, int len, u_int32_t CRCvalue=0xFFFFFFFF);
   bool isValid() { return crc32(data, length, value) == 0; }
   static bool isValid(const char *d, int len, u_int32_t CRCvalue=0xFFFFFFFF) { return crc32(d, len, CRCvalue) == 0; }
   static u_int32_t crc32(const char *d, int len, u_int32_t CRCvalue);
protected:
   static u_int32_t crc_table[256];

   const char *data;
   int length;
   u_int32_t value;
};

} //end of namespace

#endif