diff --git a/README.md b/README.md index 87c95bd85..ab9d577dc 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,32 @@ IPTV Live TV and Radio PVR client addon for [Kodi](http://kodi.tv) 4. `cmake -DADDONS_TO_BUILD=pvr.iptvsimple -DADDON_SRC_PREFIX=../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=../../xbmc/addons -DPACKAGE_ZIP=1 ../../xbmc/cmake/addons` 5. `make` +### Mac OSX + +In order to build the addon on mac the steps are different to Linux and Windows as the cmake command above will not produce an addon that will run in kodi. Instead using make directly as per the supported build steps for kodi on mac we can build the tools and just the addon on it's own. Following this we copy the addon into kodi. Note that we checkout kodi to a separate directory as this repo will only only be used to build the addon and nothing else. + +#### Build tools and initial addon build + +1. Get the repos + * `cd $HOME` + * `git clone https://github.com/xbmc/xbmc xbmc-addon` + * `git clone https://github.com/kodi-pvr/pvr.iptvsimple` +2. Build the kodi tools + * `cd $HOME/xbmc-addon/tools/depends` + * `./bootstrap` + * `./configure --host=x86_64-apple-darwin` + * `make -j$(getconf _NPROCESSORS_ONLN)` +3. Build the addon + * `cd $HOME/xbmc-addon` + * `make -j$(getconf _NPROCESSORS_ONLN) -C tools/depends/target/binary-addons ADDONS="pvr.iptvsimple" ADDON_SRC_PREFIX=$HOME` + +Note that the steps in the following section need to be performed before the addon is installed and you can run it in Kodi. + +#### To rebuild the addon and copy to kodi after changes (after the initial addon build) + +1. `cd $HOME/pvr.iptvsimple` +2. `./build-install-mac.sh ../xbmc-addon` + ##### Useful links * [Kodi's PVR user support](http://forum.kodi.tv/forumdisplay.php?fid=167) diff --git a/build-install-mac.sh b/build-install-mac.sh new file mode 100755 index 000000000..805e3d9ee --- /dev/null +++ b/build-install-mac.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +if [ "$#" -ne 1 ] || ! [ -d "$1" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +if [[ "$OSTYPE" != "darwin"* ]]; then + echo "Error: Script only for use on MacOSX" >&2 + exit 1 +fi + +BINARY_ADDONS_TARGET_DIR="$1/tools/depends/target/binary-addons" +MACOSX_BINARY_ADDONS_TARGET_DIR="" +KODI_ADDONS_DIR="$HOME/Library/Application Support/Kodi/addons" +ADDON_NAME=`basename -s .git \`git config --get remote.origin.url\`` + +if [ ! -d "$BINARY_ADDONS_TARGET_DIR" ]; then + echo "Error: Could not find binary addons directory at: $BINARY_ADDONS_TARGET_DIR" >&2 + exit 1 +fi + +XBMC_BUILD_ADDON_INSTALL_DIR=$(cd $1/addons/$ADDON_NAME 2> /dev/null && pwd -P) + +for DIR in "$BINARY_ADDONS_TARGET_DIR/"macosx*; do + if [ -d "${DIR}" ]; then + MACOSX_BINARY_ADDONS_TARGET_DIR="${DIR}" + fi +done + +if [ -z "$MACOSX_BINARY_ADDONS_TARGET_DIR" ]; then + echo "Error: Could not find binary addons build directory at: $BINARY_ADDONS_DIR/macosx*" >&2 + exit 1 +fi + +if [ ! -d "$KODI_ADDONS_DIR" ]; then + echo "Error: Kodi addons dir does not exist at: $KODI_ADDONS_DIR" >&2 + exit 1 +fi + +cd "$MACOSX_BINARY_ADDONS_TARGET_DIR" +make +rm -rf "$KODI_ADDONS_DIR/$ADDON_NAME" +cp -rf "$XBMC_BUILD_ADDON_INSTALL_DIR" "$KODI_ADDONS_DIR" \ No newline at end of file diff --git a/pvr.iptvsimple/addon.xml.in b/pvr.iptvsimple/addon.xml.in index 2788190bb..4bb20960c 100644 --- a/pvr.iptvsimple/addon.xml.in +++ b/pvr.iptvsimple/addon.xml.in @@ -1,7 +1,7 @@ @ADDON_DEPENDS@ diff --git a/pvr.iptvsimple/changelog.txt b/pvr.iptvsimple/changelog.txt index 53f415f23..5f8dfe54c 100644 --- a/pvr.iptvsimple/changelog.txt +++ b/pvr.iptvsimple/changelog.txt @@ -1,3 +1,7 @@ +v4.1.0 +- Support EXTVCOPT in m3u8 +- Build helper script for OSX + v4.0.2 - Fix wrong EPG times due to DST on Windows diff --git a/src/PVRIptvData.cpp b/src/PVRIptvData.cpp index 4385ff8bd..ce7947e5f 100644 --- a/src/PVRIptvData.cpp +++ b/src/PVRIptvData.cpp @@ -22,19 +22,21 @@ * */ +#include "PVRIptvData.h" + +#include "client.h" +#include "p8-platform/util/StringUtils.h" +#include "rapidxml/rapidxml.hpp" +#include "zlib.h" + #include #include #include +#include #include #include #include -#include "zlib.h" -#include "rapidxml/rapidxml.hpp" -#include "PVRIptvData.h" -#include "p8-platform/util/StringUtils.h" -#include "client.h" - #define M3U_START_MARKER "#EXTM3U" #define M3U_INFO_MARKER "#EXTINF" #define TVG_INFO_ID_MARKER "tvg-id=" @@ -44,6 +46,7 @@ #define TVG_INFO_CHNO_MARKER "tvg-chno=" #define GROUP_NAME_MARKER "group-title=" #define KODIPROP_MARKER "#KODIPROP:" +#define EXTVLCOPT_MARKER "#EXTVLCOPT:" #define RADIO_MARKER "radio=" #define PLAYLIST_TYPE_MARKER "#EXT-X-PLAYLIST-TYPE:" #define CHANNEL_LOGO_EXTENSION ".png" @@ -54,10 +57,10 @@ using namespace ADDON; using namespace rapidxml; template -inline bool GetNodeValue(const xml_node * pRootNode, const char* strTag, std::string& strStringValue) +inline bool GetNodeValue(const xml_node* pRootNode, const char* strTag, std::string& strStringValue) { - xml_node *pChildNode = pRootNode->first_node(strTag); - if (pChildNode == NULL) + xml_node* pChildNode = pRootNode->first_node(strTag); + if (!pChildNode) { return false; } @@ -66,10 +69,10 @@ inline bool GetNodeValue(const xml_node * pRootNode, const char* strTag, std } template -inline bool GetAttributeValue(const xml_node * pNode, const char* strAttributeName, std::string& strStringValue) +inline bool GetAttributeValue(const xml_node* pNode, const char* strAttributeName, std::string& strStringValue) { - xml_attribute *pAttribute = pNode->first_attribute(strAttributeName); - if (pAttribute == NULL) + xml_attribute* pAttribute = pNode->first_attribute(strAttributeName); + if (!pAttribute) { return false; } @@ -146,9 +149,9 @@ PVRIptvData::PVRIptvData(void) LoadPlayList(); } -void *PVRIptvData::Process(void) +void* PVRIptvData::Process(void) { - return NULL; + return nullptr; } PVRIptvData::~PVRIptvData(void) @@ -172,7 +175,7 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) int iReaded = 0; int iCount = 0; - while(iCount < 3) // max 3 tries + while (iCount < 3) // max 3 tries { if ((iReaded = GetCachedFileContents(TVG_FILE_NAME, m_strXMLTVUrl, data, g_bCacheEPG)) != 0) { @@ -191,7 +194,7 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) return false; } - char * buffer; + char* buffer; // gzip packed if (data[0] == '\x1F' && data[1] == '\x8B' && data[2] == '\x08') @@ -229,13 +232,13 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) { xmlDoc.parse<0>(buffer); } - catch(parse_error p) + catch (parse_error p) { XBMC->Log(LOG_ERROR, "Unable parse EPG XML: %s", p.what()); return false; } - xml_node<> *pRootElement = xmlDoc.first_node("tv"); + xml_node<>* pRootElement = xmlDoc.first_node("tv"); if (!pRootElement) { XBMC->Log(LOG_ERROR, "Invalid EPG XML: no tag found"); @@ -247,16 +250,16 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) m_epg.clear(); int iBroadCastId = 0; - xml_node<> *pChannelNode = NULL; - for(pChannelNode = pRootElement->first_node("channel"); pChannelNode; pChannelNode = pChannelNode->next_sibling("channel")) + xml_node<>* pChannelNode; + for (pChannelNode = pRootElement->first_node("channel"); pChannelNode; pChannelNode = pChannelNode->next_sibling("channel")) { std::string strName; std::string strId; - if(!GetAttributeValue(pChannelNode, "id", strId)) + if (!GetAttributeValue(pChannelNode, "id", strId)) continue; GetNodeValue(pChannelNode, "display-name", strName); - if (FindChannel(strId, strName) == NULL) + if (!FindChannel(strId, strName)) continue; PVRIptvEpgChannel epgChannel; @@ -264,8 +267,8 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) epgChannel.strName = strName; // get icon if available - xml_node<> *pIconNode = pChannelNode->first_node("icon"); - if (pIconNode == NULL || !GetAttributeValue(pIconNode, "src", epgChannel.strIcon)) + xml_node<>* pIconNode = pChannelNode->first_node("icon"); + if (!pIconNode || !GetAttributeValue(pIconNode, "src", epgChannel.strIcon)) epgChannel.strIcon = ""; m_epg.push_back(epgChannel); @@ -284,39 +287,38 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) iMinShiftTime = SECONDS_IN_DAY; iMaxShiftTime = -SECONDS_IN_DAY; - std::vector::iterator it; - for (it = m_channels.begin(); it < m_channels.end(); ++it) + for (const auto& channel : m_channels) { - if (it->iTvgShift + m_iEPGTimeShift < iMinShiftTime) - iMinShiftTime = it->iTvgShift + m_iEPGTimeShift; - if (it->iTvgShift + m_iEPGTimeShift > iMaxShiftTime) - iMaxShiftTime = it->iTvgShift + m_iEPGTimeShift; + if (channel.iTvgShift + m_iEPGTimeShift < iMinShiftTime) + iMinShiftTime = channel.iTvgShift + m_iEPGTimeShift; + if (channel.iTvgShift + m_iEPGTimeShift > iMaxShiftTime) + iMaxShiftTime = channel.iTvgShift + m_iEPGTimeShift; } } - PVRIptvEpgChannel *epg = NULL; - for(pChannelNode = pRootElement->first_node("programme"); pChannelNode; pChannelNode = pChannelNode->next_sibling("programme")) + PVRIptvEpgChannel* epg; + for (pChannelNode = pRootElement->first_node("programme"); pChannelNode; pChannelNode = pChannelNode->next_sibling("programme")) { std::string strId; if (!GetAttributeValue(pChannelNode, "channel", strId)) continue; - if (NULL == epg || StringUtils::CompareNoCase(epg->strId, strId) != 0) + if (!epg || StringUtils::CompareNoCase(epg->strId, strId) != 0) { - if ((epg = FindEpg(strId)) == NULL) + if (!(epg = FindEpg(strId))) continue; } std::string strStart, strStop; - if ( !GetAttributeValue(pChannelNode, "start", strStart) - || !GetAttributeValue(pChannelNode, "stop", strStop)) + if (!GetAttributeValue(pChannelNode, "start", strStart) || + !GetAttributeValue(pChannelNode, "stop", strStop)) continue; long long iTmpStart = ParseDateTime(strStart); long long iTmpEnd = ParseDateTime(strStop); - if ( (iTmpEnd + iMaxShiftTime < iStart) - || (iTmpStart + iMinShiftTime > iEnd)) + if ((iTmpEnd + iMaxShiftTime < iStart) || + (iTmpStart + iMinShiftTime > iEnd)) continue; PVRIptvEpgEntry entry; @@ -332,8 +334,8 @@ bool PVRIptvData::LoadEPG(time_t iStart, time_t iEnd) GetNodeValue(pChannelNode, "desc", entry.strPlot); GetNodeValue(pChannelNode, "category", entry.strGenreString); - xml_node<> *pIconNode = pChannelNode->first_node("icon"); - if (pIconNode == NULL || !GetAttributeValue(pIconNode, "src", entry.strIconPath)) + xml_node<>* pIconNode = pChannelNode->first_node("icon"); + if (!pIconNode || !GetAttributeValue(pIconNode, "src", entry.strIconPath)) entry.strIconPath = ""; epg->epg.push_back(entry); @@ -368,12 +370,12 @@ bool PVRIptvData::LoadPlayList(void) std::stringstream stream(strPlaylistContent); /* load channels */ - bool bFirst = true; - bool bIsRealTime = true; - int iChannelIndex = 0; - int iUniqueGroupId = 0; - int iChannelNum = g_iStartNumber; - int iEPGTimeShift = 0; + bool bFirst = true; + bool bIsRealTime = true; + int iChannelIndex = 0; + int iUniqueGroupId = 0; + int iChannelNum = g_iStartNumber; + int iEPGTimeShift = 0; std::vector iCurrentGroupId; PVRIptvChannel tmpChannel; @@ -384,7 +386,7 @@ bool PVRIptvData::LoadPlayList(void) tmpChannel.iTvgShift = 0; std::string strLine; - while(std::getline(stream, strLine)) + while (std::getline(stream, strLine)) { strLine = StringUtils::TrimRight(strLine, " \t\r\n"); strLine = StringUtils::TrimLeft(strLine, " \t"); @@ -406,7 +408,7 @@ bool PVRIptvData::LoadPlayList(void) if (StringUtils::Left(strLine, strlen(M3U_START_MARKER)) == M3U_START_MARKER) { double fTvgShift = atof(ReadMarkerValue(strLine, TVG_INFO_SHIFT_MARKER).c_str()); - iEPGTimeShift = (int) (fTvgShift * 3600.0); + iEPGTimeShift = (int)(fTvgShift * 3600.0); continue; } else @@ -432,18 +434,20 @@ bool PVRIptvData::LoadPlayList(void) std::string strRadio = ""; // parse line - int iColon = (int)strLine.find(':'); - int iComma = (int)strLine.rfind(','); + int iColon = static_cast(strLine.find(':')); + int iComma = static_cast(strLine.rfind(',')); if (iColon >= 0 && iComma >= 0 && iComma > iColon) { // parse name iComma++; - strChnlName = StringUtils::Right(strLine, (int)strLine.size() - iComma); + strChnlName = StringUtils::Right(strLine, static_cast(strLine.size() - iComma)); strChnlName = StringUtils::Trim(strChnlName); tmpChannel.strChannelName = XBMC->UnknownToUTF8(strChnlName.c_str()); // parse info - std::string strInfoLine = StringUtils::Mid(strLine, ++iColon, --iComma - iColon); + iColon++; + iComma--; + const std::string strInfoLine = StringUtils::Mid(strLine, iColon, iComma - iColon); strTvgId = ReadMarkerValue(strInfoLine, TVG_INFO_ID_MARKER); strTvgName = ReadMarkerValue(strInfoLine, TVG_INFO_NAME_MARKER); @@ -484,14 +488,14 @@ bool PVRIptvData::LoadPlayList(void) if (!strGroupName.empty()) { std::stringstream streamGroups(strGroupName); - PVRIptvChannelGroup * pGroup; iCurrentGroupId.clear(); - while(std::getline(streamGroups, strGroupName, ';')) + while (std::getline(streamGroups, strGroupName, ';')) { strGroupName = XBMC->UnknownToUTF8(strGroupName.c_str()); + const PVRIptvChannelGroup* pGroup = FindGroup(strGroupName); - if ((pGroup = FindGroup(strGroupName)) == NULL) + if (!pGroup) { PVRIptvChannelGroup group; group.strGroupName = strGroupName; @@ -511,13 +515,26 @@ bool PVRIptvData::LoadPlayList(void) } else if (StringUtils::Left(strLine, strlen(KODIPROP_MARKER)) == KODIPROP_MARKER) { - std::string value = ReadMarkerValue(strLine, KODIPROP_MARKER); + const std::string value = ReadMarkerValue(strLine, KODIPROP_MARKER); + auto pos = value.find('='); + if (pos != std::string::npos) + { + const std::string prop = value.substr(0, pos); + const std::string propValue = value.substr(pos + 1); + tmpChannel.properties.insert({prop, propValue}); + } + } + else if (StringUtils::Left(strLine, strlen(EXTVLCOPT_MARKER)) == EXTVLCOPT_MARKER) + { + const std::string value = ReadMarkerValue(strLine, EXTVLCOPT_MARKER); auto pos = value.find('='); if (pos != std::string::npos) { - std::string prop = value.substr(0,pos); - std::string propValue = value.substr(pos+1); + const std::string prop = value.substr(0, pos); + const std::string propValue = value.substr(pos + 1); tmpChannel.properties.insert({prop, propValue}); + + XBMC->Log(LOG_DEBUG, "Found #EXTVLCOPT property: '%s' value: '%s'", prop.c_str(), propValue.c_str()); } } else if (StringUtils::Left(strLine, strlen(PLAYLIST_TYPE_MARKER)) == PLAYLIST_TYPE_MARKER) @@ -527,9 +544,7 @@ bool PVRIptvData::LoadPlayList(void) } else if (strLine[0] != '#') { - XBMC->Log(LOG_DEBUG, - "Found URL: '%s' (current channel name: '%s')", - strLine.c_str(), tmpChannel.strChannelName.c_str()); + XBMC->Log(LOG_DEBUG, "Found URL: '%s' (current channel name: '%s')", strLine.c_str(), tmpChannel.strChannelName.c_str()); if (bIsRealTime) tmpChannel.properties.insert({PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true"}); @@ -549,11 +564,10 @@ bool PVRIptvData::LoadPlayList(void) iChannelNum++; - std::vector::iterator it; - for (auto it = iCurrentGroupId.begin(); it != iCurrentGroupId.end(); ++it) + for (int myGroupId : iCurrentGroupId) { - channel.bRadio = m_groups.at(*it - 1).bRadio; - m_groups.at(*it - 1).members.push_back(iChannelIndex); + channel.bRadio = m_groups.at(myGroupId - 1).bRadio; + m_groups.at(myGroupId - 1).members.push_back(iChannelIndex); } m_channels.push_back(channel); @@ -616,11 +630,11 @@ bool PVRIptvData::LoadGenres(void) return false; } - xml_node<> *pRootElement = xmlDoc.first_node("genres"); + xml_node<>* pRootElement = xmlDoc.first_node("genres"); if (!pRootElement) return false; - for (xml_node<> *pGenreNode = pRootElement->first_node("genre"); pGenreNode; pGenreNode = pGenreNode->next_sibling("genre")) + for (xml_node<>* pGenreNode = pRootElement->first_node("genre"); pGenreNode; pGenreNode = pGenreNode->next_sibling("genre")) { std::string buff; if (!GetAttributeValue(pGenreNode, "type", buff)) @@ -634,8 +648,7 @@ bool PVRIptvData::LoadGenres(void) genre.iGenreType = atoi(buff.c_str()); genre.iGenreSubType = 0; - if ( GetAttributeValue(pGenreNode, "subtype", buff) - && StringUtils::IsNaturalNumber(buff)) + if (GetAttributeValue(pGenreNode, "subtype", buff) && StringUtils::IsNaturalNumber(buff)) genre.iGenreSubType = atoi(buff.c_str()); m_genres.push_back(genre); @@ -656,7 +669,7 @@ PVR_ERROR PVRIptvData::GetChannels(ADDON_HANDLE handle, bool bRadio) P8PLATFORM::CLockObject lock(m_mutex); for (unsigned int iChannelPtr = 0; iChannelPtr < m_channels.size(); iChannelPtr++) { - PVRIptvChannel &channel = m_channels.at(iChannelPtr); + PVRIptvChannel& channel = m_channels.at(iChannelPtr); if (channel.bRadio == bRadio) { PVR_CHANNEL xbmcChannel; @@ -677,13 +690,13 @@ PVR_ERROR PVRIptvData::GetChannels(ADDON_HANDLE handle, bool bRadio) return PVR_ERROR_NO_ERROR; } -bool PVRIptvData::GetChannel(const PVR_CHANNEL &channel, PVRIptvChannel &myChannel) +bool PVRIptvData::GetChannel(const PVR_CHANNEL& channel, PVRIptvChannel& myChannel) { P8PLATFORM::CLockObject lock(m_mutex); for (unsigned int iChannelPtr = 0; iChannelPtr < m_channels.size(); iChannelPtr++) { - PVRIptvChannel &thisChannel = m_channels.at(iChannelPtr); - if (thisChannel.iUniqueId == (int) channel.iUniqueId) + PVRIptvChannel& thisChannel = m_channels.at(iChannelPtr); + if (thisChannel.iUniqueId == static_cast(channel.iUniqueId)) { myChannel.iUniqueId = thisChannel.iUniqueId; myChannel.bRadio = thisChannel.bRadio; @@ -710,17 +723,16 @@ int PVRIptvData::GetChannelGroupsAmount(void) PVR_ERROR PVRIptvData::GetChannelGroups(ADDON_HANDLE handle, bool bRadio) { P8PLATFORM::CLockObject lock(m_mutex); - std::vector::iterator it; - for (it = m_groups.begin(); it != m_groups.end(); ++it) + for (const auto& group : m_groups) { - if (it->bRadio == bRadio) + if (group.bRadio == bRadio) { PVR_CHANNEL_GROUP xbmcGroup; memset(&xbmcGroup, 0, sizeof(PVR_CHANNEL_GROUP)); - xbmcGroup.iPosition = 0; /* not supported */ - xbmcGroup.bIsRadio = bRadio; /* is radio group */ - strncpy(xbmcGroup.strGroupName, it->strGroupName.c_str(), sizeof(xbmcGroup.strGroupName) - 1); + xbmcGroup.iPosition = 0; /* not supported */ + xbmcGroup.bIsRadio = bRadio; /* is radio group */ + strncpy(xbmcGroup.strGroupName, group.strGroupName.c_str(), sizeof(xbmcGroup.strGroupName) - 1); PVR->TransferChannelGroup(handle, &xbmcGroup); } @@ -729,25 +741,24 @@ PVR_ERROR PVRIptvData::GetChannelGroups(ADDON_HANDLE handle, bool bRadio) return PVR_ERROR_NO_ERROR; } -PVR_ERROR PVRIptvData::GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &group) +PVR_ERROR PVRIptvData::GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP& group) { P8PLATFORM::CLockObject lock(m_mutex); - PVRIptvChannelGroup *myGroup; - if ((myGroup = FindGroup(group.strGroupName)) != NULL) + const PVRIptvChannelGroup* myGroup = FindGroup(group.strGroupName); + if (myGroup) { - std::vector::iterator it; - for (it = myGroup->members.begin(); it != myGroup->members.end(); ++it) + for (const auto& memberId : myGroup->members) { - if ((*it) < 0 || (*it) >= (int)m_channels.size()) + if ((memberId) < 0 || (memberId) >= static_cast(m_channels.size())) continue; - PVRIptvChannel &channel = m_channels.at(*it); + PVRIptvChannel& channel = m_channels.at(memberId); PVR_CHANNEL_GROUP_MEMBER xbmcGroupMember; memset(&xbmcGroupMember, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER)); strncpy(xbmcGroupMember.strGroupName, group.strGroupName, sizeof(xbmcGroupMember.strGroupName) - 1); xbmcGroupMember.iChannelUniqueId = channel.iUniqueId; - xbmcGroupMember.iChannelNumber = channel.iChannelNumber; + xbmcGroupMember.iChannelNumber = channel.iChannelNumber; PVR->TransferChannelGroupMember(handle, &xbmcGroupMember); } @@ -759,10 +770,9 @@ PVR_ERROR PVRIptvData::GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHA PVR_ERROR PVRIptvData::GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, time_t iStart, time_t iEnd) { P8PLATFORM::CLockObject lock(m_mutex); - std::vector::iterator myChannel; - for (myChannel = m_channels.begin(); myChannel < m_channels.end(); ++myChannel) + for (const auto& myChannel : m_channels) { - if (myChannel->iUniqueId != iChannelUid) + if (myChannel.iUniqueId != iChannelUid) continue; if (iStart > m_iLastStart || iEnd > m_iLastEnd) @@ -776,16 +786,15 @@ PVR_ERROR PVRIptvData::GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, ti } } - PVRIptvEpgChannel *epg; - if ((epg = FindEpgForChannel(*myChannel)) == NULL || epg->epg.size() == 0) + const PVRIptvEpgChannel* epg = FindEpgForChannel(myChannel); + if (!epg || epg->epg.size() == 0) return PVR_ERROR_NO_ERROR; - int iShift = m_bTSOverride ? m_iEPGTimeShift : myChannel->iTvgShift + m_iEPGTimeShift; + int iShift = m_bTSOverride ? m_iEPGTimeShift : myChannel.iTvgShift + m_iEPGTimeShift; - std::vector::iterator myTag; - for (myTag = epg->epg.begin(); myTag < epg->epg.end(); ++myTag) + for (const auto& myTag : epg->epg) { - if ((myTag->endTime + iShift) < iStart) + if ((myTag.endTime + iShift) < iStart) continue; int iGenreType, iGenreSubType; @@ -793,43 +802,43 @@ PVR_ERROR PVRIptvData::GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, ti EPG_TAG tag; memset(&tag, 0, sizeof(EPG_TAG)); - tag.iUniqueBroadcastId = myTag->iBroadcastId; - tag.strTitle = myTag->strTitle.c_str(); + tag.iUniqueBroadcastId = myTag.iBroadcastId; + tag.strTitle = myTag.strTitle.c_str(); tag.iUniqueChannelId = iChannelUid; - tag.startTime = myTag->startTime + iShift; - tag.endTime = myTag->endTime + iShift; - tag.strPlotOutline = myTag->strPlotOutline.c_str(); - tag.strPlot = myTag->strPlot.c_str(); - tag.strOriginalTitle = NULL; /* not supported */ - tag.strCast = NULL; /* not supported */ - tag.strDirector = NULL; /* not supported */ - tag.strWriter = NULL; /* not supported */ + tag.startTime = myTag.startTime + iShift; + tag.endTime = myTag.endTime + iShift; + tag.strPlotOutline = myTag.strPlotOutline.c_str(); + tag.strPlot = myTag.strPlot.c_str(); + tag.strOriginalTitle = nullptr; /* not supported */ + tag.strCast = nullptr; /* not supported */ + tag.strDirector = nullptr; /* not supported */ + tag.strWriter = nullptr; /* not supported */ tag.iYear = 0; /* not supported */ - tag.strIMDBNumber = NULL; /* not supported */ - tag.strIconPath = myTag->strIconPath.c_str(); - if (FindEpgGenre(myTag->strGenreString, iGenreType, iGenreSubType)) + tag.strIMDBNumber = nullptr; /* not supported */ + tag.strIconPath = myTag.strIconPath.c_str(); + if (FindEpgGenre(myTag.strGenreString, iGenreType, iGenreSubType)) { tag.iGenreType = iGenreType; tag.iGenreSubType = iGenreSubType; - tag.strGenreDescription = NULL; + tag.strGenreDescription = nullptr; } else { tag.iGenreType = EPG_GENRE_USE_STRING; tag.iGenreSubType = 0; /* not supported */ - tag.strGenreDescription = myTag->strGenreString.c_str(); + tag.strGenreDescription = myTag.strGenreString.c_str(); } tag.iParentalRating = 0; /* not supported */ tag.iStarRating = 0; /* not supported */ tag.iSeriesNumber = 0; /* not supported */ tag.iEpisodeNumber = 0; /* not supported */ tag.iEpisodePartNumber = 0; /* not supported */ - tag.strEpisodeName = NULL; /* not supported */ + tag.strEpisodeName = nullptr; /* not supported */ tag.iFlags = EPG_TAG_FLAG_UNDEFINED; PVR->TransferEpgEntry(handle, &tag); - if ((myTag->startTime + iShift) > iEnd) + if ((myTag.startTime + iShift) > iEnd) break; } @@ -839,7 +848,7 @@ PVR_ERROR PVRIptvData::GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, ti return PVR_ERROR_NO_ERROR; } -int PVRIptvData::GetFileContents(std::string& url, std::string &strContent) +int PVRIptvData::GetFileContents(const std::string& url, std::string& strContent) { strContent.clear(); void* fileHandle = XBMC->OpenFile(url.c_str(), 0); @@ -854,73 +863,66 @@ int PVRIptvData::GetFileContents(std::string& url, std::string &strContent) return strContent.length(); } -PVRIptvChannel * PVRIptvData::FindChannel(const std::string &strId, const std::string &strName) +const PVRIptvChannel* PVRIptvData::FindChannel(const std::string& strId, const std::string& strName) const { - std::string strTvgName = strName; - StringUtils::Replace(strTvgName, ' ', '_'); + const std::string strTvgName = std::regex_replace(strName, std::regex(" "), "_"); - std::vector::iterator it; - for(it = m_channels.begin(); it < m_channels.end(); ++it) + for (const auto& myChannel : m_channels) { - if (it->strTvgId == strId) - return &*it; + if (myChannel.strTvgId == strId) + return &myChannel; if (strTvgName == "") continue; - if (it->strTvgName == strTvgName) - return &*it; + if (myChannel.strTvgName == strTvgName) + return &myChannel; - if (it->strChannelName == strName) - return &*it; + if (myChannel.strChannelName == strName) + return &myChannel; } - return NULL; + return nullptr; } -PVRIptvChannelGroup * PVRIptvData::FindGroup(const std::string &strName) +const PVRIptvChannelGroup* PVRIptvData::FindGroup(const std::string& strName) const { - std::vector::iterator it; - for(it = m_groups.begin(); it < m_groups.end(); ++it) + for (const auto& myGroup : m_groups) { - if (it->strGroupName == strName) - return &*it; + if (myGroup.strGroupName == strName) + return &myGroup; } - return NULL; + return nullptr; } -PVRIptvEpgChannel * PVRIptvData::FindEpg(const std::string &strId) +PVRIptvEpgChannel* PVRIptvData::FindEpg(const std::string& strId) { - std::vector::iterator it; - for(it = m_epg.begin(); it < m_epg.end(); ++it) + for (auto& myEpgChannel : m_epg) { - if (StringUtils::CompareNoCase(it->strId, strId) == 0) - return &*it; + if (StringUtils::CompareNoCase(myEpgChannel.strId, strId) == 0) + return &myEpgChannel; } - return NULL; + return nullptr; } -PVRIptvEpgChannel * PVRIptvData::FindEpgForChannel(PVRIptvChannel &channel) +const PVRIptvEpgChannel* PVRIptvData::FindEpgForChannel(const PVRIptvChannel& channel) const { - std::vector::iterator it; - for(it = m_epg.begin(); it < m_epg.end(); ++it) + for (const auto& myEpgChannel : m_epg) { - if (it->strId == channel.strTvgId) - return &*it; + if (myEpgChannel.strId == channel.strTvgId) + return &myEpgChannel; - std::string strName = it->strName; - StringUtils::Replace(strName, ' ', '_'); - if (strName == channel.strTvgName - || it->strName == channel.strTvgName) - return &*it; + const std::string strName = std::regex_replace(myEpgChannel.strName, std::regex(" "), "_"); + if (strName == channel.strTvgName || myEpgChannel.strName == channel.strTvgName) + return &myEpgChannel; - if (it->strName == channel.strChannelName) - return &*it; + if (myEpgChannel.strName == channel.strChannelName) + return &myEpgChannel; } - return NULL; + return nullptr; } bool PVRIptvData::FindEpgGenre(const std::string& strGenre, int& iType, int& iSubType) @@ -928,13 +930,12 @@ bool PVRIptvData::FindEpgGenre(const std::string& strGenre, int& iType, int& iSu if (m_genres.empty()) return false; - std::vector::iterator it; - for (it = m_genres.begin(); it != m_genres.end(); ++it) + for (const auto& myGenre : m_genres) { - if (StringUtils::CompareNoCase(it->strGenre, strGenre) == 0) + if (StringUtils::CompareNoCase(myGenre.strGenre, strGenre) == 0) { - iType = it->iGenreType; - iSubType = it->iGenreSubType; + iType = myGenre.iGenreType; + iSubType = myGenre.iGenreSubType; return true; } } @@ -947,7 +948,8 @@ bool PVRIptvData::FindEpgGenre(const std::string& strGenre, int& iType, int& iSu * Author: Andrew Lim Chong Liang * http://windrealm.org */ -bool PVRIptvData::GzipInflate( const std::string& compressedBytes, std::string& uncompressedBytes ) { +bool PVRIptvData::GzipInflate(const std::string& compressedBytes, std::string& uncompressedBytes) +{ #define HANDLE_CALL_ZLIB(status) { \ if(status != Z_OK) { \ @@ -956,48 +958,48 @@ bool PVRIptvData::GzipInflate( const std::string& compressedBytes, std::string& } \ } - if ( compressedBytes.size() == 0 ) + if (compressedBytes.size() == 0) { - uncompressedBytes = compressedBytes ; - return true ; + uncompressedBytes = compressedBytes; + return true; } - uncompressedBytes.clear() ; + uncompressedBytes.clear(); - unsigned full_length = compressedBytes.size() ; + unsigned full_length = compressedBytes.size(); unsigned half_length = compressedBytes.size() / 2; - unsigned uncompLength = full_length ; - char* uncomp = (char*) calloc( sizeof(char), uncompLength ); + unsigned uncompLength = full_length; + char* uncomp = static_cast(calloc(sizeof(char), uncompLength)); z_stream strm; - strm.next_in = (Bytef *) compressedBytes.c_str(); - strm.avail_in = compressedBytes.size() ; + strm.next_in = (Bytef*)compressedBytes.c_str(); + strm.avail_in = compressedBytes.size(); strm.total_out = 0; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; - bool done = false ; + bool done = false; - HANDLE_CALL_ZLIB(inflateInit2(&strm, (16+MAX_WBITS))); + HANDLE_CALL_ZLIB(inflateInit2(&strm, (16 + MAX_WBITS))); while (!done) { // If our output buffer is too small - if (strm.total_out >= uncompLength ) + if (strm.total_out >= uncompLength) { // Increase size of output buffer - uncomp = (char *) realloc(uncomp, uncompLength + half_length); - if (uncomp == NULL) + uncomp = static_cast(realloc(uncomp, uncompLength + half_length)); + if (!uncomp) return false; - uncompLength += half_length ; + uncompLength += half_length; } - strm.next_out = (Bytef *) (uncomp + strm.total_out); + strm.next_out = (Bytef*)(uncomp + strm.total_out); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. - int err = inflate (&strm, Z_SYNC_FLUSH); + int err = inflate(&strm, Z_SYNC_FLUSH); if (err == Z_STREAM_END) done = true; else if (err != Z_OK) @@ -1006,23 +1008,23 @@ bool PVRIptvData::GzipInflate( const std::string& compressedBytes, std::string& } } - HANDLE_CALL_ZLIB(inflateEnd (&strm)); + HANDLE_CALL_ZLIB(inflateEnd(&strm)); - for ( size_t i=0; iFileExists(strCachedPath.c_str(), false)) @@ -1060,17 +1062,16 @@ int PVRIptvData::GetCachedFileContents(const std::string &strCachedName, const s void PVRIptvData::ApplyChannelsLogos() { - std::vector::iterator channel; - for(channel = m_channels.begin(); channel < m_channels.end(); ++channel) + for (auto& channel : m_channels) { - if (!channel->strTvgLogo.empty()) + if (!channel.strTvgLogo.empty()) { if (!m_strLogoPath.empty() // special proto - && channel->strTvgLogo.find("://") == std::string::npos) - channel->strLogoPath = PathCombine(m_strLogoPath, channel->strTvgLogo); + && channel.strTvgLogo.find("://") == std::string::npos) + channel.strLogoPath = PathCombine(m_strLogoPath, channel.strTvgLogo); else - channel->strLogoPath = channel->strTvgLogo; + channel.strLogoPath = channel.strTvgLogo; } } } @@ -1079,21 +1080,20 @@ void PVRIptvData::ApplyChannelsLogosFromEPG() { bool bUpdated = false; - std::vector::iterator channel; - for (channel = m_channels.begin(); channel < m_channels.end(); ++channel) + for (auto& channel : m_channels) { - PVRIptvEpgChannel *epg; - if ((epg = FindEpgForChannel(*channel)) == NULL || epg->strIcon.empty()) + const PVRIptvEpgChannel* epg = FindEpgForChannel(channel); + if (!epg || epg->strIcon.empty()) continue; // 1 - prefer logo from playlist - if (!channel->strLogoPath.empty() && g_iEPGLogos == 1) + if (!channel.strLogoPath.empty() && g_iEPGLogos == 1) continue; // 2 - prefer logo from epg if (!epg->strIcon.empty() && g_iEPGLogos == 2) { - channel->strLogoPath = epg->strIcon; + channel.strLogoPath = epg->strIcon; bUpdated = true; } } @@ -1102,7 +1102,7 @@ void PVRIptvData::ApplyChannelsLogosFromEPG() PVR->TriggerChannelUpdate(); } -void PVRIptvData::ReaplyChannelsLogos(const char * strNewPath) +void PVRIptvData::ReaplyChannelsLogos(const char* strNewPath) { P8PLATFORM::CLockObject lock(m_mutex); if (strlen(strNewPath) > 0) @@ -1115,7 +1115,7 @@ void PVRIptvData::ReaplyChannelsLogos(const char * strNewPath) } } -void PVRIptvData::ReloadEPG(const char * strNewPath) +void PVRIptvData::ReloadEPG(const char* strNewPath) { P8PLATFORM::CLockObject lock(m_mutex); if (strNewPath != m_strXMLTVUrl) @@ -1125,16 +1125,16 @@ void PVRIptvData::ReloadEPG(const char * strNewPath) if (LoadEPG(m_iLastStart, m_iLastEnd)) { - for(unsigned int iChannelPtr = 0, max = m_channels.size(); iChannelPtr < max; iChannelPtr++) + for (unsigned int iChannelPtr = 0, max = m_channels.size(); iChannelPtr < max; iChannelPtr++) { - PVRIptvChannel &myChannel = m_channels.at(iChannelPtr); + PVRIptvChannel& myChannel = m_channels.at(iChannelPtr); PVR->TriggerEpgUpdate(myChannel.iUniqueId); } } } } -void PVRIptvData::ReloadPlayList(const char * strNewPath) +void PVRIptvData::ReloadPlayList(const char* strNewPath) { P8PLATFORM::CLockObject lock(m_mutex); if (strNewPath != m_strM3uUrl) @@ -1150,14 +1150,14 @@ void PVRIptvData::ReloadPlayList(const char * strNewPath) } } -std::string PVRIptvData::ReadMarkerValue(std::string &strLine, const char* strMarkerName) +std::string PVRIptvData::ReadMarkerValue(const std::string& strLine, const char* strMarkerName) { - int iMarkerStart = (int) strLine.find(strMarkerName); + int iMarkerStart = static_cast(strLine.find(strMarkerName)); if (iMarkerStart >= 0) { - std::string strMarker = strMarkerName; + const std::string strMarker = strMarkerName; iMarkerStart += strMarker.length(); - if (iMarkerStart < (int)strLine.length()) + if (iMarkerStart < static_cast(strLine.length())) { char cFind = ' '; if (strLine[iMarkerStart] == '"') @@ -1165,7 +1165,7 @@ std::string PVRIptvData::ReadMarkerValue(std::string &strLine, const char* strMa cFind = '"'; iMarkerStart++; } - int iMarkerEnd = (int)strLine.find(cFind, iMarkerStart); + int iMarkerEnd = static_cast(strLine.find(cFind, iMarkerStart)); if (iMarkerEnd < 0) { iMarkerEnd = strLine.length(); @@ -1177,7 +1177,7 @@ std::string PVRIptvData::ReadMarkerValue(std::string &strLine, const char* strMa return std::string(""); } -int PVRIptvData::GetChannelId(const char * strChannelName, const char * strStreamUrl) +int PVRIptvData::GetChannelId(const char* strChannelName, const char* strStreamUrl) { std::string concat(strChannelName); concat.append(strStreamUrl); @@ -1185,7 +1185,7 @@ int PVRIptvData::GetChannelId(const char * strChannelName, const char * strStrea const char* strString = concat.c_str(); int iId = 0; int c; - while (c = *strString++) + while ((c = *strString++)) iId = ((iId << 5) + iId) + c; /* iId * 33 + c */ return abs(iId); diff --git a/src/PVRIptvData.h b/src/PVRIptvData.h index 6d02b8f8a..d127fd225 100644 --- a/src/PVRIptvData.h +++ b/src/PVRIptvData.h @@ -23,20 +23,21 @@ * */ -#include -#include #include "p8-platform/os.h" #include "libXBMC_pvr.h" #include "p8-platform/threads/threads.h" +#include +#include + struct PVRIptvEpgEntry { - int iBroadcastId; - int iChannelId; - int iGenreType; - int iGenreSubType; - time_t startTime; - time_t endTime; + int iBroadcastId; + int iChannelId; + int iGenreType; + int iGenreSubType; + time_t startTime; + time_t endTime; std::string strTitle; std::string strPlotOutline; std::string strPlot; @@ -46,19 +47,19 @@ struct PVRIptvEpgEntry struct PVRIptvEpgChannel { - std::string strId; - std::string strName; - std::string strIcon; + std::string strId; + std::string strName; + std::string strIcon; std::vector epg; }; struct PVRIptvChannel { - bool bRadio; - int iUniqueId; - int iChannelNumber; - int iEncryptionSystem; - int iTvgShift; + bool bRadio; + int iUniqueId; + int iChannelNumber; + int iEncryptionSystem; + int iTvgShift; std::string strChannelName; std::string strLogoPath; std::string strStreamURL; @@ -70,68 +71,68 @@ struct PVRIptvChannel struct PVRIptvChannelGroup { - bool bRadio; - int iGroupId; - std::string strGroupName; - std::vector members; + bool bRadio; + int iGroupId; + std::string strGroupName; + std::vector members; }; struct PVRIptvEpgGenre { - int iGenreType; - int iGenreSubType; - std::string strGenre; + int iGenreType; + int iGenreSubType; + std::string strGenre; }; class PVRIptvData : public P8PLATFORM::CThread { public: PVRIptvData(void); - virtual ~PVRIptvData(void); + ~PVRIptvData(void); - virtual int GetChannelsAmount(void); - virtual PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio); - virtual bool GetChannel(const PVR_CHANNEL &channel, PVRIptvChannel &myChannel); - virtual int GetChannelGroupsAmount(void); - virtual PVR_ERROR GetChannelGroups(ADDON_HANDLE handle, bool bRadio); - virtual PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &group); - virtual PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, time_t iStart, time_t iEnd); - virtual void ReaplyChannelsLogos(const char * strNewPath); - virtual void ReloadPlayList(const char * strNewPath); - virtual void ReloadEPG(const char * strNewPath); + int GetChannelsAmount(void); + PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio); + bool GetChannel(const PVR_CHANNEL& channel, PVRIptvChannel& myChannel); + int GetChannelGroupsAmount(void); + PVR_ERROR GetChannelGroups(ADDON_HANDLE handle, bool bRadio); + PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP& group); + PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, int iChannelUid, time_t iStart, time_t iEnd); + void ReaplyChannelsLogos(const char* strNewPath); + void ReloadPlayList(const char* strNewPath); + void ReloadEPG(const char* strNewPath); protected: - virtual bool LoadPlayList(void); - virtual bool LoadEPG(time_t iStart, time_t iEnd); - virtual bool LoadGenres(void); - virtual int GetFileContents(std::string& url, std::string &strContent); - virtual PVRIptvChannel* FindChannel(const std::string &strId, const std::string &strName); - virtual PVRIptvChannelGroup* FindGroup(const std::string &strName); - virtual PVRIptvEpgChannel* FindEpg(const std::string &strId); - virtual PVRIptvEpgChannel* FindEpgForChannel(PVRIptvChannel &channel); - virtual bool FindEpgGenre(const std::string& strGenre, int& iType, int& iSubType); - virtual bool GzipInflate( const std::string &compressedBytes, std::string &uncompressedBytes); - virtual int GetCachedFileContents(const std::string &strCachedName, const std::string &strFilePath, - std::string &strContent, const bool bUseCache = false); - virtual void ApplyChannelsLogos(); - virtual void ApplyChannelsLogosFromEPG(); - virtual std::string ReadMarkerValue(std::string &strLine, const char * strMarkerName); - virtual int GetChannelId(const char * strChannelName, const char * strStreamUrl); + bool LoadPlayList(void); + bool LoadEPG(time_t iStart, time_t iEnd); + bool LoadGenres(void); + int GetFileContents(const std::string& url, std::string& strContent); + const PVRIptvChannel* FindChannel(const std::string& strId, const std::string& strName) const; + const PVRIptvChannelGroup* FindGroup(const std::string& strName) const; + PVRIptvEpgChannel* FindEpg(const std::string& strId); + const PVRIptvEpgChannel* FindEpgForChannel(const PVRIptvChannel& channel) const; + bool FindEpgGenre(const std::string& strGenre, int& iType, int& iSubType); + bool GzipInflate(const std::string& compressedBytes, std::string& uncompressedBytes); + int GetCachedFileContents(const std::string& strCachedName, const std::string& strFilePath, + std::string& strContent, const bool bUseCache = false); + void ApplyChannelsLogos(); + void ApplyChannelsLogosFromEPG(); + std::string ReadMarkerValue(const std::string& strLine, const char* strMarkerName); + int GetChannelId(const char* strChannelName, const char* strStreamUrl); protected: - virtual void *Process(void); + void* Process(void) override; private: - bool m_bTSOverride; - int m_iEPGTimeShift; - int m_iLastStart; - int m_iLastEnd; - std::string m_strXMLTVUrl; - std::string m_strM3uUrl; - std::string m_strLogoPath; - std::vector m_groups; - std::vector m_channels; - std::vector m_epg; - std::vector m_genres; - P8PLATFORM::CMutex m_mutex; + bool m_bTSOverride; + int m_iEPGTimeShift; + int m_iLastStart; + int m_iLastEnd; + std::string m_strXMLTVUrl; + std::string m_strM3uUrl; + std::string m_strLogoPath; + std::vector m_groups; + std::vector m_channels; + std::vector m_epg; + std::vector m_genres; + P8PLATFORM::CMutex m_mutex; }; diff --git a/src/client.cpp b/src/client.cpp index b3dc701af..fcfe01d6d 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -23,9 +23,10 @@ */ #include "client.h" -#include "xbmc_pvr_dll.h" + #include "PVRIptvData.h" #include "p8-platform/util/util.h" +#include "xbmc_pvr_dll.h" using namespace ADDON; @@ -39,40 +40,40 @@ using namespace ADDON; #endif #endif -bool m_bCreated = false; -ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN; -PVRIptvData *m_data = NULL; +bool m_bCreated = false; +ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN; +PVRIptvData* m_data = nullptr; PVRIptvChannel m_currentChannel; /* User adjustable settings are saved here. * Default values are defined inside client.h * and exported to the other source files. */ -std::string g_strUserPath = ""; +std::string g_strUserPath = ""; std::string g_strClientPath = ""; -CHelper_libXBMC_addon *XBMC = NULL; -CHelper_libXBMC_pvr *PVR = NULL; +CHelper_libXBMC_addon* XBMC = nullptr; +CHelper_libXBMC_pvr* PVR = nullptr; -std::string g_strTvgPath = ""; -std::string g_strM3UPath = ""; -std::string g_strLogoPath = ""; -int g_iEPGTimeShift = 0; -int g_iStartNumber = 1; -bool g_bTSOverride = true; -bool g_bCacheM3U = false; -bool g_bCacheEPG = false; -int g_iEPGLogos = 0; +std::string g_strTvgPath = ""; +std::string g_strM3UPath = ""; +std::string g_strLogoPath = ""; +int g_iEPGTimeShift = 0; +int g_iStartNumber = 1; +bool g_bTSOverride = true; +bool g_bCacheM3U = false; +bool g_bCacheEPG = false; +int g_iEPGLogos = 0; -extern std::string PathCombine(const std::string &strPath, const std::string &strFileName) +extern std::string PathCombine(const std::string& strPath, const std::string& strFileName) { std::string strResult = strPath; if (strResult.at(strResult.size() - 1) == '\\' || - strResult.at(strResult.size() - 1) == '/') + strResult.at(strResult.size() - 1) == '/') { strResult.append(strFileName); } - else + else { strResult.append("/"); strResult.append(strFileName); @@ -81,29 +82,29 @@ extern std::string PathCombine(const std::string &strPath, const std::string &st return strResult; } -extern std::string GetClientFilePath(const std::string &strFileName) +extern std::string GetClientFilePath(const std::string& strFileName) { return PathCombine(g_strClientPath, strFileName); } -extern std::string GetUserFilePath(const std::string &strFileName) +extern std::string GetUserFilePath(const std::string& strFileName) { return PathCombine(g_strUserPath, strFileName); } -extern "C" { - +extern "C" +{ void ADDON_ReadSettings(void) { char buffer[1024]; int iPathType = 0; - if (!XBMC->GetSetting("m3uPathType", &iPathType)) + if (!XBMC->GetSetting("m3uPathType", &iPathType)) { iPathType = 1; } if (iPathType) { - if (XBMC->GetSetting("m3uUrl", &buffer)) + if (XBMC->GetSetting("m3uUrl", &buffer)) { g_strM3UPath = buffer; } @@ -114,23 +115,23 @@ void ADDON_ReadSettings(void) } else { - if (XBMC->GetSetting("m3uPath", &buffer)) + if (XBMC->GetSetting("m3uPath", &buffer)) { g_strM3UPath = buffer; } g_bCacheM3U = false; } - if (!XBMC->GetSetting("startNum", &g_iStartNumber)) + if (!XBMC->GetSetting("startNum", &g_iStartNumber)) { g_iStartNumber = 1; } - if (!XBMC->GetSetting("epgPathType", &iPathType)) + if (!XBMC->GetSetting("epgPathType", &iPathType)) { iPathType = 1; } if (iPathType) { - if (XBMC->GetSetting("epgUrl", &buffer)) + if (XBMC->GetSetting("epgUrl", &buffer)) { g_strTvgPath = buffer; } @@ -141,7 +142,7 @@ void ADDON_ReadSettings(void) } else { - if (XBMC->GetSetting("epgPath", &buffer)) + if (XBMC->GetSetting("epgPath", &buffer)) { g_strTvgPath = buffer; } @@ -156,11 +157,11 @@ void ADDON_ReadSettings(void) { g_bTSOverride = true; } - if (!XBMC->GetSetting("logoPathType", &iPathType)) + if (!XBMC->GetSetting("logoPathType", &iPathType)) { iPathType = 1; } - if (XBMC->GetSetting(iPathType ? "logoBaseUrl" : "logoPath", &buffer)) + if (XBMC->GetSetting(iPathType ? "logoBaseUrl" : "logoPath", &buffer)) { g_strLogoPath = buffer; } @@ -177,7 +178,7 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props) return ADDON_STATUS_UNKNOWN; } - PVR_PROPERTIES* pvrprops = (PVR_PROPERTIES*)props; + PVR_PROPERTIES* pvrprops = static_cast(props); XBMC = new CHelper_libXBMC_addon; if (!XBMC->RegisterMe(hdl)) @@ -196,8 +197,8 @@ ADDON_STATUS ADDON_Create(void* hdl, void* props) XBMC->Log(LOG_DEBUG, "%s - Creating the PVR IPTV Simple add-on", __FUNCTION__); - m_CurStatus = ADDON_STATUS_UNKNOWN; - g_strUserPath = pvrprops->strUserPath; + m_CurStatus = ADDON_STATUS_UNKNOWN; + g_strUserPath = pvrprops->strUserPath; g_strClientPath = pvrprops->strClientPath; if (!XBMC->DirectoryExists(g_strUserPath.c_str())) @@ -226,9 +227,9 @@ void ADDON_Destroy() m_CurStatus = ADDON_STATUS_UNKNOWN; } -ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +ADDON_STATUS ADDON_SetSetting(const char* settingName, const void* settingValue) { - // reset cache and restart addon + // reset cache and restart addon std::string strFile = GetUserFilePath(M3U_FILE_NAME); if (XBMC->FileExists(strFile.c_str(), false)) @@ -249,29 +250,21 @@ ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) * PVR Client AddOn specific public library functions ***********************************************************/ -void OnSystemSleep() -{ -} +void OnSystemSleep() {} -void OnSystemWake() -{ -} +void OnSystemWake() {} -void OnPowerSavingActivated() -{ -} +void OnPowerSavingActivated() {} -void OnPowerSavingDeactivated() -{ -} +void OnPowerSavingDeactivated() {} PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities) { - pCapabilities->bSupportsEPG = true; - pCapabilities->bSupportsTV = true; - pCapabilities->bSupportsRadio = true; - pCapabilities->bSupportsChannelGroups = true; - pCapabilities->bSupportsRecordings = false; + pCapabilities->bSupportsEPG = true; + pCapabilities->bSupportsTV = true; + pCapabilities->bSupportsRadio = true; + pCapabilities->bSupportsChannelGroups = true; + pCapabilities->bSupportsRecordings = false; pCapabilities->bSupportsRecordingsRename = false; pCapabilities->bSupportsRecordingsLifetimeChange = false; pCapabilities->bSupportsDescrambleInfo = false; @@ -279,33 +272,33 @@ PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities) return PVR_ERROR_NO_ERROR; } -const char *GetBackendName(void) +const char* GetBackendName(void) { - static const char *strBackendName = "IPTV Simple PVR Add-on"; + static const char* strBackendName = "IPTV Simple PVR Add-on"; return strBackendName; } -const char *GetBackendVersion(void) +const char* GetBackendVersion(void) { static std::string strBackendVersion = STR(IPTV_VERSION); return strBackendVersion.c_str(); } -const char *GetConnectionString(void) +const char* GetConnectionString(void) { static std::string strConnectionString = "connected"; return strConnectionString.c_str(); } -const char *GetBackendHostname(void) +const char* GetBackendHostname(void) { return ""; } -PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed) +PVR_ERROR GetDriveSpace(long long* iTotal, long long* iUsed) { *iTotal = 0; - *iUsed = 0; + *iUsed = 0; return PVR_ERROR_NO_ERROR; } @@ -350,10 +343,8 @@ PVR_ERROR GetChannelStreamProperties(const PVR_CHANNEL* channel, PVR_NAMED_VALUE { for (auto& prop : m_currentChannel.properties) { - strncpy(properties[*iPropertiesCount].strName, prop.first.c_str(), - sizeof(properties[*iPropertiesCount].strName) - 1); - strncpy(properties[*iPropertiesCount].strValue, prop.second.c_str(), - sizeof(properties[*iPropertiesCount].strName) - 1); + strncpy(properties[*iPropertiesCount].strName, prop.first.c_str(), sizeof(properties[*iPropertiesCount].strName) - 1); + strncpy(properties[*iPropertiesCount].strValue, prop.second.c_str(), sizeof(properties[*iPropertiesCount].strName) - 1); (*iPropertiesCount)++; } } @@ -379,7 +370,7 @@ PVR_ERROR GetChannelGroups(ADDON_HANDLE handle, bool bRadio) return PVR_ERROR_SERVER_ERROR; } -PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &group) +PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP& group) { if (m_data) return m_data->GetChannelGroupMembers(handle, group); @@ -387,7 +378,7 @@ PVR_ERROR GetChannelGroupMembers(ADDON_HANDLE handle, const PVR_CHANNEL_GROUP &g return PVR_ERROR_SERVER_ERROR; } -PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS &signalStatus) +PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) { snprintf(signalStatus.strAdapterName, sizeof(signalStatus.strAdapterName), "IPTV Simple Adapter 1"); snprintf(signalStatus.strAdapterStatus, sizeof(signalStatus.strAdapterStatus), "OK"); @@ -401,43 +392,43 @@ int GetRecordingsAmount(bool deleted) { return -1; } PVR_ERROR GetRecordings(ADDON_HANDLE handle, bool deleted) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR GetRecordingStreamProperties(const PVR_RECORDING*, PVR_NAMED_VALUE*, unsigned int*) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR OpenDialogChannelScan(void) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR CallMenuHook(const PVR_MENUHOOK &menuhook, const PVR_MENUHOOK_DATA &item) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR DeleteChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR RenameChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR OpenDialogChannelSettings(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR OpenDialogChannelAdd(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; } -void CloseLiveStream(void) { } -bool OpenRecordedStream(const PVR_RECORDING &recording) { return false; } -bool OpenLiveStream(const PVR_CHANNEL &channel) { return false; } +PVR_ERROR CallMenuHook(const PVR_MENUHOOK& menuhook, const PVR_MENUHOOK_DATA& item) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR DeleteChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR RenameChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR OpenDialogChannelSettings(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR OpenDialogChannelAdd(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; } +void CloseLiveStream(void) {} +bool OpenRecordedStream(const PVR_RECORDING& recording) { return false; } +bool OpenLiveStream(const PVR_CHANNEL& channel) { return false; } void CloseRecordedStream(void) {} -int ReadRecordedStream(unsigned char *pBuffer, unsigned int iBufferSize) { return 0; } +int ReadRecordedStream(unsigned char* pBuffer, unsigned int iBufferSize) { return 0; } long long SeekRecordedStream(long long iPosition, int iWhence /* = SEEK_SET */) { return 0; } long long LengthRecordedStream(void) { return 0; } void DemuxReset(void) {} void DemuxFlush(void) {} void FillBuffer(bool mode) {} -int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize) { return 0; } +int ReadLiveStream(unsigned char* pBuffer, unsigned int iBufferSize) { return 0; } long long SeekLiveStream(long long iPosition, int iWhence /* = SEEK_SET */) { return -1; } long long LengthLiveStream(void) { return -1; } -PVR_ERROR DeleteRecording(const PVR_RECORDING &recording) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR RenameRecording(const PVR_RECORDING &recording) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR SetRecordingPlayCount(const PVR_RECORDING &recording, int count) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR SetRecordingLastPlayedPosition(const PVR_RECORDING &recording, int lastplayedposition) { return PVR_ERROR_NOT_IMPLEMENTED; } -int GetRecordingLastPlayedPosition(const PVR_RECORDING &recording) { return -1; } +PVR_ERROR DeleteRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR RenameRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR SetRecordingPlayCount(const PVR_RECORDING& recording, int count) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR SetRecordingLastPlayedPosition(const PVR_RECORDING& recording, int lastplayedposition) { return PVR_ERROR_NOT_IMPLEMENTED; } +int GetRecordingLastPlayedPosition(const PVR_RECORDING& recording) { return -1; } PVR_ERROR GetRecordingEdl(const PVR_RECORDING&, PVR_EDL_ENTRY[], int*) { return PVR_ERROR_NOT_IMPLEMENTED; }; -PVR_ERROR GetTimerTypes(PVR_TIMER_TYPE types[], int *size) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR GetTimerTypes(PVR_TIMER_TYPE types[], int* size) { return PVR_ERROR_NOT_IMPLEMENTED; } int GetTimersAmount(void) { return -1; } PVR_ERROR GetTimers(ADDON_HANDLE handle) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR AddTimer(const PVR_TIMER &timer) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR DeleteTimer(const PVR_TIMER &timer, bool bForceDelete) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR UpdateTimer(const PVR_TIMER &timer) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR AddTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR DeleteTimer(const PVR_TIMER& timer, bool bForceDelete) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR UpdateTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED; } void DemuxAbort(void) {} -DemuxPacket* DemuxRead(void) { return NULL; } +DemuxPacket* DemuxRead(void) { return nullptr; } bool IsRealTimeStream(void) { return true; } void PauseStream(bool bPaused) {} bool CanSeekStream(void) { return false; } -bool SeekTime(double,bool,double*) { return false; } -void SetSpeed(int) {}; +bool SeekTime(double, bool, double*) { return false; } +void SetSpeed(int){}; PVR_ERROR UndeleteRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR DeleteAllRecordingsFromTrash() { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR SetEPGTimeFrame(int) { return PVR_ERROR_NOT_IMPLEMENTED; } @@ -448,7 +439,6 @@ PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES*) { return PVR_ERROR_NOT_IMP PVR_ERROR IsEPGTagRecordable(const EPG_TAG*, bool*) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR IsEPGTagPlayable(const EPG_TAG*, bool*) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR GetEPGTagStreamProperties(const EPG_TAG*, PVR_NAMED_VALUE*, unsigned int*) { return PVR_ERROR_NOT_IMPLEMENTED; } -PVR_ERROR GetEPGTagEdl(const EPG_TAG* epgTag, PVR_EDL_ENTRY edl[], int *size) { return PVR_ERROR_NOT_IMPLEMENTED; } +PVR_ERROR GetEPGTagEdl(const EPG_TAG* epgTag, PVR_EDL_ENTRY edl[], int* size) { return PVR_ERROR_NOT_IMPLEMENTED; } PVR_ERROR GetStreamReadChunkSize(int* chunksize) { return PVR_ERROR_NOT_IMPLEMENTED; } - } // extern "C" diff --git a/src/client.h b/src/client.h index 972eab592..a5450a8be 100644 --- a/src/client.h +++ b/src/client.h @@ -26,31 +26,31 @@ #include "libXBMC_addon.h" #include "libXBMC_pvr.h" -#define M3U_FILE_NAME "iptv.m3u.cache" -#define TVG_FILE_NAME "xmltv.xml.cache" +#define M3U_FILE_NAME "iptv.m3u.cache" +#define TVG_FILE_NAME "xmltv.xml.cache" /*! * @brief PVR macros for string exchange */ -#define PVR_STRCPY(dest, source) do { strncpy(dest, source, sizeof(dest)-1); dest[sizeof(dest)-1] = '\0'; } while(0) +#define PVR_STRCPY(dest, source) do { strncpy(dest, source, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; } while (0) #define PVR_STRCLR(dest) memset(dest, 0, sizeof(dest)) -extern bool m_bCreated; -extern std::string g_strUserPath; -extern std::string g_strClientPath; -extern ADDON::CHelper_libXBMC_addon *XBMC; -extern CHelper_libXBMC_pvr *PVR; +extern bool m_bCreated; +extern std::string g_strUserPath; +extern std::string g_strClientPath; +extern ADDON::CHelper_libXBMC_addon* XBMC; +extern CHelper_libXBMC_pvr* PVR; extern std::string g_strM3UPath; extern std::string g_strTvgPath; extern std::string g_strLogoPath; -extern int g_iEPGTimeShift; -extern int g_iStartNumber; -extern bool g_bTSOverride; -extern bool g_bCacheM3U; -extern bool g_bCacheEPG; -extern int g_iEPGLogos; +extern int g_iEPGTimeShift; +extern int g_iStartNumber; +extern bool g_bTSOverride; +extern bool g_bCacheM3U; +extern bool g_bCacheEPG; +extern int g_iEPGLogos; -extern std::string PathCombine(const std::string &strPath, const std::string &strFileName); -extern std::string GetClientFilePath(const std::string &strFileName); -extern std::string GetUserFilePath(const std::string &strFileName); +extern std::string PathCombine(const std::string& strPath, const std::string& strFileName); +extern std::string GetClientFilePath(const std::string& strFileName); +extern std::string GetUserFilePath(const std::string& strFileName);