//指定サービスの全EPG情報を列挙する //引数: // enumEpgInfoListProc [IN]EPG情報のリストを取得するコールバック関数 // param [IN]コールバック引数 DWORD CEpgDataCap3Util::EnumEpgInfoList( WORD originalNetworkID, WORD transportStreamID, WORD serviceID, BOOL (CALLBACK *enumEpgInfoListProc)(DWORD epgInfoListSize, EPG_EVENT_INFO* epgInfoList, LPVOID param), LPVOID param ) { if( module == NULL || id == 0 ){ return ERR_NOT_INIT; } if( pfnEnumEpgInfoListEP3 == NULL ){ DWORD epgInfoListSize; EPG_EVENT_INFO* epgInfoList; DWORD ret = pfnGetEpgInfoListEP3(id, originalNetworkID, transportStreamID, serviceID, &epgInfoListSize, &epgInfoList); if( ret == NO_ERR && enumEpgInfoListProc(epgInfoListSize, NULL, param) != FALSE ){ enumEpgInfoListProc(epgInfoListSize, epgInfoList, param); } return ret; } return pfnEnumEpgInfoListEP3(id, originalNetworkID, transportStreamID, serviceID, enumEpgInfoListProc, param); }
//指定サービスの全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; }