mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-09-11 23:50:58 +02:00
reformat wiith unix2dos & astyle
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@1495 e54a6e83-5905-42d5-8d5c-058d10e6a962
Origin commit data
------------------
Commit: 7dab3d9e3e
Author: Jacek Jendrzej <overx300@gmail.com>
Date: 2011-05-26 (Thu, 26 May 2011)
This commit is contained in:
@@ -129,28 +129,31 @@ inline unsigned min(unsigned a, unsigned b)
|
||||
|
||||
static int get_table(unsigned char hi, unsigned char mid, unsigned char lo)
|
||||
{
|
||||
char lang[4];
|
||||
lang[0] = hi; lang[1] = mid; lang[2] = lo; lang[3] = 0;
|
||||
if(!strcmp(lang, "pol"))
|
||||
return 2;
|
||||
else if(!strcmp(lang, "tur"))
|
||||
return 9;
|
||||
else if(!strcmp(lang, "gre"))
|
||||
return 7;
|
||||
else if(!strcmp(lang, "rus"))
|
||||
return 5;
|
||||
else if(!strcmp(lang, "bul"))
|
||||
return 5;
|
||||
else if(!strcmp(lang, "ara"))
|
||||
return 6;
|
||||
return 0;
|
||||
char lang[4];
|
||||
lang[0] = hi;
|
||||
lang[1] = mid;
|
||||
lang[2] = lo;
|
||||
lang[3] = 0;
|
||||
if(!strcmp(lang, "pol"))
|
||||
return 2;
|
||||
else if(!strcmp(lang, "tur"))
|
||||
return 9;
|
||||
else if(!strcmp(lang, "gre"))
|
||||
return 7;
|
||||
else if(!strcmp(lang, "rus"))
|
||||
return 5;
|
||||
else if(!strcmp(lang, "bul"))
|
||||
return 5;
|
||||
else if(!strcmp(lang, "ara"))
|
||||
return 6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool check_blacklisted(const t_original_network_id onid, const t_transport_stream_id tsid)
|
||||
{
|
||||
if ( (onid == 0x0001) &&
|
||||
((tsid == 0x03F0) || (tsid == 0x0408) || (tsid == 0x040E) || (tsid == 0x0412) || (tsid == 0x0416) || (tsid == 0x041E) ||
|
||||
(tsid == 0x0420) || (tsid == 0x0422) || (tsid == 0x0424) || (tsid == 0x0444) ))
|
||||
((tsid == 0x03F0) || (tsid == 0x0408) || (tsid == 0x040E) || (tsid == 0x0412) || (tsid == 0x0416) || (tsid == 0x041E) ||
|
||||
(tsid == 0x0420) || (tsid == 0x0422) || (tsid == 0x0424) || (tsid == 0x0444) ))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -186,9 +189,9 @@ void SIsectionEIT::parsePDCDescriptor(const char *buf, SIevent &e, unsigned maxl
|
||||
t.tm_min = s->pil2 & 0x3F;
|
||||
t.tm_sec = 0;
|
||||
if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
|
||||
t.tm_year++;
|
||||
t.tm_year++;
|
||||
else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
|
||||
t.tm_year--;
|
||||
t.tm_year--;
|
||||
e.vps = mktime(&t);
|
||||
// fprintf(stderr, "SIsectionEIT::parsePDCDescriptor: vps: %ld %s", e.vps, ctime(&e.vps));
|
||||
}
|
||||
@@ -293,108 +296,108 @@ void SIsectionEIT::parseExtendedEventDescriptor(const char *buf, SIevent &e, uns
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
std::string SIsectionEIT::freesatHuffmanDecode(std::string input)
|
||||
{
|
||||
const char *src = input.c_str();
|
||||
uint size = input.length();
|
||||
const char *src = input.c_str();
|
||||
uint size = input.length();
|
||||
|
||||
if (src[1] == 1 || src[1] == 2)
|
||||
{
|
||||
std::string uncompressed(size * 3, ' ');
|
||||
uint p = 0;
|
||||
struct hufftab *table;
|
||||
unsigned table_length;
|
||||
if (src[1] == 1)
|
||||
{
|
||||
table = fsat_huffman1;
|
||||
table_length = sizeof(fsat_huffman1) / sizeof(fsat_huffman1[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = fsat_huffman2;
|
||||
table_length = sizeof(fsat_huffman2) / sizeof(fsat_huffman2[0]);
|
||||
}
|
||||
unsigned value = 0, byte = 2, bit = 0;
|
||||
while (byte < 6 && byte < size)
|
||||
{
|
||||
value |= src[byte] << ((5-byte) * 8);
|
||||
byte++;
|
||||
}
|
||||
char lastch = START;
|
||||
if (src[1] == 1 || src[1] == 2)
|
||||
{
|
||||
std::string uncompressed(size * 3, ' ');
|
||||
uint p = 0;
|
||||
struct hufftab *table;
|
||||
unsigned table_length;
|
||||
if (src[1] == 1)
|
||||
{
|
||||
table = fsat_huffman1;
|
||||
table_length = sizeof(fsat_huffman1) / sizeof(fsat_huffman1[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = fsat_huffman2;
|
||||
table_length = sizeof(fsat_huffman2) / sizeof(fsat_huffman2[0]);
|
||||
}
|
||||
unsigned value = 0, byte = 2, bit = 0;
|
||||
while (byte < 6 && byte < size)
|
||||
{
|
||||
value |= src[byte] << ((5-byte) * 8);
|
||||
byte++;
|
||||
}
|
||||
char lastch = START;
|
||||
|
||||
do
|
||||
{
|
||||
bool found = false;
|
||||
unsigned bitShift = 0;
|
||||
if (lastch == ESCAPE)
|
||||
{
|
||||
found = true;
|
||||
// Encoded in the next 8 bits.
|
||||
// Terminated by the first ASCII character.
|
||||
char nextCh = (value >> 24) & 0xff;
|
||||
bitShift = 8;
|
||||
if ((nextCh & 0x80) == 0)
|
||||
lastch = nextCh;
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned j = 0; j < table_length; j++)
|
||||
{
|
||||
if (table[j].last == lastch)
|
||||
{
|
||||
unsigned mask = 0, maskbit = 0x80000000;
|
||||
for (short kk = 0; kk < table[j].bits; kk++)
|
||||
{
|
||||
mask |= maskbit;
|
||||
maskbit >>= 1;
|
||||
}
|
||||
if ((value & mask) == table[j].value)
|
||||
{
|
||||
char nextCh = table[j].next;
|
||||
bitShift = table[j].bits;
|
||||
if (nextCh != STOP && nextCh != ESCAPE)
|
||||
{
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
}
|
||||
found = true;
|
||||
lastch = nextCh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
// Shift up by the number of bits.
|
||||
for (unsigned b = 0; b < bitShift; b++)
|
||||
{
|
||||
value = (value << 1) & 0xfffffffe;
|
||||
if (byte < size)
|
||||
value |= (src[byte] >> (7-bit)) & 1;
|
||||
if (bit == 7)
|
||||
{
|
||||
bit = 0;
|
||||
byte++;
|
||||
}
|
||||
else bit++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entry missing in table.
|
||||
uncompressed.resize(p);
|
||||
uncompressed.append("...");
|
||||
return uncompressed;
|
||||
}
|
||||
} while (lastch != STOP && value != 0);
|
||||
|
||||
do
|
||||
{
|
||||
bool found = false;
|
||||
unsigned bitShift = 0;
|
||||
if (lastch == ESCAPE)
|
||||
{
|
||||
found = true;
|
||||
// Encoded in the next 8 bits.
|
||||
// Terminated by the first ASCII character.
|
||||
char nextCh = (value >> 24) & 0xff;
|
||||
bitShift = 8;
|
||||
if ((nextCh & 0x80) == 0)
|
||||
lastch = nextCh;
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned j = 0; j < table_length; j++)
|
||||
{
|
||||
if (table[j].last == lastch)
|
||||
{
|
||||
unsigned mask = 0, maskbit = 0x80000000;
|
||||
for (short kk = 0; kk < table[j].bits; kk++)
|
||||
{
|
||||
mask |= maskbit;
|
||||
maskbit >>= 1;
|
||||
}
|
||||
if ((value & mask) == table[j].value)
|
||||
{
|
||||
char nextCh = table[j].next;
|
||||
bitShift = table[j].bits;
|
||||
if (nextCh != STOP && nextCh != ESCAPE)
|
||||
{
|
||||
if (p >= uncompressed.length())
|
||||
uncompressed.resize(p+10);
|
||||
uncompressed[p++] = nextCh;
|
||||
}
|
||||
found = true;
|
||||
lastch = nextCh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
// Shift up by the number of bits.
|
||||
for (unsigned b = 0; b < bitShift; b++)
|
||||
{
|
||||
value = (value << 1) & 0xfffffffe;
|
||||
if (byte < size)
|
||||
value |= (src[byte] >> (7-bit)) & 1;
|
||||
if (bit == 7)
|
||||
{
|
||||
bit = 0;
|
||||
byte++;
|
||||
}
|
||||
else bit++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entry missing in table.
|
||||
uncompressed.resize(p);
|
||||
uncompressed.append("...");
|
||||
return uncompressed;
|
||||
}
|
||||
} while (lastch != STOP && value != 0);
|
||||
|
||||
uncompressed.resize(p);
|
||||
return uncompressed;
|
||||
}
|
||||
else return input;
|
||||
return uncompressed;
|
||||
}
|
||||
else return input;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -420,7 +423,7 @@ void SIsectionEIT::parseShortEventDescriptor(const char *buf, SIevent &e, unsign
|
||||
#endif
|
||||
} else
|
||||
#endif // 0
|
||||
{
|
||||
{
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
// e.setName(language, buf[0] == 0x1f ? freesatHuffmanDecode(std::string(buf, evt->event_name_length)) : std::string(buf, evt->event_name_length));
|
||||
|
||||
@@ -444,7 +447,7 @@ void SIsectionEIT::parseShortEventDescriptor(const char *buf, SIevent &e, unsign
|
||||
#endif
|
||||
} else
|
||||
#endif // 0
|
||||
{
|
||||
{
|
||||
#ifdef ENABLE_FREESATEPG
|
||||
// e.setText(language, buf[1] == 0x1f ? freesatHuffmanDecode(std::string(++buf, textlength)) : std::string(++buf, textlength));
|
||||
std::string tmp_str = buf[1] == 0x1f ? freesatHuffmanDecode(std::string(++buf, textlength)) : std::string(++buf, textlength);
|
||||
@@ -539,106 +542,106 @@ void SIsectionEIT::parse(void)
|
||||
#ifdef ENABLE_PPT
|
||||
void SIsectionPPT::parseLinkageDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
if(maxlen>=sizeof(struct descr_linkage_header))
|
||||
{
|
||||
SIlinkage l((const struct descr_linkage_header *)buf);
|
||||
e.linkage_descs.insert(e.linkage_descs.end(), l);
|
||||
if(maxlen>=sizeof(struct descr_linkage_header))
|
||||
{
|
||||
SIlinkage l((const struct descr_linkage_header *)buf);
|
||||
e.linkage_descs.insert(e.linkage_descs.end(), l);
|
||||
// printf("LinkName: %s\n", l.name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SIsectionPPT::parseComponentDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
if(maxlen>=sizeof(struct descr_component_header))
|
||||
e.components.insert(SIcomponent((const struct descr_component_header *)buf));
|
||||
if(maxlen>=sizeof(struct descr_component_header))
|
||||
e.components.insert(SIcomponent((const struct descr_component_header *)buf));
|
||||
}
|
||||
|
||||
void SIsectionPPT::parseContentDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
||||
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
||||
return; // defekt
|
||||
const char *classification=buf+sizeof(struct descr_generic_header);
|
||||
while(classification<=buf+sizeof(struct descr_generic_header)+cont->descriptor_length-2) {
|
||||
e.contentClassification+=std::string(classification, 1);
|
||||
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
||||
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
||||
return; // defekt
|
||||
const char *classification=buf+sizeof(struct descr_generic_header);
|
||||
while(classification<=buf+sizeof(struct descr_generic_header)+cont->descriptor_length-2) {
|
||||
e.contentClassification+=std::string(classification, 1);
|
||||
// printf("Content: 0x%02hhx\n", *classification);
|
||||
e.userClassification+=std::string(classification+1, 1);
|
||||
e.userClassification+=std::string(classification+1, 1);
|
||||
// printf("User: 0x%02hhx\n", *(classification+1));
|
||||
classification+=2;
|
||||
}
|
||||
classification+=2;
|
||||
}
|
||||
}
|
||||
|
||||
void SIsectionPPT::parseParentalRatingDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
||||
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
||||
return; // defekt
|
||||
const char *s=buf+sizeof(struct descr_generic_header);
|
||||
while(s<buf+sizeof(struct descr_generic_header)+cont->descriptor_length-4) {
|
||||
e.ratings.insert(SIparentalRating(std::string(s, 3), *(s+3)));
|
||||
s+=4;
|
||||
}
|
||||
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
||||
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
||||
return; // defekt
|
||||
const char *s=buf+sizeof(struct descr_generic_header);
|
||||
while(s<buf+sizeof(struct descr_generic_header)+cont->descriptor_length-4) {
|
||||
e.ratings.insert(SIparentalRating(std::string(s, 3), *(s+3)));
|
||||
s+=4;
|
||||
}
|
||||
}
|
||||
|
||||
void SIsectionPPT::parseExtendedEventDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_extended_event_header *evt=(struct descr_extended_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_extended_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
struct descr_extended_event_header *evt=(struct descr_extended_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_extended_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
|
||||
std::string language;
|
||||
language += evt->iso_639_2_language_code_hi + evt->iso_639_2_language_code_mid + evt->iso_639_2_language_code_lo;
|
||||
std::string language;
|
||||
language += evt->iso_639_2_language_code_hi + evt->iso_639_2_language_code_mid + evt->iso_639_2_language_code_lo;
|
||||
|
||||
unsigned char *items=(unsigned char *)(buf+sizeof(struct descr_extended_event_header));
|
||||
while(items<(unsigned char *)(buf+sizeof(struct descr_extended_event_header)+evt->length_of_items)) {
|
||||
if(*items) {
|
||||
if(*(items+1) < 0x06) // other code table
|
||||
e.itemDescription=std::string((const char *)(items+2), min(maxlen-((const char *)items+2-buf), (*items)-1));
|
||||
else
|
||||
e.itemDescription=std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items));
|
||||
unsigned char *items=(unsigned char *)(buf+sizeof(struct descr_extended_event_header));
|
||||
while(items<(unsigned char *)(buf+sizeof(struct descr_extended_event_header)+evt->length_of_items)) {
|
||||
if(*items) {
|
||||
if(*(items+1) < 0x06) // other code table
|
||||
e.itemDescription=std::string((const char *)(items+2), min(maxlen-((const char *)items+2-buf), (*items)-1));
|
||||
else
|
||||
e.itemDescription=std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items));
|
||||
// printf("Item Description: %s\n", e.itemDescription.c_str());
|
||||
}
|
||||
items+=1+*items;
|
||||
if(*items) {
|
||||
e.item=std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items));
|
||||
}
|
||||
items+=1+*items;
|
||||
if(*items) {
|
||||
e.item=std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items));
|
||||
// printf("Item: %s\n", e.item.c_str());
|
||||
}
|
||||
items+=1+*items;
|
||||
}
|
||||
if(*items) {
|
||||
if(*(items+1) < 0x06) // other code table
|
||||
e.appendExtendedText(language, std::string((const char *)(items+2),min(maxlen-((const char *)items+2-buf), (*items)-1)));
|
||||
else
|
||||
e.appendExtendedText(language, std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items)));
|
||||
}
|
||||
items+=1+*items;
|
||||
}
|
||||
if(*items) {
|
||||
if(*(items+1) < 0x06) // other code table
|
||||
e.appendExtendedText(language, std::string((const char *)(items+2),min(maxlen-((const char *)items+2-buf), (*items)-1)));
|
||||
else
|
||||
e.appendExtendedText(language, std::string((const char *)(items+1), min(maxlen-((const char *)items+1-buf), *items)));
|
||||
// printf("Extended Text: %s\n", e.extendedText.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SIsectionPPT::parseShortEventDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
|
||||
std::string language;
|
||||
language += evt->language_code_hi + evt->language_code_mid + evt->language_code_lo;
|
||||
std::string language;
|
||||
language += evt->language_code_hi + evt->language_code_mid + evt->language_code_lo;
|
||||
|
||||
buf+=sizeof(struct descr_short_event_header);
|
||||
if(evt->event_name_length) {
|
||||
if(*buf < 0x06) // other code table
|
||||
e.setName(language, std::string(buf+1, evt->event_name_length-1));
|
||||
else
|
||||
e.setName(language, std::string(buf, evt->event_name_length));
|
||||
}
|
||||
buf+=sizeof(struct descr_short_event_header);
|
||||
if(evt->event_name_length) {
|
||||
if(*buf < 0x06) // other code table
|
||||
e.setName(language, std::string(buf+1, evt->event_name_length-1));
|
||||
else
|
||||
e.setName(language, std::string(buf, evt->event_name_length));
|
||||
}
|
||||
|
||||
buf+=evt->event_name_length;
|
||||
unsigned char textlength=*((unsigned char *)buf);
|
||||
if(textlength > 2) {
|
||||
if(*(buf+1) < 0x06) // other code table
|
||||
e.setText(language, std::string((++buf)+1, textlength-1));
|
||||
else
|
||||
e.setText(language, std::string(++buf, textlength));
|
||||
}
|
||||
buf+=evt->event_name_length;
|
||||
unsigned char textlength=*((unsigned char *)buf);
|
||||
if(textlength > 2) {
|
||||
if(*(buf+1) < 0x06) // other code table
|
||||
e.setText(language, std::string((++buf)+1, textlength-1));
|
||||
else
|
||||
e.setText(language, std::string(++buf, textlength));
|
||||
}
|
||||
|
||||
// printf("Name: %s\n", e.name.c_str());
|
||||
// printf("Text: %s\n", e.text.c_str());
|
||||
@@ -647,42 +650,42 @@ void SIsectionPPT::parseShortEventDescriptor(const char *buf, SIevent &e, unsign
|
||||
|
||||
void SIsectionPPT::parsePrivateContentOrderDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
|
||||
#if 0
|
||||
// to be done
|
||||
unsigned char Order_number_length;
|
||||
char Order_number[Order_number_length];
|
||||
unsigned char Order_price_length;
|
||||
char Order_price[Order_price_length];
|
||||
unsigned char Order_phone_number_length;
|
||||
char Order_phone_number[Order_phone_number_length];
|
||||
unsigned char SMS_order_information_length;
|
||||
char SMS_order_information[SMS_order_information_length];
|
||||
unsigned char URL_order_information_length;
|
||||
char URL_order_information[URL_order_information_length];
|
||||
unsigned char Order_number_length;
|
||||
char Order_number[Order_number_length];
|
||||
unsigned char Order_price_length;
|
||||
char Order_price[Order_price_length];
|
||||
unsigned char Order_phone_number_length;
|
||||
char Order_phone_number[Order_phone_number_length];
|
||||
unsigned char SMS_order_information_length;
|
||||
char SMS_order_information[SMS_order_information_length];
|
||||
unsigned char URL_order_information_length;
|
||||
char URL_order_information[URL_order_information_length];
|
||||
#endif
|
||||
}
|
||||
|
||||
void SIsectionPPT::parsePrivateParentalInformationDescriptor(const char *buf, SIevent &e, unsigned maxlen)
|
||||
{
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
struct descr_short_event_header *evt=(struct descr_short_event_header *)buf;
|
||||
if((evt->descriptor_length+sizeof(descr_generic_header)>maxlen) || (evt->descriptor_length<sizeof(struct descr_short_event_header)-sizeof(descr_generic_header)))
|
||||
return; // defekt
|
||||
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
|
||||
if (sizeof(struct descr_generic_header)+1 < evt->descriptor_length) {
|
||||
e.ratings.insert(SIparentalRating(std::string("", 0), *(buf)));
|
||||
}
|
||||
if (sizeof(struct descr_generic_header)+1 < evt->descriptor_length) {
|
||||
e.ratings.insert(SIparentalRating(std::string("", 0), *(buf)));
|
||||
}
|
||||
#if 0
|
||||
unsigned char rating;
|
||||
unsigned char Controll_time_t1[3]; // BCD coded
|
||||
unsigned char Controll_time_t2[3]; // BCD coded
|
||||
unsigned char Parental_information_length;
|
||||
unsigned char Parental_information[Parental_information_length];
|
||||
unsigned char rating;
|
||||
unsigned char Controll_time_t1[3]; // BCD coded
|
||||
unsigned char Controll_time_t2[3]; // BCD coded
|
||||
unsigned char Parental_information_length;
|
||||
unsigned char Parental_information[Parental_information_length];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -707,7 +710,7 @@ void SIsectionPPT::parsePrivateContentTransmissionDescriptor(const char *buf, SI
|
||||
tm_buf[0] = *(p);
|
||||
tm_buf[1] = *(p+1);
|
||||
starttime_loop_length = (*(p+2))/3;
|
||||
for (i=0;i<starttime_loop_length; i++) {
|
||||
for (i=0; i<starttime_loop_length; i++) {
|
||||
tm_buf[2] = *(p+3*i+3);
|
||||
tm_buf[3] = *(p+3*i+4);
|
||||
tm_buf[4] = *(p+3*i+5);
|
||||
@@ -788,7 +791,8 @@ void SIsectionPPT::parse(void)
|
||||
|
||||
actPos = &buffer[sizeof(SI_section_PPT_header)];
|
||||
|
||||
/*while (actPos < &buffer[bufferLength])*/ {
|
||||
/*while (actPos < &buffer[bufferLength])*/
|
||||
{
|
||||
SIevent e;
|
||||
descriptors_loop_length = (((SI_section_PPT_header*)buffer)->descriptor_section_length_hi << 8) | ((SI_section_PPT_header*)buffer)->descriptor_section_length_lo;
|
||||
e.eventID = (unsigned short)(content_id()); // ??
|
||||
@@ -804,42 +808,42 @@ void SIsectionPPT::parse(void)
|
||||
/********************/
|
||||
void SIsectionSDT::parseNVODreferenceDescriptor(const char *buf, SIservice &s)
|
||||
{
|
||||
struct descr_generic_header *hdr=(struct descr_generic_header *)buf;
|
||||
unsigned short *spointer=(unsigned short *)(buf+sizeof(struct descr_generic_header));
|
||||
while((const char *)spointer<=buf+sizeof(struct descr_generic_header)+hdr->descriptor_length-2) {
|
||||
unsigned short transportStreamID=*spointer++;
|
||||
unsigned short originalNetworkID=*spointer++;
|
||||
unsigned short sID=*spointer++;
|
||||
s.nvods.insert(SInvodReference(transportStreamID, originalNetworkID, sID));
|
||||
}
|
||||
struct descr_generic_header *hdr=(struct descr_generic_header *)buf;
|
||||
unsigned short *spointer=(unsigned short *)(buf+sizeof(struct descr_generic_header));
|
||||
while((const char *)spointer<=buf+sizeof(struct descr_generic_header)+hdr->descriptor_length-2) {
|
||||
unsigned short transportStreamID=*spointer++;
|
||||
unsigned short originalNetworkID=*spointer++;
|
||||
unsigned short sID=*spointer++;
|
||||
s.nvods.insert(SInvodReference(transportStreamID, originalNetworkID, sID));
|
||||
}
|
||||
}
|
||||
|
||||
void SIsectionSDT::parseServiceDescriptor(const char *buf, SIservice &s)
|
||||
{
|
||||
bool is_blacklisted;
|
||||
bool is_blacklisted;
|
||||
|
||||
struct descr_service_header *sv=(struct descr_service_header *)buf;
|
||||
buf+=sizeof(struct descr_service_header);
|
||||
s.serviceTyp=sv->service_typ;
|
||||
is_blacklisted = check_blacklisted(s.original_network_id, s.transport_stream_id);
|
||||
if(sv->service_provider_name_length) {
|
||||
//if(*buf < 0x06) // other code table
|
||||
struct descr_service_header *sv=(struct descr_service_header *)buf;
|
||||
buf+=sizeof(struct descr_service_header);
|
||||
s.serviceTyp=sv->service_typ;
|
||||
is_blacklisted = check_blacklisted(s.original_network_id, s.transport_stream_id);
|
||||
if(sv->service_provider_name_length) {
|
||||
//if(*buf < 0x06) // other code table
|
||||
// s.providerName=std::string(buf+1, sv->service_provider_name_length-1);
|
||||
// else
|
||||
// s.providerName=std::string(buf, sv->service_provider_name_length);
|
||||
if ((*buf > 0x05) && (is_blacklisted))
|
||||
s.providerName = CDVBString(("\x05" + std::string((const char *)(buf))).c_str(), sv->service_provider_name_length+1).getContent();
|
||||
else
|
||||
s.providerName = CDVBString((const char *)(buf), sv->service_provider_name_length).getContent();
|
||||
}
|
||||
buf+=sv->service_provider_name_length;
|
||||
unsigned char servicenamelength=*((unsigned char *)buf);
|
||||
if(servicenamelength) {
|
||||
if ((*buf+1 > 0x05) && (is_blacklisted))
|
||||
s.serviceName = CDVBString(("\x05" + std::string((const char *)(++buf))).c_str(), servicenamelength+1).getContent();
|
||||
else
|
||||
s.serviceName = CDVBString((const char *)(++buf), servicenamelength).getContent();
|
||||
}
|
||||
if ((*buf > 0x05) && (is_blacklisted))
|
||||
s.providerName = CDVBString(("\x05" + std::string((const char *)(buf))).c_str(), sv->service_provider_name_length+1).getContent();
|
||||
else
|
||||
s.providerName = CDVBString((const char *)(buf), sv->service_provider_name_length).getContent();
|
||||
}
|
||||
buf+=sv->service_provider_name_length;
|
||||
unsigned char servicenamelength=*((unsigned char *)buf);
|
||||
if(servicenamelength) {
|
||||
if ((*buf+1 > 0x05) && (is_blacklisted))
|
||||
s.serviceName = CDVBString(("\x05" + std::string((const char *)(++buf))).c_str(), servicenamelength+1).getContent();
|
||||
else
|
||||
s.serviceName = CDVBString((const char *)(++buf), servicenamelength).getContent();
|
||||
}
|
||||
// printf("Provider-Name: %s\n", s.providerName.c_str());
|
||||
// printf("Service-Name: %s\n", s.serviceName.c_str());
|
||||
}
|
||||
@@ -854,30 +858,30 @@ void SIsectionSDT::parsePrivateDataDescriptor(const char *buf, SIservice &s)
|
||||
|
||||
void SIsectionSDT::parseDescriptors(const char *des, unsigned len, SIservice &s)
|
||||
{
|
||||
struct descr_generic_header *desc;
|
||||
des += sizeof(struct sdt_service);
|
||||
len -= sizeof(struct sdt_service);
|
||||
while(len>=sizeof(struct descr_generic_header)) {
|
||||
desc=(struct descr_generic_header *)des;
|
||||
struct descr_generic_header *desc;
|
||||
des += sizeof(struct sdt_service);
|
||||
len -= sizeof(struct sdt_service);
|
||||
while(len>=sizeof(struct descr_generic_header)) {
|
||||
desc=(struct descr_generic_header *)des;
|
||||
// printf("Type: %s\n", decode_descr(desc->descriptor_tag));
|
||||
// printf("Length: %hhu\n", desc->descriptor_length);
|
||||
if(desc->descriptor_tag==0x48) {
|
||||
if(desc->descriptor_tag==0x48) {
|
||||
// printf("Found service descriptor\n");
|
||||
parseServiceDescriptor((const char *)desc, s);
|
||||
}
|
||||
else if(desc->descriptor_tag==0x4b) {
|
||||
parseServiceDescriptor((const char *)desc, s);
|
||||
}
|
||||
else if(desc->descriptor_tag==0x4b) {
|
||||
// printf("Found NVOD reference descriptor\n");
|
||||
parseNVODreferenceDescriptor((const char *)desc, s);
|
||||
}
|
||||
else if(desc->descriptor_tag==0x5f) {
|
||||
parseNVODreferenceDescriptor((const char *)desc, s);
|
||||
}
|
||||
else if(desc->descriptor_tag==0x5f) {
|
||||
// printf("Found Private Data Specifier\n");
|
||||
parsePrivateDataDescriptor((const char *)desc, s);
|
||||
}
|
||||
// hotfix for ARD crash
|
||||
if ((int) len<desc->descriptor_length+2) break;
|
||||
len-=desc->descriptor_length+2;
|
||||
des+=desc->descriptor_length+2;
|
||||
}
|
||||
parsePrivateDataDescriptor((const char *)desc, s);
|
||||
}
|
||||
// hotfix for ARD crash
|
||||
if ((int) len<desc->descriptor_length+2) break;
|
||||
len-=desc->descriptor_length+2;
|
||||
des+=desc->descriptor_length+2;
|
||||
}
|
||||
}
|
||||
|
||||
// Die infos aus dem Puffer holen
|
||||
@@ -1004,7 +1008,7 @@ void SIsectionBAT::parse(void)
|
||||
// SIbouquet s((bh->bouquet_id_hi << 8) | bh->bouquet_id_lo); //Create a new Bouquet entry
|
||||
// printf("ident: %hu actpos: %p buf+bl: %p desclen: %hu\n", bi.bouquet_id, actPos, buffer+bufferLength, descriptors_loop_length);
|
||||
int count = 0;
|
||||
//Fill out Bouquet Name
|
||||
//Fill out Bouquet Name
|
||||
//count = parseDescriptors(((const char *)bh) + sizeof(SI_section_BAT_header), descriptors_loop_length, s, bh->section_number, count);
|
||||
const char *des = ((const char *)bh) + sizeof(SI_section_BAT_header);
|
||||
unsigned len = descriptors_loop_length;
|
||||
@@ -1021,12 +1025,12 @@ void SIsectionBAT::parse(void)
|
||||
//struct descr_generic_header *sv=(struct descr_generic_header *)buf;
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
if(desc->descriptor_length) {
|
||||
/*
|
||||
if(*buf < 0x06) // other code table
|
||||
s.bouquetName=std::string(buf+1, sv->descriptor_length-1);
|
||||
else
|
||||
s.bouquetName=std::string(buf, sv->descriptor_length);
|
||||
*/
|
||||
/*
|
||||
if(*buf < 0x06) // other code table
|
||||
s.bouquetName=std::string(buf+1, sv->descriptor_length-1);
|
||||
else
|
||||
s.bouquetName=std::string(buf, sv->descriptor_length);
|
||||
*/
|
||||
//Mega stupid providers do not reserve their own bouquet_id
|
||||
//So we do it for them... f*ck that's stupid too, but what else can we do...
|
||||
if (bouquet_id == 0x0001) {
|
||||
@@ -1046,7 +1050,7 @@ void SIsectionBAT::parse(void)
|
||||
struct private_data_specifier *pds=(struct private_data_specifier *)buf;
|
||||
buf+=sizeof(struct private_data_specifier);
|
||||
current_private_data_specifier=(((pds->byte1 << 24) | (pds->byte2 << 16)) | (pds->byte3 << 8)) | pds->byte4;
|
||||
//printf("Private Data Specifier: %08x\n", current_private_data_specifier);
|
||||
//printf("Private Data Specifier: %08x\n", current_private_data_specifier);
|
||||
}
|
||||
len-=desc->descriptor_length+2;
|
||||
des+=desc->descriptor_length+2;
|
||||
@@ -1063,35 +1067,35 @@ void SIsectionBAT::parse(void)
|
||||
if (bouquet_id != 0x0001) {
|
||||
while (actPos <= &buffer[bufferLength - sizeof(struct bat_service)]) {
|
||||
sv = (struct bat_service *)actPos;
|
||||
//s.transport_stream_id = (sv->transport_stream_id_hi << 8) | sv->transport_stream_id_lo;
|
||||
//s.original_network_id = (sv->original_network_id_hi << 8) | sv->original_network_id_lo;
|
||||
// s.position = (uint16_t) (((bh->section_number & 0x1f) << 11) + (count & 0x7ff));
|
||||
// printf("Section Number: %d Count: %d position: %04x\n", bh->section_number, count, s.position);
|
||||
//s.transport_stream_id = (sv->transport_stream_id_hi << 8) | sv->transport_stream_id_lo;
|
||||
//s.original_network_id = (sv->original_network_id_hi << 8) | sv->original_network_id_lo;
|
||||
// s.position = (uint16_t) (((bh->section_number & 0x1f) << 11) + (count & 0x7ff));
|
||||
// printf("Section Number: %d Count: %d position: %04x\n", bh->section_number, count, s.position);
|
||||
descriptors_length = (sv->descriptors_loop_length_hi << 8) | sv->descriptors_loop_length_lo;
|
||||
// Transport Stream Loop
|
||||
//count = parseDescriptors(((const char *)sv) + sizeof(struct bat_service), descriptors_length, s, bh->section_number, count,
|
||||
//(const char *) bouquetName[0]);
|
||||
bool found = false;
|
||||
// Transport Stream Loop
|
||||
//count = parseDescriptors(((const char *)sv) + sizeof(struct bat_service), descriptors_length, s, bh->section_number, count,
|
||||
//(const char *) bouquetName[0]);
|
||||
bool found = false;
|
||||
int loop_count = 1;
|
||||
while (loop_count >= 0) {
|
||||
while (loop_count >= 0) {
|
||||
|
||||
const char *des_ = ((const char *)sv) + sizeof(struct bat_service);
|
||||
len = descriptors_length;
|
||||
|
||||
while(len>=sizeof(struct descr_generic_header)) {
|
||||
desc=(struct descr_generic_header *)des_;
|
||||
desc=(struct descr_generic_header *)des_;
|
||||
// printf("Type: %s\n", decode_descr(desc->descriptor_tag));
|
||||
// printf("Length: %hhu\n", desc->descriptor_length);
|
||||
const char *buf = (const char *) desc;
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
unsigned short dlen = desc->descriptor_length;
|
||||
if ((desc->descriptor_tag==0x41) && (loop_count == 0) && (current_private_data_specifier != 0x00000002)) {
|
||||
if ((desc->descriptor_tag==0x41) && (loop_count == 0) && (current_private_data_specifier != 0x00000002)) {
|
||||
// printf("Found service list descriptor\n");
|
||||
//count = parseServiceListDescriptor((const char *)desc, s, section_no, count);
|
||||
//struct descr_generic_header *sv=(struct descr_generic_header *)buf;
|
||||
//count = parseServiceListDescriptor((const char *)desc, s, section_no, count);
|
||||
//struct descr_generic_header *sv=(struct descr_generic_header *)buf;
|
||||
|
||||
while(dlen >= sizeof(struct service_list_entry)) {
|
||||
struct service_list_entry *sl=(struct service_list_entry *)buf;
|
||||
while(dlen >= sizeof(struct service_list_entry)) {
|
||||
struct service_list_entry *sl=(struct service_list_entry *)buf;
|
||||
buf+=sizeof(struct service_list_entry);
|
||||
SIbouquet bs(bouquet_id);
|
||||
bs.bouquetName = bouquetName;
|
||||
@@ -1117,7 +1121,7 @@ void SIsectionBAT::parse(void)
|
||||
(oe->channel_number_hi << 8) | oe->channel_number_lo);
|
||||
*/
|
||||
if ( ((sl->service_id_hi << 8) | sl->service_id_lo) ==
|
||||
((oe->service_id_hi << 8) | oe->service_id_lo)) {
|
||||
((oe->service_id_hi << 8) | oe->service_id_lo)) {
|
||||
bs.position = (oe->channel_number_hi << 8) | oe->channel_number_lo;
|
||||
/*
|
||||
printf("Found Search: %04x Service_id: %04x Posi:%04x\n",
|
||||
@@ -1137,7 +1141,7 @@ void SIsectionBAT::parse(void)
|
||||
bsv.insert(bs);
|
||||
dlen -= sizeof(struct service_list_entry);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (desc->descriptor_tag == 0x5f) {
|
||||
struct private_data_specifier *pds=(struct private_data_specifier *)buf;
|
||||
@@ -1145,7 +1149,7 @@ void SIsectionBAT::parse(void)
|
||||
if ((pds->byte1 != 0) || (pds->byte2 != 0) || (pds->byte3 != 0) || (pds->byte4 != 0))
|
||||
current_private_data_specifier=(((pds->byte1 << 24) | (pds->byte2 << 16)) |
|
||||
(pds->byte3 << 8)) | pds->byte4;
|
||||
//printf("Private Data Specifier: %08x\n", current_private_data_specifier);
|
||||
//printf("Private Data Specifier: %08x\n", current_private_data_specifier);
|
||||
}
|
||||
if (desc->descriptor_tag == 0x81) {
|
||||
if (current_private_data_specifier == 0x55504300) {
|
||||
@@ -1194,9 +1198,9 @@ void SIsectionBAT::parse(void)
|
||||
SIbouquet bs(bouquet_id);
|
||||
bs.bouquetName = bouquetName;
|
||||
bs.transport_stream_id = (sv->transport_stream_id_hi << 8) |
|
||||
sv->transport_stream_id_lo;
|
||||
sv->transport_stream_id_lo;
|
||||
bs.original_network_id = (sv->original_network_id_hi << 8) |
|
||||
sv->original_network_id_lo;
|
||||
sv->original_network_id_lo;
|
||||
bs.service_id = (oe->service_id_hi << 8) | oe->service_id_lo;
|
||||
bs.serviceTyp = oe->service_type;
|
||||
bs.position = (oe->channel_number_hi << 8) | oe->channel_number_lo;
|
||||
@@ -1207,14 +1211,14 @@ void SIsectionBAT::parse(void)
|
||||
|
||||
}
|
||||
}
|
||||
len-=desc->descriptor_length+2;
|
||||
des_+=desc->descriptor_length+2;
|
||||
}
|
||||
len-=desc->descriptor_length+2;
|
||||
des_+=desc->descriptor_length+2;
|
||||
}
|
||||
loop_count--;
|
||||
}
|
||||
|
||||
actPos += sizeof(struct bat_service) + descriptors_length;
|
||||
// count++;
|
||||
// count++;
|
||||
}
|
||||
}
|
||||
parsed = 1;
|
||||
@@ -1222,10 +1226,10 @@ void SIsectionBAT::parse(void)
|
||||
|
||||
void SIsectionNIT::copyDeliveryDescriptor(const char *buf, SInetwork &s)
|
||||
{
|
||||
//struct descr_generic_header *sv=(struct descr_generic_header *)buf;
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
memmove(s.delivery_descriptor, buf, sizeof(struct satellite_delivery_descriptor)); //same size as cable...
|
||||
//printf("Bouquet-Name: %s\n", s.bouquetName.c_str());
|
||||
//struct descr_generic_header *sv=(struct descr_generic_header *)buf;
|
||||
buf+=sizeof(struct descr_generic_header);
|
||||
memmove(s.delivery_descriptor, buf, sizeof(struct satellite_delivery_descriptor)); //same size as cable...
|
||||
//printf("Bouquet-Name: %s\n", s.bouquetName.c_str());
|
||||
}
|
||||
|
||||
void SIsectionNIT::parseDescriptors(const char *des, unsigned len, SInetwork &s)
|
||||
@@ -1236,28 +1240,28 @@ void SIsectionNIT::parseDescriptors(const char *des, unsigned len, SInetwork &s)
|
||||
// t_original_network_id onid;
|
||||
// unsigned short orbital_pos;
|
||||
|
||||
struct descr_generic_header *desc;
|
||||
des += sizeof(struct nit_transponder);
|
||||
len -= sizeof(struct nit_transponder);
|
||||
struct descr_generic_header *desc;
|
||||
des += sizeof(struct nit_transponder);
|
||||
len -= sizeof(struct nit_transponder);
|
||||
|
||||
while(len>=sizeof(struct descr_generic_header)) {
|
||||
desc=(struct descr_generic_header *)des;
|
||||
while(len>=sizeof(struct descr_generic_header)) {
|
||||
desc=(struct descr_generic_header *)des;
|
||||
// printf("Type: %s\n", decode_descr(desc->descriptor_tag));
|
||||
// printf("Length: %hhu\n", desc->descriptor_length);
|
||||
if ( (desc->descriptor_tag==0x43) || (desc->descriptor_tag==0x44) ) {
|
||||
s.delivery_type = desc->descriptor_tag;
|
||||
if ( (desc->descriptor_tag==0x43) || (desc->descriptor_tag==0x44) ) {
|
||||
s.delivery_type = desc->descriptor_tag;
|
||||
// printf("Found satellite_delivery_system_descriptor\n");
|
||||
copyDeliveryDescriptor((const char *)desc, s);
|
||||
copyDeliveryDescriptor((const char *)desc, s);
|
||||
// ddp = &s.delivery_descriptor[0];
|
||||
// sdd = (struct satellite_delivery_descriptor *)ddp;
|
||||
// tsid = s.transport_stream_id;
|
||||
// onid = s.original_network_id;
|
||||
// orbital_pos = (sdd->orbital_pos_hi << 8) | sdd->orbital_pos_lo;
|
||||
// printf("ONID: %04x TSID: %04x Orbital Position: %d\n", onid, tsid, orbital_pos);
|
||||
}
|
||||
len-=desc->descriptor_length+2;
|
||||
des+=desc->descriptor_length+2;
|
||||
}
|
||||
}
|
||||
len-=desc->descriptor_length+2;
|
||||
des+=desc->descriptor_length+2;
|
||||
}
|
||||
}
|
||||
|
||||
// Die infos aus dem Puffer holen
|
||||
@@ -1318,29 +1322,29 @@ void SIsectionNIT::parse(void)
|
||||
// ansonsten die Anzahl gelesener Bytes
|
||||
inline int readNbytes(int fd, char *buf, int n, unsigned timeoutInSeconds)
|
||||
{
|
||||
int j;
|
||||
for(j=0; j<n;) {
|
||||
struct pollfd ufds;
|
||||
int j;
|
||||
for(j=0; j<n;) {
|
||||
struct pollfd ufds;
|
||||
// memset(&ufds, 0, sizeof(ufds));
|
||||
ufds.fd=fd;
|
||||
ufds.events=POLLIN|POLLPRI;
|
||||
ufds.revents=0;
|
||||
int rc=poll(&ufds, 1, timeoutInSeconds*1000);
|
||||
if(!rc)
|
||||
return 0; // timeout
|
||||
else if(rc<0) {
|
||||
perror ("poll");
|
||||
return -1;
|
||||
}
|
||||
int r=read (fd, buf, n-j);
|
||||
if(r<=0) {
|
||||
perror ("read");
|
||||
return -1;
|
||||
}
|
||||
j+=r;
|
||||
buf+=r;
|
||||
}
|
||||
return j;
|
||||
ufds.fd=fd;
|
||||
ufds.events=POLLIN|POLLPRI;
|
||||
ufds.revents=0;
|
||||
int rc=poll(&ufds, 1, timeoutInSeconds*1000);
|
||||
if(!rc)
|
||||
return 0; // timeout
|
||||
else if(rc<0) {
|
||||
perror ("poll");
|
||||
return -1;
|
||||
}
|
||||
int r=read (fd, buf, n-j);
|
||||
if(r<=0) {
|
||||
perror ("read");
|
||||
return -1;
|
||||
}
|
||||
j+=r;
|
||||
buf+=r;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
//
|
||||
|
Reference in New Issue
Block a user