/* * section and descriptor parser * * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "types.h" time_t dvbdate_to_unixtime(dvbdate_t dvbdate) { int k = 0; struct tm tm; double mjd; /* check for the undefined value */ if ((dvbdate[0] == 0xff) && (dvbdate[1] == 0xff) && (dvbdate[2] == 0xff) && (dvbdate[3] == 0xff) && (dvbdate[4] == 0xff)) { return -1; } memset(&tm, 0, sizeof(tm)); mjd = (dvbdate[0] << 8) | dvbdate[1]; tm.tm_year = (int) ((mjd - 15078.2) / 365.25); tm.tm_mon = (int) (((mjd - 14956.1) - (int) (tm.tm_year * 365.25)) / 30.6001); tm.tm_mday = (int) mjd - 14956 - (int) (tm.tm_year * 365.25) - (int) (tm.tm_mon * 30.6001); if ((tm.tm_mon == 14) || (tm.tm_mon == 15)) k = 1; tm.tm_year += k; tm.tm_mon = tm.tm_mon - 2 - k * 12; tm.tm_sec = bcd_to_integer(dvbdate[4]); tm.tm_min = bcd_to_integer(dvbdate[3]); tm.tm_hour = bcd_to_integer(dvbdate[2]); return mktime(&tm); } void unixtime_to_dvbdate(time_t unixtime, dvbdate_t dvbdate) { struct tm tm; double l = 0; int mjd; /* the undefined value */ if (unixtime == -1) { memset(dvbdate, 0xff, 5); return; } gmtime_r(&unixtime, &tm); tm.tm_mon++; if ((tm.tm_mon == 1) || (tm.tm_mon == 2)) l = 1; mjd = 14956 + tm.tm_mday + (int) ((tm.tm_year - l) * 365.25) + (int) ((tm.tm_mon + 1 + l * 12) * 30.6001); dvbdate[0] = (mjd & 0xff00) >> 8; dvbdate[1] = mjd & 0xff; dvbdate[2] = integer_to_bcd(tm.tm_hour); dvbdate[3] = integer_to_bcd(tm.tm_min); dvbdate[4] = integer_to_bcd(tm.tm_sec); } int dvbduration_to_seconds(dvbduration_t dvbduration) { int seconds = 0; seconds += (bcd_to_integer(dvbduration[0]) * 60 * 60); seconds += (bcd_to_integer(dvbduration[1]) * 60); seconds += bcd_to_integer(dvbduration[2]); return seconds; } void seconds_to_dvbduration(int seconds, dvbduration_t dvbduration) { int hours, mins; hours = seconds / (60*60); seconds -= (hours * 60 * 60); mins = seconds / 60; seconds -= (mins * 60); dvbduration[0] = integer_to_bcd(hours); dvbduration[1] = integer_to_bcd(mins); dvbduration[2] = integer_to_bcd(seconds); } int dvbhhmm_to_seconds(dvbhhmm_t dvbhhmm) { int seconds = 0; seconds += (bcd_to_integer(dvbhhmm[0]) * 60 * 60); seconds += (bcd_to_integer(dvbhhmm[1]) * 60); return seconds; } void seconds_to_dvbhhmm(int seconds, dvbhhmm_t dvbhhmm) { int hours, mins; hours = seconds / (60*60); seconds -= (hours * 60 * 60); mins = seconds / 60; dvbhhmm[0] = integer_to_bcd(hours); dvbhhmm[1] = integer_to_bcd(mins); } uint32_t integer_to_bcd(uint32_t intval) { uint32_t val = 0; int i; for(i=0; i<=28;i+=4) { val |= ((intval % 10) << i); intval /= 10; } return val; } uint32_t bcd_to_integer(uint32_t bcdval) { uint32_t val = 0; int i; for(i=28; i>=0;i-=4) { val += ((bcdval >> i) & 0x0f); if (i != 0) val *= 10; } return val; } const char *dvb_charset(char *dvb_text, int dvb_text_length, int *consumed) { char *charset = "ISO6937"; int used = 0; if (dvb_text_length == 0) goto exit; if (dvb_text[0] >= 32) goto exit; if (dvb_text[0] == 0x10) { if (dvb_text_length < 3) goto exit; used = 3; uint16_t ext = (dvb_text[1] << 8) | dvb_text[2]; switch(ext) { case 0x01: charset = "ISO8859-1"; break; case 0x02: charset = "ISO8859-2"; break; case 0x03: charset = "ISO8859-3"; break; case 0x04: charset = "ISO8859-4"; break; case 0x05: charset = "ISO8859-5"; break; case 0x06: charset = "ISO8859-6"; break; case 0x07: charset = "ISO8859-7"; break; case 0x08: charset = "ISO8859-8"; break; case 0x09: charset = "ISO8859-9"; break; case 0x0a: charset = "ISO8859-10"; break; case 0x0b: charset = "ISO8859-11"; break; case 0x0d: charset = "ISO8859-13"; break; case 0x0e: charset = "ISO8859-14"; break; case 0x0f: charset = "ISO8859-15"; break; default: used = 0; break; } } else { used = 1; switch(dvb_text[0]) { case 0x01: charset = "ISO8859-5"; break; case 0x02: charset = "ISO8859-6"; break; case 0x03: charset = "ISO8859-7"; break; case 0x04: charset = "ISO8859-8"; break; case 0x05: charset = "ISO8859-9"; break; case 0x06: charset = "ISO8859-10"; break; case 0x07: charset = "ISO8859-11"; break; case 0x09: charset = "ISO8859-13"; break; case 0x0a: charset = "ISO8859-14"; break; case 0x0b: charset = "ISO8859-15"; break; case 0x11: charset = "UTF16"; break; case 0x12: charset = "EUC-KR"; break; case 0x13: charset = "GB2312"; break; case 0x14: charset = "GBK"; break; case 0x15: charset = "UTF8"; break; default: used = 0; break; } } exit: *consumed = used; return charset; }