Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Some fix and improvment for VDR 1.3.4



See attached patch files.

Some explanation of modifications :

1) ExtendedEventDescriptor handling doesn't work fine. Items should not be
concat with description text.
See this example :

EventInformationSection
  ExtentedEventDescriptor
    Description = "The cat eats the "
    ItemLoop
      Item
        ItemDescription = "Producer"
        Item = "Spielberg"
      Item
        ItemDescription = "Year"
        Item = "2004"
  ExtentedEventDescriptor
    Description = "mouse."

After parsing description member becomes "The cat eats the
ProducerSpielbergYear2004mouse." instead of "The cat eats the mouse.". I have
patched this handling on descriptor.[ch] and eit.c files.

2) I have added items handling on attached patch files. In EPG, 'I' tag has
been added : "I <item description>:<item>". I have some problem using sscanf
for reading back from epg.data file : uncomment line 234 in file epg.c causes
Segmentation fault.

3) I have correct descriptor.c file concerning nibble_content structure
aligment problem. I have also added nibbles handling on epg.[hc] and eit.c
files. In EPG, 'N' tag has been added : "N <cnl1>:<cnl2>:<un1>:<un2>". (c =
content, n = nibble, l = level, u = user)

4) I have correct descriptor.c file concerning parental_rating structure
aligment problem (same as 3)). I have added parental rating handling on
epg.[hc] and eit.c files. In EPG, 'R' tag has been added : "R <rating>".

Stephane ESTE-GRACIAS


--- libsi/descriptor.c.orig	2004-02-26 14:32:31.000000000 +0100
+++ libsi/descriptor.c	2004-02-26 16:34:07.000000000 +0100
@@ -67,32 +67,12 @@ int ExtendedEventDescriptors::getTextLen
       if (!d)
          continue;
       ret+=d->text.getLength()+1; //plus a blank
-      ExtendedEventDescriptor::Item item;
-      for (Loop::Iterator it; d->itemLoop.hasNext(it);   ) {
-         item=d->itemLoop.getNext(it);
-         ret+=item.item.getLength();
-         ret+=item.itemDescription.getLength();
-         ret+=2; //the blanks
-      }
-   }
-   return ret;
-}
-
-//is there a case where this function does not return the same as getTextLength?
-int ExtendedEventDescriptors::getMaximumTextLength() {
-   int ret=0;
-   for (int i=0;i<length;i++) {
-      ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
-      if (!d)
-         continue;
-      ret+=d->text.getLength()+1; //plus a blank
-      ret+=d->itemLoop.getLength();
    }
    return ret;
 }
 
 char *ExtendedEventDescriptors::getText() {
-   char *text=new char[getMaximumTextLength()];
+   char *text=new char[getTextLength()];
    return getText(text);
 }
 
@@ -110,25 +90,6 @@ char *ExtendedEventDescriptors::getText(
          memcpy(buffer+index, tempbuf, len);
          index+=len;
       }
-
-      ExtendedEventDescriptor::Item item;
-      for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
-         item=d->itemLoop.getNext(it);
-
-         item.item.getText(tempbuf);
-         len=strlen(tempbuf);
-         if (len) {
-            memcpy(buffer+index, tempbuf, len);
-            index+=len;
-         }
-
-         item.itemDescription.getText(tempbuf);
-         len=strlen(tempbuf);
-         if (len) {
-            memcpy(buffer+index, tempbuf, len);
-            index+=len;
-         }
-      }
    }
    buffer[index]='\0';
    return buffer;
