EPG_SECTION_STATUS CEpgDBUtil::GetSectionStatusService( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, BOOL l_eitFlag ) { CBlockLock lock(&this->dbLock); map<ULONGLONG, SERVICE_EVENT_INFO>::const_iterator itr = this->serviceEventMap.find(_Create64Key(originalNetworkID, transportStreamID, serviceID)); if( itr != this->serviceEventMap.end() ){ if( l_eitFlag ){ //L-EITの状況 if( itr->second.lastTableID != 0 && itr->second.lastTableID <= 0x4F ){ return CheckSectionAll(itr->second.sectionList) ? EpgLEITAll : EpgNeedData; } }else{ //H-EITの状況 if( itr->second.lastTableID > 0x4F ){ //拡張情報がない場合も「たまった」とみなす BOOL extFlag = itr->second.lastTableIDExt == 0 || CheckSectionAll(itr->second.sectionExtList); return CheckSectionAll(itr->second.sectionList) ? (extFlag ? EpgHEITAll : EpgBasicAll) : (extFlag ? EpgExtendAll : EpgNeedData); } } } return EpgNoData; }
BOOL CEpgDBManager::SearchServiceName( WORD ONID, WORD TSID, WORD SID, wstring& serviceName ) { if( Lock() == FALSE ) return FALSE; if( _IsLoadingData() == TRUE ){ UnLock(); return FALSE; } BOOL ret = FALSE; LONGLONG key = _Create64Key(ONID, TSID, SID); map<LONGLONG, EPGDB_SERVICE_DATA*>::iterator itr; itr = this->epgMap.find(key); if( itr != this->epgMap.end() ){ serviceName = itr->second->serviceInfo.service_name; ret = TRUE; } UnLock(); return ret; }
BOOL CEpgDBManager::SearchEpg( WORD ONID, WORD TSID, WORD SID, WORD EventID, EPGDB_EVENT_INFO** result ) { if( Lock() == FALSE ) return FALSE; if( _IsLoadingData() == TRUE ){ UnLock(); return FALSE; } BOOL ret = FALSE; LONGLONG key = _Create64Key(ONID, TSID, SID); map<LONGLONG, EPGDB_SERVICE_DATA*>::iterator itr; itr = this->epgMap.find(key); if( itr != this->epgMap.end() ){ map<WORD, EPGDB_EVENT_INFO*>::iterator itrInfo; itrInfo = itr->second->eventMap.find(EventID); if( itrInfo != itr->second->eventMap.end() ){ *result = itrInfo->second; ret = TRUE; } } UnLock(); return ret; }
//EPG取得対象のサービス一覧を取得する //戻り値: // エラーコード //引数: // chList [OUT]EPG取得するチャンネル一覧 void CChSetUtil::GetEpgCapService( vector<EPGCAP_SERVICE_INFO>* chList ) { map<ULONGLONG, ULONGLONG> addMap; multimap<LONGLONG, CH_DATA4>::iterator itrCh4; for( itrCh4 = this->chText4.chList.begin(); itrCh4 != this->chText4.chList.end(); itrCh4++ ){ LONGLONG key = _Create64Key(itrCh4->second.originalNetworkID, itrCh4->second.transportStreamID, itrCh4->second.serviceID); map<LONGLONG, CH_DATA5>::iterator itrCh5; itrCh5 = this->chText5.chList.find(key); if( itrCh5 != this->chText5.chList.end() ){ ULONGLONG addKey = ((ULONGLONG)itrCh4->second.space) << 32 | itrCh4->second.ch; map<ULONGLONG, ULONGLONG>::iterator itrAdd; itrAdd = addMap.find(addKey); if( itrAdd == addMap.end() ){ if( itrCh5->second.epgCapFlag == TRUE ){ EPGCAP_SERVICE_INFO item; item.ONID = itrCh5->second.originalNetworkID; item.TSID = itrCh5->second.transportStreamID; item.SID = itrCh5->second.serviceID; chList->push_back(item); addMap.insert(pair<ULONGLONG, ULONGLONG>(addKey,addKey)); } } } } }
BOOL CTunerManager::GetCh( DWORD tunerID, WORD ONID, WORD TSID, WORD SID, DWORD* space, DWORD* ch ) { map<DWORD, TUNER_INFO*>::iterator itr; for( itr = this->tunerMap.begin(); itr != this->tunerMap.end(); itr++ ){ multimap<LONGLONG, CH_DATA4>::iterator itrCh; LONGLONG key = _Create64Key(ONID, TSID, SID); itrCh = itr->second->chUtil.chList.find(key); if( itrCh != itr->second->chUtil.chList.end() ){ if( space != NULL ){ *space = itrCh->second.space; } if( ch != NULL ){ *ch = itrCh->second.ch; } return TRUE; } } return FALSE; }
BOOL CParseChText4::DelCh(WORD originalNetworkID, WORD transportStreamID, WORD serviceID) { LONGLONG iKey = _Create64Key(originalNetworkID, transportStreamID, serviceID ); multimap<LONGLONG, CH_DATA4>::iterator itrF; itrF = this->chList.find(iKey); if( itrF != this->chList.end() ){ this->chList.erase(itrF); } return TRUE; }
BOOL CParseChText4::ParseText(LPCWSTR filePath) { if( filePath == NULL ){ return FALSE; } this->chList.clear(); this->filePath = filePath; HANDLE hFile = _CreateFile2( filePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ){ return FALSE; } DWORD dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize == 0 ){ CloseHandle(hFile); return TRUE; } char* pszBuff = new char[dwFileSize+1]; if( pszBuff == NULL ){ CloseHandle(hFile); return FALSE; } ZeroMemory(pszBuff,dwFileSize+1); DWORD dwRead=0; ReadFile( hFile, pszBuff, dwFileSize, &dwRead, NULL ); string strRead = pszBuff; CloseHandle(hFile); SAFE_DELETE_ARRAY(pszBuff) string parseLine=""; size_t iIndex = 0; size_t iFind = 0; while( iFind != string::npos ){ iFind = strRead.find("\r\n", iIndex); if( iFind == (int)string::npos ){ parseLine = strRead.substr(iIndex); //strRead.clear(); }else{ parseLine = strRead.substr(iIndex,iFind-iIndex); //strRead.erase( 0, iIndex+2 ); iIndex = iFind + 2; } CH_DATA4 Item; if( Parse1Line(parseLine, &Item) == TRUE ){ LONGLONG iKey = _Create64Key(Item.originalNetworkID, Item.transportStreamID, Item.serviceID ); this->chList.insert( pair<LONGLONG, CH_DATA4>(iKey,Item) ); } } return TRUE; }
BOOL CParseChText5::AddCh(CH_DATA5 chInfo ) { LONGLONG iKey = _Create64Key(chInfo.originalNetworkID, chInfo.transportStreamID, chInfo.serviceID ); map<LONGLONG, CH_DATA5>::iterator itrF; itrF = this->chList.find(iKey); if( itrF == this->chList.end() ){ this->chList.insert( pair<LONGLONG, CH_DATA5>(iKey,chInfo) ); }else{ itrF->second = chInfo; return FALSE; } return TRUE; }
//指定イベントのEPG情報を取得する //引数: // originalNetworkID [IN]取得対象のoriginalNetworkID // transportStreamID [IN]取得対象のtransportStreamID // serviceID [IN]取得対象のServiceID // EventID [IN]取得対象のEventID // pfOnlyFlag [IN]p/fからのみ検索するかどうか // epgInfo [OUT]EPG情報(DLL内で自動的にdeleteする。次に取得を行うまで有効) BOOL CEpgDBUtil::SearchEpgInfo( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, WORD eventID, BYTE pfOnlyFlag, EPG_EVENT_INFO** epgInfo_ ) { CBlockLock lock(&this->dbLock); this->searchEpgInfo.reset(); ULONGLONG key = _Create64Key(originalNetworkID, transportStreamID, serviceID); map<ULONGLONG, SERVICE_EVENT_INFO>::iterator itr; itr = serviceEventMap.find(key); if( itr == serviceEventMap.end() ){ return FALSE; } if( itr->second.nowEvent != NULL && itr->second.nowEvent->event_id == eventID ){ this->searchEpgInfo.reset(new EPG_EVENT_INFO); CopyEpgInfo(this->searchEpgInfo.get(), itr->second.nowEvent.get()); *epgInfo_ = this->searchEpgInfo.get(); }else if( itr->second.nextEvent != NULL && itr->second.nextEvent->event_id == eventID ){ this->searchEpgInfo.reset(new EPG_EVENT_INFO); CopyEpgInfo(this->searchEpgInfo.get(), itr->second.nextEvent.get()); *epgInfo_ = this->searchEpgInfo.get(); } if( this->searchEpgInfo != NULL ){ if( (*epgInfo_)->extInfo == NULL && itr->second.eventMap.count(eventID) && itr->second.eventMap[eventID]->extInfo ){ (*epgInfo_)->extInfo = new EPG_EXTENDED_EVENT_INFO; (*epgInfo_)->extInfo->DeepCopy(*itr->second.eventMap[eventID]->extInfo); } return TRUE; } if( pfOnlyFlag == 0 ){ map<WORD, std::unique_ptr<EVENT_INFO>>::iterator itrEvent; itrEvent = itr->second.eventMap.find(eventID); if( itrEvent != itr->second.eventMap.end() ){ this->searchEpgInfo.reset(new EPG_EVENT_INFO); CopyEpgInfo(this->searchEpgInfo.get(), itrEvent->second.get()); *epgInfo_ = this->searchEpgInfo.get(); return TRUE; } } return FALSE; }
//EPGデータの取得対象かを設定する //戻り値: // TRUE(成功)、FALSE(失敗) //引数: // originalNetworkID [IN]ONID // transportStreamID [IN]TSID // serviceID [IN]ServiceID // enable [IN]EPGデータの取得対象かどうか BOOL CParseChText5::SetEpgCapMode( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, BOOL enable ) { LONGLONG iKey = _Create64Key(originalNetworkID, transportStreamID, serviceID ); map<LONGLONG, CH_DATA5>::iterator itrF; itrF = this->chList.find(iKey); if( itrF != this->chList.end() ){ itrF->second.epgCapFlag = enable; } return TRUE; }
BOOL CChSetUtil::IsPartial( WORD ONID, WORD TSID, WORD SID ) { LONGLONG key = _Create64Key(ONID, TSID, SID); map<LONGLONG, CH_DATA5>::iterator itr; itr = this->chText5.chList.find(key); if( itr != this->chText5.chList.end() ){ if( itr->second.partialFlag == 1 ){ return TRUE; } } return FALSE; }
BOOL CParseChText4::AddCh(CH_DATA4 chInfo ) { LONGLONG iKey = _Create64Key(chInfo.originalNetworkID, chInfo.transportStreamID, chInfo.serviceID ); multimap<LONGLONG, CH_DATA4>::iterator itrF; itrF = this->chList.find(iKey); if( itrF == this->chList.end() ){ this->chList.insert( pair<LONGLONG, CH_DATA4>(iKey,chInfo) ); }else{ if( itrF->second.ch == chInfo.ch && itrF->second.space == chInfo.space ){ return FALSE; }else{ this->chList.insert( pair<LONGLONG, CH_DATA4>(iKey,chInfo) ); } } return TRUE; }
BOOL CTunerManager::IsSupportService( DWORD tunerID, WORD ONID, WORD TSID, WORD SID ) { map<DWORD, TUNER_INFO*>::iterator itr; itr = this->tunerMap.find(tunerID); if( itr == this->tunerMap.end() ){ return FALSE; } multimap<LONGLONG, CH_DATA4>::iterator itrCh; LONGLONG key = _Create64Key(ONID, TSID, SID); itrCh = itr->second->chUtil.chList.find(key); if( itrCh == itr->second->chUtil.chList.end() ){ return FALSE; } return TRUE; }
BOOL CTunerManager::GetSupportServiceTuner( WORD ONID, WORD TSID, WORD SID, vector<DWORD>* idList ) { if( idList == NULL ){ return FALSE; } map<DWORD, TUNER_INFO*>::iterator itr; for( itr = this->tunerMap.begin(); itr != this->tunerMap.end(); itr++ ){ multimap<LONGLONG, CH_DATA4>::iterator itrCh; LONGLONG key = _Create64Key(ONID, TSID, SID); itrCh = itr->second->chUtil.chList.find(key); if( itrCh != itr->second->chUtil.chList.end() ){ idList->push_back(itr->first); } } return TRUE; }
//指定サービスの現在or次のEPG情報を取得する //引数: // originalNetworkID [IN]取得対象のoriginalNetworkID // transportStreamID [IN]取得対象のtransportStreamID // serviceID [IN]取得対象のServiceID // nextFlag [IN]TRUE(次の番組)、FALSE(現在の番組) // epgInfo [OUT]EPG情報(DLL内で自動的にdeleteする。次に取得を行うまで有効) BOOL CEpgDBUtil::GetEpgInfo( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, BOOL nextFlag, EPG_EVENT_INFO** epgInfo_ ) { CBlockLock lock(&this->dbLock); this->epgInfo.reset(); ULONGLONG key = _Create64Key(originalNetworkID, transportStreamID, serviceID); map<ULONGLONG, SERVICE_EVENT_INFO>::iterator itr; itr = serviceEventMap.find(key); if( itr == serviceEventMap.end() ){ return FALSE; } if( itr->second.nowEvent != NULL && nextFlag == FALSE ){ this->epgInfo.reset(new EPG_EVENT_INFO); CopyEpgInfo(this->epgInfo.get(), itr->second.nowEvent.get()); *epgInfo_ = this->epgInfo.get(); }else if( itr->second.nextEvent != NULL && nextFlag == TRUE ){ this->epgInfo.reset(new EPG_EVENT_INFO); CopyEpgInfo(this->epgInfo.get(), itr->second.nextEvent.get()); *epgInfo_ = this->epgInfo.get(); } if( this->epgInfo != NULL ){ if( (*epgInfo_)->extInfo == NULL && itr->second.eventMap.count((*epgInfo_)->event_id) && itr->second.eventMap[(*epgInfo_)->event_id]->extInfo ){ (*epgInfo_)->extInfo = new EPG_EXTENDED_EVENT_INFO; (*epgInfo_)->extInfo->DeepCopy(*itr->second.eventMap[(*epgInfo_)->event_id]->extInfo); } return TRUE; } return FALSE; }
BOOL CEpgDBManager::SearchEpg( WORD ONID, WORD TSID, WORD SID, LONGLONG startTime, DWORD durationSec, EPGDB_EVENT_INFO** result ) { if( Lock() == FALSE ) return FALSE; if( _IsLoadingData() == TRUE ){ UnLock(); return FALSE; } BOOL ret = FALSE; LONGLONG key = _Create64Key(ONID, TSID, SID); map<LONGLONG, EPGDB_SERVICE_DATA*>::iterator itr; itr = this->epgMap.find(key); if( itr != this->epgMap.end() ){ map<WORD, EPGDB_EVENT_INFO*>::iterator itrInfo; for( itrInfo = itr->second->eventMap.begin(); itrInfo != itr->second->eventMap.end(); itrInfo++ ){ if( itrInfo->second->StartTimeFlag == 1 && itrInfo->second->DurationFlag == 1 ){ if( startTime == ConvertI64Time(itrInfo->second->start_time) && durationSec == itrInfo->second->durationSec ){ *result = itrInfo->second; ret = TRUE; break; } } } } UnLock(); return ret; }
UINT WINAPI CEpgDBManager::LoadThread(LPVOID param) { CEpgDBManager* sys = (CEpgDBManager*)param; OutputDebugString(L"Start Load EpgData\r\n"); DWORD time = GetTickCount(); CEpgDataCap3Util epgUtil; if( epgUtil.Initialize(FALSE) == FALSE ){ OutputDebugString(L"★EpgDataCap3.dllの初期化に失敗しました。\r\n"); return 0; } //EPGファイルの検索 vector<wstring> epgFileList; wstring epgDataPath = L""; GetSettingPath(epgDataPath); epgDataPath += EPG_SAVE_FOLDER; wstring searchKey = epgDataPath; searchKey += L"\\*_epg.dat"; WIN32_FIND_DATA findData; HANDLE find; //指定フォルダのファイル一覧取得 find = FindFirstFile( searchKey.c_str(), &findData); if ( find == INVALID_HANDLE_VALUE ) { //1つも存在しない epgUtil.UnInitialize(); return 0; } do{ if( (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ){ //本当に拡張子DLL? if( IsExt(findData.cFileName, L".dat" ) == TRUE ){ //見つかったファイルを一覧に追加 wstring epgFilePath = L""; Format(epgFilePath, L"%s\\%s", epgDataPath.c_str(), findData.cFileName); epgFileList.push_back(epgFilePath); } } }while(FindNextFile(find, &findData)); FindClose(find); //EPGファイルの解析 for( size_t i=0; i<epgFileList.size(); i++ ){ HANDLE file = _CreateFile( epgFileList[i].c_str(), GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( file != INVALID_HANDLE_VALUE ){ FILETIME CreationTime; FILETIME LastAccessTime; FILETIME LastWriteTime; GetFileTime(file, &CreationTime, &LastAccessTime, &LastWriteTime); LONGLONG fileTime = ((LONGLONG)LastWriteTime.dwHighDateTime)<<32 | (LONGLONG)LastWriteTime.dwLowDateTime; if( fileTime + 7*24*60*60*I64_1SEC < GetNowI64Time() ){ //1週間以上前のファイルなので削除 CloseHandle(file); DeleteFile( epgFileList[i].c_str() ); _OutputDebugString(L"★delete %s", epgFileList[i].c_str()); }else{ DWORD fileSize = GetFileSize( file, NULL ); BYTE readBuff[188*1024]; DWORD readSize = 0; while( readSize < fileSize ){ if( ::WaitForSingleObject(sys->loadStopEvent, 0) != WAIT_TIMEOUT ){ //キャンセルされた CloseHandle(file); epgUtil.UnInitialize(); return 0; } DWORD read=0; ReadFile( file, &readBuff, 188*1024, &read, NULL ); for( DWORD i=0; i<read; i+=188 ){ epgUtil.AddTSPacket(readBuff+i, 188); } readSize+=read; Sleep(0); } CloseHandle(file); } } Sleep(0); } //EPGデータを取得 DWORD serviceListSize = 0; SERVICE_INFO* serviceList = NULL; if( epgUtil.GetServiceListEpgDB(&serviceListSize, &serviceList) == FALSE ){ epgUtil.UnInitialize(); return 0; } for( DWORD i=0; i<serviceListSize; i++ ){ LONGLONG key = _Create64Key(serviceList[i].original_network_id, serviceList[i].transport_stream_id, serviceList[i].service_id); EPGDB_SERVICE_DATA* item = new EPGDB_SERVICE_DATA; item->serviceInfo.ONID = serviceList[i].original_network_id; item->serviceInfo.TSID = serviceList[i].transport_stream_id; item->serviceInfo.SID = serviceList[i].service_id; if( serviceList[i].extInfo != NULL ){ item->serviceInfo.service_type = serviceList[i].extInfo->service_type; item->serviceInfo.partialReceptionFlag = serviceList[i].extInfo->partialReceptionFlag; if( serviceList[i].extInfo->service_provider_name != NULL ){ item->serviceInfo.service_provider_name = serviceList[i].extInfo->service_provider_name; } if( serviceList[i].extInfo->service_name != NULL ){ item->serviceInfo.service_name = serviceList[i].extInfo->service_name; } if( serviceList[i].extInfo->network_name != NULL ){ item->serviceInfo.network_name = serviceList[i].extInfo->network_name; } if( serviceList[i].extInfo->ts_name != NULL ){ item->serviceInfo.ts_name = serviceList[i].extInfo->ts_name; } item->serviceInfo.remote_control_key_id = serviceList[i].extInfo->remote_control_key_id; } sys->epgMap.insert(pair<LONGLONG, EPGDB_SERVICE_DATA*>(key, item)); DWORD epgInfoListSize = 0; EPG_EVENT_INFO* epgInfoList = NULL; if( epgUtil.GetEpgInfoList(item->serviceInfo.ONID, item->serviceInfo.TSID, item->serviceInfo.SID, &epgInfoListSize, &epgInfoList) == TRUE ){ for( DWORD j=0; j<epgInfoListSize; j++ ){ EPGDB_EVENT_INFO* itemEvent = new EPGDB_EVENT_INFO; sys->ConvertEpgInfo(item->serviceInfo.ONID, item->serviceInfo.TSID, item->serviceInfo.SID, epgInfoList+j, itemEvent); item->eventMap.insert(pair<WORD, EPGDB_EVENT_INFO*>(itemEvent->event_id, itemEvent)); } } Sleep(0); } _OutputDebugString(L"End Load EpgData %dmsec\r\n", GetTickCount()-time); epgUtil.UnInitialize(); return 0; }
BOOL CEpgDBUtil::AddEIT(WORD PID, const CEITTable* eit, __int64 streamTime) { if( eit == NULL ){ return FALSE; } CBlockLock lock(&this->dbLock); ULONGLONG key = _Create64Key(eit->original_network_id, eit->transport_stream_id, eit->service_id); //サービスのmapを取得 map<ULONGLONG, SERVICE_EVENT_INFO>::iterator itr; SERVICE_EVENT_INFO* serviceInfo = NULL; itr = serviceEventMap.find(key); if( itr == serviceEventMap.end() ){ serviceInfo = &serviceEventMap.insert(std::make_pair(key, SERVICE_EVENT_INFO())).first->second; }else{ serviceInfo = &itr->second; } SI_TAG siTag; siTag.tableID = eit->table_id; siTag.version = eit->version_number; siTag.time = (DWORD)(streamTime / (10 * I64_1SEC)); if( eit->table_id <= 0x4F && eit->section_number <= 1 ){ //[p/f] if( siTag.time == 0 ){ //チャンネル変更時の応答性のため、タイムスタンプ不明の[p/f]が来たらDB上の不明でない[p/f]をクリアする //EPGファイルを入力するときは古い[p/f]による上書きが発生するので、利用側で時系列にするかタイムスタンプを確定させる工夫が必要 if( serviceInfo->nowEvent && serviceInfo->nowEvent->time != 0 || serviceInfo->nextEvent && serviceInfo->nextEvent->time != 0 ){ serviceInfo->nowEvent.reset(); serviceInfo->nextEvent.reset(); } } if( eit->eventInfoList.empty() ){ //空セクション if( eit->section_number == 0 ){ if( serviceInfo->nowEvent && siTag.time >= serviceInfo->nowEvent->time ){ serviceInfo->nowEvent.reset(); } }else{ if( serviceInfo->nextEvent && siTag.time >= serviceInfo->nextEvent->time ){ serviceInfo->nextEvent.reset(); } } } } //イベントごとに更新必要が判定 for( size_t i=0; i<eit->eventInfoList.size(); i++ ){ const CEITTable::EVENT_INFO_DATA* eitEventInfo = &eit->eventInfoList[i]; map<WORD, std::unique_ptr<EVENT_INFO>>::iterator itrEvent; EVENT_INFO* eventInfo = NULL; if( eitEventInfo->running_status == 1 || eitEventInfo->running_status == 3 ){ //非実行中または停止中 _OutputDebugString(L"★非実行中または停止中イベント ONID:0x%04x TSID:0x%04x SID:0x%04x EventID:0x%04x %04d/%02d/%02d %02d:%02d", eit->original_network_id, eit->transport_stream_id, eit->service_id, eitEventInfo->event_id, eitEventInfo->start_time.wYear, eitEventInfo->start_time.wMonth, eitEventInfo->start_time.wDay, eitEventInfo->start_time.wHour, eitEventInfo->start_time.wMinute ); continue; } #ifdef DEBUG_EIT wsprintfA(g_szDebugEIT, "%c%04x.%02x%02x.%02d.%d\r\n", eit->table_id <= 0x4F ? 'P' : 'S', eitEventInfo->event_id, eit->table_id, eit->section_number, eit->version_number, siTag.time % 1000000); #endif //[actual]と[other]は等価に扱う //[p/f]と[schedule]は各々完全に独立してデータベースを作成する if( eit->table_id <= 0x4F && eit->section_number <= 1 ){ //[p/f] if( eit->section_number == 0 ){ if( eitEventInfo->StartTimeFlag == FALSE ){ OutputDebugString(L"Invalid EIT[p/f]\r\n"); }else if( serviceInfo->nowEvent == NULL || siTag.time >= serviceInfo->nowEvent->time ){ if( serviceInfo->nowEvent == NULL || serviceInfo->nowEvent->event_id != eitEventInfo->event_id ){ //イベント入れ替わり serviceInfo->nowEvent.reset(); if( serviceInfo->nextEvent && serviceInfo->nextEvent->event_id == eitEventInfo->event_id ){ serviceInfo->nowEvent.swap(serviceInfo->nextEvent); serviceInfo->nowEvent->time = 0; } } if( serviceInfo->nowEvent == NULL ){ eventInfo = new EVENT_INFO; serviceInfo->nowEvent.reset(eventInfo); eventInfo->event_id = eitEventInfo->event_id; eventInfo->time = 0; eventInfo->tagBasic.version = 0xFF; eventInfo->tagBasic.time = 0; eventInfo->tagExt.version = 0xFF; eventInfo->tagExt.time = 0; }else{ eventInfo = serviceInfo->nowEvent.get(); } } }else{ if( serviceInfo->nextEvent == NULL || siTag.time >= serviceInfo->nextEvent->time ){ if( serviceInfo->nextEvent == NULL || serviceInfo->nextEvent->event_id != eitEventInfo->event_id ){ serviceInfo->nextEvent.reset(); if( serviceInfo->nowEvent && serviceInfo->nowEvent->event_id == eitEventInfo->event_id ){ serviceInfo->nextEvent.swap(serviceInfo->nowEvent); serviceInfo->nextEvent->time = 0; } } if( serviceInfo->nextEvent == NULL ){ eventInfo = new EVENT_INFO; serviceInfo->nextEvent.reset(eventInfo); eventInfo->event_id = eitEventInfo->event_id; eventInfo->time = 0; eventInfo->tagBasic.version = 0xFF; eventInfo->tagBasic.time = 0; eventInfo->tagExt.version = 0xFF; eventInfo->tagExt.time = 0; }else{ eventInfo = serviceInfo->nextEvent.get(); } } } }else if( PID != 0x0012 || eit->table_id > 0x4F ){ //[schedule]もしくは(H-EITでないとき)[p/f after] //TODO: イベント消滅には対応していない(クラス設計的に対応は厳しい)。EDCB的には実用上のデメリットはあまり無い if( eitEventInfo->StartTimeFlag == FALSE || eitEventInfo->DurationFlag == FALSE ){ OutputDebugString(L"Invalid EIT[schedule]\r\n"); }else{ itrEvent = serviceInfo->eventMap.find(eitEventInfo->event_id); if( itrEvent == serviceInfo->eventMap.end() ){ eventInfo = new EVENT_INFO; eventInfo->event_id = eitEventInfo->event_id; serviceInfo->eventMap[eventInfo->event_id].reset(eventInfo); eventInfo->time = 0; eventInfo->tagBasic.version = 0xFF; eventInfo->tagBasic.time = 0; eventInfo->tagExt.version = 0xFF; eventInfo->tagExt.time = 0; }else{ eventInfo = itrEvent->second.get(); } } } if( eventInfo ){ //開始時間等はタイムスタンプのみを基準に更新 if( siTag.time >= eventInfo->time ){ eventInfo->StartTimeFlag = eitEventInfo->StartTimeFlag; eventInfo->start_time = eitEventInfo->start_time; eventInfo->DurationFlag = eitEventInfo->DurationFlag; eventInfo->durationSec = (eitEventInfo->durationHH * 60 + eitEventInfo->durationMM) * 60 + eitEventInfo->durationSS; eventInfo->freeCAFlag = eitEventInfo->free_CA_mode; eventInfo->time = siTag.time; } //記述子はテーブルバージョンも加味して更新(単に効率のため) if( siTag.time >= eventInfo->tagExt.time ){ if( eit->version_number != eventInfo->tagExt.version || eit->table_id != eventInfo->tagExt.tableID || siTag.time > eventInfo->tagExt.time + 180 ){ if( AddExtEvent(eventInfo, &eitEventInfo->descriptorList) != FALSE ){ eventInfo->tagExt = siTag; } }else{ eventInfo->tagExt.time = siTag.time; } } //[schedule extended]以外 if( (eit->table_id < 0x58 || 0x5F < eit->table_id) && (eit->table_id < 0x68 || 0x6F < eit->table_id) ){ if( eit->table_id > 0x4F && eventInfo->tagBasic.version != 0xFF && eventInfo->tagBasic.tableID <= 0x4F ){ //[schedule][p/f after]とも運用するサービスがあれば[p/f after]を優先する(今のところサービス階層が分離しているのであり得ないはず) _OutputDebugString(L"Conflicts EIT[schedule][p/f after] SID:0x%04x EventID:0x%04x\r\n", eit->service_id, eventInfo->event_id); }else if( siTag.time >= eventInfo->tagBasic.time ){ if( eit->version_number != eventInfo->tagBasic.version || eit->table_id != eventInfo->tagBasic.tableID || siTag.time > eventInfo->tagBasic.time + 180 ){ AddBasicInfo(eventInfo, &eitEventInfo->descriptorList, eit->original_network_id, eit->transport_stream_id); } eventInfo->tagBasic = siTag; } } } } if( eit->original_network_id == 0x0003 ){ return TRUE; } //セクションステータス if( PID != 0x0012 ){ //L-EIT if( eit->table_id <= 0x4F ){ if( serviceInfo->lastTableID != eit->table_id || serviceInfo->sectionList[0].version != eit->version_number + 1 ){ serviceInfo->lastTableID = 0; } if( serviceInfo->lastTableID == 0 ){ //リセット memset(&serviceInfo->sectionList.front(), 0, sizeof(SECTION_FLAG_INFO) * 8); for( int i = 1; i < 8; i++ ){ //第0テーブル以外のセクションを無視 memset(serviceInfo->sectionList[i].ignoreFlags, 0xFF, sizeof(serviceInfo->sectionList[0].ignoreFlags)); } serviceInfo->lastTableID = eit->table_id; } //第0セグメント以外のセクションを無視 memset(serviceInfo->sectionList[0].ignoreFlags + 1, 0xFF, sizeof(serviceInfo->sectionList[0].ignoreFlags) - 1); //第0セグメントの送られないセクションを無視 for( int i = eit->segment_last_section_number % 8 + 1; i < 8; i++ ){ serviceInfo->sectionList[0].ignoreFlags[0] |= 1 << i; } serviceInfo->sectionList[0].version = eit->version_number + 1; serviceInfo->sectionList[0].flags[0] |= 1 << (eit->section_number % 8); } }else{ //H-EIT if( eit->table_id > 0x4F ){ BYTE& lastTableID = eit->table_id % 16 >= 8 ? serviceInfo->lastTableIDExt : serviceInfo->lastTableID; vector<SECTION_FLAG_INFO>& sectionList = eit->table_id % 16 >= 8 ? serviceInfo->sectionExtList : serviceInfo->sectionList; if( sectionList.empty() ){ //拡張情報はないことも多いので遅延割り当て sectionList.resize(8); } if( lastTableID != eit->last_table_id ){ lastTableID = 0; }else if( sectionList[eit->table_id % 8].version != 0 && sectionList[eit->table_id % 8].version != eit->version_number + 1 ){ OutputDebugString(L"EIT[schedule] updated\r\n"); lastTableID = 0; } if( lastTableID == 0 ){ //リセット memset(§ionList.front(), 0, sizeof(SECTION_FLAG_INFO) * 8); for( int i = eit->last_table_id % 8 + 1; i < 8; i++ ){ //送られないテーブルのセクションを無視 memset(sectionList[i].ignoreFlags, 0xFF, sizeof(sectionList[0].ignoreFlags)); } lastTableID = eit->last_table_id; } //送られないセグメントのセクションを無視 memset(sectionList[eit->table_id % 8].ignoreFlags + eit->last_section_number / 8 + 1, 0xFF, sizeof(sectionList[0].ignoreFlags) - eit->last_section_number / 8 - 1); if( eit->table_id % 8 == 0 && streamTime > 0 ){ //放送済みセグメントのセクションを無視 memset(sectionList[0].ignoreFlags, 0xFF, streamTime / (3 * 60 * 60 * I64_1SEC) % 8); } //このセグメントの送られないセクションを無視 for( int i = eit->segment_last_section_number % 8 + 1; i < 8; i++ ){ sectionList[eit->table_id % 8].ignoreFlags[eit->section_number / 8] |= 1 << i; } sectionList[eit->table_id % 8].version = eit->version_number + 1; sectionList[eit->table_id % 8].flags[eit->section_number / 8] |= 1 << (eit->section_number % 8); } } return TRUE; }
BOOL CEpgDBUtil::AddServiceList(const CNITTable* nit) { if( nit == NULL ){ return FALSE; } CBlockLock lock(&this->dbLock); wstring network_nameW = L""; for( size_t i=0; i<nit->descriptorList.size(); i++ ){ if( nit->descriptorList[i].GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::network_name_descriptor ){ const AribDescriptor::CDescriptor* networkName = &nit->descriptorList[i]; DWORD srcSize; const char* src = networkName->GetStringOrEmpty(AribDescriptor::d_char, &srcSize); if( srcSize > 0 ){ CARIB8CharDecode arib; string network_name = ""; arib.PSISI((const BYTE*)src, srcSize, &network_name); AtoW(network_name, network_nameW); } } } for( size_t i=0; i<nit->TSInfoList.size(); i++ ){ const CNITTable::TS_INFO_DATA* tsInfo = &nit->TSInfoList[i]; //サービス情報更新用 map<DWORD, DB_TS_INFO>::iterator itrFind; itrFind = this->serviceInfoList.find((DWORD)tsInfo->original_network_id << 16 | tsInfo->transport_stream_id); if( itrFind != this->serviceInfoList.end() ){ itrFind->second.network_name = network_nameW; } for( size_t j=0; j<tsInfo->descriptorList.size(); j++ ){ const AribDescriptor::CDescriptor* desc = &tsInfo->descriptorList[j]; if( desc->GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::service_list_descriptor ){ AribDescriptor::CDescriptor::CLoopPointer lp; if( desc->EnterLoop(lp) ){ for( DWORD k=0; desc->SetLoopIndex(lp, k); k++ ){ ULONGLONG key = _Create64Key(tsInfo->original_network_id, tsInfo->transport_stream_id, (WORD)desc->GetNumber(AribDescriptor::service_id, lp)); map<ULONGLONG, BYTE>::iterator itrService; itrService = this->serviceList.find(key); if( itrService == this->serviceList.end() ){ this->serviceList.insert(pair<ULONGLONG, BYTE>(key, (BYTE)desc->GetNumber(AribDescriptor::service_type, lp))); } } } } if( desc->GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::ts_information_descriptor && itrFind != this->serviceInfoList.end()){ //ts_nameとremote_control_key_id DWORD srcSize; const char* src = desc->GetStringOrEmpty(AribDescriptor::ts_name_char, &srcSize); if( srcSize > 0 ){ CARIB8CharDecode arib; string ts_name = ""; arib.PSISI((const BYTE*)src, srcSize, &ts_name); AtoW(ts_name, itrFind->second.ts_name); } itrFind->second.remote_control_key_id = (BYTE)desc->GetNumber(AribDescriptor::remote_control_key_id); } if( desc->GetNumber(AribDescriptor::descriptor_tag) == AribDescriptor::partial_reception_descriptor && itrFind != this->serviceInfoList.end()){ //部分受信フラグ AribDescriptor::CDescriptor::CLoopPointer lp; if( desc->EnterLoop(lp) ){ map<WORD,DB_SERVICE_INFO>::iterator itrService; for( DWORD k=0; desc->SetLoopIndex(lp, k); k++ ){ itrService = itrFind->second.serviceList.find((WORD)desc->GetNumber(AribDescriptor::service_id, lp)); if( itrService != itrFind->second.serviceList.end() ){ itrService->second.partialReceptionFlag = 1; } } } } } } return TRUE; }
//指定サービスの全EPG情報を取得する // originalNetworkID [IN]取得対象のoriginalNetworkID // transportStreamID [IN]取得対象のtransportStreamID // serviceID [IN]取得対象のServiceID // epgInfoListSize [OUT]epgInfoListの個数 // epgInfoList [OUT]EPG情報のリスト(DLL内で自動的にdeleteする。次に取得を行うまで有効) BOOL CEpgDBUtil::GetEpgInfoList( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, DWORD* epgInfoListSize, EPG_EVENT_INFO** epgInfoList_ ) { CBlockLock lock(&this->dbLock); ULONGLONG key = _Create64Key(originalNetworkID, transportStreamID, serviceID); map<ULONGLONG, SERVICE_EVENT_INFO>::iterator itr; itr = serviceEventMap.find(key); if( itr == serviceEventMap.end() ){ return FALSE; } EVENT_INFO* evtPF[2] = {itr->second.nowEvent.get(), itr->second.nextEvent.get()}; if( evtPF[0] == NULL || evtPF[1] && evtPF[0]->event_id > evtPF[1]->event_id ){ std::swap(evtPF[0], evtPF[1]); } size_t listSize = itr->second.eventMap.size() + (evtPF[0] && itr->second.eventMap.count(evtPF[0]->event_id) == 0 ? 1 : 0) + (evtPF[1] && itr->second.eventMap.count(evtPF[1]->event_id) == 0 ? 1 : 0); if( listSize == 0 ){ return FALSE; } *epgInfoListSize = (DWORD)listSize; this->epgInfoList.reset(new EPG_EVENT_INFO[*epgInfoListSize]); map<WORD, std::unique_ptr<EVENT_INFO>>::iterator itrEvt = itr->second.eventMap.begin(); DWORD count = 0; while( evtPF[0] || itrEvt != itr->second.eventMap.end() ){ EPG_EXTENDED_EVENT_INFO* extInfoSchedule = NULL; EVENT_INFO* evt; if( itrEvt == itr->second.eventMap.end() || evtPF[0] && evtPF[0]->event_id < itrEvt->first ){ //[p/f]を出力 evt = evtPF[0]; evtPF[0] = evtPF[1]; evtPF[1] = NULL; }else{ if( evtPF[0] && evtPF[0]->event_id == itrEvt->first ){ //両方あるときは[p/f]を優先 evt = evtPF[0]; evtPF[0] = evtPF[1]; evtPF[1] = NULL; if( evt->extInfo == NULL && itrEvt->second->extInfo ){ extInfoSchedule = new EPG_EXTENDED_EVENT_INFO; extInfoSchedule->DeepCopy(*itrEvt->second->extInfo); } }else{ //[schedule]を出力 evt = itrEvt->second.get(); } itrEvt++; } CopyEpgInfo(this->epgInfoList.get()+count, evt); if( extInfoSchedule ){ this->epgInfoList[count].extInfo = extInfoSchedule; } count++; } *epgInfoList_ = this->epgInfoList.get(); return TRUE; }
DWORD CRestApiManager::GetSearchEvent(string param, HTTP_STREAM* sendParam, CEpgDBManager* epgDB) { DWORD ret = NO_ERR; map<string,string> paramMap; while(param.size()>0){ string buff; Separate(param, "&", buff, param); if(buff.size()>0){ string key; string val; Separate(buff, "=", key, val); paramMap.insert(pair<string,string>(key, val)); } } map<string,string>::iterator itr; WORD network = 0xFFFF; itr = paramMap.find("network"); if( itr != paramMap.end() ){ network = (WORD)atoi(itr->second.c_str()); } WORD days = 0; itr = paramMap.find("days"); if( itr != paramMap.end() ){ days = (WORD)atoi(itr->second.c_str()); } wstring andkey; itr = paramMap.find("andkey"); if( itr != paramMap.end() ){ string utf8; UrlDecode(itr->second.c_str(), (DWORD)itr->second.size(), utf8); UTF8toW(utf8, andkey); } wstring notkey; itr = paramMap.find("notkey"); if( itr != paramMap.end() ){ string utf8; UrlDecode(itr->second.c_str(), (DWORD)itr->second.size(), utf8); UTF8toW(utf8, notkey); } vector<DWORD> genru; itr = paramMap.find("genru"); if( itr != paramMap.end() ){ string val = itr->second; string id; while(val.size() > 0 ){ Separate(val, "-", id, val); genru.push_back((DWORD)atoi(id.c_str())); } } DWORD index = 0; itr = paramMap.find("index"); if( itr != paramMap.end() ){ index = (DWORD)atoi(itr->second.c_str()); } DWORD count = 200; itr = paramMap.find("count"); if( itr != paramMap.end() ){ count = (DWORD)atoi(itr->second.c_str()); } WORD basicOnly = 1; itr = paramMap.find("basic"); if( itr != paramMap.end() ){ basicOnly = (WORD)atoi(itr->second.c_str()); } //検索条件 EPGDB_SEARCH_KEY_INFO searchKey; searchKey.andKey = andkey; searchKey.notKey = notkey; for( size_t i=0; i<genru.size(); i++){ EPGDB_CONTENT_DATA item; item.content_nibble_level_1 = (BYTE)(genru[i]>>8); item.content_nibble_level_2 = (BYTE)(genru[i]&0x00FF); searchKey.contentList.push_back(item); } //対象サービス vector<EPGDB_SERVICE_INFO> list; if( epgDB->GetServiceList(&list) == TRUE ){ if( network != 0xFFFF ){ for( size_t i=0; i<list.size(); i++ ){ __int64 key = _Create64Key(list[i].ONID,list[i].TSID, list[i].SID); if( 0x7880 <= list[i].ONID && list[i].ONID<= 0x7FE8 ){ //地デジ if( (network & 0x0001) > 0 ){ searchKey.serviceList.push_back(key); } }else if( list[i].ONID == 0x0004 ){ //BS if( (network & 0x0002) > 0 ){ searchKey.serviceList.push_back(key); } }else if( list[i].ONID == 0x0006 || list[i].ONID == 0x0007 ){ //CS if( (network & 0x0004) > 0 ){ searchKey.serviceList.push_back(key); } }else{ //その他 if( (network & 0x0008) > 0 ){ searchKey.serviceList.push_back(key); } } } } } //対象期間 __int64 chkTime = 0; if( days > 0 ){ SYSTEMTIME now; GetLocalTime(&now); now.wHour = 0; now.wMinute = 0; now.wSecond = 0; now.wMilliseconds = 0; chkTime = ConvertI64Time(now); chkTime += days*(29*60*60*I64_1SEC); } vector<EPGDB_SEARCH_KEY_INFO> keyList; keyList.push_back(searchKey); vector<EPGDB_EVENT_INFO*> resultList; wstring xml = L""; string utf8 = ""; epgDB->SearchEpg(&keyList, &resultList); map<__int64, __int64> addID; map<__int64, __int64>::iterator itrAdd; if ( resultList.size() > 0 ){ xml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><entry>"; DWORD total = 0; DWORD findCount = 0; wstring serviceinfo = L"<items>"; wstring buff; for( size_t i = 0; i<resultList.size(); i++){ if( days > 0 ){ if( chkTime < ConvertI64Time(resultList[i]->start_time)){ continue; } } if( resultList[i]->eventGroupInfo != NULL ){ BOOL find = FALSE; for( size_t j=0; j<resultList[i]->eventGroupInfo->eventDataList.size(); j++ ){ __int64 evid = _Create64Key2(resultList[i]->eventGroupInfo->eventDataList[j].original_network_id, resultList[i]->eventGroupInfo->eventDataList[j].transport_stream_id, resultList[i]->eventGroupInfo->eventDataList[j].service_id, resultList[i]->eventGroupInfo->eventDataList[j].event_id); itrAdd = addID.find(evid); if( itrAdd != addID.end() ){ find = TRUE; } } if( find == TRUE ){ continue; } } __int64 evid = _Create64Key2(resultList[i]->original_network_id, resultList[i]->transport_stream_id, resultList[i]->service_id, resultList[i]->event_id); addID.insert(pair<__int64, __int64>(evid,evid)); if( total < index ){ total++; continue; } if( index + count <= total ){ total++; continue; } total++; findCount++; EPGDB_EVENT_INFO* eventInfo = resultList[i]; serviceinfo += L"<eventinfo>"; Format(buff, L"<ONID>%d</ONID>", eventInfo->original_network_id); serviceinfo += buff; Format(buff, L"<TSID>%d</TSID>", eventInfo->transport_stream_id); serviceinfo += buff; Format(buff, L"<SID>%d</SID>", eventInfo->service_id); serviceinfo += buff; Format(buff, L"<eventID>%d</eventID>", eventInfo->event_id); serviceinfo += buff; if( eventInfo->StartTimeFlag == 1 ){ Format(buff, L"<startDate>%04d/%02d/%02d</startDate>", eventInfo->start_time.wYear, eventInfo->start_time.wMonth, eventInfo->start_time.wDay); serviceinfo += buff; Format(buff, L"<startTime>%02d:%02d:%02d</startTime>", eventInfo->start_time.wHour, eventInfo->start_time.wMinute, eventInfo->start_time.wSecond); serviceinfo += buff; Format(buff, L"<startDayOfWeek>%d</startDayOfWeek>", eventInfo->start_time.wDayOfWeek); serviceinfo += buff; } if( eventInfo->DurationFlag == 1 ){ Format(buff, L"<duration>%d</duration>", eventInfo->durationSec); serviceinfo += buff; } if( eventInfo->shortInfo != NULL ){ wstring chk = eventInfo->shortInfo->event_name; CheckXMLChar(chk); Format(buff, L"<event_name>%s</event_name>", chk.c_str()); serviceinfo += buff; chk = eventInfo->shortInfo->text_char; CheckXMLChar(chk); Format(buff, L"<event_text>%s</event_text>", chk.c_str()); serviceinfo += buff; } if( eventInfo->contentInfo != NULL ){ serviceinfo += L""; for( size_t k=0; k<eventInfo->contentInfo->nibbleList.size(); k++){ wstring nibble = L""; Format(nibble,L"<contentInfo><nibble1>%d</nibble1><nibble2>%d</nibble2></contentInfo>", eventInfo->contentInfo->nibbleList[k].content_nibble_level_1, eventInfo->contentInfo->nibbleList[k].content_nibble_level_2); serviceinfo += nibble; } } if( eventInfo->eventGroupInfo != NULL ){ for( size_t k=0; k<eventInfo->eventGroupInfo->eventDataList.size(); k++){ wstring group = L""; Format(group,L"<groupInfo><ONID>%d</ONID><TSID>%d</TSID><SID>%d</SID><eventID>%d</eventID></groupInfo>", eventInfo->eventGroupInfo->eventDataList[k].original_network_id, eventInfo->eventGroupInfo->eventDataList[k].transport_stream_id, eventInfo->eventGroupInfo->eventDataList[k].service_id, eventInfo->eventGroupInfo->eventDataList[k].event_id ); serviceinfo += group; } } Format(buff, L"<freeCAFlag>%d</freeCAFlag>", eventInfo->freeCAFlag); serviceinfo += buff; if( basicOnly == 0 ){ if( eventInfo->extInfo != NULL ){ wstring chk = eventInfo->extInfo->text_char; CheckXMLChar(chk); Format(buff, L"<event_ext_text>%s</event_ext_text>", chk.c_str()); serviceinfo += buff; } if( eventInfo->componentInfo != NULL ){ Format(buff, L"<videoInfo><stream_content>%d</stream_content><component_type>%d</component_type><component_tag>%d</component_tag><text>%s</text></videoInfo>", eventInfo->componentInfo->stream_content, eventInfo->componentInfo->component_type, eventInfo->componentInfo->component_tag, eventInfo->componentInfo->text_char.c_str() ); serviceinfo += buff; } if( eventInfo->audioInfo != NULL ){ for( size_t k=0; k<eventInfo->audioInfo->componentList.size(); k++ ){ Format(buff, L"<audioInfo><stream_content>%d</stream_content><component_type>%d</component_type><component_tag>%d</component_tag><stream_type>%d</stream_type><simulcast_group_tag>%d</simulcast_group_tag><ES_multi_lingual_flag>%d</ES_multi_lingual_flag><main_component_flag>%d</main_component_flag><quality_indicator>%d</quality_indicator><sampling_rate>%d</sampling_rate><text>%s</text></audioInfo>", eventInfo->audioInfo->componentList[k].stream_content, eventInfo->audioInfo->componentList[k].component_type, eventInfo->audioInfo->componentList[k].component_tag, eventInfo->audioInfo->componentList[k].stream_type, eventInfo->audioInfo->componentList[k].simulcast_group_tag, eventInfo->audioInfo->componentList[k].ES_multi_lingual_flag, eventInfo->audioInfo->componentList[k].main_component_flag, eventInfo->audioInfo->componentList[k].quality_indicator, eventInfo->audioInfo->componentList[k].sampling_rate, eventInfo->audioInfo->componentList[k].text_char.c_str() ); serviceinfo += buff; } } if( eventInfo->eventRelayInfo != NULL ){ for( size_t k=0; k<eventInfo->eventRelayInfo->eventDataList.size(); k++){ wstring group = L""; Format(group,L"<relayInfo><ONID>%d</ONID><TSID>%d</TSID><SID>%d</SID><eventID>%d</eventID></relayInfo>", eventInfo->eventRelayInfo->eventDataList[k].original_network_id, eventInfo->eventRelayInfo->eventDataList[k].transport_stream_id, eventInfo->eventRelayInfo->eventDataList[k].service_id, eventInfo->eventRelayInfo->eventDataList[k].event_id ); serviceinfo += group; } } } serviceinfo += L"</eventinfo>"; } serviceinfo += L"</items>"; Format(buff, L"<total>%d</total><index>%d</index><count>%d</count>", total, index, findCount); xml += buff; xml += serviceinfo; xml += L"</entry>"; }else{ xml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><entry>"; xml += L"<err>EPGデータを読み込み中、または存在しません</err>"; xml += L"</entry>"; } WtoUTF8(xml, utf8); sendParam->dataSize = (DWORD)utf8.size(); sendParam->data = new BYTE[sendParam->dataSize]; memcpy(sendParam->data, utf8.c_str(), sendParam->dataSize); if( sendParam->dataSize > 0 ){ Format(sendParam->httpHeader, "HTTP/1.0 200 OK\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", sendParam->dataSize); }else{ sendParam->httpHeader = "HTTP/1.0 400 Bad Request\r\nConnection: close\r\n\r\n"; } return ret; }
//指定サービスの全EPG情報を列挙する BOOL CEpgDBUtil::EnumEpgInfoList( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, BOOL (CALLBACK *enumEpgInfoListProc)(DWORD, EPG_EVENT_INFO*, LPVOID), LPVOID param ) { CBlockLock lock(&this->dbLock); map<ULONGLONG, SERVICE_EVENT_INFO>::iterator itr = this->serviceEventMap.find(_Create64Key(originalNetworkID, transportStreamID, serviceID)); if( itr == this->serviceEventMap.end() ){ return FALSE; } const EVENT_INFO* evtPF[2] = {itr->second.nowEvent.get(), itr->second.nextEvent.get()}; if( evtPF[0] == NULL || evtPF[1] && evtPF[0]->event_id > evtPF[1]->event_id ){ std::swap(evtPF[0], evtPF[1]); } size_t listSize = itr->second.eventMap.size() + (evtPF[0] && itr->second.eventMap.count(evtPF[0]->event_id) == 0 ? 1 : 0) + (evtPF[1] && itr->second.eventMap.count(evtPF[1]->event_id) == 0 ? 1 : 0); if( listSize == 0 ){ return FALSE; } if( enumEpgInfoListProc((DWORD)listSize, NULL, param) == FALSE ){ return TRUE; } BYTE info[__alignof(EPG_EVENT_INFO) + sizeof(EPG_EVENT_INFO) * 32]; map<WORD, std::unique_ptr<EVENT_INFO>>::iterator itrEvt = itr->second.eventMap.begin(); DWORD count = 0; while( evtPF[0] || itrEvt != itr->second.eventMap.end() ){ //デストラクタを呼ばないよう領域だけ割り当て(POD構造体だけなので無問題)、マスターを直接参照して構築する EPG_EVENT_INFO* item = AlignCeil<EPG_EVENT_INFO>(info) + count; EPG_EXTENDED_EVENT_INFO* extInfoSchedule = NULL; const EVENT_INFO* evt; if( itrEvt == itr->second.eventMap.end() || evtPF[0] && evtPF[0]->event_id < itrEvt->first ){ //[p/f]を出力 evt = evtPF[0]; evtPF[0] = evtPF[1]; evtPF[1] = NULL; }else{ if( evtPF[0] && evtPF[0]->event_id == itrEvt->first ){ //両方あるときは[p/f]を優先 evt = evtPF[0]; evtPF[0] = evtPF[1]; evtPF[1] = NULL; if( evt->extInfo == NULL ){ extInfoSchedule = itrEvt->second->extInfo; } }else{ //[schedule]を出力 evt = itrEvt->second.get(); } itrEvt++; } memcpy(item, static_cast<const EPG_EVENT_INFO*>(evt), sizeof(EPG_EVENT_INFO)); if( extInfoSchedule ){ item->extInfo = extInfoSchedule; } if( ++count >= 32 ){ if( enumEpgInfoListProc(count, AlignCeil<EPG_EVENT_INFO>(info), param) == FALSE ){ return TRUE; } count = 0; } } if( count > 0 ){ enumEpgInfoListProc(count, AlignCeil<EPG_EVENT_INFO>(info), param); } return TRUE; }