📄 epgdec.cpp
字号:
static QDomElement
element(QDomDocument& doc, const tag_length_value& tlv)
{
QString name (element_tables[tlv.tag].element_name);
QDomElement e = doc.createElement (name);
map<string,string> attr;
_BYTE* end = tlv.value+tlv.length;
dectab* at = element_tables[tlv.tag].tags;
/* set default attributes */
for(size_t k=0; k<element_tables[tlv.tag].size; k++) {
if(at[k].decode == enum_attr)
attr[at[k].name] = at[k].vals[1];
}
tag_length_value a(tlv.value);
while(a.is_attribute())
{
attribute(attr, tlv.tag, a);
_BYTE* p = a.value+a.length;
if(p>=end)
break;
tag_length_value b(p);
a = b;
}
for(map<string,string>::iterator i = attr.begin(); i != attr.end(); i++)
e.setAttribute (QString(i->first.c_str()), QString().fromUtf8(i->second.c_str()));
_BYTE* p = a.value;
while(p<end)
{
if(a.is_string_token_table() && !tlv.is_child_element())
string_token_table(a);
else if(a.is_default_id() && !tlv.is_child_element()) {
default_content_id = get_uint24(p);
p+=3;
}
else if(a.is_child_element()) {
e.appendChild (element(doc, a));
}
else if(a.is_cdata()) {
string value = decode_string(a.value, a.length);
QDomText t = doc.createTextNode (QString ().fromUtf8 (value.c_str()));
e.appendChild (t);
}
p = a.value+a.length;
if(p>=end)
break;
tag_length_value b(p);
a = b;
}
return e;
}
static string
decode_genre_href (const _BYTE* p, size_t len)
{
int cs = p[0] & 0xff;
if(cs < 1 || cs > 8)
return "";
stringstream out;
out << "urn:tva:metadata:cs:" << classificationScheme[cs] << ":2005:";
switch (len)
{
case 2:
out << cs << '.' << int(p[1]);
break;
case 3:
out << cs << '.' << int(p[1]) << '.' << int(p[2]);
break;
case 4:
out << cs << '.' << int(p[1]) << '.' << int(p[2]) << '.' << int(p[3]);
break;
}
return out.str();
}
string
decode_string (const _BYTE* p, size_t len)
{
size_t i;
string out;
for (i = 0; i < len; i++)
{
char c = p[i];
if (1 <= c && c <= 19)
if (c == 0x9 || c == 0xa || c == 0xd)
out += c;
else
out += token_list[p[i]];
else
out += c;
}
return out;
}
static string
decode_uint16 (const _BYTE* p)
{
stringstream out;
out << get_uint16(p);
return out.str();
}
static string
decode_uint24 (const _BYTE* p)
{
stringstream out;
out << int(get_uint24(p));
return out.str();
}
static string
decode_sid (const _BYTE* p)
{
stringstream out;
out << hex << int(p[0]) << '.' << int(p[1]) << '.' << int(p[2]);
return out.str();
}
static string
decode_dateandtime(const _BYTE* p)
{
uint32_t mjd;
uint32_t h = p[0], m = p[1], l = p[2];
uint16_t n, year;
_BYTE month, day;
int hours, minutes, seconds = 0;
int utc_flag, lto_flag, sign = 0, lto = 0;
mjd = (((((h << 8) | m) << 8) | l) >> 6) & 0x1ffff;
CModJulDate ModJulDate(mjd);
year = ModJulDate.GetYear();
day = ModJulDate.GetDay();
month = ModJulDate.GetMonth();
lto_flag = p[2] & 0x10;
utc_flag = p[2] & 0x08;
n = (p[2] << 8) | p[3];
hours = (n >> 6) & 0x1f;
minutes = n & 0x3f;
n = 4;
if (utc_flag)
{
seconds = p[n] >> 2;
n += 2;
}
if (lto_flag)
{
sign = p[n] & 0x20;
lto = p[n] & 0x3f;
}
if(hours>=24) {
hours -= 24;
mjd++;
}
stringstream out;
out << year << '-';
if(month<10) out << '0';
out << int(month) << '-';
out << int(day) << 'T';
if(hours<10) out << '0';
out << hours << ':';
if(minutes<10) out << '0';
out << minutes << ':';
if(seconds<10) out << '0';
out << seconds << (sign ? '-' : '+');
int ltoh = lto/2;
if(ltoh<10) out << '0';
out << ltoh << ':';
int ltom = (30 * lto) % 30;
if(ltom<10) out << '0';
out << ltom;
return out.str();
}
static string
decode_duration (const _BYTE* p)
{
uint16_t hours, minutes, seconds;
seconds = get_uint16(p);
minutes = seconds / 60;
seconds = seconds % 60;
hours = minutes / 60;
minutes = minutes % 60;
stringstream out;
out << "PT" << hours << 'H' << minutes << 'M' << seconds << 'S';
return out.str();
}
static string
decode_bitrate (const _BYTE* p)
{
stringstream out;
uint16_t n = get_uint16(p);
out << float(n) / 0.1f;
return out.str();
}
static string
decode_attribute_name(const dectab& tab)
{
if (tab.name == NULL)
{
return "unknown";
}
if (strlen (tab.name) > 64) /* some reasonably big number */
{
return "too long";
}
return tab.name;
}
static string
decode_attribute_value (enum_attr_t format, const _BYTE* p, size_t len)
{
switch(format) {
case nu_attr:
return "undefined";
break;
case enum_attr:
return "undecoded enum";
break;
case string_attr:
return decode_string(p, len);
break;
case u16_attr:
return decode_uint16(p);
break;
case u24_attr:
return decode_uint24(p);
break;
case datetime_attr:
return decode_dateandtime(p);
break;
case duration_attr:
return decode_duration(p);
break;
case sid_attr:
return decode_sid(p);
break;
case genre_href_attr:
return decode_genre_href(p, len);
break;
case bitrate_attr:
return decode_bitrate(p);
break;
default:
return "";
break;
}
}
static void attribute(map<string,string>& out, _BYTE element_tag, tag_length_value& tlv)
{
size_t el = size_t(element_tag);
size_t e = sizeof (element_tables) / sizeof (eltab_t);
if (el >= e)
{
cerr << "illegal element id" << int(el) << endl;
return;
}
eltab_t a = element_tables[el];
size_t attr = tlv.tag&0x0f;
size_t n = a.size;
if (attr >= n) {
cerr << "out of range attribute id " << attr << " for element id " << int(el) << endl;
} else {
dectab tab = a.tags[attr];
string name = decode_attribute_name(tab);
string value;
if(tab.decode == enum_attr) {
// TODO if MSVC6 has ptrdiff_t then remove the int version.
#if defined(_MSC_VER) && (_MSC_VER < 1400)
int index = tlv.value[0];
int num_vals = reinterpret_cast<int>(tab.vals[0]);
#else
/* needed for 64 bit compatibility */
ptrdiff_t index = tlv.value[0];
ptrdiff_t num_vals = (tab.vals[0] - (const char*)0);
#endif
if(index<num_vals && index>0)
value = tab.vals[index];
else
value = "out of range";
} else {
value = decode_attribute_value(tab.decode, tlv.value, tlv.length);
}
out[name] = value;
}
}
static void string_token_table(const tag_length_value& tlv)
{
size_t i = 0;
_BYTE* p = tlv.value;
for (i = 0; i < 20; i++)
token_list[i][0] = 0;
for (i = 0; i < tlv.length;)
{
_BYTE tok = p[i++];
size_t tlen = p[i++];
memcpy (token_list[tok], &p[i], tlen);
token_list[tok][tlen] = 0;
i += tlen;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -