bool CDVDSubtitleParserVplayer::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; // Vplayer subtitles have 1-second resolution m_framerate = DVD_TIME_BASE; // Vplayer subtitles don't have StopTime, so we use following subtitle's StartTime // for that, unless gap was more than 4 seconds. Then we set subtitle duration // for 4 seconds, to not have text hanging around in silent scenes... int iDefaultDuration = 4 * (int)m_framerate; char line[1024]; CRegExp reg; if (!reg.RegComp("([0-9]+):([0-9]+):([0-9]+):([^|]*?)(\\|([^|]*?))?$")) return false; CDVDOverlayText* pPrevOverlay = NULL; while (m_pStream->ReadLine(line, sizeof(line))) { if (reg.RegFind(line) > -1) { std::string hour = reg.GetReplaceString("\\1"); std::string min = reg.GetReplaceString("\\2"); std::string sec = reg.GetReplaceString("\\3"); std::string lines[3]; lines[0] = reg.GetReplaceString("\\4"); lines[1] = reg.GetReplaceString("\\6"); lines[2] = reg.GetReplaceString("\\8"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * (3600*atoi(hour.c_str()) + 60*atoi(min.c_str()) + atoi(sec.c_str())); // set StopTime for previous overlay if (pPrevOverlay) { if ( (pOverlay->iPTSStartTime - pPrevOverlay->iPTSStartTime) < iDefaultDuration) pPrevOverlay->iPTSStopTime = pOverlay->iPTSStartTime; else pPrevOverlay->iPTSStopTime = pPrevOverlay->iPTSStartTime + iDefaultDuration; } pPrevOverlay = pOverlay; for (int i = 0; i < 3 && !lines[i].empty(); i++) pOverlay->AddElement(new CDVDOverlayText::CElementText(lines[i].c_str())); m_collection.Add(pOverlay); } // set StopTime for the last subtitle if (pPrevOverlay) pPrevOverlay->iPTSStopTime = pPrevOverlay->iPTSStartTime + iDefaultDuration; } return true; }
void CLabelFormatter::AssembleMask(unsigned int label, const CStdString& mask) { assert(label < 2); m_staticContent[label].clear(); m_dynamicContent[label].clear(); // we want to match [<prefix>%A<postfix] // but allow %%, %[, %] to be in the prefix and postfix. Anything before the first [ // could be a mask that's not surrounded with [], so pass to SplitMask. CRegExp reg; reg.RegComp("(^|[^%])\\[(([^%]|%%|%\\]|%\\[)*)%([" MASK_CHARS "])(([^%]|%%|%\\]|%\\[)*)\\]"); CStdString work(mask); int findStart = -1; while ((findStart = reg.RegFind(work.c_str())) >= 0) { // we've found a match for a pre/postfixed string // send anything char *s1 = reg.GetReplaceString("\\1"); char *s2 = reg.GetReplaceString("\\2"); char *s4 = reg.GetReplaceString("\\4"); char *s5 = reg.GetReplaceString("\\5"); SplitMask(label, work.Left(findStart) + s1); m_dynamicContent[label].push_back(CMaskString(s2, *s4, s5)); free(s1); free(s2); free(s4); free(s5); work = work.Mid(findStart + reg.GetFindLen()); } SplitMask(label, work); assert(m_staticContent[label].size() == m_dynamicContent[label].size() + 1); }
bool CDVDSubtitleParserSami::Open(CDVDStreamInfo &hints) { if (!m_pStream->Open(m_strFileName)) return false; char line[1024]; char text[1024]; CRegExp reg; if (!reg.RegComp("<SYNC START=([0-9]+)>")) assert(0); bool reuse=false; while (reuse || m_pStream->ReadLine(line, sizeof(line))) { if (reg.RegFind(line) > -1) { char* startFrame = reg.GetReplaceString("\\1"); m_pStream->ReadLine(text,sizeof(text)); m_pStream->ReadLine(line,sizeof(line)); if (reg.RegFind(line) > -1) { char* endFrame = reg.GetReplaceString("\\1"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = atoi(startFrame)*DVD_TIME_BASE/1000; pOverlay->iPTSStopTime = atoi(endFrame)*DVD_TIME_BASE/1000; CStdStringW strUTF16; CStdStringA strUTF8; g_charsetConverter.subtitleCharsetToW(text, strUTF16); g_charsetConverter.wToUTF8(strUTF16, strUTF8); if (strUTF8.IsEmpty()) continue; // add a new text element to our container pOverlay->AddElement(new CDVDOverlayText::CElementText(strUTF8.c_str())); reuse = true; free(endFrame); m_collection.Add(pOverlay); } free(startFrame); } else reuse = false; } return true; }
void CScraperParser::ConvertJSON(CStdString &string) { CRegExp reg; reg.RegComp("\\\\u([0-f]{4})"); while (reg.RegFind(string.c_str()) > -1) { int pos = reg.GetSubStart(1); std::string szReplace = reg.GetReplaceString("\\1"); CStdString replace; replace.Format("&#x%s;", szReplace.c_str()); string.replace(string.begin()+pos-2, string.begin()+pos+4, replace); } CRegExp reg2; reg2.RegComp("\\\\x([0-9]{2})([^\\\\]+;)"); while (reg2.RegFind(string.c_str()) > -1) { int pos1 = reg2.GetSubStart(1); int pos2 = reg2.GetSubStart(2); std::string szHexValue = reg2.GetReplaceString("\\1"); CStdString replace; replace.Format("%c", strtol(szHexValue.c_str(), NULL, 16)); string.replace(string.begin()+pos1-2, string.begin()+pos2+reg2.GetSubLength(2), replace); } string.Replace("\\\"","\""); }
TEST(TestRegExp, GetReplaceString) { CRegExp regex; EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\.")); EXPECT_EQ(0, regex.RegFind("Test string.")); EXPECT_STREQ("string", regex.GetReplaceString("\\2")); }
void CPosixMountProvider::GetDrives(VECSOURCES &drives) { std::vector<CStdString> result; CRegExp reMount; #ifdef __APPLE__ reMount.RegComp("on (.+) \\(([^,]+)"); #else reMount.RegComp("on (.+) type ([^ ]+)"); #endif char line[1024]; FILE* pipe = popen("mount", "r"); if (pipe) { while (fgets(line, sizeof(line) - 1, pipe)) { if (reMount.RegFind(line) != -1) { bool accepted = false; char* mount = reMount.GetReplaceString("\\1"); char* fs = reMount.GetReplaceString("\\2"); // Here we choose which filesystems are approved if (strcmp(fs, "fuseblk") == 0 || strcmp(fs, "vfat") == 0 || strcmp(fs, "ext2") == 0 || strcmp(fs, "ext3") == 0 || strcmp(fs, "reiserfs") == 0 || strcmp(fs, "xfs") == 0 || strcmp(fs, "ntfs-3g") == 0 || strcmp(fs, "iso9660") == 0 || strcmp(fs, "fusefs") == 0 || strcmp(fs, "hfs") == 0) accepted = true; // Ignore root if (strcmp(mount, "/") == 0) accepted = false; if(accepted) result.push_back(mount); free(fs); free(mount); } } pclose(pipe); } for (unsigned int i = 0; i < result.size(); i++) { CMediaSource share; share.strPath = result[i]; share.strName = URIUtils::GetFileName(result[i]); share.m_ignore = true; drives.push_back(share); } }
void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives) { // mounted usb disks std::vector<CStdString> result; CRegExp reMount; reMount.RegComp("^(.+?)\\s+(.+?)\\s+(.+?)\\s"); char line[1024]; FILE* pipe = fopen("/proc/mounts", "r"); if (pipe) { while (fgets(line, sizeof(line) - 1, pipe)) { if (reMount.RegFind(line) != -1) { bool accepted = false; std::string mountStr = reMount.GetReplaceString("\\2"); std::string fsStr = reMount.GetReplaceString("\\3"); const char* mount = mountStr.c_str(); const char* fs = fsStr.c_str(); // Here we choose which filesystems are approved if (strcmp(fs, "fuseblk") == 0 || strcmp(fs, "vfat") == 0 || strcmp(fs, "ext2") == 0 || strcmp(fs, "ext3") == 0 || strcmp(fs, "ext4") == 0 || strcmp(fs, "reiserfs") == 0 || strcmp(fs, "xfs") == 0 || strcmp(fs, "ntfs-3g") == 0 || strcmp(fs, "iso9660") == 0 || strcmp(fs, "exfat") == 0 || strcmp(fs, "fusefs") == 0 || strcmp(fs, "hfs") == 0) accepted = true; // Ignore everything but usb if (!StringUtils::StartsWith(mountStr, "/mnt/usb")) accepted = false; if(accepted) result.push_back(mount); } } fclose(pipe); } else CLog::Log(LOGERROR, "Cannot read mount points"); for (unsigned int i = 0; i < result.size(); i++) { CMediaSource share; share.strPath = unescape(result[i]); share.strName = URIUtils::GetFileName(share.strPath); share.m_ignore = true; removableDrives.push_back(share); } }
void CLabelFormatter::SplitMask(unsigned int label, const CStdString &mask) { assert(label < 2); CRegExp reg; reg.RegComp("%([" MASK_CHARS "])"); CStdString work(mask); int findStart = -1; while ((findStart = reg.RegFind(work.c_str())) >= 0) { // we've found a match m_staticContent[label].push_back(work.Left(findStart)); m_dynamicContent[label].push_back(CMaskString("", *reg.GetReplaceString("\\1"), "")); work = work.Mid(findStart + reg.GetFindLen()); } m_staticContent[label].push_back(work); }
bool CDVDSubtitleParserMicroDVD::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; CLog::Log(LOGDEBUG, "%s - framerate %d:%d", __FUNCTION__, hints.fpsrate, hints.fpsscale); if (hints.fpsscale > 0 && hints.fpsrate > 0) { m_framerate = (double)hints.fpsscale / (double)hints.fpsrate; m_framerate *= DVD_TIME_BASE; } else m_framerate = DVD_TIME_BASE / 25.0; char line[1024]; CRegExp reg; if (!reg.RegComp("\\{([0-9]+)\\}\\{([0-9]+)\\}")) return false; CDVDSubtitleTagMicroDVD TagConv; while (m_pStream->ReadLine(line, sizeof(line))) { if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = 0; int pos = reg.RegFind(line); if (pos > -1) { const char* text = line + pos + reg.GetFindLen(); std::string startFrame = reg.GetReplaceString("\\1"); std::string endFrame = reg.GetReplaceString("\\2"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * atoi(startFrame.c_str()); pOverlay->iPTSStopTime = m_framerate * atoi(endFrame.c_str()); TagConv.ConvertLine(pOverlay, text, strlen(text)); m_collection.Add(pOverlay); } } return true; }
bool CDVDSubtitleParserMPL2::Open(CDVDStreamInfo &hints) { if (!CDVDSubtitleParserText::Open()) return false; // MPL2 is time-based, with 0.1s accuracy m_framerate = DVD_TIME_BASE / 10.0; char line[1024]; CRegExp reg; if (!reg.RegComp("\\[([0-9]+)\\]\\[([0-9]+)\\]")) return false; CDVDSubtitleTagMicroDVD TagConv; while (m_pStream->ReadLine(line, sizeof(line))) { if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = 0; int pos = reg.RegFind(line); if (pos > -1) { const char* text = line + pos + reg.GetFindLen(); char* startFrame = reg.GetReplaceString("\\1"); char* endFrame = reg.GetReplaceString("\\2"); CDVDOverlayText* pOverlay = new CDVDOverlayText(); pOverlay->Acquire(); // increase ref count with one so that we can hold a handle to this overlay pOverlay->iPTSStartTime = m_framerate * atoi(startFrame); pOverlay->iPTSStopTime = m_framerate * atoi(endFrame); TagConv.ConvertLine(pOverlay, text, strlen(text)); free(startFrame); free(endFrame); m_collection.Add(pOverlay); } } return true; }
void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives) { // mounted usb disks char* buf = NULL; FILE* pipe; std::map<std::string, std::string> result; CRegExp reMount; reMount.RegComp("^(.+?)\\s+(.+?)\\s+(.+?)\\s"); /* /proc/mounts is only guaranteed atomic for the current read * operation, so we need to read it all at once. */ if ((pipe = fopen("/proc/mounts", "r"))) { char* new_buf; size_t buf_len = 4096; while ((new_buf = (char*)realloc(buf, buf_len * sizeof(char)))) { size_t nread; buf = new_buf; nread = fread(buf, sizeof(char), buf_len, pipe); if (nread == buf_len) { rewind(pipe); buf_len *= 2; } else { buf[nread] = '\0'; if (!feof(pipe)) new_buf = NULL; break; } } if (!new_buf) { free(buf); buf = NULL; } fclose(pipe); } else CLog::Log(LOGERROR, "Cannot read mount points"); if (buf) { char* line; char* saveptr = NULL; line = strtok_r(buf, "\n", &saveptr); while (line) { if (reMount.RegFind(line) != -1) { bool accepted = false; std::string device = reMount.GetReplaceString("\\1"); std::string mountStr = reMount.GetReplaceString("\\2"); std::string fsStr = reMount.GetReplaceString("\\3"); const char* fs = fsStr.c_str(); // Here we choose which filesystems are approved if (strcmp(fs, "fuseblk") == 0 || strcmp(fs, "vfat") == 0 || strcmp(fs, "ext2") == 0 || strcmp(fs, "ext3") == 0 || strcmp(fs, "ext4") == 0 || strcmp(fs, "reiserfs") == 0 || strcmp(fs, "xfs") == 0 || strcmp(fs, "ntfs-3g") == 0 || strcmp(fs, "iso9660") == 0 || strcmp(fs, "exfat") == 0 || strcmp(fs, "fusefs") == 0 || strcmp(fs, "hfs") == 0) accepted = true; // Ignore sdcards if (!StringUtils::StartsWith(device, "/dev/block/vold/") || mountStr.find("sdcard") != std::string::npos || mountStr.find("secure/asec") != std::string::npos) accepted = false; if(accepted) result[device] = mountStr; } line = strtok_r(NULL, "\n", &saveptr); } free(buf); } for (std::map<std::string, std::string>::const_iterator i = result.begin(); i != result.end(); ++i) { CMediaSource share; share.strPath = unescape(i->second); share.strName = URIUtils::GetFileName(share.strPath); share.m_ignore = true; removableDrives.push_back(share); } }
void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives) { // mounted usb disks char* buf = NULL; FILE* pipe; CRegExp reMount; reMount.RegComp("^(.+?)\\s+(.+?)\\s+(.+?)\\s+(.+?)\\s"); /* /proc/mounts is only guaranteed atomic for the current read * operation, so we need to read it all at once. */ if ((pipe = fopen("/proc/mounts", "r"))) { char* new_buf; size_t buf_len = 4096; while ((new_buf = (char*)realloc(buf, buf_len * sizeof(char)))) { size_t nread; buf = new_buf; nread = fread(buf, sizeof(char), buf_len, pipe); if (nread == buf_len) { rewind(pipe); buf_len *= 2; } else { buf[nread] = '\0'; if (!feof(pipe)) new_buf = NULL; break; } } if (!new_buf) { free(buf); buf = NULL; } fclose(pipe); } else CLog::Log(LOGERROR, "Cannot read mount points"); if (buf) { char* line; char* saveptr = NULL; line = strtok_r(buf, "\n", &saveptr); while (line) { if (reMount.RegFind(line) != -1) { std::string deviceStr = reMount.GetReplaceString("\\1"); std::string mountStr = reMount.GetReplaceString("\\2"); std::string fsStr = reMount.GetReplaceString("\\3"); std::string optStr = reMount.GetReplaceString("\\4"); // Blacklist bool bl_ok = true; // Reject unreadable if (!XFILE::CDirectory::Exists(mountStr)) bl_ok = false; // What mount points are rejected for (unsigned int i=0; i < ARRAY_SIZE(mountBL); ++i) if (StringUtils::StartsWithNoCase(mountStr, mountBL[i])) bl_ok = false; if (bl_ok) { // What filesystems are accepted bool fsok = false; for (unsigned int i=0; i < ARRAY_SIZE(typeWL); ++i) if (StringUtils::StartsWithNoCase(fsStr, typeWL[i])) continue; // What devices are accepted bool devok = false; for (unsigned int i=0; i < ARRAY_SIZE(deviceWL); ++i) if (StringUtils::StartsWithNoCase(deviceStr, deviceWL[i])) devok = true; // What mount points are accepted bool mountok = false; for (unsigned int i=0; i < ARRAY_SIZE(mountWL); ++i) if (StringUtils::StartsWithNoCase(mountStr, mountWL[i])) mountok = true; if(devok && (fsok || mountok)) { CMediaSource share; share.strPath = unescape(mountStr); share.strName = URIUtils::GetFileName(mountStr); share.m_ignore = true; removableDrives.push_back(share); } } } line = strtok_r(NULL, "\n", &saveptr); } free(buf); } }
bool CMusicInfoTagLoaderSid::Load(const CStdString& strFileName, CMusicInfoTag& tag) { CStdString strFileToLoad = strFileName; int iTrack = 0; CStdString strExtension; CUtil::GetExtension(strFileName,strExtension); strExtension.MakeLower(); if (strExtension==".sidstream") { // Extract the track to play CStdString strFile=CUtil::GetFileName(strFileName); int iStart=strFile.ReverseFind("-")+1; iTrack = atoi(strFile.substr(iStart, strFile.size()-iStart-10).c_str()); // The directory we are in, is the file // that contains the bitstream to play, // so extract it CStdString strPath=strFileName; CUtil::GetDirectory(strPath, strFileToLoad); CUtil::RemoveSlashAtEnd(strFileToLoad); // we want the filename } CStdString strFileNameLower(strFileToLoad); strFileNameLower.MakeLower(); int iHVSC = strFileNameLower.find("hvsc"); // need hvsc in path name since our lookupfile is based on hvsc paths if (iHVSC < 0) { iHVSC = strFileNameLower.find("c64music"); if (iHVSC >= 0) iHVSC += 8; } else iHVSC += 4; if( iHVSC < 0 ) { tag.SetLoaded(false); return( false ); } CStdString strHVSCpath = strFileToLoad.substr(iHVSC,strFileToLoad.length()-1); strHVSCpath.Replace('\\','/'); // unix paths strHVSCpath.MakeLower(); char temp[8192]; CRegExp reg; if (!reg.RegComp("TITLE: ([^\r\n]*)\r?\n[^A]*ARTIST: ([^\r\n]*)\r?\n")) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"stil.txt"); // changeme? std::ifstream f(temp); if( !f.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate stil.txt"); tag.SetLoaded(false); return( false ); } const char* szStart = NULL; const char* szEnd = NULL; char temp2[8191]; char* temp3 = temp2; while( !f.eof() && !szEnd ) { f.read(temp,8191); CStdString strLower = temp; strLower.MakeLower(); if (!szStart) szStart= (char *)strstr(strLower.c_str(),strHVSCpath.c_str()); if (szStart) { szEnd = strstr(szStart+strHVSCpath.size(),".sid"); if (szEnd) { memcpy(temp3,temp+(szStart-strLower.c_str()),szEnd-szStart); temp3 += szEnd-szStart; } else { memcpy(temp3,temp+(szStart-strLower.c_str()),strlen(szStart)); szStart = NULL; temp3 += strlen(szStart); } } } f.close(); if (!f.eof() && szEnd) { temp2[temp3-temp2] = '\0'; temp3 = strstr(temp2,"TITLE:"); } else temp3 = NULL; if (temp3) { for (int i=0;i<iTrack-1;++i) // skip tracks { int iStart = reg.RegFind(temp3); if (!iStart) { tag.SetLoaded(false); return false; } temp3 += iStart; } if(reg.RegFind(temp3) > -1) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szMins = NULL; char* szSecs = NULL; CRegExp reg2; reg2.RegComp("(.*) \\(([0-9]*):([0-9]*)\\)"); if (reg2.RegFind(szTitle) > -1) { szMins = reg2.GetReplaceString("\\2"); szSecs = reg2.GetReplaceString("\\3"); char* szTemp = reg2.GetReplaceString("\\1"); free(szTitle); szTitle = szTemp; } tag.SetLoaded(true); tag.SetURL(strFileToLoad); tag.SetTrackNumber(iTrack); if (szMins && szSecs) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); tag.SetTitle(szTitle); tag.SetArtist(szArtist); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szMins ) free(szMins); if( szSecs ) free(szSecs); } } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"sidlist.csv"); // changeme? std::ifstream f2(temp); if( !f2.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate sidlist.csv"); tag.SetLoaded(false); return( false ); } while( !f2.eof() ) { f2.getline(temp,8191); CStdString strTemp(temp); strTemp.MakeLower(); unsigned int iFind = strTemp.find(strHVSCpath); if (iFind == string::npos) continue; char temp2[1024]; char temp3[1024]; strncpy(temp3,temp+iFind,strlen(strHVSCpath)); temp3[strlen(strHVSCpath)] = '\0'; sprintf(temp2,"\"%s\",\"[^\"]*\",\"[^\"]*\",\"([^\"]*)\",\"([^\"]*)\",\"([0-9]*)[^\"]*\",\"[0-9]*\",\"[0-9]*\",\"",temp3); for (int i=0;i<iTrack-1;++i) strcat(temp2,"[0-9]*:[0-9]* "); strcat(temp2,"([0-9]*):([0-9]*)"); if( !reg.RegComp(temp2) ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } if( reg.RegFind(temp) >= 0 ) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szYear = reg.GetReplaceString("\\3"); char* szMins = reg.GetReplaceString("\\4"); char* szSecs = reg.GetReplaceString("\\5"); tag.SetLoaded(true); tag.SetTrackNumber(iTrack); if (tag.GetDuration() == 0) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); if (tag.GetTitle() == "") tag.SetTitle(szTitle); if (tag.GetArtist() == "") tag.SetArtist(szArtist); SYSTEMTIME dateTime; dateTime.wYear = atoi(szYear); tag.SetReleaseDate(dateTime); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szYear ) free(szYear); if( szMins ) free(szMins); if( szSecs ) free(szSecs); f2.close(); return( true ); } } f2.close(); tag.SetLoaded(false); return( false ); }
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl http; CURI url(strPath); CStdString strName, strLink; CStdString strBasePath = url.GetFileName(); if(!http.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__); return false; } CRegExp reItem; reItem.RegComp("<a href=\"(.*)\">(.*)</a>"); /* read response from server into string buffer */ char buffer[MAX_PATH + 1024]; while(http.ReadString(buffer, sizeof(buffer)-1)) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); if (reItem.RegFind(strBuffer.c_str()) >= 0) { strLink = reItem.GetReplaceString("\\1"); strName = reItem.GetReplaceString("\\2"); if(strLink[0] == '/') strLink = strLink.Mid(1); CStdString strNameTemp = strName.Trim(); CStdString strLinkTemp = strLink; CUtil::RemoveSlashAtEnd(strLinkTemp); CUtil::RemoveSlashAtEnd(strNameTemp); CUtil::UrlDecode(strLinkTemp); if (strNameTemp == strLinkTemp) { g_charsetConverter.unknownToUTF8(strName); CUtil::RemoveSlashAtEnd(strName); CFileItemPtr pItem(new CFileItem(strName)); pItem->m_strPath = strBasePath + strLink; pItem->SetProperty("IsHTTPDirectory", true); if(CUtil::HasSlashAtEnd(pItem->m_strPath)) pItem->m_bIsFolder = true; url.SetFileName(pItem->m_strPath); pItem->m_strPath = url.Get(); if (!pItem->m_bIsFolder && g_advancedSettings.m_bHTTPDirectoryStatFilesize) { CFileCurl file; file.Open(url); pItem->m_dwSize= file.GetLength(); file.Close(); } if (!pItem->m_bIsFolder && pItem->m_dwSize == 0) { CRegExp reSize; reSize.RegComp(">([0-9.]+)(K|M|G)</td>"); if (reSize.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSize.GetReplaceString("\\1")); CStdString strUnit = reSize.GetReplaceString("\\2"); if (strUnit == "M") Size = Size * 1024; else if (strUnit == "G") Size = Size * 1000 * 1024; pItem->m_dwSize = (int64_t)(Size * 1024); } } items.Add(pItem); } } } http.Close(); return true; }
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CCurlFile http; CURL url(strPath); CStdString strName, strLink; CStdString strBasePath = url.GetFileName(); if(!http.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__); return false; } CRegExp reItem(true); // HTML is case-insensitive reItem.RegComp("<a href=\"(.*)\">(.*)</a>"); CRegExp reDateTime(true); reDateTime.RegComp("<td align=\"right\">([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) +</td>"); CRegExp reDateTimeNginx(true); reDateTimeNginx.RegComp("</a> +([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) "); CRegExp reSize(true); reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>"); CRegExp reSizeNginx; reSizeNginx.RegComp("([0-9]+)$"); /* read response from server into string buffer */ char buffer[MAX_PATH + 1024]; while(http.ReadString(buffer, sizeof(buffer)-1)) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); if (reItem.RegFind(strBuffer.c_str()) >= 0) { strLink = reItem.GetReplaceString("\\1"); strName = reItem.GetReplaceString("\\2"); if(strLink[0] == '/') strLink = strLink.Mid(1); CStdString strNameTemp = strName.Trim(); CStdString strLinkTemp = strLink; URIUtils::RemoveSlashAtEnd(strLinkTemp); URIUtils::RemoveSlashAtEnd(strNameTemp); CURL::Decode(strLinkTemp); if (strNameTemp == strLinkTemp && strLinkTemp != "..") { CStdStringW wName, wLink, wConverted; g_charsetConverter.unknownToUTF8(strName); g_charsetConverter.utf8ToW(strName, wName, false); HTML::CHTMLUtil::ConvertHTMLToW(wName, wConverted); g_charsetConverter.wToUTF8(wConverted, strName); URIUtils::RemoveSlashAtEnd(strName); g_charsetConverter.unknownToUTF8(strLink); g_charsetConverter.utf8ToW(strLink, wLink, false); HTML::CHTMLUtil::ConvertHTMLToW(wLink, wConverted); g_charsetConverter.wToUTF8(wConverted, strLink); CFileItemPtr pItem(new CFileItem(strName)); pItem->SetProperty("IsHTTPDirectory", true); url.SetFileName(strBasePath + strLink); pItem->SetPath(url.Get()); if(URIUtils::HasSlashAtEnd(pItem->GetPath())) pItem->m_bIsFolder = true; CStdString day, month, year, hour, minute; if (reDateTime.RegFind(strBuffer.c_str()) >= 0) { day = reDateTime.GetReplaceString("\\1"); month = reDateTime.GetReplaceString("\\2"); year = reDateTime.GetReplaceString("\\3"); hour = reDateTime.GetReplaceString("\\4"); minute = reDateTime.GetReplaceString("\\5"); } else if (reDateTimeNginx.RegFind(strBuffer.c_str()) >= 0) { day = reDateTimeNginx.GetReplaceString("\\1"); month = reDateTimeNginx.GetReplaceString("\\2"); year = reDateTimeNginx.GetReplaceString("\\3"); hour = reDateTimeNginx.GetReplaceString("\\4"); minute = reDateTimeNginx.GetReplaceString("\\5"); } if (day.length() > 0 && month.length() > 0 && year.length() > 0) { pItem->m_dateTime = CDateTime(atoi(year.c_str()), CDateTime::MonthStringToMonthNum(month), atoi(day.c_str()), atoi(hour.c_str()), atoi(minute.c_str()), 0); } if (!pItem->m_bIsFolder) { if (reSize.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSize.GetReplaceString("\\1")); CStdString strUnit = reSize.GetReplaceString("\\2"); if (strUnit == "K") Size = Size * 1024; else if (strUnit == "M") Size = Size * 1024 * 1024; else if (strUnit == "G") Size = Size * 1000 * 1024 * 1024; pItem->m_dwSize = (int64_t)Size; } else if (reSizeNginx.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSizeNginx.GetReplaceString("\\1")); pItem->m_dwSize = (int64_t)Size; } else if (g_advancedSettings.m_bHTTPDirectoryStatFilesize) // As a fallback get the size by stat-ing the file (slow) { CCurlFile file; file.Open(url); pItem->m_dwSize=file.GetLength(); file.Close(); } } items.Add(pItem); } } } http.Close(); items.SetProperty("IsHTTPDirectory", true); return true; }