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: descriptor.c 2.0 2007/02/03 11:45:58 kls Exp $
10  *                                                                         *
11  ***************************************************************************/
12 
13 #include <string.h>
14 #include "descriptor.h"
15 
16 namespace SI {
17 
Parse()18 void ShortEventDescriptor::Parse() {
19    int offset=0;
20    const descr_short_event *s;
21    data.setPointerAndOffset<const descr_short_event>(s, offset);
22    languageCode[0]=s->lang_code1;
23    languageCode[1]=s->lang_code2;
24    languageCode[2]=s->lang_code3;
25    languageCode[3]=0;
26    name.setDataAndOffset(data+offset, s->event_name_length, offset);
27    const descr_short_event_mid *mid;
28    data.setPointerAndOffset<const descr_short_event_mid>(mid, offset);
29    text.setData(data+offset, mid->text_length);
30 }
31 
getDescriptorNumber()32 int ExtendedEventDescriptor::getDescriptorNumber() {
33    return s->descriptor_number;
34 }
35 
getLastDescriptorNumber()36 int ExtendedEventDescriptor::getLastDescriptorNumber() {
37    return s->last_descriptor_number;
38 }
39 
Parse()40 void ExtendedEventDescriptor::Parse() {
41    int offset=0;
42    data.setPointerAndOffset<const descr_extended_event>(s, offset);
43    languageCode[0]=s->lang_code1;
44    languageCode[1]=s->lang_code2;
45    languageCode[2]=s->lang_code3;
46    languageCode[3]=0;
47    itemLoop.setDataAndOffset(data+offset, s->length_of_items, offset);
48    const descr_extended_event_mid *mid;
49    data.setPointerAndOffset<const descr_extended_event_mid>(mid, offset);
50    text.setData(data+offset, mid->text_length);
51 }
52 
Parse()53 void ExtendedEventDescriptor::Item::Parse() {
54    int offset=0;
55    const item_extended_event *first;
56    data.setPointerAndOffset<const item_extended_event>(first, offset);
57    itemDescription.setDataAndOffset(data+offset, first->item_description_length, offset);
58    const item_extended_event_mid *mid;
59    data.setPointerAndOffset<const item_extended_event_mid>(mid, offset);
60    item.setData(data+offset, mid->item_length);
61 }
62 
63 /*int ExtendedEventDescriptors::getTextLength() {
64    int ret=0;
65    for (int i=0;i<length;i++) {
66       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
67       if (!d)
68          continue;
69       ret+=d->text.getLength();
70       ExtendedEventDescriptor::Item item;
71       for (Loop::Iterator it; d->itemLoop.hasNext(it);   ) {
72          item=d->itemLoop.getNext(it);
73          ret+=item.item.getLength();
74          ret+=item.itemDescription.getLength();
75          ret+=2; //the blanks
76       }
77    }
78    return ret;
79 }*/
80 
getMaximumTextLength(const char * separation1,const char * separation2)81 int ExtendedEventDescriptors::getMaximumTextLength(const char *separation1, const char *separation2) {
82    //add length of plain text, of itemized text with separators, and for one separator between the two fields.
83    return getMaximumTextPlainLength()+getMaximumTextItemizedLength(separation1, separation2)+strlen(separation2);
84 }
85 
getText(const char * separation1,const char * separation2)86 char *ExtendedEventDescriptors::getText(const char *separation1, const char *separation2) {
87    int size = getMaximumTextLength(separation1, separation2);
88    char *text=new char[size];
89    return getText(text, size, separation1, separation2);
90 }
91 
getText(char * buffer,int size,const char * separation1,const char * separation2)92 char *ExtendedEventDescriptors::getText(char *buffer, int size, const char *separation1, const char *separation2) {
93    int index=0, len;
94    for (int i=0;i<length;i++) {
95       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
96       if (!d)
97          continue;
98       d->text.getText(buffer+index, size);
99       len = strlen(buffer+index);
100       index += len;
101       size -= len;
102    }
103 
104    int sepLen1 = strlen(separation1);
105    int sepLen2 = strlen(separation2);
106    bool separated = false;
107    for (int i=0;i<length;i++) {
108       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
109       if (!d)
110          continue;
111 
112       ExtendedEventDescriptor::Item item;
113       for (Loop::Iterator it; d->itemLoop.getNext(item, it);   ) {
114          if (!separated && size > sepLen2) {
115             strcpy(buffer+index, separation2); // let's have a separator between the long text and the items
116             index += sepLen2;
117             size -= sepLen2;
118             separated = true;
119          }
120 
121          item.itemDescription.getText(buffer+index, size);
122          len = strlen(buffer+index);
123          index += len;
124          size -= len;
125          if (size > sepLen1) {
126             strcpy(buffer+index, separation1);
127             index += sepLen1;
128             size -= sepLen1;
129          }
130 
131          item.item.getText(buffer+index, size);
132          len = strlen(buffer+index);
133          index += len;
134          size -= len;
135          if (size > sepLen2) {
136             strcpy(buffer+index, separation2);
137             index += sepLen2;
138             size -= sepLen2;
139          }
140       }
141    }
142 
143    buffer[index]='\0';
144    return buffer;
145 }
146 
getMaximumTextPlainLength()147 int ExtendedEventDescriptors::getMaximumTextPlainLength() {
148    int ret=0;
149    for (int i=0;i<length;i++) {
150       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
151       if (!d)
152          continue;
153       ret+=d->text.getLength();
154    }
155    return ret;
156 }
157 
getTextPlain()158 char *ExtendedEventDescriptors::getTextPlain() {
159    int size = getMaximumTextPlainLength();
160    char *text=new char[size];
161    return getTextPlain(text, size);
162 }
163 
getTextPlain(char * buffer,int size)164 char *ExtendedEventDescriptors::getTextPlain(char *buffer, int size) {
165    int index=0, len;
166    for (int i=0;i<length;i++) {
167       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
168       if (!d)
169          continue;
170       d->text.getText(buffer+index, size);
171       len = strlen(buffer+index);
172       index += len;
173       size -= len;
174    }
175    buffer[index]='\0';
176    return buffer;
177 }
178 
getMaximumTextItemizedLength(const char * separation1,const char * separation2)179 int ExtendedEventDescriptors::getMaximumTextItemizedLength(const char *separation1, const char *separation2) {
180    int ret=0;
181    int sepLength=strlen(separation1)+strlen(separation2);
182    for (int i=0;i<length;i++) {
183       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
184       if (!d)
185          continue;
186       //The length includes two 8-bit length fields which have already been subtracted from sepLength //XXX kls 2004-06-06: what does this mean???
187       ret+=d->itemLoop.getLength()+sepLength;
188    }
189    return ret;
190 }
191 
getTextItemized(const char * separation1,const char * separation2)192 char *ExtendedEventDescriptors::getTextItemized(const char *separation1, const char *separation2) {
193    int size = getMaximumTextItemizedLength(separation1, separation2);
194    char *text=new char[size];
195    return getTextItemized(text, size, separation1, separation2);
196 }
197 
getTextItemized(char * buffer,int size,const char * separation1,const char * separation2)198 char *ExtendedEventDescriptors::getTextItemized(char *buffer, int size, const char *separation1, const char *separation2) {
199    int index=0, len;
200    int sepLen1 = strlen(separation1);
201    int sepLen2 = strlen(separation2);
202    for (int i=0;i<length;i++) {
203       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
204       if (!d)
205          continue;
206 
207       ExtendedEventDescriptor::Item item;
208       for (Loop::Iterator it; d->itemLoop.getNext(item, it);   ) {
209          item.itemDescription.getText(buffer+index, size);
210          len = strlen(buffer+index);
211          index += len;
212          size -= len;
213          if (size > sepLen1) {
214             strcpy(buffer+index, separation1);
215             index += sepLen1;
216             size -= sepLen1;
217          }
218 
219          item.item.getText(buffer+index, size);
220          len = strlen(buffer+index);
221          index += len;
222          size -= len;
223          if (size > sepLen2) {
224             strcpy(buffer+index, separation2);
225             index += sepLen2;
226             size -= sepLen2;
227          }
228       }
229    }
230    buffer[index]='\0';
231    return buffer;
232 }
233 
234 //returns the itemized text pair by pair. Maximum length for buffers is 256.
235 //Return value is false if and only if the end of the list is reached.
getTextItemized(Loop::Iterator & it,bool & valid,char * itemDescription,char * itemText,int sizeItemDescription,int sizeItemText)236 bool ExtendedEventDescriptors::getTextItemized(Loop::Iterator &it, bool &valid, char *itemDescription, char *itemText, int sizeItemDescription, int sizeItemText) {
237    //The iterator has to store two values: The descriptor index (4bit)
238    //and the item loop index (max overall length 256, min item length 16 => max number 128 => 7bit)
239    valid=false;
240 
241    int index=(it.i & 0x780) >> 7; // 0x780 == 1111 000 0000
242    it.i &= 0x7F; //0x7F == 111 1111
243 
244    for (;index<length;index++) {
245       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[index];
246       if (!d)
247          continue;
248 
249       ExtendedEventDescriptor::Item item;
250       if (d->itemLoop.getNext(item, it)) {
251          item.item.getText(itemDescription, sizeItemDescription);
252          item.itemDescription.getText(itemText, sizeItemText);
253          valid=true;
254          break;
255       } else {
256          it.reset();
257          continue;
258       }
259    }
260 
261    it.i &= 0x7F;
262    it.i |= (index & 0xF) << 7; //0xF == 1111
263 
264    return index<length;
265 }
266 
getReferenceServiceId()267 int TimeShiftedEventDescriptor::getReferenceServiceId() const {
268    return HILO(s->reference_service_id);
269 }
270 
getReferenceEventId()271 int TimeShiftedEventDescriptor::getReferenceEventId() const {
272    return HILO(s->reference_event_id);
273 }
274 
Parse()275 void TimeShiftedEventDescriptor::Parse() {
276    s=data.getData<const descr_time_shifted_event>();
277 }
278 
Parse()279 void ContentDescriptor::Parse() {
280    //this descriptor is only a header and a loop
281    nibbleLoop.setData(data+sizeof(descr_content), getLength()-sizeof(descr_content));
282 }
283 
getContentNibbleLevel1()284 int ContentDescriptor::Nibble::getContentNibbleLevel1() const {
285    return s->content_nibble_level_1;
286 }
287 
getContentNibbleLevel2()288 int ContentDescriptor::Nibble::getContentNibbleLevel2() const {
289    return s->content_nibble_level_2;
290 }
291 
getUserNibble1()292 int ContentDescriptor::Nibble::getUserNibble1() const {
293    return s->user_nibble_1;
294 }
295 
getUserNibble2()296 int ContentDescriptor::Nibble::getUserNibble2() const {
297    return s->user_nibble_2;
298 }
299 
Parse()300 void ContentDescriptor::Nibble::Parse() {
301    s=data.getData<const nibble_content>();
302 }
303 
Parse()304 void ParentalRatingDescriptor::Parse() {
305    //this descriptor is only a header and a loop
306    ratingLoop.setData(data+sizeof(descr_parental_rating), getLength()-sizeof(descr_parental_rating));
307 }
308 
getRating()309 int ParentalRatingDescriptor::Rating::getRating() const {
310    return s->rating;
311 }
312 
Parse()313 void ParentalRatingDescriptor::Rating::Parse() {
314    s=data.getData<const parental_rating>();
315    languageCode[0]=s->lang_code1;
316    languageCode[1]=s->lang_code2;
317    languageCode[2]=s->lang_code3;
318    languageCode[3]=0;
319 }
320 
Parse()321 void TeletextDescriptor::Parse() {
322    //this descriptor is only a header and a loop
323    teletextLoop.setData(data+sizeof(descr_teletext), getLength()-sizeof(descr_teletext));
324 }
325 
Parse()326 void TeletextDescriptor::Teletext::Parse() {
327    s=data.getData<const item_teletext>();
328    languageCode[0]=s->lang_code1;
329    languageCode[1]=s->lang_code2;
330    languageCode[2]=s->lang_code3;
331    languageCode[3]=0;
332 }
333 
getTeletextType()334 int TeletextDescriptor::Teletext::getTeletextType() const {
335    return s->type;
336 }
337 
getTeletextMagazineNumber()338 int TeletextDescriptor::Teletext::getTeletextMagazineNumber() const {
339    return s->magazine_number;
340 }
341 
getTeletextPageNumber()342 int TeletextDescriptor::Teletext::getTeletextPageNumber() const {
343    return s->page_number;
344 }
345 
getCaType()346 int CaDescriptor::getCaType() const {
347    return HILO(s->CA_type);
348 }
349 
getCaPid()350 int CaDescriptor::getCaPid() const {
351    return HILO(s->CA_PID);
352 }
353 
Parse()354 void CaDescriptor::Parse() {
355    int offset=0;
356    data.setPointerAndOffset<const descr_ca>(s, offset);
357    if (checkSize(getLength()-offset))
358       privateData.assign(data.getData(offset), getLength()-offset);
359 }
360 
getComponentTag()361 int StreamIdentifierDescriptor::getComponentTag() const {
362    return s->component_tag;
363 }
364 
Parse()365 void StreamIdentifierDescriptor::Parse() {
366    s=data.getData<const descr_stream_identifier>();
367 }
368 
Parse()369 void NetworkNameDescriptor::Parse() {
370    name.setData(data+sizeof(descr_network_name), getLength()-sizeof(descr_network_name));
371 }
372 
Parse()373 void CaIdentifierDescriptor::Parse() {
374    identifiers.setData(data+sizeof(descr_ca_identifier), getLength()-sizeof(descr_ca_identifier));
375 }
376 
getCarouselId()377 int CarouselIdentifierDescriptor::getCarouselId() const {
378    return (HILO(s->carousel_id_hi) << 16) | HILO(s->carousel_id_lo);
379 }
380 
getFormatId()381 int CarouselIdentifierDescriptor::getFormatId() const {
382    return s->FormatId;
383 }
384 
Parse()385 void CarouselIdentifierDescriptor::Parse() {
386    s=data.getData<const descr_carousel_identifier>();
387 }
388 
Parse()389 void ServiceListDescriptor::Parse() {
390    serviceLoop.setData(data+sizeof(descr_service_list), getLength()-sizeof(descr_service_list));
391 }
392 
getServiceId()393 int ServiceListDescriptor::Service::getServiceId() const {
394    return HILO(s->service_id);
395 }
396 
getServiceType()397 int ServiceListDescriptor::Service::getServiceType() const {
398    return s->service_type;
399 }
400 
Parse()401 void ServiceListDescriptor::Service::Parse() {
402    s=data.getData<const descr_service_list_loop>();
403 }
404 
getFrequency()405 int SatelliteDeliverySystemDescriptor::getFrequency() const {
406    return (HILO(s->frequency_hi) << 16) | HILO(s->frequency_lo);
407 }
408 
getOrbitalPosition()409 int SatelliteDeliverySystemDescriptor::getOrbitalPosition() const {
410    return HILO(s->orbital_position);
411 }
412 
getWestEastFlag()413 int SatelliteDeliverySystemDescriptor::getWestEastFlag() const {
414    return s->west_east_flag;
415 }
416 
getPolarization()417 int SatelliteDeliverySystemDescriptor::getPolarization() const {
418    return s->polarization;
419 }
420 
getModulationSystem()421 int SatelliteDeliverySystemDescriptor::getModulationSystem() const {
422    return s->modulation_system;
423 }
424 
getModulationType()425 int SatelliteDeliverySystemDescriptor::getModulationType() const {
426    return s->modulation_type;
427 }
428 
getRollOff()429 int SatelliteDeliverySystemDescriptor::getRollOff() const {
430    return s->roll_off;
431 }
432 
getSymbolRate()433 int SatelliteDeliverySystemDescriptor::getSymbolRate() const {
434    return (HILO(s->symbol_rate_hi) << 12) | (s->symbol_rate_lo_1 << 4) | s->symbol_rate_lo_2;
435 }
436 
getFecInner()437 int SatelliteDeliverySystemDescriptor::getFecInner() const {
438    return s->fec_inner;
439 }
440 
Parse()441 void SatelliteDeliverySystemDescriptor::Parse() {
442    s=data.getData<const descr_satellite_delivery_system>();
443 }
444 
getFrequency()445 int CableDeliverySystemDescriptor::getFrequency() const {
446    return (HILO(s->frequency_hi) << 16) | HILO(s->frequency_lo);
447 }
448 
getFecOuter()449 int CableDeliverySystemDescriptor::getFecOuter() const {
450    return s->fec_outer;
451 }
452 
getModulation()453 int CableDeliverySystemDescriptor::getModulation() const {
454    return s->modulation;
455 }
456 
getSymbolRate()457 int CableDeliverySystemDescriptor::getSymbolRate() const {
458    return (HILO(s->symbol_rate_hi) << 12) | (s->symbol_rate_lo_1 << 4) | s->symbol_rate_lo_2;
459 }
460 
getFecInner()461 int CableDeliverySystemDescriptor::getFecInner() const {
462    return s->fec_inner;
463 }
464 
Parse()465 void CableDeliverySystemDescriptor::Parse() {
466    s=data.getData<const descr_cable_delivery_system>();
467 }
468 
getFrequency()469 int TerrestrialDeliverySystemDescriptor::getFrequency() const {
470    return (HILO(s->frequency_hi) << 16) | HILO(s->frequency_lo);
471 }
472 
getPriority()473 int TerrestrialDeliverySystemDescriptor::getPriority() const {
474    return s->priority;
475 }
476 
getTimeSlicingIndicator()477 int TerrestrialDeliverySystemDescriptor::getTimeSlicingIndicator() const {
478    return s->time_slicing_indicator;
479 }
480 
getMpeFecIndicator()481 int TerrestrialDeliverySystemDescriptor::getMpeFecIndicator() const {
482    return s->mpe_fec_indicator;
483 }
484 
getBandwidth()485 int TerrestrialDeliverySystemDescriptor::getBandwidth() const {
486    return s->bandwidth;
487 }
488 
getConstellation()489 int TerrestrialDeliverySystemDescriptor::getConstellation() const {
490    return s->constellation;
491 }
492 
getHierarchy()493 int TerrestrialDeliverySystemDescriptor::getHierarchy() const {
494    return s->hierarchy;
495 }
496 
getCodeRateHP()497 int TerrestrialDeliverySystemDescriptor::getCodeRateHP() const {
498    return s->code_rate_HP;
499 }
500 
getCodeRateLP()501 int TerrestrialDeliverySystemDescriptor::getCodeRateLP() const {
502    return s->code_rate_LP;
503 }
504 
getGuardInterval()505 int TerrestrialDeliverySystemDescriptor::getGuardInterval() const {
506    return s->guard_interval;
507 }
508 
getTransmissionMode()509 int TerrestrialDeliverySystemDescriptor::getTransmissionMode() const {
510    return s->transmission_mode;
511 }
512 
getOtherFrequency()513 bool TerrestrialDeliverySystemDescriptor::getOtherFrequency() const {
514    return s->other_frequency_flag;
515 }
516 
Parse()517 void TerrestrialDeliverySystemDescriptor::Parse() {
518    s=data.getData<const descr_terrestrial_delivery>();
519 }
520 
getServiceType()521 int ServiceDescriptor::getServiceType() const {
522    return s->service_type;
523 }
524 
Parse()525 void ServiceDescriptor::Parse() {
526    int offset=0;
527    data.setPointerAndOffset<const descr_service>(s, offset);
528    providerName.setDataAndOffset(data+offset, s->provider_name_length, offset);
529    const descr_service_mid *mid;
530    data.setPointerAndOffset<const descr_service_mid>(mid, offset);
531    serviceName.setData(data+offset, mid->service_name_length);
532 }
533 
Parse()534 void NVODReferenceDescriptor::Parse() {
535    serviceLoop.setData(data+sizeof(descr_nvod_reference), getLength()-sizeof(descr_nvod_reference));
536 }
537 
getTransportStream()538 int NVODReferenceDescriptor::Service::getTransportStream() const {
539    return HILO(s->transport_stream_id);
540 }
541 
getOriginalNetworkId()542 int NVODReferenceDescriptor::Service::getOriginalNetworkId() const {
543    return HILO(s->original_network_id);
544 }
545 
getServiceId()546 int NVODReferenceDescriptor::Service::getServiceId() const {
547    return HILO(s->service_id);
548 }
549 
Parse()550 void NVODReferenceDescriptor::Service::Parse() {
551    s=data.getData<const item_nvod_reference>();
552 }
553 
getReferenceServiceId()554 int TimeShiftedServiceDescriptor::getReferenceServiceId() const {
555    return HILO(s->reference_service_id);
556 }
557 
Parse()558 void TimeShiftedServiceDescriptor::Parse() {
559    s=data.getData<const descr_time_shifted_service>();
560 }
561 
getStreamContent()562 int ComponentDescriptor::getStreamContent() const {
563    return s->stream_content;
564 }
565 
getComponentType()566 int ComponentDescriptor::getComponentType() const {
567    return s->component_type;
568 }
569 
getComponentTag()570 int ComponentDescriptor::getComponentTag() const {
571    return s->component_tag;
572 }
573 
Parse()574 void ComponentDescriptor::Parse() {
575    int offset=0;
576    data.setPointerAndOffset<const descr_component>(s, offset);
577    languageCode[0]=s->lang_code1;
578    languageCode[1]=s->lang_code2;
579    languageCode[2]=s->lang_code3;
580    languageCode[3]=0;
581    description.setData(data+offset, getLength()-offset);
582 }
583 
Parse()584 void PrivateDataSpecifierDescriptor::Parse() {
585    s=data.getData<const descr_private_data_specifier>();
586 }
587 
getPrivateDataSpecifier()588 int PrivateDataSpecifierDescriptor::getPrivateDataSpecifier() const {
589    return (HILO(s->private_data_specifier_hi) << 16) | HILO(s->private_data_specifier_lo);
590 }
591 
Parse()592 void SubtitlingDescriptor::Parse() {
593    subtitlingLoop.setData(data+sizeof(descr_subtitling), getLength()-sizeof(descr_subtitling));
594 }
595 
getSubtitlingType()596 int SubtitlingDescriptor::Subtitling::getSubtitlingType() const {
597    return s->subtitling_type;
598 }
599 
getCompositionPageId()600 int SubtitlingDescriptor::Subtitling::getCompositionPageId() const {
601    return HILO(s->composition_page_id);
602 }
603 
getAncillaryPageId()604 int SubtitlingDescriptor::Subtitling::getAncillaryPageId() const {
605    return HILO(s->ancillary_page_id);
606 }
607 
Parse()608 void SubtitlingDescriptor::Subtitling::Parse() {
609    s=data.getData<const item_subtitling>();
610    languageCode[0]=s->lang_code1;
611    languageCode[1]=s->lang_code2;
612    languageCode[2]=s->lang_code3;
613    languageCode[3]=0;
614 }
615 
getNewOriginalNetworkId()616 int ServiceMoveDescriptor::getNewOriginalNetworkId() const {
617    return HILO(s->new_original_network_id);
618 }
619 
getNewTransportStreamId()620 int ServiceMoveDescriptor::getNewTransportStreamId() const {
621    return HILO(s->new_transport_stream_id);
622 }
623 
getNewServiceId()624 int ServiceMoveDescriptor::getNewServiceId() const {
625    return HILO(s->new_service_id);
626 }
627 
Parse()628 void ServiceMoveDescriptor::Parse() {
629    s=data.getData<const descr_service_move>();
630 }
631 
getCodingType()632 int FrequencyListDescriptor::getCodingType() const {
633    return s->coding_type;
634 }
635 
Parse()636 void FrequencyListDescriptor::Parse() {
637    int offset=0;
638    data.setPointerAndOffset<const descr_frequency_list>(s, offset);
639    frequencies.setData(data+offset, getLength()-offset);
640 }
641 
Parse()642 void ServiceIdentifierDescriptor::Parse() {
643    textualServiceIdentifier.setData(data+sizeof(descr_service_identifier), getLength()-sizeof(descr_service_identifier));
644 }
645 
Parse()646 void MultilingualNameDescriptor::Parse() {
647    nameLoop.setData(data+sizeof(descr_multilingual_network_name), getLength()-sizeof(descr_multilingual_network_name));
648 }
649 
Parse()650 void MultilingualNameDescriptor::Name::Parse() {
651    int offset=0;
652    const entry_multilingual_name *s;
653    data.setPointerAndOffset<const entry_multilingual_name>(s, offset);
654    languageCode[0]=s->lang_code1;
655    languageCode[1]=s->lang_code2;
656    languageCode[2]=s->lang_code3;
657    languageCode[3]=0;
658    name.setData(data+offset, s->text_length);
659 }
660 
getComponentTag()661 int MultilingualComponentDescriptor::getComponentTag() const {
662    return s->component_tag;
663 }
664 
Parse()665 void MultilingualComponentDescriptor::Parse() {
666    int offset=0;
667    data.setPointerAndOffset<const descr_multilingual_component>(s, offset);
668    nameLoop.setData(data+sizeof(descr_multilingual_component), getLength()-sizeof(descr_multilingual_component));
669 }
670 
Parse()671 void MultilingualServiceNameDescriptor::Parse() {
672    nameLoop.setData(data+sizeof(descr_multilingual_network_name), getLength()-sizeof(descr_multilingual_network_name));
673 }
674 
Parse()675 void MultilingualServiceNameDescriptor::Name::Parse() {
676    int offset=0;
677    const entry_multilingual_name *s;
678    data.setPointerAndOffset<const entry_multilingual_name>(s, offset);
679    languageCode[0]=s->lang_code1;
680    languageCode[1]=s->lang_code2;
681    languageCode[2]=s->lang_code3;
682    languageCode[3]=0;
683    providerName.setDataAndOffset(data+offset, s->text_length, offset);
684    const entry_multilingual_service_name_mid *mid;
685    data.setPointerAndOffset<const entry_multilingual_service_name_mid>(mid, offset);
686    name.setData(data+offset, mid->service_name_length);
687 }
688 
Parse()689 void LocalTimeOffsetDescriptor::Parse() {
690    localTimeOffsetLoop.setData(data+sizeof(descr_local_time_offset), getLength()-sizeof(descr_local_time_offset));
691 }
692 
getCountryId()693 int LocalTimeOffsetDescriptor::LocalTimeOffset::getCountryId() const {
694    return s->country_region_id;
695 }
696 
getLocalTimeOffsetPolarity()697 int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffsetPolarity() const {
698    return s->local_time_offset_polarity;
699 }
700 
getLocalTimeOffset()701 int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffset() const {
702    return (s->local_time_offset_h << 8) | s->local_time_offset_m;
703 }
704 
getTimeOfChange()705 time_t LocalTimeOffsetDescriptor::LocalTimeOffset::getTimeOfChange() const {
706    return DVBTime::getTime(s->time_of_change_mjd_hi, s->time_of_change_mjd_lo, s->time_of_change_time_h, s->time_of_change_time_m, s->time_of_change_time_s);
707 }
708 
getNextTimeOffset()709 int LocalTimeOffsetDescriptor::LocalTimeOffset::getNextTimeOffset() const {
710    return (s->next_time_offset_h << 8) | s->next_time_offset_m;
711 }
712 
Parse()713 void LocalTimeOffsetDescriptor::LocalTimeOffset::Parse() {
714    s=data.getData<const local_time_offset_entry>();
715    countryCode[0]=s->country_code1;
716    countryCode[1]=s->country_code2;
717    countryCode[2]=s->country_code3;
718    countryCode[3]=0;
719 }
720 
Parse()721 void LinkageDescriptor::Parse() {
722    int offset=0;
723    s1 = NULL;
724    data.setPointerAndOffset<const descr_linkage>(s, offset);
725    if (checkSize(getLength()-offset)) {
726       if (getLinkageType() == LinkageTypeMobileHandover)
727          data.setPointerAndOffset<const descr_linkage_8>(s1, offset);
728       privateData.assign(data.getData(offset), getLength()-offset);
729       }
730 }
731 
getTransportStreamId()732 int LinkageDescriptor::getTransportStreamId() const {
733    return HILO(s->transport_stream_id);
734 }
735 
getOriginalNetworkId()736 int LinkageDescriptor::getOriginalNetworkId() const {
737    return HILO(s->original_network_id);
738 }
739 
getServiceId()740 int LinkageDescriptor::getServiceId() const {
741    return HILO(s->service_id);
742 }
743 
getLinkageType()744 LinkageType LinkageDescriptor::getLinkageType() const {
745    return (LinkageType)s->linkage_type;
746 }
747 
getHandOverType()748 int LinkageDescriptor::getHandOverType() const {
749    return s1 == NULL ? 0 : s1->hand_over_type;
750 }
751 
getOriginType()752 int LinkageDescriptor::getOriginType() const {
753    return s1 == NULL ? 0 : s1->origin_type;
754 }
755 
getId()756 int LinkageDescriptor::getId() const {
757    return s1 == NULL ? 0 : HILO(s1->id);
758 }
759 
Parse()760 void ISO639LanguageDescriptor::Parse() {
761    languageLoop.setData(data+sizeof(descr_iso_639_language), getLength()-sizeof(descr_iso_639_language));
762 
763    //all this is for backwards compatibility only
764    Loop::Iterator it;
765    Language first;
766    if (languageLoop.getNext(first, it)) {
767       languageCode[0]=first.languageCode[0];
768       languageCode[1]=first.languageCode[1];
769       languageCode[2]=first.languageCode[2];
770       languageCode[3]=0;
771    } else
772       languageCode[0]=0;
773 }
774 
Parse()775 void ISO639LanguageDescriptor::Language::Parse() {
776    s=data.getData<const descr_iso_639_language_loop>();
777    languageCode[0]=s->lang_code1;
778    languageCode[1]=s->lang_code2;
779    languageCode[2]=s->lang_code3;
780    languageCode[3]=0;
781 }
782 
getAudioType()783 AudioType ISO639LanguageDescriptor::Language::getAudioType() {
784    return (AudioType)s->audio_type;
785 }
786 
Parse()787 void PDCDescriptor::Parse() {
788    int offset=0;
789    data.setPointerAndOffset<const descr_pdc>(s, offset);
790 }
791 
getDay()792 int PDCDescriptor::getDay() const {
793    return ((s->pil0 & 0x0F) << 1) | ((s->pil1 & 0x80) >> 7);
794 }
795 
getMonth()796 int PDCDescriptor::getMonth() const {
797    return (s->pil1 >> 3) & 0x0F;
798 }
799 
getHour()800 int PDCDescriptor::getHour() const {
801    return ((s->pil1 & 0x07) << 2) | ((s->pil2 & 0xC0) >> 6);
802 }
803 
getMinute()804 int PDCDescriptor::getMinute() const {
805    return s->pil2 & 0x3F;
806 }
807 
Parse()808 void AncillaryDataDescriptor::Parse() {
809    int offset=0;
810    data.setPointerAndOffset<const descr_ancillary_data>(s, offset);
811 }
812 
getAncillaryDataIdentifier()813 int AncillaryDataDescriptor::getAncillaryDataIdentifier() const {
814    return s->ancillary_data_identifier;
815 }
816 
Parse()817 void S2SatelliteDeliverySystemDescriptor::Parse() {
818    int offset=0;
819    input_stream_identifier=0;
820    data.setPointerAndOffset<const descr_s2_satellite_delivery_system>(s, offset);
821    if (s->scrambling_sequence_selector)
822       data.setPointerAndOffset<const descr_scrambling_sequence_selector>(sss, offset);
823    if (s->multiple_input_stream_flag)
824       input_stream_identifier = *data.getData(offset++);
825 }
826 
getScramblingSequenceSelector()827 int S2SatelliteDeliverySystemDescriptor::getScramblingSequenceSelector() const {
828    return s->scrambling_sequence_selector;
829 }
830 
getMultipleInputStreamFlag()831 int S2SatelliteDeliverySystemDescriptor::getMultipleInputStreamFlag() const {
832    return s->multiple_input_stream_flag;
833 }
834 
getBackwardsCompatibilityIndicator()835 int S2SatelliteDeliverySystemDescriptor::getBackwardsCompatibilityIndicator() const {
836    return s->backwards_compatibility_indicator;
837 }
838 
getScramblingSequenceIndex()839 int S2SatelliteDeliverySystemDescriptor::getScramblingSequenceIndex() const {
840    return sss == NULL ? 0 : (sss->scrambling_sequence_index_hi_lo << 16) | HILO(sss->scrambling_sequence_index_lo);
841 }
842 
Parse()843 void ExtensionDescriptor::Parse() {
844    int offset=0;
845    data.setPointerAndOffset<const descr_extension>(s, offset);
846 }
847 
getExtensionDescriptorTag()848 int ExtensionDescriptor::getExtensionDescriptorTag() const {
849    return s->descriptor_tag_extension;
850 }
851 
getOriginalNetworkId()852 int PremiereContentTransmissionDescriptor::getOriginalNetworkId() const {
853    return HILO(s->original_network_id);
854 }
855 
getTransportStreamId()856 int PremiereContentTransmissionDescriptor::getTransportStreamId() const {
857    return HILO(s->transport_stream_id);
858 }
859 
getServiceId()860 int PremiereContentTransmissionDescriptor::getServiceId() const {
861    return HILO(s->service_id);
862 }
863 
Parse()864 void PremiereContentTransmissionDescriptor::Parse() {
865    s=data.getData<const descr_premiere_content_transmission>();
866    startDayLoop.setData(data+sizeof(descr_premiere_content_transmission), getLength()-sizeof(descr_premiere_content_transmission));
867 }
868 
getMJD()869 int PremiereContentTransmissionDescriptor::StartDayEntry::getMJD() const {
870    return HILO(s->mjd);
871 }
872 
getLoopLength()873 int PremiereContentTransmissionDescriptor::StartDayEntry::getLoopLength() const {
874    return s->start_time_loop;
875 }
876 
getLength()877 int PremiereContentTransmissionDescriptor::StartDayEntry::getLength() {
878    return sizeof(item_premiere_content_transmission_day)+getLoopLength();
879 }
880 
Parse()881 void PremiereContentTransmissionDescriptor::StartDayEntry::Parse() {
882    s=data.getData<const item_premiere_content_transmission_day>();
883    startTimeLoop.setData(data+sizeof(item_premiere_content_transmission_day), getLoopLength());
884 }
885 
getStartTime(int mjd)886 time_t PremiereContentTransmissionDescriptor::StartDayEntry::StartTimeEntry::getStartTime(int mjd) const {
887    return DVBTime::getTime(mjd >> 8, mjd & 0xff, s->start_time_h, s->start_time_m, s->start_time_s);
888 }
889 
Parse()890 void PremiereContentTransmissionDescriptor::StartDayEntry::StartTimeEntry::Parse() {
891    s=data.getData<const item_premiere_content_transmission_time>();
892 }
893 
Parse()894 void ApplicationSignallingDescriptor::Parse() {
895    entryLoop.setData(data+sizeof(descr_application_signalling), getLength()-sizeof(descr_application_signalling));
896 }
897 
getApplicationType()898 int ApplicationSignallingDescriptor::ApplicationEntryDescriptor::getApplicationType() const {
899    return HILO(s->application_type);
900 }
901 
getAITVersionNumber()902 int ApplicationSignallingDescriptor::ApplicationEntryDescriptor::getAITVersionNumber() const {
903    return s->AIT_version_number;
904 }
905 
Parse()906 void ApplicationSignallingDescriptor::ApplicationEntryDescriptor::Parse() {
907    s=data.getData<const application_signalling_entry>();
908 }
909 
isServiceBound()910 bool MHP_ApplicationDescriptor::isServiceBound() const {
911    return s->service_bound_flag;
912 }
913 
getVisibility()914 int MHP_ApplicationDescriptor::getVisibility() const {
915    return s->visibility;
916 }
917 
getApplicationPriority()918 int MHP_ApplicationDescriptor::getApplicationPriority() const {
919    return s->application_priority;
920 }
921 
Parse()922 void MHP_ApplicationDescriptor::Parse() {
923    int offset=0;
924    const descr_application *dapp;
925    data.setPointerAndOffset<const descr_application>(dapp, offset);
926    profileLoop.setDataAndOffset(data+offset, dapp->application_profiles_length, offset);
927    data.setPointerAndOffset<const descr_application_end>(s, offset);
928    transportProtocolLabels.setData(data+offset, getLength()-offset);
929 }
930 
getApplicationProfile()931 int MHP_ApplicationDescriptor::Profile::getApplicationProfile() const {
932       return HILO(s->application_profile);
933 }
934 
getVersionMajor()935 int MHP_ApplicationDescriptor::Profile::getVersionMajor() const {
936       return s->version_major;
937 }
938 
getVersionMinor()939 int MHP_ApplicationDescriptor::Profile::getVersionMinor() const {
940       return s->version_minor;
941 }
942 
getVersionMicro()943 int MHP_ApplicationDescriptor::Profile::getVersionMicro() const {
944       return s->version_micro;
945 }
946 
Parse()947 void MHP_ApplicationDescriptor::Profile::Parse() {
948    s=data.getData<application_profile_entry>();
949 }
950 
Parse()951 void MHP_ApplicationNameDescriptor::Parse() {
952    nameLoop.setData(data+sizeof(descr_application_name), getLength()-sizeof(descr_application_name));
953 }
954 
Parse()955 void MHP_ApplicationNameDescriptor::NameEntry::Parse() {
956    const descr_application_name_entry *s;
957    s=data.getData<const descr_application_name_entry>();
958    name.setData(data+sizeof(descr_application_name_entry), s->application_name_length);
959    languageCode[0]=s->lang_code1;
960    languageCode[1]=s->lang_code2;
961    languageCode[2]=s->lang_code3;
962    languageCode[3]=0;
963 }
964 
getProtocolId()965 int MHP_TransportProtocolDescriptor::getProtocolId() const {
966    return HILO(s->protocol_id);
967 }
968 
getProtocolLabel()969 int MHP_TransportProtocolDescriptor::getProtocolLabel() const {
970    return s->transport_protocol_label;
971 }
972 
isRemote()973 bool MHP_TransportProtocolDescriptor::isRemote() const {
974    return remote;
975 }
976 
getComponentTag()977 int MHP_TransportProtocolDescriptor::getComponentTag() const {
978    return componentTag;
979 }
980 
Parse()981 void MHP_TransportProtocolDescriptor::Parse() {
982    int offset=0;
983    data.setPointerAndOffset<const descr_transport_protocol>(s, offset);
984    if (getProtocolId() == ObjectCarousel) {
985       const transport_via_oc *oc;
986       data.setPointerAndOffset<const transport_via_oc>(oc, offset);
987       remote=oc->remote;
988       if (remote) {
989          const transport_via_oc_remote_end *rem;
990          data.setPointerAndOffset<const transport_via_oc_remote_end>(rem, offset);
991          componentTag=rem->component_tag;
992       } else {
993          const transport_via_oc_end *rem;
994          data.setPointerAndOffset<const transport_via_oc_end>(rem, offset);
995          componentTag=rem->component_tag;
996       }
997    } else { //unimplemented
998       remote=false;
999       componentTag=-1;
1000    }
1001 }
1002 
Parse()1003 void MHP_DVBJApplicationDescriptor::Parse() {
1004    applicationLoop.setData(data+sizeof(descr_dvbj_application), getLength()-sizeof(descr_dvbj_application));
1005 }
1006 
Parse()1007 void MHP_DVBJApplicationDescriptor::ApplicationEntry::Parse() {
1008    const descr_dvbj_application_entry *entry=data.getData<const descr_dvbj_application_entry>();
1009    parameter.setData(data+sizeof(descr_dvbj_application_entry), entry->parameter_length);
1010 }
1011 
Parse()1012 void MHP_DVBJApplicationLocationDescriptor::Parse() {
1013    int offset=0;
1014    const descr_dvbj_application_location *first;
1015    data.setPointerAndOffset<const descr_dvbj_application_location>(first, offset);
1016    baseDirectory.setDataAndOffset(data+offset, first->base_directory_length, offset);
1017    const descr_dvbj_application_location_mid *mid;
1018    data.setPointerAndOffset<const descr_dvbj_application_location_mid>(mid, offset);
1019    classPath.setDataAndOffset(data+offset, mid->classpath_extension_length, offset);
1020    initialClass.setData(data+offset, getLength()-offset);
1021 }
1022 
getIconFlags()1023 int MHP_ApplicationIconsDescriptor::getIconFlags() const {
1024    return HILO(s->icon_flags);
1025 }
1026 
Parse()1027 void MHP_ApplicationIconsDescriptor::Parse() {
1028    int offset=0;
1029    const descr_application_icons_descriptor *first;
1030    data.setPointerAndOffset<const descr_application_icons_descriptor>(first, offset);
1031    iconLocator.setDataAndOffset(data+offset, first->icon_locator_length, offset);
1032    data.setPointerAndOffset<const descr_application_icons_descriptor_end>(s, offset);
1033 }
1034 
1035 } //end of namespace
1036