@@ -148,7 +109,7 @@ void TimeShiftedEventDescriptor::Parse()
 
 void ContentDescriptor::Parse() {
    //this descriptor is only a header and a loop
-   nibbleLoop.setData(data+sizeof(SectionHeader), getLength()-sizeof(SectionHeader));
+   nibbleLoop.setData(data+sizeof(descr_content), getLength()-sizeof(descr_content));
 }
 
 int ContentDescriptor::Nibble::getContentNibbleLevel1() const {
@@ -173,7 +134,7 @@ void ContentDescriptor::Nibble::Parse() 
 
 void ParentalRatingDescriptor::Parse() {
    //this descriptor is only a header and a loop
-   ratingLoop.setData(data+sizeof(SectionHeader), getLength()-sizeof(SectionHeader));
+   ratingLoop.setData(data+sizeof(descr_parental_rating), getLength()-sizeof(descr_parental_rating));
 }
 
 int ParentalRatingDescriptor::Rating::getRating() const {
--- epg.h.orig	2004-02-26 10:55:58.000000000 +0100
+++ epg.h	2004-02-26 15:00:56.000000000 +0100
@@ -21,6 +21,31 @@
 
 class cSchedule;
 
+class cItem : public cListObject {
+private:
+  char *itemDescription; // Item description
+  char *item;            // Item text
+public:
+  cItem(const char *ItemDescription, const char *Item);
+  ~cItem();
+  const char *ItemDescription(void) const { return itemDescription; }
+  const char *Item(void) const { return item; }
+};
+
+class cNibble : public cListObject {
+private:
+  int contentNibbleLevel1;  // First level content identifier
+  int contentNibbleLevel2;  // Second level content identifier
+  int userNibble1;          // First broadcaster content identifier
+  int userNibble2;          // Second broadcaster content identifier
+public:
+  cNibble(int ContentNibbleLevel1, int ContentNibbleLevel2, int UserNibble1, int UserNibble2);
+  int ContentNibbleLevel1(void) const { return contentNibbleLevel1; };
+  int ContentNibbleLevel2(void) const { return contentNibbleLevel2; };
+  int UserNibble1(void) const { return userNibble1; };
+  int UserNibble2(void) const { return userNibble2; };
+};
+
 class cEvent : public cListObject {
 private:
   tChannelID channelID;  // Channel ID of program for this event
@@ -33,6 +58,9 @@ private:
   char *title;           // Title of this event
   char *shortText;       // Short description of this event (typically the episode name in case of a series)
   char *description;     // Description of this event
+  cList<cItem> *items;   // Item list of this event
+  cList<cNibble> *nibbles; // Nibble list of this event
+  int rating;            // Parental rating of this event
   time_t startTime;      // Start time of this event
   int duration;          // Duration of this event in seconds
   //XXX find an other solution, avoiding channelNumber???
@@ -49,6 +77,9 @@ public:
   const char *Title(void) const { return title; }
   const char *ShortText(void) const { return shortText; }
   const char *Description(void) const { return description; }
+  cList<cItem> *Items(void) const { return items; }
+  cList<cNibble> *Nibbles(void) const { return nibbles; }
+  int ParentalRating(void) const { return rating; }
   time_t StartTime(void) const { return startTime; }
   int Duration(void) const { return duration; }
   int ChannelNumber(void) const { return channelNumber; }
@@ -63,6 +94,9 @@ public:
   void SetTitle(const char *Title);
   void SetShortText(const char *ShortText);
   void SetDescription(const char *Description);
+  void AddItem(cItem *Item);
+  void AddNibble(cNibble *Nibble);
+  void SetParentalRating(int Rating);
   void SetStartTime(time_t StartTime);
   void SetDuration(int Duration);
   void SetChannelNumber(int ChannelNumber) const { ((cEvent *)this)->channelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const' //XXX
--- libsi/descriptor.h.orig	2004-02-26 14:32:40.000000000 +0100
+++ libsi/descriptor.h	2004-02-26 14:33:07.000000000 +0100
@@ -50,13 +50,8 @@ private:
 
 class ExtendedEventDescriptors : public DescriptorGroup {
 public:
-     //don't use
    int getTextLength();
-     //really fast
-   int getMaximumTextLength();
-   //same semantics as with SI::String
    char *getText();
-   //buffer must at least be getTextLength(), getMaximumTextLength() is a good choice
    char *getText(char *buffer);
 };
 
--- eit.c.orig	2004-02-26 10:55:28.000000000 +0100
+++ eit.c	2004-02-26 17:09:34.000000000 +0100
@@ -91,6 +91,7 @@ cEIT::cEIT(cSchedules *Schedules, int So
 
       int LanguagePreferenceShort = -1;
       int LanguagePreferenceExt = -1;
+      int LanguagePreferenceRating = -1;
       bool UseExtendedEventDescriptor = false;
       SI::Descriptor *d;
       SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
@@ -122,9 +123,25 @@ cEIT::cEIT(cSchedules *Schedules, int So
                     }
                  }
                  break;
-            case SI::ContentDescriptorTag:
+            case SI::ContentDescriptorTag: {
+                 SI::ContentDescriptor *cd = (SI::ContentDescriptor *)d;
+                 SI::ContentDescriptor::Nibble nibble;
+                 for (SI::Loop::Iterator iterator; cd->nibbleLoop.hasNext(iterator); ) {
+                    nibble = cd->nibbleLoop.getNext(iterator);
+                    pEvent->AddNibble(new cNibble(nibble.getContentNibbleLevel1(), nibble.getContentNibbleLevel2(), nibble.getUserNibble1(), nibble.getUserNibble2()));
+                    }
+                 }
                  break;
-            case SI::ParentalRatingDescriptorTag:
+            case SI::ParentalRatingDescriptorTag: {
+                 SI::ParentalRatingDescriptor *prd = (SI::ParentalRatingDescriptor *)d;
+                 SI::ParentalRatingDescriptor::Rating rating;
+                 for (SI::Loop::Iterator iterator; prd->ratingLoop.hasNext(iterator); ) {
+                    rating = prd->ratingLoop.getNext(iterator);
+                    if (I18nIsPreferredLanguage(Setup.EPGLanguages, I18nLanguageIndex(rating.languageCode), LanguagePreferenceRating)) {
+                       pEvent->SetParentalRating(rating.getRating());
+                       }
+                    }
+                 }
                  break;
             case SI::TimeShiftedEventDescriptorTag: {
                  SI::TimeShiftedEventDescriptor *tsed = (SI::TimeShiftedEventDescriptor *)d;
@@ -181,8 +198,22 @@ cEIT::cEIT(cSchedules *Schedules, int So
             pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer));
             }
          if (ExtendedEventDescriptors) {
-            char buffer[ExtendedEventDescriptors->getMaximumTextLength()];
+            char buffer[ExtendedEventDescriptors->getTextLength()];
             pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer));
+
+            SI::ExtendedEventDescriptor **array = (SI::ExtendedEventDescriptor **) ExtendedEventDescriptors->getDescriptors();
+            for (int i=0; i<ExtendedEventDescriptors->getLength(); i++) {
+               SI::ExtendedEventDescriptor *d = (SI::ExtendedEventDescriptor *) array[i];
+               if (!d)
+                 continue;
+               SI::ExtendedEventDescriptor::Item item;
+               for (SI::Loop::Iterator it; d->itemLoop.hasNext(it); ) {
+                  item = d->itemLoop.getNext(it);
+                  char itemDescriptionText[item.itemDescription.getLength()];
+                  char itemText[item.item.getLength()];
+                  pEvent->AddItem(new cItem(item.itemDescription.getText(itemDescriptionText), item.item.getText(itemText)));
+                  }
+               }
             }
          }
       delete ExtendedEventDescriptors;
