vdr  2.0.6
si.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (c) 2003 by Marcel Wiesweg *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 2 of the License, or *
7  * (at your option) any later version. *
8  * *
9  * $Id: si.h 2.6 2012/10/15 11:56:06 kls Exp $
10  * *
11  ***************************************************************************/
12 
13 #ifndef LIBSI_SI_H
14 #define LIBSI_SI_H
15 
16 #include <stdint.h>
17 
18 #include "util.h"
19 #include "headers.h"
20 
21 namespace SI {
22 
23 enum TableId { TableIdPAT = 0x00, //program association section
24  TableIdCAT = 0x01, //conditional access section
25  TableIdPMT = 0x02, //program map section
26  TableIdTSDT = 0x03,//transport stream description section
27  TableIdNIT = 0x40, //network information, actual network section
28  TableIdNIT_other = 0x41, //network information section, other network
29  TableIdSDT = 0x42, //service description section
31  TableIdBAT = 0x4A, //bouquet association section
32  TableIdEIT_presentFollowing = 0x4E, //event information section
34  //range from 0x50 to 0x5F
37  //range from 0x60 to 0x6F
40  TableIdTDT = 0x70, //time date section
41  TableIdRST = 0x71, //running status section
42  TableIdST = 0x72, //stuffing section
43  TableIdTOT = 0x73, //time offset section
44  TableIdDIT = 0x7E, //discontinuity information section
45  TableIdSIT = 0x7F, //service information section
46  TableIdAIT = 0x74, //application information section
47  TableIdPremiereCIT = 0xA0 //premiere content information section
48  };
49 
50 
52  // defined by ISO/IEC 13818-1
70  // defined by ISO-13818-6 (DSM-CC)
72  // 0x14 - 0x3F Reserved
73  // defined by ETSI (EN 300 468)
125  // defined by ETSI (EN 300 468) v 1.7.1
137  // Extension descriptors
150 
151  // Defined by ETSI TS 102 812 (MHP)
152  // They once again start with 0x00 (see page 234, MHP specification)
158  // 0x05 - 0x0A is unimplemented this library
171  // Premiere private Descriptor Tags
173 
174  //a descriptor currently unimplemented in this library
175  //the actual value 0xFF is "forbidden" according to the spec.
177 };
178 
180 
186  };
187 
198  };
199 
204  };
205 
206 /* Some principles:
207  - Objects that return references to other objects contained in their data must make sure
208  that the returned objects have been parsed.
209  (the Loop subclasses take care of that.)
210  Note that this does not apply to Loops and Strings (their are never returned by reference, BTW).
211 */
212 
213 class Object : public Parsable {
214 public:
215  Object();
216  Object(CharArray &d);
217  //can only be called once since data is immutable
218  void setData(const unsigned char*data, int size, bool doCopy=true);
219  CharArray getData() { return data; }
220  //returns the valid flag which indicates if data is all right or errors have been encountered
221  bool isValid() { return data.isValid(); }
222  virtual int getLength() = 0;
223 protected:
225  //is protected - not used for sections
226  template <class T> friend class StructureLoop;
227  void setData(CharArray &d);
228  //returns whether the given offset fits within the limits of the actual data
229  //The valid flag will be set accordingly
230  bool checkSize(int offset);
231 };
232 
233 class Section : public Object {
234 public:
235  //convenience: sets data and parses if doParse
236  Section(const unsigned char *data, bool doCopy=true);
237  Section() {}
238  TableId getTableId() const;
239  virtual int getLength();
240 
241  static int getLength(const unsigned char *d);
242  static TableId getTableId(const unsigned char *d);
243 };
244 
245 class CRCSection : public Section {
246 public:
247  //convenience: sets data and parses if doParse
248  CRCSection(const unsigned char *data, bool doCopy=true) : Section(data, doCopy) {}
250  bool isCRCValid();
251  //convenience: isValid+CheckParse
252  bool CheckCRCAndParse();
253 };
254 
255 /* A section which has the ExtendedSectionHeader
256  (section_syntax_indicator==1) */
257 class NumberedSection : public CRCSection {
258 public:
259  NumberedSection(const unsigned char *data, bool doCopy=true) : CRCSection(data, doCopy) {}
261  int getTableIdExtension() const;
262  bool getCurrentNextIndicator() const;
263  int getVersionNumber() const;
264  int getSectionNumber() const;
265  int getLastSectionNumber() const;
266  bool moreThanOneSection() const { return getLastSectionNumber()>0; }
267 
268  static int getTableIdExtension(const unsigned char *d);
269 };
270 
271 class VariableLengthPart : public Object {
272 public:
273  //never forget to call this
274  void setData(CharArray d, int l) { Object::setData(d); checkSize(l); length=l; }
275  //convenience method
276  void setDataAndOffset(CharArray d, int l, int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; }
277  virtual int getLength() { return length; }
278 private:
279  int length;
280 };
281 
282 class LoopElement : public Object {
283 };
284 
285 class Descriptor : public LoopElement {
286 public:
287  virtual int getLength();
289 
290  static int getLength(const unsigned char *d);
291  static DescriptorTag getDescriptorTag(const unsigned char *d);
292 protected:
293  friend class DescriptorLoop;
294  //returns a subclass of descriptor according to the data given.
295  //The object is allocated with new and must be delete'd.
296  //setData() will have been called, CheckParse() not.
297  //if returnUnimplemetedDescriptor==true:
298  // Never returns null - maybe the UnimplementedDescriptor.
299  //if returnUnimplemetedDescriptor==false:
300  // Never returns the UnimplementedDescriptor - maybe null
301  static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor);
302 };
303 
304 class Loop : public VariableLengthPart {
305 public:
306  class Iterator {
307  public:
308  Iterator() { i=0; }
309  void reset() { i=0; }
310  private:
311  template <class T> friend class StructureLoop;
312  friend class DescriptorLoop;
313  template <class T> friend class TypeLoop;
315  int i;
316  };
317 protected:
318  virtual void Parse() {}
319 };
320 
321 //contains LoopElements of one type only
322 template <class T> class StructureLoop : public Loop {
323 public:
324  //currently you must use a while-loop testing for hasNext()
325  //i must be 0 to get the first descriptor (with the first call)
326  bool getNext(T &obj, Iterator &it)
327  {
328  if (!isValid() || it.i >= getLength())
329  return false;
330  CharArray d=data;
331  d.addOffset(it.i);
332  T ret;
333  ret.setData(d);
334  ret.CheckParse();
335  if (!checkSize(ret.getLength()))
336  return false;
337  it.i+=ret.getLength();
338  obj=ret;
339  return true;
340  }
342  {
343  if (!isValid() || it.i >= getLength())
344  return 0;
345  CharArray d=data;
346  d.addOffset(it.i);
347  T *ret=new T();
348  ret->setData(d);
349  ret->CheckParse();
350  if (!checkSize(ret->getLength())) {
351  delete ret;
352  return 0;
353  }
354  it.i+=ret->getLength();
355  return ret;
356  }
357  //bool hasNext(Iterator &it) { return getLength() > it.i; }
358 };
359 
360 //contains descriptors of different types
361 class DescriptorLoop : public Loop {
362 public:
364  //i must be 0 to get the first descriptor (with the first call)
365  //All returned descriptors must be delete'd.
366  //returns null if no more descriptors available
367  Descriptor *getNext(Iterator &it);
368  //return the next descriptor with given tag, or 0 if not available.
369  //if returnUnimplemetedDescriptor==true:
370  // an UnimplementedDescriptor may be returned if the next matching descriptor is unimplemented,
371  // 0 will be returned if and only if no matching descriptor is found.
372  //if returnUnimplemetedDescriptor==false:
373  // if 0 is returned, either no descriptor with the given tag was found,
374  // or descriptors were found, but the descriptor type is not implemented
375  //In either case, a return value of 0 indicates that no further calls to this method
376  //with the iterator shall be made.
377  Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false);
378  //return the next descriptor with one of the given tags, or 0 if not available.
379  //if returnUnimplemetedDescriptor==true:
380  // returns 0 if and only if no descriptor with one of the given tags was found.
381  // The UnimplementedDescriptor may be returned.
382  //if returnUnimplemetedDescriptor==false:
383  // if 0 is returned, either no descriptor with one of the given tags was found,
384  // or descriptors were found, but none of them are implemented.
385  // The UnimplementedDescriptor will never be returned.
386  //In either case, a return value of 0 indicates that no further calls to this method
387  //with the iterator shall be made.
388  Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false);
389  //returns the number of descriptors in this loop
391  //writes the tags of the descriptors in this loop in the array,
392  // which must at least have the size getNumberOfDescriptors().
393  //The number of descriptors, i.e. getNumberOfDescriptors(), is returned.
394  // You can specify the array type (Descriptor tags are 8 Bit,
395  // you might e.g. choose a char, short, int or DescriptorTag array)
396  template <typename T> int getDescriptorTags(T *tags)
397  {
398  const unsigned char *p=data.getData();
399  const unsigned char *end=p+getLength();
400  int count=0;
401  while (p < end) {
402  tags[count++]=(T)Descriptor::getDescriptorTag(p);
403  p+=Descriptor::getLength(p);
404  }
405  return count;
406  }
407 protected:
408  Descriptor *createDescriptor(int &i, bool returnUnimplemetedDescriptor);
410 };
411 
412 typedef uint8_t EightBit;
413 typedef uint16_t SixteenBit;
414 typedef uint32_t ThirtyTwoBit;
415 typedef uint64_t SixtyFourBit;
416 
417 template <typename T> class TypeLoop : public Loop {
418 public:
419  int getCount() { return getLength()/sizeof(T); }
420  T operator[](const int index) const
421  {
422  switch (sizeof(T)) {
423  case 1:
424  return data[index];
425  case 2:
426  return data.TwoBytes(index);
427  case 4:
428  return data.FourBytes(index);
429  case 8:
430  return (SixtyFourBit(data.FourBytes(index)) << 32) | data.FourBytes(index+4);
431  default:
432  return 0; // just to avoid a compiler warning
433  }
434  return 0; // just to avoid a compiler warning
435  }
436  T getNext(Iterator &it) const
437  {
438  T ret=operator[](it.i);
439  it.i+=sizeof(T);
440  return ret;
441  }
442  bool hasNext(Iterator &it) { return isValid() && (getLength() > it.i); }
443 };
444 
446 public:
448 };
449 
450 //Premiere Content Information Table
452 public:
454 };
455 
456 //The content of the ExtendedEventDescriptor may be split over several
457 //descriptors if the text is longer than 256 bytes.
458 //The following classes provide base functionality to handle this case.
459 class GroupDescriptor : public Descriptor {
460 public:
461  virtual int getDescriptorNumber() = 0;
462  virtual int getLastDescriptorNumber() = 0;
463 };
464 
466 public:
469  void Add(GroupDescriptor *d);
470  void Delete();
471  int getLength() { return length; }
473  bool isComplete(); //if all descriptors have been added
474 protected:
475  int length;
478 };
479 
480 class String : public VariableLengthPart {
481 public:
482  //A note to the length: getLength() returns the length of the raw data.
483  //The text may be shorter. Its length can be obtained with one of the
484  //getText functions and strlen.
485 
486  //returns text. Data is allocated with new and must be delete'd by the user.
487  char *getText();
488  //copies text into given buffer.
489  //a buffer of size getLength()+1 is guaranteed to be sufficiently large.
490  //In most descriptors the string length is an 8-bit field,
491  //so the maximum there is 256.
492  //returns the given buffer for convenience.
493  //The emphasis marks 0x86 and 0x87 are still available.
494  char *getText(char *buffer, int size);
495  //The same semantics as for getText(char*) apply.
496  //The short version of the text according to ETSI TR 101 211 (chapter 4.6)
497  //will be written into the shortVersion buffer (which should, therefore, have the same
498  //length as buffer). If no shortVersion is available, shortVersion will contain
499  //an empty string.
500  //The emphasis marks 0x86 and 0x87 are still available in buffer, but not in shortVersion.
501  char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
502 protected:
503  virtual void Parse() {}
504  void decodeText(char *buffer, int size);
505  void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
506 };
507 
508 // Call this function to set the system character table. CharacterTable is a string
509 // like "iso8859-15" or "utf-8" (case insensitive).
510 // Returns true if the character table was recognized.
511 bool SetSystemCharacterTable(const char *CharacterTable);
512 // Determines the character table used in the given buffer and returns
513 // a string indicating that table. If no table can be determined, the
514 // default ISO6937 is returned. If a table can be determined, the buffer
515 // and length are adjusted accordingly.
516 const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL);
517 bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode);
519 
520 } //end of namespace
521 
522 #endif //LIBSI_SI_H
~DescriptorGroup()
Definition: si.c:187
bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode)
Definition: si.c:381
static Descriptor * getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor)
Definition: si.c:500
void setDataAndOffset(CharArray d, int l, int &offset)
Definition: si.h:276
Section()
Definition: si.h:237
GroupDescriptor ** array
Definition: si.h:476
T * getNextAsPointer(Iterator &it)
Definition: si.h:341
char * getText()
Definition: si.c:221
bool systemCharacterTableIsSingleByte(void)
Definition: si.c:316
Definition: si.h:179
bool getCurrentNextIndicator() const
Definition: si.c:80
CharArray getData()
Definition: si.h:219
Definition: si.h:480
RunningStatus
Definition: si.h:181
Descriptor * createDescriptor(int &i, bool returnUnimplemetedDescriptor)
Definition: si.c:159
bool isComplete()
Definition: si.c:214
const char * getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte)
Definition: si.c:345
int getDescriptorTags(T *tags)
Definition: si.h:396
virtual int getLength()
Definition: si.h:277
CRCSection()
Definition: si.h:249
void Delete()
Definition: si.c:193
bool isCRCValid()
Definition: si.c:61
int getNumberOfDescriptors()
Definition: si.c:170
DescriptorTag
Definition: si.h:51
uint64_t SixtyFourBit
Definition: si.h:415
virtual void Parse()
Definition: si.h:318
DescriptorTag getDescriptorTag() const
Definition: si.c:100
LinkageType
Definition: si.h:188
virtual void Parse()
Definition: si.h:503
TableId getTableId() const
Definition: si.c:45
uint32_t ThirtyTwoBit
Definition: si.h:414
virtual int getLastDescriptorNumber()=0
Definition: descriptor.c:16
int getSectionNumber() const
Definition: si.c:88
NumberedSection(const unsigned char *data, bool doCopy=true)
Definition: si.h:259
T operator[](const int index) const
Definition: si.h:420
virtual int getLength()
Definition: si.c:96
bool checkSize(int offset)
Definition: si.c:37
Definition: si.h:179
uint16_t SixteenBit
Definition: si.h:413
virtual int getLength()
Definition: si.c:49
int getTableIdExtension() const
Definition: si.c:72
virtual int getLength()=0
DescriptorLoop()
Definition: si.h:363
bool moreThanOneSection() const
Definition: si.h:266
uint8_t EightBit
Definition: si.h:412
Object()
Definition: si.c:23
void setData(const unsigned char *data, int size, bool doCopy=true)
Definition: si.c:29
DescriptorTagDomain domain
Definition: si.h:409
bool deleteOnDesctruction
Definition: si.h:477
virtual int getDescriptorNumber()=0
void setData(CharArray d, int l)
Definition: si.h:274
Definition: si.h:213
void Add(GroupDescriptor *d)
Definition: si.c:201
bool SetSystemCharacterTable(const char *CharacterTable)
Definition: si.c:321
void decodeText(char *buffer, int size)
Definition: si.c:424
bool CheckCRCAndParse()
Definition: si.c:65
DescriptorTagDomain
Definition: si.h:179
bool hasNext(Iterator &it)
Definition: si.h:442
GroupDescriptor ** getDescriptors()
Definition: si.h:472
T getNext(Iterator &it) const
Definition: si.h:436
int getVersionNumber() const
Definition: si.c:84
int getLastSectionNumber() const
Definition: si.c:92
bool getNext(T &obj, Iterator &it)
Definition: si.h:326
int getLength()
Definition: si.h:471
bool isValid()
Definition: si.h:221
CharArray data
Definition: si.h:224
u_int16_t TwoBytes(const int index) const
Definition: util.h:59
Definition: si.h:304
CRCSection(const unsigned char *data, bool doCopy=true)
Definition: si.h:248
void addOffset(int offset)
Definition: util.h:65
Definition: si.h:179
AudioType
Definition: si.h:200
u_int32_t FourBytes(const int index) const
Definition: util.h:60
TableId
Definition: si.h:23
const unsigned char * getData() const
Definition: util.h:51
int getCount()
Definition: si.h:419
Descriptor * getNext(Iterator &it)
Definition: si.c:112
DescriptorGroup(bool deleteOnDesctruction=true)
Definition: si.c:181
void reset()
Definition: si.h:309