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