--- epg.c.orig	2004-02-26 10:56:09.000000000 +0100
+++ epg.c	2004-02-26 18:06:14.000000000 +0100
@@ -14,6 +14,32 @@
 #include <ctype.h>
 #include <time.h>
 
+// --- cItem -----------------------------------------------------------------
+
+cItem::cItem(const char *ItemDescription, const char *Item)
+{
+  itemDescription = NULL;
+  item = NULL;
+  itemDescription = strcpyrealloc(itemDescription, ItemDescription);
+  item = strcpyrealloc(item, Item);
+}
+
+cItem::~cItem()
+{
+  free(itemDescription);
+  free(item);
+}
+
+// --- cNibble ---------------------------------------------------------------
+
+cNibble::cNibble(int ContentNibbleLevel1, int ContentNibbleLevel2, int UserNibble1, int UserNibble2)
+{
+  contentNibbleLevel1 = ContentNibbleLevel1;
+  contentNibbleLevel2 = ContentNibbleLevel2;
+  userNibble1 = UserNibble1;
+  userNibble2 = UserNibble2;
+}
+
 // --- cEvent ----------------------------------------------------------------
 
 cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
@@ -26,6 +52,9 @@ cEvent::cEvent(tChannelID ChannelID, u_i
   title = NULL;
   shortText = NULL;
   description = NULL;
+  items = NULL;
+  nibbles = NULL;
+  rating = 0;
   startTime = 0;
   duration = 0;
   channelNumber = 0;
@@ -36,6 +65,8 @@ cEvent::~cEvent()
   free(title);
   free(shortText);
   free(description);
+  delete(items);
+  delete(nibbles);
 }
 
 void cEvent::SetEventID(u_int16_t EventID)
