/* DMW_PsiUtil.c DST TV MW PSI Scan Module Various utility functions Copyright 2006~2009 Digital STREAM Technology, Inc. All Rights Reserved */ #include "DMW_Platform.h" #include "DLIB_PSIP_Parser.h" #include "DMW_PsiUtil.h" // here, we use debug print routine of psi engine DHL_MODULE("psieng", 0); #if COMMENT ____Strings____(){} #endif const char *PSIUTIL_TidString(UINT8 t) { const char *p; const char *table_id_string_mod_32[] = { "pat", "cat", "pmt", 0, 0, 0, 0, "mgt", // 0x00~0x07, or 0xc0~0xc7 "tvt", "cvt", "rrt", "eit", "ett", "stt", "det", "dst", // 0xc8~0xcf 0, "nrt", "ltst", "dcct", "dcst", 0, 0, 0, // 0xd0~0xd7 "eas", 0, 0, 0, 0, 0, 0, "dsmcc_ast", // 0x38~0x3f, or 0xd8~ }; p = table_id_string_mod_32[t & 0x1f]; return p ? p : "?"; } char *PSIUTIL_ChannelNumberString(int major, int minor, char *buf) { static char buf0[22]; // ÃÖ´ë Å©±â.. if (buf == NULL) buf = buf0; if (minor == EPG_ONE_PART_CHANNEL_INDICATOR) sprintf(buf, "%d", major); else sprintf(buf, "%d-%d", major, minor); return buf; } //----------------------- // GpsTimeString/GpsTimeString2 // // GPS timeÀ» user time Çü½ÄÀ¸·Î º¯È¯Çؼ­ stringÀ¸·Î ¸¸µé¾îÁÖ´Â ÇÔ¼öÀÌ´Ù. // caller°¡ stringÀúÀå¿¡ »ç¿ëµÉ buffer¸¦ ÁöÁ¤Çϴ°ÍÀÌ ±ÇÀåµÈ´Ù. Å©±â´Â ÀûÀýÇϰÔ.. // ¸¸¾à °£´ÜÇÏ°Ô Å×½ºÆ®ÇÒ ¸ñÀûÀ̶ó¸é NULL·Î ÁöÁ¤ÇÏ¿© static buffer¸¦ »ç¿ëÇÒ ¼öµµ ÀÖÀ¸³ª // ÀÌ °æ¿ì multiple instance¸¦ »ç¿ëÇÏÁö ¸øÇÔ¿¡ À¯ÀÇÇ϶ó.. // char *PSIUTIL_GpsTimeString2(UINT32 gps, char *buf, int level) { #if SYS_TIME_MODULE_ENABLED // 0: (3:20), 1: (3:20:15) 2: (4/19 3:20:15) 3: (2004/4/19 ¿ù 3:20:15) char *WdayString_k[7]={"ÀÏ", "¿ù", "È­", "¼ö", "¸ñ", "±Ý", "Åä"}; char *WdayString_e[7]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static char _buf[100]; STime_t s; DMW_ConvertUTC2LocalTime(&g_EpgDebugTimeContext, DMW_ConvertGPS2UTC(&g_EpgDebugTimeContext, gps), &s); if (buf == NULL) buf = _buf; if (level >= 4) sprintf(buf, "%d/%d/%d %s %2d:%02d:%02d [tz%+d]", s.year, s.month, s.day, s.wday<7?WdayString_e[s.wday]:"", s.hour, s.min, s.sec, g_EpgDebugTimeContext.nTimeZone); else if (level >= 3) sprintf(buf, "%d/%d/%d %s %2d:%02d:%02d", s.year, s.month, s.day, s.wday<7?WdayString_k[s.wday]:"", s.hour, s.min, s.sec); else if (level >= 2) sprintf(buf, "%d/%d %2d:%02d:%02d", s.month, s.day, s.hour, s.min, s.sec); else if (level >= 1) sprintf(buf, "%2d:%02d:%02d", s.hour, s.min, s.sec); else sprintf(buf, "%2d:%02d", s.hour, s.min); return buf; #else return "(NoSysTime API)"; #endif } char *PSIUTIL_GpsTimeString(UINT32 gps, char *buf) { return PSIUTIL_GpsTimeString2(gps, buf, 3); } #if COMMENT ____Helper____(){} #endif /* ÀÚµ¿ÀûÀ¸·Î Null setting±îÁö ÇÏ´Â Free API.. null pointer ¿¡µµ ¾ÈÀü. ex: PSIUTIL_FreeTable(&mgt); */ void PSIUTIL_FreeTable(void *tablePtrPtr) { if (tablePtrPtr == NULL || *(void **)tablePtrPtr == NULL) return; FreeAtscTable(*(void **)tablePtrPtr); *(void **)tablePtrPtr = NULL; } /* return non-zero if pat is different. return zero if same pat exist. assumption: if pat1 and pat2 is non-null, it should be "valid". */ BOOL PSIUTIL_IsEquivalentPat(MPEG_PAT *pat1, MPEG_PAT *pat2) { int i; if (pat1 == NULL || pat2 == NULL) return FALSE; if (pat1->version_number != pat2->version_number) return FALSE; if (pat1->transport_stream_id != pat2->transport_stream_id) return FALSE; if (pat1->numPrograms != pat2->numPrograms) return FALSE; if (!pat1->programs || !pat2->programs) return FALSE; // program ³»¿ëÀº °°°í ¼ø¼­¸¸ º¯°æµÇ¾îµµ ¼­·Î ´Ù¸¥ °ÍÀ¸·Î °£ÁÖÇÑ´Ù. // ¿Ö³ÄÇϸé pat¿¡¼­ÀÇ index Á¤º¸°¡ Áß¿äÇÑ Àǹ̸¦ °®±â ¶§¹®. for (i=0; inumPrograms; i++) { if (pat1->programs[i].program_map_PID != pat2->programs[i].program_map_PID) return FALSE; if (pat1->programs[i].program_number != pat2->programs[i].program_number) return FALSE; } return TRUE; } BOOL PSIUTIL_IsEquivalentMgt(mgtSectionPtr_t mgt1, mgtSectionPtr_t mgt2) { int i, k; // ÇØ´ç table_type À» ã¾Æ¼­ ºñ±³ÇÏ´Â ¹æ½Ä.. if (mgt1 == NULL || mgt2 == NULL) return FALSE; // it means it should not be ignored any way. if (mgt1->tables_defined != mgt2->tables_defined) return FALSE; for (i=0; itables_defined; i++) { mgtTablePtr_t tb1, tb2; tb1 = &mgt1->table[i]; // cafrii 050330 add // ¸ÕÀú ÀÌ tb1 ÀÌ mgt1¿¡ ÀÌ¹Ì ÀÖ¾ú´ø typeÀÎÁö °Ë»ç.. // µ¿ÀÏÇÑ table typeÀÌ ¼­·Î ´Ù¸¥ °ª (PID µî) À» °¡Áö°í // ¿©·¯°³°¡ Á¸ÀçÇÒ °æ¿ì, Ç×»ó different table·Î °£ÁֵǴ ¹®Á¦ ¼öÁ¤. // for (k=0; ktable[k].table_type == tb1->table_type) break; } if (k < i) continue; // ÀÌ table 'tb1' Àº ÀÌ¹Ì ¾Õ¿¡ ÀÖ´Â ´Ù¸¥ table°ú µ¿ÀÏÇÏ´Ù.. // find tbl->table_type in mgt2 // if not found, return as different for (k=0; ktables_defined; k++) { if (tb1->table_type == mgt2->table[k].table_type) break; } if (k >= mgt2->tables_defined) // 'tb1->table_type' not found! return FALSE; tb2 = &mgt2->table[k]; // compare pid, version, num bytes if (tb1->table_type_PID != tb2->table_type_PID || tb1->table_type_version_number != tb2->table_type_version_number || tb1->number_bytes != tb2->number_bytes) return FALSE; } return TRUE; } BOOL PSIUTIL_IsEquivalentVct(xvctPtr_t vct1, xvctPtr_t vct2) { int i; if (vct1 == NULL || vct2 == NULL) return FALSE; if (vct1->is_cvct != vct2->is_cvct) return FALSE; if (vct1->transport_stream_id != vct2->transport_stream_id || vct1->version_number != vct2->version_number || vct1->numChannels != vct2->numChannels) return FALSE; // todo.. // »ó¼¼ ³»¿ë±îÁö ¸ðµÎ ºñ±³´Â Èûµé´Ù.. // ¾îÂ¥ÇÇ hardware filter ¶Ç´Â version change Á¤º¸·Î µ¿ÀÛÇÒ °ÍÀ̹ǷΠ// debug message ¼öÁØ¿¡¼­ ÀÇ¹Ì ÀÖ´Â Á¤µµ·Î¸¸ üũ.. return TRUE; } BOOL PSIUTIL_IsEquivalentStt(sttSectionPtr_t stt1, sttSectionPtr_t stt2) { if (stt1 == NULL || stt2 == NULL) return FALSE; // it means it should not be ignored any way. if (stt1->system_time != stt2->system_time) return FALSE; if (stt1->GPS_UTC_offset != stt2->GPS_UTC_offset) return FALSE; if (stt1->daylight_savings.DS_status != stt2->daylight_savings.DS_status || stt1->daylight_savings.DS_day_of_month != stt2->daylight_savings.DS_day_of_month || stt1->daylight_savings.DS_hour != stt2->daylight_savings.DS_hour) return FALSE; return TRUE; } mgtTablePtr_t PSIUTIL_FindTableInMgt(mgtSection_t *mgt, int type) { // mgt ¿¡¼­ ÇØ´ç typeÀÇ table Á¤º¸¸¦ µÇµ¹·ÁÁØ´Ù. int i; if (mgt == NULL) return NULL; for (i=0; itables_defined; i++) { if (mgt->table[i].table_type == (table_type_k)type) return &(mgt->table[i]); } return NULL; } void PSIUTIL_ComparePrintTwoMgts(mgtSectionPtr_t mgt1, mgtSectionPtr_t mgt2, int debuglevel) { // µÎ°³ÀÇ mgt tableÀ» ¼­·Î ºñ±³ Ãâ·ÂÇØÁØ´Ù. // mgtTablePtr_t tbl1, tbl2; char buf1[20], buf2[20]; int i, k; int candidate; //char *hdr = "_PID ver size"; dprint(debuglevel, " MGT1 ver %d, %d tables MGT2 ver %d, %d tables\n", mgt1 ? mgt1->version_number : 0, mgt1 ? mgt1->tables_defined : 0, mgt2 ? mgt2->version_number : 0, mgt2 ? mgt2->tables_defined : 0); for (i=0; i<1; i++) { tbl1 = PSIUTIL_FindTableInMgt(mgt1, tt_terrestrial_VCT_cni_1); tbl2 = PSIUTIL_FindTableInMgt(mgt2, tt_terrestrial_VCT_cni_1); if (tbl1 == NULL && tbl2 == NULL) continue; if (tbl1 == NULL) sprintf(buf1, "-------------"); else sprintf(buf1, "%04x %3d %4d", tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes); if (tbl2 == NULL) sprintf(buf2, "-------------"); else sprintf(buf2, "%04x %3d %4d", tbl2->table_type_PID, tbl2->table_type_version_number, tbl2->number_bytes); dprint(debuglevel, " TVCT %s %s\n", buf1, buf2); } for (i=0; i<1; i++) { tbl1 = PSIUTIL_FindTableInMgt(mgt1, tt_cable_VCT_cni_1); tbl2 = PSIUTIL_FindTableInMgt(mgt2, tt_cable_VCT_cni_1); if (tbl1 == NULL && tbl2 == NULL) continue; if (tbl1 == NULL) sprintf(buf1, "-------------"); else sprintf(buf1, "%04x %3d %4d", tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes); if (tbl2 == NULL) sprintf(buf2, "-------------"); else sprintf(buf2, "%04x %3d %4d", tbl2->table_type_PID, tbl2->table_type_version_number, tbl2->number_bytes); dprint(debuglevel, " CVCT %s %s\n", buf1, buf2); } // eit for (i=0; i<128; i++) { tbl1 = PSIUTIL_FindTableInMgt(mgt1, tt_EIT_min+i); tbl2 = PSIUTIL_FindTableInMgt(mgt2, tt_EIT_min+i); if (tbl1 == NULL && tbl2 == NULL) continue; if (tbl1 == NULL) sprintf(buf1, "-------------"); else sprintf(buf1, "%04x %3d %4d", tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes); if (tbl2 == NULL) sprintf(buf2, "-------------"); else sprintf(buf2, "%04x %3d %4d", tbl2->table_type_PID, tbl2->table_type_version_number, tbl2->number_bytes); // Mgt1¿¡¼­ Mgt2ÀÇ EIT-iÀÇ Á¤º¸ (PID, version, bytesize)¿Í °°Àº EIT¸¦ ã´Â´Ù.. candidate = -1; for (k=i; tbl2 && ktable_type_PID == tbl2->table_type_PID && tbl1->table_type_version_number == tbl2->table_type_version_number && tbl1->number_bytes == tbl2->number_bytes) { candidate = k; break; } } dprint(debuglevel, " Eit-%03d %s %s", i, buf1, buf2); if (candidate >= 0) dprint(debuglevel, " <-- Eit-%d", candidate); dprint(debuglevel, "\n"); } dprint(debuglevel, "\n"); // ett for (i=0; i<128; i++) { tbl1 = PSIUTIL_FindTableInMgt(mgt1, tt_event_ETT_min+i); tbl2 = PSIUTIL_FindTableInMgt(mgt2, tt_event_ETT_min+i); if (tbl1 == NULL && tbl2 == NULL) continue; if (tbl1 == NULL) sprintf(buf1, "-------------"); else sprintf(buf1, "%04x %3d %4d", tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes); if (tbl2 == NULL) sprintf(buf2, "-------------"); else sprintf(buf2, "%04x %3d %4d", tbl2->table_type_PID, tbl2->table_type_version_number, tbl2->number_bytes); // Mgt1¿¡¼­ Mgt2ÀÇ EIT-iÀÇ Á¤º¸ (PID, version, bytesize)¿Í °°Àº EIT¸¦ ã´Â´Ù.. candidate = -1; for (k=i; tbl2 && ktable_type_PID == tbl2->table_type_PID && tbl1->table_type_version_number == tbl2->table_type_version_number && tbl1->number_bytes == tbl2->number_bytes) { candidate = k; break; } } dprint(debuglevel, " Ett-%03d %s %s", i, buf1, buf2); if (candidate >= 0) dprint(debuglevel, " <-- Ett-%d", candidate); dprint(debuglevel, "\n"); } } #if COMMENT ____DbgPrint____(){} #endif #include "DMW_DebugUtil.h" #define SimplePrint DMW_DBG_SimplePrint #define USE_CODECONV_LIB 1 #if USE_CODECONV_LIB #include "DMW_CodeConv.h" #define UC_ConvUc2Ks DMW_ConvUc2Ks #define UC_FreeKsString DMW_FreeKsString #define UC_UniPrint DMW_UniPrint #else // ÇØ´ç library°¡ ¾ø´Â °æ¿ì ±ÞÁ¶Çؼ­ ¸¸µç Àӽà ÇÔ¼ö.. // ¿µ¹® ASCII ¿µ¿ªÀÇ Uicode¶ó¸é ºÒÆíÇÔ ¾øÀÌ »ç¿ë °¡´ÉÇÔ. PSI_STATIC UINT8 *UC_ConvUc2Ks(UINT16 *ucs, int len) { UINT8 *ks; int i; if (len < 0) { for (i=0; i<256; i++) { // ÃÖ´ë ±ÛÀÚ 256.. if (ucs[i] == 0) break; } len = i; } ks = OS_Calloc(len+1, 1); if (!ks) return NULL; for (i=0; i> 8) == 0) ks[i] = (ucs[i] & 0xff); else ks[i] = '.'; } return ks; } PSI_STATIC void UC_FreeKsString(UINT8 *ks) { OS_Free(&ks); } PSI_STATIC int UC_UniPrint(UINT16 *ucs, int len) { UINT8 *s; s = UC_ConvUc2Ks(ucs, len); if (s) { dprint((char *)s); UC_FreeKsString(s); } return 0; } #endif // USE_CODECONV_LIB /* Warning! the content of buffer @p is modified! NOT recommend to using this function.. */ int PSIUTIL_UniPrint(UINT8 *p, int numChar) { #define SWAP16(c) ((((c) & 0xff) << 8U) | (((c) >> 8) & 0xff)) UINT16 test = 0x1234; BOOL bLE = *(UINT8 *)&test == 0x12 ? FALSE : TRUE; int i; UINT16 *ucs = (UINT16 *)p; if (numChar < 0) { // auto-detect length. for (i=0; i<256; i++) { // max 256.. if (ucs[i] == 0) break; } numChar = i; } #if 1 // DMW_UNIPRINT_ENABLED if (bLE) { // swap each codes.. for (i=0; i> 8) & 0xff); else SimplePrint("."); } else { if ((ucs[i] >> 8) == 0) SimplePrint("%c", ucs[i] & 0xff); else SimplePrint("."); } } #endif } //----------------------- // PSIUTIL_ConvertMss2Ks // // MSS (MultipleStringStructure)¸¦ KS ¿Ï¼ºÇüÀ¸·Î º¯È¯ÇÑ´Ù. // caller°¡ ÁöÁ¤ÇÑ ¹öÆÛ¸¦ »ç¿ëÇϸç, ¹öÆÛ Å©±â¸¦ ³Ñ¾î¼³ °æ¿ì truncate µÊ. // MSS ¾È¿¡´Â ¿©·¯°³ÀÇ string ÀÌ Á¸ÀçÇÒ ¼ö Àִµ¥, instance´Â ÃßÃâÇϰíÀÚ ÇÏ´Â // stringÀÇ instance ¹øÈ£ÀÌ´Ù. (0ºÎÅÍ ½ÃÀÛÇÏ´Â À妽º °ª) // MSS¿¡ ¿øÇÏ´Â string instance°¡ ¾øÀ¸¸é statusNotFound °¡ ¸®ÅϵȴÙ. // #define MAX_SEGMENT_STR_SIZE 256 STATUS PSIUTIL_ConvertMss2Ks(UINT8 *mssPtr, UINT16 mssLen, char *buf, int max_buflen, char *lang, int instance) { // if 'lang' is non-NULL, lang should be ISO-639 language code. ex: "eng", "kor" // if lang is NULL, instance should be 0 ~ mStringPtr->number_strings-1 // string is filled upto max_buflen-1 and null-terminator is attached at tail of string. multipleStringPtr_t mStringPtr = NULL; msStringPtr_t p; INT32 j, pos; char string[MAX_SEGMENT_STR_SIZE]; DHL_RESULT err = DHL_OK; STATUS status = statusOK; // cafrii 060609 init bugfix UINT8 *ks; if (buf == NULL || max_buflen < 1) return statusInvalidArgument; if (mssPtr == NULL) return statusInvalidArgument; buf[0] = 0; // cafrii 060719 bugfix!! DS083 if (mssLen <= 0) { // ±×³É empty stringÀ¸·Î ¸®ÅÏ. status = statusOK; goto label_exit; } // mssLenÀÌ 0ÀÎ °æ¿ì mStringPtrÀÌ NULL À̸鼭 noError¸®ÅϵÊ. err = ParseMultipleString(mssPtr, mssLen, &mStringPtr); if (IsError(err) || mStringPtr == NULL) { // cafrii 050315 change mStringPtr = NULL; // cafrii 050315 add status = (err==DHL_FAIL_BAD_FORMAT ? statusPSIPError : statusOutOfMemory); goto label_exit; } if (lang && (lang[0] == 0 || lang[0] == ' ')) lang = NULL; if (lang) { UINT32 code; for (j=0; jnumber_strings; j++) { code = mStringPtr->msString[j].ISO639_language_code; if ((char)((code>>16)&0xff) == lang[0] && (char)((code>>8)&0xff) == lang[1] && (char)((code)&0xff) == lang[2]) { instance = j; break; } } } if (instance < 0 || instance >= mStringPtr->number_strings) { status = statusNotFound; goto label_exit; } p = & mStringPtr->msString[instance]; pos = 0; //langcode = p->ISO639_language_code; //SimplePrint("(%c%c%c) ", (char)(langcode >> 16), (char)(langcode >> 8), (char)(langcode)); for (j=0; jnumber_segments; j++) { switch (p->segment[j].compression_type) { case cm_None: // ÁÖÀÇ!! compresse_string_byte°¡ address alignÀÌ µÇ¾î ÀÖÁö ¾Ê´Ù¸é ¿¡·¯°¡ ³¯Áöµµ ¸ð¸£°ÚÀ½.. if (p->segment[j].mode == tm_ISO10646_1_Page_0x00) { // 0x00 // ASCII, ISO Latin-1 (Roman) // if (pos + p->segment[j].number_bytes < max_buflen) { memcpy(buf+pos, p->segment[j].compress_string_byte, p->segment[j].number_bytes); pos += p->segment[j].number_bytes; } else { // cafrii 060314, º¹»çÇÒ ¼ö ÀÖ´Â ¸¸Å­¸¸ º¹»çÇÑ´Ù. int len = max_buflen - 1 - pos; memcpy(buf+pos, p->segment[j].compress_string_byte, len); pos += len; buf[pos] = 0; status = statusOK; // is it better to notify warning? goto label_exit; } } else if (p->segment[j].mode == tm_ISO10646_1_16_bit) { // 0x3F // ISO/IEC 10646-1 mode (all) - KOREAN mode only // ks = UC_ConvUc2Ks((UINT16 *)p->segment[j].compress_string_byte, p->segment[j].number_bytes/2); // length °è»êÀº ±×³É 2·Î ³ª´®. Ȧ¼ö ÀÎ °æ¿ì ¸¶Áö¸·Àº À߸®³ª, Á¦´ë·Î µÈ code¶ó¸é // Ç×»ó 2ÀÇ ¹è¼öÀÏ °ÍÀ̹ǷΠ¹®Á¦ ¾ø´Ù. if (pos + strlen((char *)ks) < (size_t)max_buflen) { memcpy(buf+pos, ks, strlen((char *)ks)); pos += strlen((char *)ks); UC_FreeKsString(ks); } else { // cafrii 060314, º¹»çÇÒ ¼ö ÀÖ´Â ¸¸Å­¸¸ º¹»çÇÑ´Ù. int len = max_buflen - 1 - pos; memcpy(buf+pos, ks, len); UC_FreeKsString(ks); pos += len; // ¸¶Áö¸· ±ÛÀÚ°¡ ÇѱÛÀÏ °æ¿ì 1byte À߸®¸é ÀÌ»óÇÏ°Ô Ç¥ÇöµÉ ¼ö ÀÖÀ½. buf[pos] = 0; status = statusOK; // is it better to notify warning? goto label_exit; } } else if (p->segment[j].mode == 0x48) { // ¿Ï¼ºÇü ÇѱÛ.. // ±×³É Ãâ·ÂÇϸé Shell font°¡ Çѱ۷Πº¸¿©ÁÙ °ÍÀÓ.. // if (pos + p->segment[j].number_bytes < max_buflen) { memcpy(buf+pos, p->segment[j].compress_string_byte, p->segment[j].number_bytes); pos += p->segment[j].number_bytes; } else { // cafrii 060314, º¹»çÇÒ ¼ö ÀÖ´Â ¸¸Å­¸¸ º¹»çÇÑ´Ù. int len = max_buflen - 1 - pos; memcpy(buf+pos, p->segment[j].compress_string_byte, len); pos += len; // ¸¶Áö¸· ±ÛÀÚ°¡ ÇѱÛÀÏ °æ¿ì 1byte À߸®¸é ÀÌ»óÇÏ°Ô Ç¥ÇöµÉ ¼ö ÀÖÀ½. buf[pos] = 0; status = statusOK; // is it better to notify warning? goto label_exit; } } else { char errmsg[40]; int len; sprintf(errmsg, "!!Unsupported(%x)!!", p->segment[j].mode); len = strlen(errmsg); if (pos + len < max_buflen) { memcpy(buf+pos, errmsg, len); pos += len; } } break; case cm_Huffman_C4C5: case cm_Huffman_C6C7: DecodeHuffmanString(p->segment[j].compress_string_byte, p->segment[j].number_bytes, p->segment[j].compression_type, string, MAX_SEGMENT_STR_SIZE); ks = UC_ConvUc2Ks((UINT16 *)string, -1); if (pos + strlen((char *)ks) < (size_t)max_buflen) { memcpy(buf+pos, ks, strlen((char *)ks)); pos += strlen((char *)ks); UC_FreeKsString(ks); } else { // cafrii 060314, º¹»çÇÒ ¼ö ÀÖ´Â ¸¸Å­¸¸ º¹»çÇÑ´Ù. int len = max_buflen - 1 - pos; memcpy(buf+pos, ks, len); UC_FreeKsString(ks); pos += len; // ¸¶Áö¸· ±ÛÀÚ°¡ ÇѱÛÀÏ °æ¿ì 1byte À߸®¸é ÀÌ»óÇÏ°Ô Ç¥ÇöµÉ ¼ö ÀÖÀ½. buf[pos] = 0; status = statusOK; // is it better to notify warning? goto label_exit; } break; } } buf[pos] = 0; // null terminate label_exit: if (mStringPtr) FreeMultipleString(mStringPtr); return status; } //----------------------- // PSIUTIL_PrintMSS // // PSIP¿¡¼­ »ç¿ëÇÏ´Â multipleStringÀ» µð¹ö±ëÀÌ ÆíÇϵµ·Ï Ãâ·ÂÇØÁØ´Ù.. // ÃÖÁ¾ Ãâ·ÂÀ» ÇÒ ¶§ »ç¿ëÇÏ´Â ÇÔ¼ö´Â DMW_UniPrint ·Î¼­, ÀÌ ÇÔ¼öÀÇ Ãâ·Â°¡´É ¿©ºÎ¿¡ µû¶ó // ÀϺΠ±ÛÀÚ´Â Ãâ·ÂÀÌ ¾ÈµÈ´Ù. // // ¸¸¾à Unicode»óÅÂÀÇ code°ªÀ» º¸°í ½ÍÀ¸¸é PrintMultipleString ÇÔ¼ö¸¦ »ç¿ëÇ϶ó.. // #define STR_SIZE 256 void PSIUTIL_PrintMSS(UINT8 *buffer, UINT16 len, int indent, int detailLevel) { multipleStringPtr_t mStringPtr = NULL; INT32 i,j,k; UINT32 langcode; char string[STR_SIZE], tmp[64]; // tmp´Â indent ¹öÆÛ ¿ë.. DHL_RESULT err; if (indent > 63) indent = 63; memset(tmp, ' ', indent); tmp[indent] = 0; // cafrii 060719 bugfix! add check. DS083 if (buffer == NULL || len == 0) { SimplePrint("%s[null]\n", tmp); goto PrintMultipleStringExit; } // lenÀÌ 0ÀÎ °æ¿ì mStringPtrÀÌ NULL À̸鼭 noError¸®ÅϵÊ. err = ParseMultipleString(buffer, len, &mStringPtr); if (IsError(err)) { // cafrii 050315 change mStringPtr = NULL; // cafrii 050315 add goto PrintMultipleStringExit; } if (mStringPtr == NULL) { SimplePrint("%s[None]\n", tmp); goto PrintMultipleStringExit; } for (i=0; inumber_strings; i++) { langcode = mStringPtr->msString[i].ISO639_language_code; SimplePrint("%s(%c%c%c) ", tmp, (char)(langcode >> 16), (char)(langcode >> 8), (char)(langcode)); for (j=0; jmsString[i].number_segments; j++) { switch (mStringPtr->msString[i].segment[j].compression_type) { case cm_None: // ÁÖÀÇ!! compresse_string_byte°¡ address alignÀÌ µÇ¾î ÀÖÁö ¾Ê´Ù¸é ¿¡·¯°¡ ³¯Áöµµ ¸ð¸£°ÚÀ½.. if (mStringPtr->msString[i].segment[j].mode == tm_ISO10646_1_Page_0x00) // 0x00 // ASCII, ISO Latin-1 (Roman) for (k=0; kmsString[i].segment[j].number_bytes; k++) SimplePrint("%c", mStringPtr->msString[i].segment[j].compress_string_byte[k]); else if (mStringPtr->msString[i].segment[j].mode == tm_ISO10646_1_16_bit) // 0x3F // ISO/IEC 10646-1 mode (all) - KOREAN mode only PSIUTIL_UniPrint((UINT8 *)(mStringPtr->msString[i].segment[j].compress_string_byte), mStringPtr->msString[i].segment[j].number_bytes/2); // length °è»êÀº ±×³É 2·Î ³ª´®. Ȧ¼ö ÀÎ °æ¿ì ¸¶Áö¸·Àº À߸®³ª, Á¦´ë·Î µÈ code¶ó¸é // Ç×»ó 2ÀÇ ¹è¼öÀÏ °ÍÀ̹ǷΠ¹®Á¦ ¾ø´Ù. else if (mStringPtr->msString[i].segment[j].mode == 0x48) // ¿Ï¼ºÇü ÇѱÛ.. // ±×³É Ãâ·ÂÇϸé Shell font°¡ Çѱ۷Πº¸¿©ÁÙ °ÍÀÓ.. for (k=0; kmsString[i].segment[j].number_bytes; k++) SimplePrint("%c", mStringPtr->msString[i].segment[j].compress_string_byte[k]); else SimplePrint("!!Unsupported(%x)!!", mStringPtr->msString[i].segment[j].mode); break; case cm_Huffman_C4C5: case cm_Huffman_C6C7: DecodeHuffmanString(mStringPtr->msString[i].segment[j].compress_string_byte, mStringPtr->msString[i].segment[j].number_bytes, mStringPtr->msString[i].segment[j].compression_type, string, STR_SIZE); PSIUTIL_UniPrint((UINT8 *)string, -1); // DecodeÇÏ´Â ÇÔ¼ö°¡ SZ Çü½ÄÀ̹ǷΠ±æÀ̸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Æµµ µÈ´Ù. break; } } SimplePrint("\n"); #if 0 if (detailLevel >= 1) { // Á» ´õ ÀÚ¼¼ÇÑ Á¤º¸¸¦ Ãâ·ÂÇϰíÀÚ Çϸé 'PrintMultipleString' ¸¦ »ç¿ëÇ϶ó.. for (j=0; jmsString[i].number_segments; j++) { SimplePrint("%s [seg%d] comp_type %d, len %d\n", tmp, j, mStringPtr->msString[i].segment[j].compression_type, mStringPtr->msString[i].segment[j].number_bytes); SimplePrint("%s ", tmp); for (k=0; kmsString[i].segment[j].number_bytes; k++) SimplePrint("%02x ", mStringPtr->msString[i].segment[j].compress_string_byte[k]); SimplePrint("\n"); } } #endif } FreeMultipleString(mStringPtr); PrintMultipleStringExit: return; } //----------------------- // PSIUTIL_PrintEit // // EitÀÇ Á¤º¸¸¦ º¸±âÁÁ°Ô Ãâ·ÂÇØÁØ´Ù. SysTime ¼³Á¤¿¡ µû¶ó ÇöÀç ½Ã°£ Ãâ·ÂÀÌ Á¤È®ÇÏÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù. // ¸¸¾à EITÀÇ ¸ðµç ÀÚ¼¼ÇÑ Á¤º¸¸¦ Ãâ·ÂÇϱ⸦ ¿øÇϸé PrintEit ¸¦ »ç¿ëÇ϶ó.. // void PSIUTIL_PrintEit(eitPtr_t eitPtr, int indent, ettSectionPtr_t *ettArray) { // indent´Â ¸Å ¶óÀÎÀÇ ¾Õ¿¡ ¸îÄ­À» µé¿©¾²±â¸¦ ÇÒ °ÍÀΰ¡ ÁöÁ¤ÇÏ´Â °ÍÀε¥, ÃÖ´ë 31±îÁö °¡´ÉÇÏ´Ù. // INT32 i; char tmp[32], buf1[64], buf2[64]; // tmp´Â µé¿©¾²±â¿ë, buf´Â TimeString¿ë if (indent > 31) indent = 31; memset(tmp, ' ', indent); tmp[indent] = 0; //SimplePrint("\n%s------ EIT ------\n", tmp); SimplePrint("%sEIT source_id %d, ver %d, %d events\n", tmp, eitPtr->source_id, eitPtr->version_number, eitPtr->numEvents); for (i=0; inumEvents; i++) { SimplePrint("%s event[%d]: id: 0x%04X, %s ~ %s, ETM %d (%s)\n", tmp, i, eitPtr->event[i].event_id, PSIUTIL_GpsTimeString2(eitPtr->event[i].start_time, buf1, 2), PSIUTIL_GpsTimeString2(eitPtr->event[i].start_time + eitPtr->event[i].length_in_seconds, buf2, 1), //eitPtr->event[i].start_time, eitPtr->event[i].length_in_seconds, eitPtr->event[i].ETM_location, eitPtr->event[i].ETM_location == ETM_none ? "None" : eitPtr->event[i].ETM_location == ETM_in_this_PTC ? "ThisPTC" : eitPtr->event[i].ETM_location == ETM_in_channel_TSID_PTC ? "ChannelTsidPTC" : "??" ); PSIUTIL_PrintMSS(eitPtr->event[i].title, eitPtr->event[i].title_length, indent+6, 0); //SimplePrint("%s desc_len %d\n", tmp, eitPtr->event[i].descriptor_length); // 'ettArray'°¡ ÀÖÀ¸¸é °°ÀÌ ettµµ Ãâ·ÂÇÑ´Ù. // ±×·±µ¥ ¿ø·¡ ¾ø´Â ettÀÎÁö, ¾ÆÁ÷ ¼ö½ÅÀÌ ´ú µÈ ettÀÎÁö ½±°Ô ¾Ë ¹æ¹ýÀÌ ¾ø´Ù. if (eitPtr->event[i].ETM_location != ETM_none && ettArray && ettArray[i]) { ettSectionPtr_t ettSectPtr = ettArray[i]; //SimplePrint("%sETT ETM_id %08x, event %x, ver %d\n", tmp, ettSectPtr->ETM_id, (ettSectPtr->ETM_id>>2) & 0x3fff, // ettSectPtr->version_number); PSIUTIL_PrintMSS(ettSectPtr->extended_text_message, ettSectPtr->extended_text_message_length, indent+7, 0); // ETT ETMÀº ÇÑÄ­ ´õ µé¿©¾²µµ·Ï ÇÏÀÚ.. } } } //----------------------- // PSIUTIL_PrintEtt // // EttÀÇ Á¤º¸¸¦ º¸±âÁÁ°Ô Ãâ·ÂÇØÁØ´Ù. // ¸¸¾à ETTÀÇ ¸ðµç ÀÚ¼¼ÇÑ Á¤º¸¸¦ Ãâ·ÂÇϱ⸦ ¿øÇϸé PrintEtt ¸¦ »ç¿ëÇ϶ó.. // void PSIUTIL_PrintEtt(ettSectionPtr_t ettSectPtr, int indent) { char tmp[32]; if (indent > 31) indent = 31; memset(tmp, ' ', indent); tmp[indent] = 0; //SimplePrint("\n%s------ ETT Section ------\n", tmp); SimplePrint("%sETT ETM_id %08x, event %x, ver %d\n", tmp, ettSectPtr->ETM_id, (ettSectPtr->ETM_id>>2) & 0x3fff, ettSectPtr->version_number); PSIUTIL_PrintMSS(ettSectPtr->extended_text_message, ettSectPtr->extended_text_message_length, indent+3, 0); } //----------------------- // PSIUTIL_PrintRrt // // RrtÀÇ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. // cafrii 060822, detail ¸ðµå¿¡¼­ ´õ ¸¹Àº Á¤º¸ Ãâ·ÂÇϰԲû ¼öÁ¤. // void PSIUTIL_PrintRrt(rrtSectionPtr_t rrt, int indent, BOOL bDetail) { int i, k; char ibuf[32]; int offset = 0; static char mssbuf[200]; STATUS status; if (indent > 31) indent = 31; memset(ibuf, ' ', indent); ibuf[indent] = 0; // °£´ÜÇϰԴ ù¹øÂ° langcode¸¸ Ãâ·Â. status = PSIUTIL_ConvertMss2Ks(rrt->rating_region_name, rrt->rating_region_name_length, mssbuf, 200, NULL, 0); SimplePrint("%s RRT ver %d, %d dims, region 0x%x { %s }\n", ibuf, (int)rrt->version_number, (int)rrt->dimensions_defined, rrt->rating_region, status ? "err" : mssbuf); if (bDetail) { // ¸ðµç langcode¸¦ ´Ù Ãâ·ÂÇÑ´Ù. PSIUTIL_PrintMSS(rrt->rating_region_name, rrt->rating_region_name_length, indent+6, 0); } for (i=0; idimensions_defined; i++) { rrtDimensionPtr_t dim = &rrt->dimension[i]; status = PSIUTIL_ConvertMss2Ks(dim->dimension_name, dim->dimension_name_length, mssbuf, 200, "eng", 0); if (status) status = PSIUTIL_ConvertMss2Ks(dim->dimension_name, dim->dimension_name_length, mssbuf, 200, "kor", 0); if (status) status = PSIUTIL_ConvertMss2Ks(dim->dimension_name, dim->dimension_name_length, mssbuf, 200, NULL, 0); SimplePrint("%s [%d] grad %d, %d values, { %s }\n", ibuf, i, (int)dim->graduated_scale, (int)dim->values_defined, status ? "err" : mssbuf); if (bDetail) PSIUTIL_PrintMSS(dim->dimension_name, dim->dimension_name_length, indent+8, 0); if (dim->first_value_empty) { offset = 1; SimplePrint("%s (%d) --\n", ibuf, 0); } for (k=0; kvalues_defined; k++) { rrtValuePtr_t value = &dim->value[k]; status = PSIUTIL_ConvertMss2Ks(value->abbrev_rating_value, value->abbrev_rating_value_length, mssbuf, 200, "eng", 0); if (status) status = PSIUTIL_ConvertMss2Ks(value->abbrev_rating_value, value->abbrev_rating_value_length, mssbuf, 200, "kor", 0); if (status) status = PSIUTIL_ConvertMss2Ks(value->abbrev_rating_value, value->abbrev_rating_value_length, mssbuf, 200, NULL, 0); SimplePrint("%s (%d) %s { %s }\n", ibuf, k+offset, value->block_on ? "ON" : "--", status ? "err" : mssbuf); // Ãß°¡ Á¤º¸ Ç¥½Ã.. if (bDetail) PSIUTIL_PrintMSS(value->abbrev_rating_value, value->abbrev_rating_value_length, indent+10, 0); // value_text Ç¥½Ã.. if (bDetail) { //SimplePrint("%s text:\n", ibuf); PSIUTIL_PrintMSS(value->rating_value, value->rating_value_length, indent+12, 0); } } } }