@@ -78,6 +109,27 @@ void cEvent::SetDescription(const char *
   description = strcpyrealloc(description, Description);
 }
 
+void cEvent::AddItem(cItem *Item)
+{
+  if (!items) {
+     items = new cList<cItem>;
+     }
+  items->Add(Item);
+}
+
+void cEvent::AddNibble(cNibble *Nibble)
+{
+  if (!nibbles) {
+     nibbles = new cList<cNibble>;
+     }
+  nibbles->Add(Nibble);
+}
+
+void cEvent::SetParentalRating(int Rating)
+{
+  rating = Rating;
+}
+
 void cEvent::SetStartTime(time_t StartTime)
 {
   startTime = StartTime;
@@ -123,6 +175,18 @@ void cEvent::Dump(FILE *f, const char *P
         fprintf(f, "%sS %s\n", Prefix, shortText);
      if (!isempty(description))
         fprintf(f, "%sD %s\n", Prefix, description);
+     if (items) {
+        for (cItem *item = items->First(); item; item = items->Next(item)) {
+            fprintf(f, "%sI %s:%s\n", Prefix, item->ItemDescription(), item->Item());
+            }
+        }
+     if (nibbles) {
+        for (cNibble *nibble = nibbles->First(); nibble; nibble = nibbles->Next(nibble)) {
+            fprintf(f, "%sN %d:%d:%d:%d\n", Prefix, nibble->ContentNibbleLevel1(), nibble->ContentNibbleLevel2(), nibble->UserNibble1(), nibble->UserNibble2());
+            }
+        }
+     if (rating)
+        fprintf(f, "%sR %d\n", Prefix, rating);
      fprintf(f, "%se\n", Prefix);
      }
 }
@@ -162,6 +226,34 @@ bool cEvent::Read(FILE *f, cSchedule *Sc
              case 'D': if (Event)
                           Event->SetDescription(t);
                        break;
+             case 'I': if (Event) {
+                          char *ItemDescription = NULL;
+                          char *Item = NULL;
+                          int n = sscanf(t, "%a[^:]:%a", &ItemDescription, &Item);
+                          if (n == 2) {
+                             //Event->AddItem(new cItem(ItemDescription, Item));
+                             }
+                          }
+                       break;
+             case 'N': if (Event) {
+                          int ContentNibbleLevel1;
+                          int ContentNibbleLevel2;
+                          int UserNibble1;
+                          int UserNibble2;
+                          int n = sscanf(t, "%d:%d:%d:%d", &ContentNibbleLevel1, &ContentNibbleLevel2, &UserNibble1, &UserNibble2);
+                          if (n == 4) {
+                             Event->AddNibble(new cNibble(ContentNibbleLevel1, ContentNibbleLevel2, UserNibble1, UserNibble2));
+                             }
+                          }
+                       break;
+             case 'R': if (Event) {
+                          int Rating;
+                          int n = sscanf(t, "%d", &Rating);
+                          if (n == 1) {
+                             Event->SetParentalRating(Rating);
+                             }
+                          }
+                       break;
              case 'e': Event = NULL;
                        break;
              case 'c': // to keep things simple we react on 'c' here

Home | Main Index | Thread Index