Пример #1
0
bool CCurlFile::Download(const CStdString& strURL, const CStdString& strFileName, LPDWORD pdwSize)
{
  CLog::Log(LOGINFO, "Download: %s->%s", strURL.c_str(), strFileName.c_str());

  CStdString strData;
  if (!Get(strURL, strData))
    return false;

  XFILE::CFile file;
  if (!file.OpenForWrite(strFileName, true))
  {
    CLog::Log(LOGERROR, "Unable to open file %s: %u",
    strFileName.c_str(), GetLastError());
    return false;
  }
  if (strData.size())
    file.Write(strData.c_str(), strData.size());
  file.Close();

  if (pdwSize != NULL)
  {
    *pdwSize = strData.size();
  }

  return true;
}
Пример #2
0
void CKaraokeLyricsText::saveLyrics()
{
  XFILE::CFile file;

  CStdString out;

  for ( unsigned int i = 0; i < m_lyrics.size(); i++ )
  {
    CStdString timing;
    timing.Format( "%02d:%02d.%d", m_lyrics[i].timing / 600, (m_lyrics[i].timing % 600) / 10, (m_lyrics[i].timing % 10) );

    if ( (m_lyrics[i].flags & LYRICS_NEW_PARAGRAPH) != 0 )
      out += "\n\n";

    if ( (m_lyrics[i].flags & LYRICS_NEW_LINE) != 0 )
      out += "\n";

    out += "[" + timing + "]" + m_lyrics[i].text;
  }

  out += "\n";

  if ( !file.OpenForWrite( "special://temp/tmp.lrc", true ) )
    return;

  file.Write( out, out.size() );
}
bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, 
    unsigned int format, unsigned int pitch, const CStdString& destFile)
{
  if(format != XB_FMT_A8R8G8B8 || !buffer) {
    CLog::Log(LOGDEBUG, "%s::%s : %s failed format=0x%x\n", CLASSNAME, __func__, destFile.c_str(), format);
    return false;
  }

  if(!Encode(buffer, height * pitch, width, height, pitch)) {
    CLog::Log(LOGDEBUG, "%s::%s : %s encode failed\n", CLASSNAME, __func__, destFile.c_str());
    return false;
  }

  XFILE::CFile file;
  if (file.OpenForWrite(destFile, true))
  {
    CLog::Log(LOGDEBUG, "%s::%s : %s width %d height %d\n", CLASSNAME, __func__, destFile.c_str(), width, height);

    file.Write(GetEncodedData(), GetEncodedSize());
    file.Close();
    return true;
  }

  return false;
}
Пример #4
0
void CAirTunesServer::SetCoverArtFromBuffer(const char *buffer, unsigned int size)
{
  XFILE::CFile tmpFile;
  const char *tmpFileName = "special://temp/airtunes_album_thumb.jpg";

  if(!size)
    return;

  if (tmpFile.OpenForWrite(tmpFileName, true))
  {
    int writtenBytes=0;
    writtenBytes = tmpFile.Write(buffer, size);
    tmpFile.Close();

    if(writtenBytes)
    {
      //reset to empty before setting the new one
      //else it won't get refreshed because the name didn't change
      g_infoManager.SetCurrentAlbumThumb("");
      g_infoManager.SetCurrentAlbumThumb(tmpFileName);
      //update the ui
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_REFRESH_THUMBS);
      g_windowManager.SendThreadMessage(msg);
    }
  }
}
Пример #5
0
TEST(TestFile, Write)
{
  XFILE::CFile *file;
  const char str[] = "TestFile.Write test string\n";
  char buf[30];
  memset(&buf, 0, sizeof(buf));

  ASSERT_TRUE((file = XBMC_CREATETEMPFILE("")) != NULL);
  file->Close();
  ASSERT_TRUE(file->OpenForWrite(XBMC_TEMPFILEPATH(file), true));
  EXPECT_EQ((int)sizeof(str), file->Write(str, sizeof(str)));
  file->Flush();
  EXPECT_EQ(0, file->GetPosition());
  file->Close();
  ASSERT_TRUE(file->Open(XBMC_TEMPFILEPATH(file)));
  EXPECT_EQ(0, file->GetPosition());
  EXPECT_EQ((int64_t)sizeof(str), file->Seek(0, SEEK_END));
  EXPECT_EQ(0, file->Seek(0, SEEK_SET));
  EXPECT_EQ((int64_t)sizeof(str), file->GetLength());
  EXPECT_EQ(sizeof(str), file->Read(buf, sizeof(buf)));
  file->Flush();
  EXPECT_EQ((int64_t)sizeof(str), file->GetPosition());
  EXPECT_TRUE(!memcmp(str, buf, sizeof(str)));
  file->Close();
  EXPECT_TRUE(XBMC_DELETETEMPFILE(file));
}
Пример #6
0
bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const std::string &thumbFile)
{
  CLog::Log(LOGDEBUG, "cached image '%s' size %dx%d", CURL::GetRedacted(thumbFile).c_str(), width, height);
  if (URIUtils::HasExtension(thumbFile, ".jpg"))
  {
#if defined(HAS_OMXPLAYER)
    if (COMXImage::CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
      return true;
#endif
  }

  unsigned char *thumb = NULL;
  unsigned int thumbsize=0;
  IImage* pImage = ImageFactory::CreateLoader(thumbFile);
  if(pImage == NULL || !pImage->CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str(), thumb, thumbsize))
  {
    CLog::Log(LOGERROR, "Failed to CreateThumbnailFromSurface for %s", CURL::GetRedacted(thumbFile).c_str());
    delete pImage;
    return false;
  }

  XFILE::CFile file;
  const bool ret = file.OpenForWrite(thumbFile, true) && file.Write(thumb, thumbsize) == thumbsize;
  pImage->ReleaseThumbnailBuffer();
  delete pImage;

  return ret;
}
Пример #7
0
bool CScraperUrl::Get(const SUrlEntry& scrURL, string& strHTML, CHTTP& http)
{
    CURL url(scrURL.m_url);
    http.SetReferer(scrURL.m_spoof);
    CStdString strCachePath;

    if (!scrURL.m_cache.IsEmpty())
    {
        CUtil::AddFileToFolder(g_advancedSettings.m_cachePath,"scrapers\\"+scrURL.m_cache,strCachePath);
        if (XFILE::CFile::Exists(strCachePath))
        {
            XFILE::CFile file;
            file.Open(strCachePath);
            char* temp = new char[(int)file.GetLength()];
            file.Read(temp,file.GetLength());
            strHTML.append(temp,temp+file.GetLength());
            file.Close();
            delete[] temp;
            return true;
        }
    }

    if (scrURL.m_post)
    {
        CStdString strOptions = url.GetOptions();
        strOptions = strOptions.substr(1);
        url.SetOptions("");
        CStdString strUrl;
        url.GetURL(strUrl);

        if (!http.Post(strUrl, strOptions, strHTML))
            return false;
    }
    else if (!http.Get(scrURL.m_url, strHTML))
        return false;

    if (scrURL.m_url.Find(".zip") > -1)
    {
        XFILE::CFileZip file;
        CStdString strBuffer;
        int iSize = file.UnpackFromMemory(strBuffer,strHTML);
        if (iSize)
        {
            strHTML.clear();
            strHTML.append(strBuffer.c_str(),strBuffer.data()+iSize);
        }
    }

    if (!scrURL.m_cache.IsEmpty())
    {
        CStdString strCachePath;
        CUtil::AddFileToFolder(g_advancedSettings.m_cachePath,"scrapers\\"+scrURL.m_cache,strCachePath);
        XFILE::CFile file;
        if (file.OpenForWrite(strCachePath,true,true))
            file.Write(strHTML.data(),strHTML.size());
        file.Close();
    }
    return true;
}
Пример #8
0
bool CXBMCTinyXML::SaveFile(const std::string& filename) const
{
  XFILE::CFile file;
  if (file.OpenForWrite(filename, true))
  {
    TiXmlPrinter printer;
    Accept(&printer);
    return file.Write(printer.CStr(), printer.Size()) == static_cast<ssize_t>(printer.Size());
  }
  return false;
}
Пример #9
0
bool COMXImage::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, 
    unsigned int format, unsigned int pitch, const CStdString& destFile)
{
  if(format != XB_FMT_A8R8G8B8 || !buffer)
    return false;

  // the omx encoder needs alligned sizes
  if(width%16 || height%16)
  {
    unsigned int new_width = (width + 15)&~15;
    unsigned int new_height = (height + 15)&~15;
    unsigned int new_pitch = new_width * 4;

    unsigned int size = new_height * new_pitch;
    unsigned char *dstBuffer = (unsigned char *)malloc(size);
    unsigned char *dst = dstBuffer;
    unsigned char *src = buffer;

    if(!dstBuffer)
      return false;

    memset(dst, 0x0, size);

    for(unsigned int y = 0; y < height; y++)
    {
      memcpy(dst, src, pitch);
      src += pitch;
      dst += new_pitch;
    }
    if(!Encode(dstBuffer, size, new_width, new_height))
    {
      free(dstBuffer);
      return false;
    }
    free(dstBuffer);
  }
  else
  {
    if(!Encode(buffer, height * pitch, width, height))
      return false;
  }

  XFILE::CFile file;
  if (file.OpenForWrite(destFile, true))
  {
    CLog::Log(LOGDEBUG, "%s::%s : %s width %d height %d\n", CLASSNAME, __func__, destFile.c_str(), width, height);

    file.Write(GetEncodedData(), GetEncodedSize());
    file.Close();
    return true;
  }

  return false;
}
Пример #10
0
bool CXBMCTinyXML::SaveFile(const CStdString &filename) const
{
  XFILE::CFile file;
  if (file.OpenForWrite(filename, true))
  {
    TiXmlPrinter printer;
    Accept(&printer);
    file.Write(printer.CStr(), printer.Size());
    return true;
  }
  return false;
}
Пример #11
0
//-------------------------------------------------------------------------------------------------------------------
bool Xcddb::writeCacheFile( const char* pBuffer, uint32_t discid )
{
  if (cCacheDir.size() == 0)
    return false;

  XFILE::CFile file;
  if (file.OpenForWrite(GetCacheFile(discid), true))
  {
    const bool ret = ( (size_t) file.Write((void*)pBuffer, strlen(pBuffer) + 1) == strlen(pBuffer) + 1);
    file.Close();
    return ret;
  }

  return false;
}
Пример #12
0
//-------------------------------------------------------------------------------------------------------------------
bool Xcddb::writeCacheFile( const char* pBuffer, uint32_t discid )
{
  if (cCacheDir.size() == 0)
    return false;

  XFILE::CFile file;
  if (file.OpenForWrite(GetCacheFile(discid), true))
  {
    OutputDebugString ( "Current cd saved to local cddb.\n" );
    file.Write( (void*) pBuffer, strlen( pBuffer ) + 1 );
    file.Close();
    return true;
  }

  return false;
}
Пример #13
0
bool fileOps::writeToFile ( CStdString filePath, char* writeBuffer, int writeLength )
{
  
  XFILE::CFile file;
  if (file.OpenForWrite(filePath)) 
  {
    file.Write((const void*)writeBuffer,writeLength);
    file.Close();
    return true;
  }
  else 
  {
    return false;
  }
  
}
Пример #14
0
bool COpenSubtitlesSearch::Download(const CFileItem *subItem,std::vector<std::string> &items)
{
  ulxr::MethodCall      methodcall(ULXR_PCHAR("DownloadSubtitles"));
  ulxr::Array subtitleIDlist;
  ulxr::RpcString ID = subItem->GetProperty("IDSubtitleFile").asString();
  subtitleIDlist.addItem(ID);
  ulxr::RpcString token = m_strToken;
  methodcall.addParam(token);
  methodcall.addParam(subtitleIDlist);
  
  ulxr::MethodResponse response = ServerChat(methodcall);
  ulxr::Struct cap = response.getResult();
  
  if (response.isOK() && cap.hasMember(ULXR_PCHAR("status")))
  {
    ulxr::RpcString status = cap.getMember(ULXR_PCHAR("status"));
    CLog::Log(LOGDEBUG, "%s - response - %s", __PRETTY_FUNCTION__, status.getString().c_str());
    if (status.getString() == "200 OK")
    {
      if (cap.hasMember(ULXR_PCHAR("data")))
      {
        ulxr::Array subs = cap.getMember(ULXR_PCHAR("data"));
        for (unsigned i = 0; i < subs.size(); ++i)
        {
          ulxr::Struct entry = subs.getItem(i);
          ulxr::RpcString data = entry.getMember(ULXR_PCHAR("data"));
          std::string zipdata = data.getString();
          std::string zipdata64Decoded = Base64::Decode(zipdata);
          std::string zipdata64DecodedInflated;
          CSubtitleUtilities::gzipInflate(zipdata64Decoded,zipdata64DecodedInflated);
          XFILE::CFile file;
          std::string destination = StringUtils::Format("special://temp/%s.%s",
                                                        StringUtils::CreateUUID().c_str(),
                                                        subItem->GetProperty("SubFormat").asString().c_str()
                                                        );
          file.OpenForWrite(destination);
          file.Write(zipdata64DecodedInflated.c_str(), zipdata64DecodedInflated.size());
          items.push_back(destination);
        }
        CLog::Log(LOGDEBUG, "%s - OpenSubitles subfile downloaded", __PRETTY_FUNCTION__);
        return true;
      }
    }
  }
  return false;
}
Пример #15
0
void CAirTunesServer::SetCoverArtFromBuffer(const char *buffer, unsigned int size)
{
  XFILE::CFile tmpFile;

  if(!size)
    return;

  CSingleLock lock(m_metadataLock);
  
  if (tmpFile.OpenForWrite(TMP_COVERART_PATH, true))
  {
    int writtenBytes=0;
    writtenBytes = tmpFile.Write(buffer, size);
    tmpFile.Close();

    if (writtenBytes > 0)
      RefreshCoverArt();
  }
}
Пример #16
0
void CGameClientInGameSaves::Save(GAME_MEMORY memoryType)
{
  uint8_t *gameMemory = nullptr;
  size_t size = 0;

  try
  {
    m_dllStruct->GetMemory(memoryType, &gameMemory, &size);
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "GAME: %s: Exception caught in GetMemory()", m_gameClient->ID().c_str());
  }

  if (size > 0)
  {
    const std::string path = GetPath(memoryType);
    XFILE::CFile file;
    if (file.OpenForWrite(path, true))
    {
      ssize_t written = 0;
      written = file.Write(gameMemory, size);
      file.Close();
      if (written == static_cast<ssize_t>(size))
      {
        CLog::Log(LOGINFO, "GAME: In-game saves (%s) written to %s", CGameClientTranslator::ToString(memoryType), path.c_str());
      }
      else
      {
        CLog::Log(LOGERROR, "GAME: Failed to write in-game saves (%s): %ld/%ld bytes written", CGameClientTranslator::ToString(memoryType), written, size);
      }
    }
    else
    {
      CLog::Log(LOGERROR, "GAME: Unable to open in-game saves (%s) from file %s", CGameClientTranslator::ToString(memoryType), path.c_str());
    }
  }
  else
  {
    CLog::Log(LOGDEBUG, "GAME: No in-game saves (%s) to save", CGameClientTranslator::ToString(memoryType));
  }
}
Пример #17
0
	void SxThumb::thumbLoaded(sp_image *image) {
        if (m_dll-> sp_image_error(image) != SP_ERROR_OK) {
			Logger::printOut("creating image error");
			m_file = "";
			//well its loaded but without image
			m_isLoaded = true;
			return;
		}

		XFILE::CFile file;
		if (file.OpenForWrite(m_file, true)) {
			const void *buffer;
			size_t len;
            buffer = m_dll->sp_image_data(image, &len);
			file.Write((const char*) buffer, len);
			file.Close();
		}

		m_isLoaded = true;
		//Logger::printOut("thumb downloaded");
	}
Пример #18
0
bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const CStdString &thumbFile)
{
  CLog::Log(LOGDEBUG, "cached image '%s' size %dx%d", thumbFile.c_str(), width, height);
  if (URIUtils::GetExtension(thumbFile).Equals(".jpg"))
  {
#if defined(HAS_OMXPLAYER)
    COMXImage *omxImage = new COMXImage();
    if (omxImage && omxImage->CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
    {
      delete omxImage;
      return true;
    }
    delete omxImage;
#endif
  }

  unsigned char *thumb = NULL;
  unsigned int thumbsize=0;
  IImage* pImage = ImageFactory::CreateLoader(thumbFile);
  if(pImage == NULL || !pImage->CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str(), thumb, thumbsize))
  {
    CLog::Log(LOGERROR, "Failed to CreateThumbnailFromSurface for %s", thumbFile.c_str());
    delete pImage;
    return false;
  }

  XFILE::CFile file;
  if (file.OpenForWrite(thumbFile, true))
  {
    file.Write(thumb, thumbsize);
    file.Close();
    pImage->ReleaseThumbnailBuffer();
    delete pImage;
    return true;
  }
  pImage->ReleaseThumbnailBuffer();
  delete pImage;
  return false;
}
Пример #19
0
void CAirTunesServer::SetCoverArtFromBuffer(const char *buffer, unsigned int size)
{
  XFILE::CFile tmpFile;
  std::string tmpFilename = TMP_COVERART_PATH_PNG;

  if(!size)
    return;

  CSingleLock lock(m_metadataLock);
  
  if (IsJPEG(buffer, size))
    tmpFilename = TMP_COVERART_PATH_JPG;

  if (tmpFile.OpenForWrite(tmpFilename, true))
  {
    int writtenBytes=0;
    writtenBytes = tmpFile.Write(buffer, size);
    tmpFile.Close();

    if (writtenBytes > 0)
      RefreshCoverArt(tmpFilename.c_str());
  }
}
Пример #20
0
bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext)
{
  CURL url(scrURL.m_url);
  http.SetReferer(scrURL.m_spoof);
  CStdString strCachePath;

  if (scrURL.m_isgz)
    http.SetContentEncoding("gzip");

  if (!scrURL.m_cache.empty())
  {
    strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/" + cacheContext + "/" + scrURL.m_cache);
    if (XFILE::CFile::Exists(strCachePath))
    {
      XFILE::CFile file;
      XFILE::auto_buffer buffer;
      if (file.LoadFile(strCachePath, buffer))
      {
        strHTML.assign(buffer.get(), buffer.length());
        return true;
      }
    }
  }

  CStdString strHTML1(strHTML);

  if (scrURL.m_post)
  {
    CStdString strOptions = url.GetOptions();
    strOptions = strOptions.substr(1);
    url.SetOptions("");

    if (!http.Post(url.Get(), strOptions, strHTML1))
      return false;
  }
  else
    if (!http.Get(url.Get(), strHTML1))
      return false;

  strHTML = strHTML1;

  std::string mimeType(http.GetMimeType());
  CMime::EFileType ftype = CMime::GetFileTypeFromMime(mimeType);
  if (ftype == CMime::FileTypeUnknown)
    ftype = CMime::GetFileTypeFromContent(strHTML);

  if (ftype == CMime::FileTypeZip || ftype == CMime::FileTypeGZip)
  {
    XFILE::CZipFile file;
    std::string strBuffer;
    int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz); // FIXME: use FileTypeGZip instead of scrURL.m_isgz?
    if (iSize > 0)
    {
      strHTML = strBuffer;
      CLog::Log(LOGDEBUG, "%s: Archive \"%s\" was unpacked in memory", __FUNCTION__, scrURL.m_url.c_str());
    }
    else
      CLog::Log(LOGWARNING, "%s: \"%s\" looks like archive, but cannot be unpacked", __FUNCTION__, scrURL.m_url.c_str());
  }

  std::string reportedCharset(http.GetServerReportedCharset());
  if (ftype == CMime::FileTypeHtml)
  {
    std::string realHtmlCharset, converted;
    if (!CCharsetDetection::ConvertHtmlToUtf8(strHTML, converted, reportedCharset, realHtmlCharset))
      CLog::Log(LOGWARNING, "%s: Can't find precise charset for HTML \"%s\", using \"%s\" as fallback", __FUNCTION__, scrURL.m_url.c_str(), realHtmlCharset.c_str());
    else
      CLog::Log(LOGDEBUG, "%s: Using \"%s\" charset for HTML \"%s\"", __FUNCTION__, realHtmlCharset.c_str(), scrURL.m_url.c_str());

    strHTML = converted;
  }
  else if (ftype == CMime::FileTypeXml)
  {
    CXBMCTinyXML xmlDoc;
    xmlDoc.Parse(strHTML, reportedCharset);
    
    std::string realXmlCharset(xmlDoc.GetUsedCharset());
    if (!realXmlCharset.empty())
    {
      CLog::Log(LOGDEBUG, "%s: Using \"%s\" charset for XML \"%s\"", __FUNCTION__, realXmlCharset.c_str(), scrURL.m_url.c_str());
      std::string converted;
      g_charsetConverter.ToUtf8(realXmlCharset, strHTML, converted);
      strHTML = converted;
    }
  }
  else if (ftype == CMime::FileTypePlainText || StringUtils::CompareNoCase(mimeType.substr(0, 5), "text/") == 0)
  {
    std::string realTextCharset, converted;
    CCharsetDetection::ConvertPlainTextToUtf8(strHTML, converted, reportedCharset, realTextCharset);
    strHTML = converted;
    if (reportedCharset != realTextCharset)
      CLog::Log(LOGWARNING, "%s: Using \"%s\" charset for plain text \"%s\" instead of server reported \"%s\" charset", __FUNCTION__, realTextCharset.c_str(), scrURL.m_url.c_str(), reportedCharset.c_str());
    else
      CLog::Log(LOGDEBUG, "%s: Using \"%s\" charset for plain text \"%s\"", __FUNCTION__, realTextCharset.c_str(), scrURL.m_url.c_str());
  }
  else if (!reportedCharset.empty())
  {
    CLog::Log(LOGDEBUG, "%s: Using \"%s\" charset for \"%s\"", __FUNCTION__, reportedCharset.c_str(), scrURL.m_url.c_str());
    if (reportedCharset != "UTF-8")
    {
      std::string converted;
      g_charsetConverter.ToUtf8(reportedCharset, strHTML, converted);
      strHTML = converted;
    }
  }
  else
    CLog::Log(LOGDEBUG, "%s: Using content of \"%s\" as binary or text with \"UTF-8\" charset", __FUNCTION__, scrURL.m_url.c_str());

  if (!scrURL.m_cache.empty())
  {
    CStdString strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/" + cacheContext + "/" + scrURL.m_cache);
    XFILE::CFile file;
    if (file.OpenForWrite(strCachePath,true))
      file.Write(strHTML.data(),strHTML.size());
    file.Close();
  }
  return true;
}
Пример #21
0
bool CFileCurl::Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML, bool bCloseConnection)
{
  XBMC::HttpCacheHandle cacheHandle = g_application.GetHttpCacheManager().Open();
  XBMC::CHttpCacheHandleGuard guard(cacheHandle);

  m_postdata = strPostData;
  
  std::string strLocalCacheName;

  m_etag.clear();
  m_httpTimeModified = 0;

  if (m_postdata.empty())
  {
    XBMC::HttpCacheReturnCode rc = g_application.GetHttpCacheManager().StartCachingURL(cacheHandle, strURL.c_str(), strLocalCacheName, m_etag, m_httpTimeModified);
    if (rc == XBMC::HTTP_CACHE_ALREADY_IN_PROGRESS)
    {
      if ( g_application.GetHttpCacheManager().WaitForURL(cacheHandle, strURL.c_str(), strLocalCacheName, 5000) == XBMC::HTTP_CACHE_OK )
        rc = XBMC::HTTP_CACHE_ALREADY_EXISTS;
      else
        rc = g_application.GetHttpCacheManager().StartCachingURL(cacheHandle, strURL.c_str(), strLocalCacheName, m_etag, m_httpTimeModified);
    }
    
    if (rc == XBMC::HTTP_CACHE_ALREADY_EXISTS)
    {
      if (ReadFile(strLocalCacheName, strHTML))
        return true;
      strLocalCacheName.clear();
    }
    else if (rc != XBMC::HTTP_CACHE_OK)
    {
      strLocalCacheName.clear();
      cacheHandle = NULL;
      m_etag.clear();
      m_httpTimeModified = 0;
    }
  }
  
  if (Open(strURL))
  {
    if (ReadData(strHTML))
    {
      long nLastCode=200;
      g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &nLastCode);

      if (bCloseConnection)
        Close();
      
      if (nLastCode == 304)
      {
        ReadFile(strLocalCacheName, strHTML);
        strLocalCacheName.clear();
      }
      
      if (!strLocalCacheName.empty() && strHTML.size() && cacheHandle)
      {
        XFILE::CFile file;
        if (file.OpenForWrite(strLocalCacheName, true))
        {
          file.Write(strHTML.data(), strHTML.size());
          file.Close();
          XBMC::HttpCacheHeaders headers;
          const char **ptr = g_application.GetHttpCacheManager().GetUsedReponseHeaders();
          while (ptr && *ptr)
          {
            std::string strHeader = m_state->m_httpheader.GetValue(*ptr).c_str();
            if (!strHeader.empty())
              headers[*ptr] = strHeader;
            ptr++;
          }
          g_application.GetHttpCacheManager().DoneCachingURL(cacheHandle, strURL.c_str(), nLastCode, headers);
        }
      }
      return true;
    }
  }
  Close();
  return false;
}
Пример #22
0
bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext)
{
  CURL url(scrURL.m_url);
  http.SetReferer(scrURL.m_spoof);
  CStdString strCachePath;

  if (scrURL.m_isgz)
    http.SetContentEncoding("gzip");

  if (!scrURL.m_cache.IsEmpty())
  {
    strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/" + cacheContext + "/" + scrURL.m_cache);
    if (XFILE::CFile::Exists(strCachePath))
    {
      XFILE::CFile file;
      XFILE::auto_buffer buffer;
      if (file.LoadFile(strCachePath, buffer))
      {
        strHTML.assign(buffer.get(), buffer.length());
        return true;
      }
    }
  }

  CStdString strHTML1(strHTML);

  if (scrURL.m_post)
  {
    CStdString strOptions = url.GetOptions();
    strOptions = strOptions.substr(1);
    url.SetOptions("");

    if (!http.Post(url.Get(), strOptions, strHTML1))
      return false;
  }
  else
    if (!http.Get(url.Get(), strHTML1))
      return false;

  strHTML = strHTML1;
  std::string fileCharset(http.GetServerReportedCharset());

  if (scrURL.m_url.Find(".zip") > -1 )
  {
    XFILE::CZipFile file;
    CStdString strBuffer;
    int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz);
    if (iSize)
    {
      fileCharset.clear();
      strHTML.clear();
      strHTML.append(strBuffer.c_str(),strBuffer.data()+iSize);
    }
  }

  if (!fileCharset.empty() && fileCharset != "UTF-8")
  {
    std::string converted;
    if (g_charsetConverter.ToUtf8(fileCharset, strHTML, converted) && !converted.empty())
      strHTML = converted;
  }

  if (!scrURL.m_cache.IsEmpty())
  {
    CStdString strCachePath = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/" + cacheContext + "/" + scrURL.m_cache);
    XFILE::CFile file;
    if (file.OpenForWrite(strCachePath,true))
      file.Write(strHTML.data(),strHTML.size());
    file.Close();
  }
  return true;
}
Пример #23
0
CStdString fileOps::GetFileFromBackend ( CStdString filenameToGet, CStdString fromStorageGroup )
{
  XBMC->Log(LOG_DEBUG,"%s - Getting File via Myth Protocol - %s",
	    __FUNCTION__,filenameToGet.c_str());
  
  if (filenameToGet.Left(1).compare("/") != 0) 
  {
    filenameToGet = "/" + filenameToGet;
  }
  
  MythFile theFile;
  
  if (fromStorageGroup.CompareNoCase("channels")==0) 
  {
    CStdString chanFilename = "/channels" + filenameToGet;
    CStdString chanSG = "c";
    theFile=mythConP.ConnectPath((char*)chanFilename.c_str(),(char*)chanSG.c_str());
  }
  else 
  {
    theFile=mythConP.ConnectPath((char*)filenameToGet.c_str(),(char*)fromStorageGroup.c_str());
  }

  if (theFile.IsNull()) 
  {
    return "";
  }
  int theFilesLength = theFile.Duration();
  if (theFilesLength <= 0) 
  {
    return "";
  }
  
  CStdString writeFilePath = baseLocalCachepath + fromStorageGroup + filenameToGet;
  checkDirectory(writeFilePath,true);
  
  XFILE::CFile writeFile;
  if (writeFile.OpenForWrite(writeFilePath))
  {
    //char* theFileBuff = new char[theFilesLength];
    int totalRead = 0;
    while (totalRead < theFilesLength)
    {
      char* theFileTmpBuff = new char[theFilesLength];
      int readData = theFile.Read(theFileTmpBuff,theFilesLength-totalRead);
      if (readData <= 0)
      {
        break;
      }
      writeFile.Write((const void*)theFileTmpBuff,readData);
      /*char *filePntr = theFileBuff;
      if (totalRead > 0) {
        filePntr += (totalRead);
      }
      if (readData > (theFilesLength-totalRead)) {
        readData = (theFilesLength-totalRead);
      }
      memcpy((void*)filePntr,(void*)theFileTmpBuff,readData);
      */
      
      totalRead += readData;
    }
    writeFile.Close();
    if (totalRead < theFilesLength) 
    {
    XBMC->Log(LOG_DEBUG,"%s - Did not Read all data - %s - %d - %d",
	      __FUNCTION__,filenameToGet.c_str(),totalRead,theFilesLength);    
    }
    return writeFilePath;
  }
  else 
  {
    return "";
  }
  
}
Пример #24
0
int CAirPlayServer::CTCPClient::ProcessRequest( std::string& responseHeader,
                                                std::string& responseBody)
{
  std::string method = m_httpParser->getMethod() ? m_httpParser->getMethod() : "";
  std::string uri = m_httpParser->getUri() ? m_httpParser->getUri() : "";
  std::string queryString = m_httpParser->getQueryString() ? m_httpParser->getQueryString() : "";
  std::string body = m_httpParser->getBody() ? m_httpParser->getBody() : "";
  std::string contentType = m_httpParser->getValue("content-type") ? m_httpParser->getValue("content-type") : "";
  m_sessionId = m_httpParser->getValue("x-apple-session-id") ? m_httpParser->getValue("x-apple-session-id") : "";
  std::string authorization = m_httpParser->getValue("authorization") ? m_httpParser->getValue("authorization") : "";
  std::string photoAction = m_httpParser->getValue("x-apple-assetaction") ? m_httpParser->getValue("x-apple-assetaction") : "";
  std::string photoCacheId = m_httpParser->getValue("x-apple-assetkey") ? m_httpParser->getValue("x-apple-assetkey") : "";

  int status = AIRPLAY_STATUS_OK;
  bool needAuth = false;
  
  if (m_sessionId.empty())
    m_sessionId = "00000000-0000-0000-0000-000000000000";

  if (ServerInstance->m_usePassword && !m_bAuthenticated)
  {
    needAuth = true;
  }

  size_t startQs = uri.find('?');
  if (startQs != std::string::npos)
  {
    uri.erase(startQs);
  }

  // This is the socket which will be used for reverse HTTP
  // negotiate reverse HTTP via upgrade
  if (uri == "/reverse")
  {
    status = AIRPLAY_STATUS_SWITCHING_PROTOCOLS;
    responseHeader = "Upgrade: PTTH/1.0\r\nConnection: Upgrade\r\n";
  }

  // The rate command is used to play/pause media.
  // A value argument should be supplied which indicates media should be played or paused.
  // 0.000000 => pause
  // 1.000000 => play
  else if (uri == "/rate")
  {
      const char* found = strstr(queryString.c_str(), "value=");
      int rate = found ? (int)(atof(found + strlen("value=")) + 0.5f) : 0;

      CLog::Log(LOGDEBUG, "AIRPLAY: got request %s with rate %i", uri.c_str(), rate);

      if (needAuth && !checkAuthorization(authorization, method, uri))
      {
        status = AIRPLAY_STATUS_NEED_AUTH;
      }
      else if (rate == 0)
      {
        if (g_application.GetAppPlayer().IsPlaying() && !g_application.GetAppPlayer().IsPaused())
        {
          CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE);
        }
      }
      else
      {
        if (g_application.GetAppPlayer().IsPausedPlayback())
        {
          CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE);
        }
      }
  }
  
  // The volume command is used to change playback volume.
  // A value argument should be supplied which indicates how loud we should get.
  // 0.000000 => silent
  // 1.000000 => loud
  else if (uri == "/volume")
  {
      const char* found = strstr(queryString.c_str(), "volume=");
      float volume = found ? (float)strtod(found + strlen("volume="), NULL) : 0;

      CLog::Log(LOGDEBUG, "AIRPLAY: got request %s with volume %f", uri.c_str(), volume);

      if (needAuth && !checkAuthorization(authorization, method, uri))
      {
        status = AIRPLAY_STATUS_NEED_AUTH;
      }
      else if (volume >= 0 && volume <= 1)
      {
        float oldVolume = g_application.GetVolume();
        volume *= 100;
        if(oldVolume != volume && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_SERVICES_AIRPLAYVOLUMECONTROL))
        {
          backupVolume();
          g_application.SetVolume(volume);          
          CApplicationMessenger::GetInstance().PostMsg(TMSG_VOLUME_SHOW, oldVolume < volume ? ACTION_VOLUME_UP : ACTION_VOLUME_DOWN);
        }
      }
  }


  // Contains a header like format in the request body which should contain a
  // Content-Location and optionally a Start-Position
  else if (uri == "/play")
  {
    std::string location;
    float position = 0.0;
    bool startPlayback = true;
    m_lastEvent = EVENT_NONE;

    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (contentType == "application/x-apple-binary-plist")
    {
      CAirPlayServer::m_isPlaying++;    
      
      if (m_pLibPlist->Load())
      {
        m_pLibPlist->EnableDelayedUnload(false);

        const char* bodyChr = m_httpParser->getBody();

        plist_t dict = NULL;
        m_pLibPlist->plist_from_bin(bodyChr, m_httpParser->getContentLength(), &dict);

        if (m_pLibPlist->plist_dict_get_size(dict))
        {
          plist_t tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Start-Position");
          if (tmpNode)
          {
            double tmpDouble = 0;
            m_pLibPlist->plist_get_real_val(tmpNode, &tmpDouble);
            position = (float)tmpDouble;
          }

          tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Content-Location");
          if (tmpNode)
          {
            location = getStringFromPlist(m_pLibPlist, tmpNode);
            tmpNode = NULL;
          }
          
          tmpNode = m_pLibPlist->plist_dict_get_item(dict, "rate");
          if (tmpNode)
          {
            double rate = 0;
            m_pLibPlist->plist_get_real_val(tmpNode, &rate);
            if (rate == 0.0)
            {
              startPlayback = false;
            }
            tmpNode = NULL;
          }

          // in newer protocol versions the location is given
          // via host and path where host is ip:port and path is /path/file.mov
          if (location.empty())
              tmpNode = m_pLibPlist->plist_dict_get_item(dict, "host");
          if (tmpNode)
          {
            location = "http://";
            location += getStringFromPlist(m_pLibPlist, tmpNode);

            tmpNode = m_pLibPlist->plist_dict_get_item(dict, "path");
            if (tmpNode)
            {
              location += getStringFromPlist(m_pLibPlist, tmpNode);
            }
          }

          if (dict)
          {
            m_pLibPlist->plist_free(dict);
          }
        }
        else
        {
          CLog::Log(LOGERROR, "Error parsing plist");
        }
        m_pLibPlist->Unload();
      }
    }
    else
    {
      CAirPlayServer::m_isPlaying++;        
      // Get URL to play
      std::string contentLocation = "Content-Location: ";
      size_t start = body.find(contentLocation);
      if (start == std::string::npos)
        return AIRPLAY_STATUS_NOT_IMPLEMENTED;
      start += contentLocation.size();
      int end = body.find('\n', start);
      location = body.substr(start, end - start);

      std::string startPosition = "Start-Position: ";
      start = body.find(startPosition);
      if (start != std::string::npos)
      {
        start += startPosition.size();
        int end = body.find('\n', start);
        std::string positionStr = body.substr(start, end - start);
        position = (float)atof(positionStr.c_str());
      }
    }

    if (status != AIRPLAY_STATUS_NEED_AUTH)
    {
      std::string userAgent(CURL::Encode("AppleCoreMedia/1.0.0.8F455 (AppleTV; U; CPU OS 4_3 like Mac OS X; de_de)"));
      location += "|User-Agent=" + userAgent;

      CFileItem fileToPlay(location, false);
      fileToPlay.SetProperty("StartPercent", position*100.0f);
      ServerInstance->AnnounceToClients(EVENT_LOADING);

      CFileItemList *l = new CFileItemList; //don't delete,
      l->Add(std::make_shared<CFileItem>(fileToPlay));
      CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, -1, -1, static_cast<void*>(l));

      // allow starting the player paused in ios8 mode (needed by camera roll app)
      if (!startPlayback)
      {
        CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE);
        g_application.GetAppPlayer().SeekPercentage(position * 100.0f);
      }
    }
  }

  // Used to perform seeking (POST request) and to retrieve current player position (GET request).
  // GET scrub seems to also set rate 1 - strange but true
  else if (uri == "/scrub")
  {
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (method == "GET")
    {
      CLog::Log(LOGDEBUG, "AIRPLAY: got GET request %s", uri.c_str());
      
      if (g_application.GetAppPlayer().GetTotalTime())
      {
        float position = ((float) g_application.GetAppPlayer().GetTime()) / 1000;
        responseBody = StringUtils::Format("duration: %.6f\r\nposition: %.6f\r\n", (float)g_application.GetAppPlayer().GetTotalTime() / 1000, position);
      }
      else 
      {
        status = AIRPLAY_STATUS_METHOD_NOT_ALLOWED;
      }
    }
    else
    {
      const char* found = strstr(queryString.c_str(), "position=");
      
      if (found && g_application.GetAppPlayer().HasPlayer())
      {
        int64_t position = (int64_t) (atof(found + strlen("position=")) * 1000.0);
        g_application.GetAppPlayer().SeekTime(position);
        CLog::Log(LOGDEBUG, "AIRPLAY: got POST request %s with pos %" PRId64, uri.c_str(), position);
      }
    }
  }

  // Sent when media playback should be stopped
  else if (uri == "/stop")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else
    {
      if (IsPlaying()) //only stop player if we started him
      {
        CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
        CAirPlayServer::m_isPlaying--;
      }
      else //if we are not playing and get the stop request - we just wanna stop picture streaming
      {
        CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_SLIDESHOW, -1, static_cast<void*>(new CAction(ACTION_STOP)));
      }
    }
    ClearPhotoAssetCache();
  }

  // RAW JPEG data is contained in the request body
  else if (uri == "/photo")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (m_httpParser->getContentLength() > 0 || photoAction == "displayCached")
    {
      XFILE::CFile tmpFile;
      std::string tmpFileName = "special://temp/airplayasset";
      bool showPhoto = true;
      bool receivePhoto = true;

      
      if (photoAction == "cacheOnly")
        showPhoto = false;
      else if (photoAction == "displayCached")
      {
        receivePhoto = false;
        if (photoCacheId.length())
          CLog::Log(LOGDEBUG, "AIRPLAY: Trying to show from cache asset: %s", photoCacheId.c_str());
      }
      
      if (photoCacheId.length())
        tmpFileName += photoCacheId;
      else
        tmpFileName += "airplay_photo";
             
      if( receivePhoto && m_httpParser->getContentLength() > 3 &&
          m_httpParser->getBody()[1] == 'P' &&
          m_httpParser->getBody()[2] == 'N' &&
          m_httpParser->getBody()[3] == 'G')
      {
        tmpFileName += ".png";
      }
      else
      {
        tmpFileName += ".jpg";
      }

      int writtenBytes=0;
      if (receivePhoto)
      {
        if (tmpFile.OpenForWrite(tmpFileName, true))
        {
          writtenBytes = tmpFile.Write(m_httpParser->getBody(), m_httpParser->getContentLength());
          tmpFile.Close();
        }
        if (photoCacheId.length())
          CLog::Log(LOGDEBUG, "AIRPLAY: Cached asset: %s", photoCacheId.c_str());
      }

      if (showPhoto)
      {
        if ((writtenBytes > 0 && (unsigned int)writtenBytes == m_httpParser->getContentLength()) || !receivePhoto)
        {
          if (!receivePhoto && !XFILE::CFile::Exists(tmpFileName))
          {
            status = AIRPLAY_STATUS_PRECONDITION_FAILED; //image not found in the cache
            if (photoCacheId.length())
              CLog::Log(LOGWARNING, "AIRPLAY: Asset %s not found in our cache.", photoCacheId.c_str());
          }
          else
            CApplicationMessenger::GetInstance().PostMsg(TMSG_PICTURE_SHOW, -1, -1, nullptr, tmpFileName);
        }
        else
        {
          CLog::Log(LOGERROR,"AirPlayServer: Error writing tmpFile.");
        }
      }
    }
  }

  else if (uri == "/playback-info")
  {
    float position = 0.0f;
    float duration = 0.0f;
    float cachePosition = 0.0f;
    bool playing = false;

    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (g_application.GetAppPlayer().HasPlayer())
    {
      if (g_application.GetAppPlayer().GetTotalTime())
      {
        position = ((float) g_application.GetAppPlayer().GetTime()) / 1000;
        duration = ((float) g_application.GetAppPlayer().GetTotalTime()) / 1000;
        playing = !g_application.GetAppPlayer().IsPaused();
        cachePosition = position + (duration * g_application.GetAppPlayer().GetCachePercentage() / 100.0f);
      }

      responseBody = StringUtils::Format(PLAYBACK_INFO, duration, cachePosition, position, (playing ? 1 : 0), duration);
      responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";

      if (g_application.GetAppPlayer().IsCaching())
      {
        CAirPlayServer::ServerInstance->AnnounceToClients(EVENT_LOADING);
      }
    }
    else
    {
      responseBody = StringUtils::Format(PLAYBACK_INFO_NOT_READY);
      responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";     
    }
  }

  else if (uri == "/server-info")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    responseBody = StringUtils::Format(SERVER_INFO, CServiceBroker::GetNetwork().GetFirstConnectedInterface()->GetMacAddress().c_str());
    responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";
  }

  else if (uri == "/slideshow-features")
  {
    // Ignore for now.
  }

  else if (uri == "/authorize")
  {
    // DRM, ignore for now.
  }
  
  else if (uri == "/setProperty")
  {
    status = AIRPLAY_STATUS_NOT_FOUND;
  }

  else if (uri == "/getProperty")
  {
    status = AIRPLAY_STATUS_NOT_FOUND;
  }

  else if (uri == "/fp-setup")
  {
    status = AIRPLAY_STATUS_PRECONDITION_FAILED;
  }  

  else if (uri == "200") //response OK from the event reverse message
  {
    status = AIRPLAY_STATUS_NO_RESPONSE_NEEDED;
  }
  else
  {
    CLog::Log(LOGERROR, "AIRPLAY Server: unhandled request [%s]\n", uri.c_str());
    status = AIRPLAY_STATUS_NOT_IMPLEMENTED;
  }

  if (status == AIRPLAY_STATUS_NEED_AUTH)
  {
    ComposeAuthRequestAnswer(responseHeader, responseBody);
  }

  return status;
}
Пример #25
0
bool CEventClient::OnPacketHELO(CEventPacket *packet)
{
  // TODO: check it last HELO packet was received less than 5 minutes back
  //       if so, do not show notification of connection.
  if (Greeted())
    return false;

  unsigned char *payload = (unsigned char *)packet->Payload();
  int psize = (int)packet->PayloadSize();

  // parse device name
  if (!ParseString(payload, psize, m_deviceName))
    return false;

  CLog::Log(LOGNOTICE, "ES: Incoming connection from %s", m_deviceName.c_str());

  // icon type
  unsigned char ltype;
  if (!ParseByte(payload, psize, ltype))
    return false;
  m_eLogoType = (LogoType)ltype;

  // client's port (if any)
  unsigned short dport;
  if (!ParseUInt16(payload, psize, dport))
    return false;
  m_iRemotePort = (unsigned int)dport;

  // 2 x reserved uint32 (8 bytes)
  unsigned int reserved;
  ParseUInt32(payload, psize, reserved);
  ParseUInt32(payload, psize, reserved);

  // image data if any
  string iconfile = "special://temp/helo";
  if (m_eLogoType != LT_NONE && psize>0)
  {
    switch (m_eLogoType)
    {
    case LT_JPEG:
      iconfile += ".jpg";
      break;

    case LT_GIF:
      iconfile += ".gif";
      break;

    default:
      iconfile += ".png";
      break;
    }
    XFILE::CFile file;
    if (file.OpenForWrite(iconfile, true))
    {
      file.Write((const void *)payload, psize);
      file.Close();
    }
    else
    {
      CLog::Log(LOGERROR, "ES: Could not write icon file");
      m_eLogoType = LT_NONE;
    }
  }

  m_bGreeted = true;
  if (m_eLogoType == LT_NONE)
  {
    CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(33200),
                                          m_deviceName.c_str());
  }
  else
  {
    CGUIDialogKaiToast::QueueNotification(iconfile.c_str(),
                                          g_localizeStrings.Get(33200),
                                          m_deviceName.c_str());
  }
  return true;
}
Пример #26
0
bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext)
{
  CURL url(scrURL.m_url);
  http.SetReferer(scrURL.m_spoof);
  CStdString strCachePath;

  if (scrURL.m_isgz)
    http.SetContentEncoding("gzip");

  if (!scrURL.m_cache.IsEmpty())
  {
    URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/"+cacheContext+"/"+scrURL.m_cache,
                              strCachePath);
    if (XFILE::CFile::Exists(strCachePath))
    {
      XFILE::CFile file;
      if (file.Open(strCachePath))
      {
        char* temp = new char[(int)file.GetLength()];
        file.Read(temp,file.GetLength());
        strHTML.clear();
        strHTML.append(temp,temp+file.GetLength());
        file.Close();
        delete[] temp;
        return true;
      }
    }
  }

  CStdString strHTML1(strHTML);

  if (scrURL.m_post)
  {
    CStdString strOptions = url.GetOptions();
    strOptions = strOptions.substr(1);
    url.SetOptions("");

    if (!http.Post(url.Get(), strOptions, strHTML1))
      return false;
  }
  else
    if (!http.Get(url.Get(), strHTML1))
      return false;

  strHTML = strHTML1;

  if (scrURL.m_url.Find(".zip") > -1 )
  {
    XFILE::CZipFile file;
    CStdString strBuffer;
    int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz);
    if (iSize)
    {
      strHTML.clear();
      strHTML.append(strBuffer.c_str(),strBuffer.data()+iSize);
    }
  }

  if (!scrURL.m_cache.IsEmpty())
  {
    CStdString strCachePath;
    URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,
                              "scrapers/"+cacheContext+"/"+scrURL.m_cache,
                              strCachePath);
    XFILE::CFile file;
    if (file.OpenForWrite(strCachePath,true))
      file.Write(strHTML.data(),strHTML.size());
    file.Close();
  }
  return true;
}
Пример #27
0
int CAirPlayServer::CTCPClient::ProcessRequest( std::string& responseHeader,
                                                std::string& responseBody)
{
  std::string method = m_httpParser->getMethod() ? m_httpParser->getMethod() : "";
  std::string uri = m_httpParser->getUri() ? m_httpParser->getUri() : "";
  std::string queryString = m_httpParser->getQueryString() ? m_httpParser->getQueryString() : "";
  std::string body = m_httpParser->getBody() ? m_httpParser->getBody() : "";
  std::string contentType = m_httpParser->getValue("content-type") ? m_httpParser->getValue("content-type") : "";
  m_sessionId = m_httpParser->getValue("x-apple-session-id") ? m_httpParser->getValue("x-apple-session-id") : "";
  std::string authorization = m_httpParser->getValue("authorization") ? m_httpParser->getValue("authorization") : "";
  int status = AIRPLAY_STATUS_OK;
  bool needAuth = false;
  
  if (m_sessionId.empty())
    m_sessionId = "00000000-0000-0000-0000-000000000000";

  if (ServerInstance->m_usePassword && !m_bAuthenticated)
  {
    needAuth = true;
  }

  size_t startQs = uri.find('?');
  if (startQs != std::string::npos)
  {
    uri.erase(startQs);
  }

  // This is the socket which will be used for reverse HTTP
  // negotiate reverse HTTP via upgrade
  if (uri == "/reverse")
  {
    status = AIRPLAY_STATUS_SWITCHING_PROTOCOLS;
    responseHeader = "Upgrade: PTTH/1.0\r\nConnection: Upgrade\r\n";
  }

  // The rate command is used to play/pause media.
  // A value argument should be supplied which indicates media should be played or paused.
  // 0.000000 => pause
  // 1.000000 => play
  else if (uri == "/rate")
  {
      const char* found = strstr(queryString.c_str(), "value=");
      int rate = found ? (int)(atof(found + strlen("value=")) + 0.5f) : 0;

      CLog::Log(LOGDEBUG, "AIRPLAY: got request %s with rate %i", uri.c_str(), rate);

      if (needAuth && !checkAuthorization(authorization, method, uri))
      {
        status = AIRPLAY_STATUS_NEED_AUTH;
      }
      else if (rate == 0)
      {
        if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
        {
          CApplicationMessenger::Get().MediaPause();
        }
      }
      else
      {
        if (g_application.m_pPlayer->IsPausedPlayback())
        {
          CApplicationMessenger::Get().MediaPause();
        }
      }
  }
  
  // The volume command is used to change playback volume.
  // A value argument should be supplied which indicates how loud we should get.
  // 0.000000 => silent
  // 1.000000 => loud
  else if (uri == "/volume")
  {
      const char* found = strstr(queryString.c_str(), "volume=");
      float volume = found ? (float)strtod(found + strlen("volume="), NULL) : 0;

      CLog::Log(LOGDEBUG, "AIRPLAY: got request %s with volume %f", uri.c_str(), volume);

      if (needAuth && !checkAuthorization(authorization, method, uri))
      {
        status = AIRPLAY_STATUS_NEED_AUTH;
      }
      else if (volume >= 0 && volume <= 1)
      {
        float oldVolume = g_application.GetVolume();
        volume *= 100;
        if(oldVolume != volume && CSettings::Get().GetBool("services.airplayvolumecontrol"))
        {
          backupVolume();
          g_application.SetVolume(volume);          
          CApplicationMessenger::Get().ShowVolumeBar(oldVolume < volume);
        }
      }
  }


  // Contains a header like format in the request body which should contain a
  // Content-Location and optionally a Start-Position
  else if (uri == "/play")
  {
    std::string location;
    float position = 0.0;
    m_lastEvent = EVENT_NONE;

    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (contentType == "application/x-apple-binary-plist")
    {
      CAirPlayServer::m_isPlaying++;    
      
      if (m_pLibPlist->Load())
      {
        m_pLibPlist->EnableDelayedUnload(false);

        const char* bodyChr = m_httpParser->getBody();

        plist_t dict = NULL;
        m_pLibPlist->plist_from_bin(bodyChr, m_httpParser->getContentLength(), &dict);

        if (m_pLibPlist->plist_dict_get_size(dict))
        {
          plist_t tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Start-Position");
          if (tmpNode)
          {
            double tmpDouble = 0;
            m_pLibPlist->plist_get_real_val(tmpNode, &tmpDouble);
            position = (float)tmpDouble;
          }

          tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Content-Location");
          if (tmpNode)
          {
            char *tmpStr = NULL;
            m_pLibPlist->plist_get_string_val(tmpNode, &tmpStr);
            location=tmpStr;
#ifdef TARGET_WINDOWS
            m_pLibPlist->plist_free_string_val(tmpStr);
#else
            free(tmpStr);
#endif
          }

          if (dict)
          {
            m_pLibPlist->plist_free(dict);
          }
        }
        else
        {
          CLog::Log(LOGERROR, "Error parsing plist");
        }
        m_pLibPlist->Unload();
      }
    }
    else
    {
      CAirPlayServer::m_isPlaying++;        
      // Get URL to play
      std::string contentLocation = "Content-Location: ";
      size_t start = body.find(contentLocation);
      if (start == std::string::npos)
        return AIRPLAY_STATUS_NOT_IMPLEMENTED;
      start += contentLocation.size();
      int end = body.find('\n', start);
      location = body.substr(start, end - start);

      std::string startPosition = "Start-Position: ";
      start = body.find(startPosition);
      if (start != std::string::npos)
      {
        start += startPosition.size();
        int end = body.find('\n', start);
        std::string positionStr = body.substr(start, end - start);
        position = (float)atof(positionStr.c_str());
      }
    }

    if (status != AIRPLAY_STATUS_NEED_AUTH)
    {
      std::string userAgent(CURL::Encode("AppleCoreMedia/1.0.0.8F455 (AppleTV; U; CPU OS 4_3 like Mac OS X; de_de)"));
      location += "|User-Agent=" + userAgent;

      CFileItem fileToPlay(location, false);
      fileToPlay.SetProperty("StartPercent", position*100.0f);
      ServerInstance->AnnounceToClients(EVENT_LOADING);
      // froce to internal dvdplayer cause it is the only
      // one who will work well with airplay
      g_application.m_eForcedNextPlayer = EPC_DVDPLAYER;
      CApplicationMessenger::Get().MediaPlay(fileToPlay);
    }
  }

  // Used to perform seeking (POST request) and to retrieve current player position (GET request).
  // GET scrub seems to also set rate 1 - strange but true
  else if (uri == "/scrub")
  {
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (method == "GET")
    {
      CLog::Log(LOGDEBUG, "AIRPLAY: got GET request %s", uri.c_str());
      
      if (g_application.m_pPlayer->GetTotalTime())
      {
        float position = ((float) g_application.m_pPlayer->GetTime()) / 1000;
        responseBody = StringUtils::Format("duration: %.6f\r\nposition: %.6f\r\n", (float)g_application.m_pPlayer->GetTotalTime() / 1000, position);
      }
      else 
      {
        status = AIRPLAY_STATUS_METHOD_NOT_ALLOWED;
      }
    }
    else
    {
      const char* found = strstr(queryString.c_str(), "position=");
      
      if (found && g_application.m_pPlayer->HasPlayer())
      {
        int64_t position = (int64_t) (atof(found + strlen("position=")) * 1000.0);
        g_application.m_pPlayer->SeekTime(position);
        CLog::Log(LOGDEBUG, "AIRPLAY: got POST request %s with pos %" PRId64, uri.c_str(), position);
      }
    }
  }

  // Sent when media playback should be stopped
  else if (uri == "/stop")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else
    {
      if (IsPlaying()) //only stop player if we started him
      {
        CApplicationMessenger::Get().MediaStop();
        CAirPlayServer::m_isPlaying--;
      }
      else //if we are not playing and get the stop request - we just wanna stop picture streaming
      {
        CApplicationMessenger::Get().SendAction(ACTION_PREVIOUS_MENU);
      }
    }
  }

  // RAW JPEG data is contained in the request body
  else if (uri == "/photo")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (m_httpParser->getContentLength() > 0)
    {
      XFILE::CFile tmpFile;
      std::string tmpFileName = "special://temp/airplay_photo.jpg";

      if( m_httpParser->getContentLength() > 3 &&
          m_httpParser->getBody()[1] == 'P' &&
          m_httpParser->getBody()[2] == 'N' &&
          m_httpParser->getBody()[3] == 'G')
      {
        tmpFileName = "special://temp/airplay_photo.png";
      }

      if (tmpFile.OpenForWrite(tmpFileName, true))
      {
        int writtenBytes=0;
        writtenBytes = tmpFile.Write(m_httpParser->getBody(), m_httpParser->getContentLength());
        tmpFile.Close();

        if (writtenBytes > 0 && (unsigned int)writtenBytes == m_httpParser->getContentLength())
        {
          CApplicationMessenger::Get().PictureShow(tmpFileName);
        }
        else
        {
          CLog::Log(LOGERROR,"AirPlayServer: Error writing tmpFile.");
        }
      }
    }
  }

  else if (uri == "/playback-info")
  {
    float position = 0.0f;
    float duration = 0.0f;
    float cachePosition = 0.0f;
    bool playing = false;

    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (g_application.m_pPlayer->HasPlayer())
    {
      if (g_application.m_pPlayer->GetTotalTime())
      {
        position = ((float) g_application.m_pPlayer->GetTime()) / 1000;
        duration = ((float) g_application.m_pPlayer->GetTotalTime()) / 1000;
        playing = !g_application.m_pPlayer->IsPaused();
        cachePosition = position + (duration * g_application.m_pPlayer->GetCachePercentage() / 100.0f);
      }

      responseBody = StringUtils::Format(PLAYBACK_INFO, duration, cachePosition, position, (playing ? 1 : 0), duration);
      responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";

      if (g_application.m_pPlayer->IsCaching())
      {
        CAirPlayServer::ServerInstance->AnnounceToClients(EVENT_LOADING);
      }
    }
    else
    {
      responseBody = StringUtils::Format(PLAYBACK_INFO_NOT_READY);
      responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";     
    }
  }

  else if (uri == "/server-info")
  {
    CLog::Log(LOGDEBUG, "AIRPLAY: got request %s", uri.c_str());
    responseBody = StringUtils::Format(SERVER_INFO, g_application.getNetwork().GetFirstConnectedInterface()->GetMacAddress().c_str());
    responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";
  }

  else if (uri == "/slideshow-features")
  {
    // Ignore for now.
  }

  else if (uri == "/authorize")
  {
    // DRM, ignore for now.
  }
  
  else if (uri == "/setProperty")
  {
    status = AIRPLAY_STATUS_NOT_FOUND;
  }

  else if (uri == "/getProperty")
  {
    status = AIRPLAY_STATUS_NOT_FOUND;
  }  

  else if (uri == "200") //response OK from the event reverse message
  {
    status = AIRPLAY_STATUS_NO_RESPONSE_NEEDED;
  }
  else
  {
    CLog::Log(LOGERROR, "AIRPLAY Server: unhandled request [%s]\n", uri.c_str());
    status = AIRPLAY_STATUS_NOT_IMPLEMENTED;
  }

  if (status == AIRPLAY_STATUS_NEED_AUTH)
  {
    ComposeAuthRequestAnswer(responseHeader, responseBody);
  }

  return status;
}
Пример #28
0
int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
                                                CStdString& responseBody,
                                                CStdString& reverseHeader,
                                                CStdString& reverseBody,
                                                CStdString& sessionId)
{
  CStdString method = m_httpParser->getMethod();
  CStdString uri = m_httpParser->getUri();
  CStdString queryString = m_httpParser->getQueryString();
  CStdString body = m_httpParser->getBody();
  CStdString contentType = m_httpParser->getValue("content-type");
  sessionId = m_httpParser->getValue("x-apple-session-id");
  CStdString authorization = m_httpParser->getValue("authorization");
  int status = AIRPLAY_STATUS_OK;
  bool needAuth = false;

  if (ServerInstance->m_usePassword && !m_bAuthenticated)
  {
    needAuth = true;
  }

  int startQs = uri.Find('?');
  if (startQs != -1)
  {
    uri = uri.Left(startQs);
  }

  // This is the socket which will be used for reverse HTTP
  // negotiate reverse HTTP via upgrade
  if (uri == "/reverse")
  {
    status = AIRPLAY_STATUS_SWITCHING_PROTOCOLS;
    responseHeader = "Upgrade: PTTH/1.0\r\nConnection: Upgrade\r\n";
  }

  // The rate command is used to play/pause media.
  // A value argument should be supplied which indicates media should be played or paused.
  // 0.000000 => pause
  // 1.000000 => play
  else if (uri == "/rate")
  {
      const char* found = strstr(queryString.c_str(), "value=");
      int rate = found ? (int)(atof(found + strlen("value=")) + 0.5f) : 0;

      if (needAuth && !checkAuthorization(authorization, method, uri))
      {
        status = AIRPLAY_STATUS_NEED_AUTH;
      }
      else if (rate == 0)
      {
        if (g_application.m_pPlayer && g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
        {
          g_application.getApplicationMessenger().MediaPause();
        }
      }
      else
      {
        if (g_application.m_pPlayer && g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->IsPaused())
        {
          g_application.getApplicationMessenger().MediaPause();
        }
      }
  }

  // Contains a header like format in the request body which should contain a
  // Content-Location and optionally a Start-Position
  else if (uri == "/play")
  {
    CStdString location;
    float position = 0.0;

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (contentType == "application/x-apple-binary-plist")
    {

      if (m_pLibPlist->Load())
      {
        m_pLibPlist->EnableDelayedUnload(false);

        const char* bodyChr = m_httpParser->getBody();

        plist_t dict = NULL;
        m_pLibPlist->plist_from_bin(bodyChr, m_httpParser->getContentLength(), &dict);

        if (m_pLibPlist->plist_dict_get_size(dict))
        {
          plist_t tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Start-Position");
          if (tmpNode)
          {
            double tmpDouble = 0;
            m_pLibPlist->plist_get_real_val(tmpNode, &tmpDouble);
            position = tmpDouble;
          }

          tmpNode = m_pLibPlist->plist_dict_get_item(dict, "Content-Location");
          if (tmpNode)
          {
            char *tmpStr = NULL;
            m_pLibPlist->plist_get_string_val(tmpNode, &tmpStr);
            location=tmpStr;
            free(tmpStr);
          }

          if (dict)
          {
            m_pLibPlist->plist_free(dict);
          }
        }
        else
        {
          CLog::Log(LOGERROR, "Error parsing plist");
        }
        m_pLibPlist->Unload();
      }
    }
    else
    {
      // Get URL to play
      int start = body.Find("Content-Location: ");
      if (start == -1)
        return AIRPLAY_STATUS_NOT_IMPLEMENTED;
      start += strlen("Content-Location: ");
      int end = body.Find('\n', start);
      location = body.Mid(start, end - start);

      start = body.Find("Start-Position");
      if (start != -1)
      {
        start += strlen("Start-Position: ");
        int end = body.Find('\n', start);
        CStdString positionStr = body.Mid(start, end - start);
        position = atof(positionStr.c_str());
      }
    }

    if (status != AIRPLAY_STATUS_NEED_AUTH)
    {
      CFileItem fileToPlay(location, false);
      fileToPlay.SetProperty("StartPercent", position*100.0f);
      g_application.getApplicationMessenger().MediaPlay(fileToPlay);
    }
  }

  // Used to perform seeking (POST request) and to retrieve current player position (GET request).
  else if (uri == "/scrub")
  {
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (method == "GET")
    {
      if (g_application.m_pPlayer && g_application.m_pPlayer->GetTotalTime())
      {
        float position = ((float) g_application.m_pPlayer->GetTime()) / 1000;
        responseBody.Format("duration: %d\r\nposition: %f", g_application.m_pPlayer->GetTotalTime(), position);
      }
    }
    else
    {
      const char* found = strstr(queryString.c_str(), "position=");
      if (found && g_application.m_pPlayer)
      {
        __int64 position = (__int64) (atof(found + strlen("position=")) * 1000.0);
        g_application.m_pPlayer->SeekTime(position);
      }
    }
  }

  // Sent when media playback should be stopped
  else if (uri == "/stop")
  {
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else
    {
      g_application.getApplicationMessenger().MediaStop();
    }
  }

  // RAW JPEG data is contained in the request body
  else if (uri == "/photo")
  {
    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (m_httpParser->getContentLength() > 0)
    {
      XFILE::CFile tmpFile;
      if (tmpFile.OpenForWrite("special://temp/airplay_photo.jpg", true))
      {
        int writtenBytes=0;
        writtenBytes = tmpFile.Write(m_httpParser->getBody(), m_httpParser->getContentLength());
        tmpFile.Close();

        if (writtenBytes > 0 && (unsigned int)writtenBytes == m_httpParser->getContentLength())
        {
          g_application.getApplicationMessenger().PictureShow("special://temp/airplay_photo.jpg");
        }
        else
        {
          CLog::Log(LOGERROR,"AirPlayServer: Error writing tmpFile.");
        }
      }
    }
  }

  else if (uri == "/playback-info")
  {
    float position = 0.0f;
    float duration = 0.0f;
    float cacheDuration = 0.0f;
    bool playing = false;

    if (needAuth && !checkAuthorization(authorization, method, uri))
    {
      status = AIRPLAY_STATUS_NEED_AUTH;
    }
    else if (g_application.m_pPlayer)
    {
      if (g_application.m_pPlayer->GetTotalTime())
      {
        position = ((float) g_application.m_pPlayer->GetTime()) / 1000;
        duration = (float) g_application.m_pPlayer->GetTotalTime();
        playing = g_application.m_pPlayer ? !g_application.m_pPlayer->IsPaused() : false;
        cacheDuration = (float) g_application.m_pPlayer->GetTotalTime() * g_application.GetCachePercentage()/100.0f;
      }

      responseBody.Format(PLAYBACK_INFO, duration, cacheDuration, position, (playing ? 1 : 0), duration);
      responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";

      if (g_application.m_pPlayer->IsCaching())
      {
        ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_LOADING);
      }
      else if (playing)
      {
        ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PLAYING);
      }
      else
      {
        ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PAUSED);
      }
    }
  }

  else if (uri == "/server-info")
  {
    responseBody.Format(SERVER_INFO, g_application.getNetwork().GetFirstConnectedInterface()->GetMacAddress());
    responseHeader = "Content-Type: text/x-apple-plist+xml\r\n";
  }

  else if (uri == "/slideshow-features")
  {
    // Ignore for now.
  }

  else if (uri == "/authorize")
  {
    // DRM, ignore for now.
  }

  else if (uri == "200") //response OK from the event reverse message
  {
    status = AIRPLAY_STATUS_NO_RESPONSE_NEEDED;
  }
  else
  {
    CLog::Log(LOGERROR, "AIRPLAY Server: unhandled request [%s]\n", uri.c_str());
    status = AIRPLAY_STATUS_NOT_IMPLEMENTED;
  }

  if (status == AIRPLAY_STATUS_NEED_AUTH)
  {
    ComposeAuthRequestAnswer(responseHeader, responseBody);
  }

  return status;
}
Пример #29
0
bool CEventClient::OnPacketNOTIFICATION(CEventPacket *packet)
{
  unsigned char *payload = (unsigned char *)packet->Payload();
  int psize = (int)packet->PayloadSize();
  string title, message;

  // parse caption
  if (!ParseString(payload, psize, title))
    return false;

  // parse message
  if (!ParseString(payload, psize, message))
    return false;

  // icon type
  unsigned char ltype;
  if (!ParseByte(payload, psize, ltype))
    return false;
  m_eLogoType = (LogoType)ltype;

  // reserved uint32
  unsigned int reserved;
  ParseUInt32(payload, psize, reserved);

  // image data if any
  string iconfile = "special://temp/notification";
  if (m_eLogoType != LT_NONE && psize>0)
  {
    switch (m_eLogoType)
    {
    case LT_JPEG:
      iconfile += ".jpg";
      break;

    case LT_GIF:
      iconfile += ".gif";
      break;

    default:
      iconfile += ".png";
      break;
    }

    XFILE::CFile file;
    if (file.OpenForWrite(iconfile, true))
    {
      file.Write((const void *)payload, psize);
      file.Close();
    }
    else
    {
      CLog::Log(LOGERROR, "ES: Could not write icon file");
      m_eLogoType = LT_NONE;
    }
  }

  if (m_eLogoType == LT_NONE)
  {
    CGUIDialogKaiToast::QueueNotification(title.c_str(),
                                          message.c_str());
  }
  else
  {
    CGUIDialogKaiToast::QueueNotification(iconfile.c_str(),
                                          title.c_str(),
                                          message.c_str());
  }
  return true;
}
Пример #30
0
bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile)
{
  //Encode raw data from buffer, save to destFile
  struct jpeg_compress_struct cinfo;
  struct my_error_mgr jerr;
  JSAMPROW row_pointer[1];
  long unsigned int outBufSize = width * height;
  unsigned char* result;
  unsigned char* src = buffer;
  unsigned char* rgbbuf, *src2, *dst2;

  if(buffer == NULL)
  {
    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface no buffer");
    return false;
  }

  result = (unsigned char*) malloc(outBufSize); //Initial buffer. Grows as-needed.
  if (result == NULL)
  {
    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface error allocating memory for image buffer");
    return false;
  }

  if(format == XB_FMT_RGB8)
  {
    rgbbuf = buffer;
  }
  else if(format == XB_FMT_A8R8G8B8)
  {
    // create a copy for bgra -> rgb.
    rgbbuf = new unsigned char [(width * height * 3)];
    unsigned char* dst = rgbbuf;
    for (unsigned int y = 0; y < height; y++)
    {
      dst2 = dst;
      src2 = src;
      for (unsigned int x = 0; x < width; x++, src2 += 4)
      {
        *dst2++ = src2[2];
        *dst2++ = src2[1];
        *dst2++ = src2[0];
      }
      dst += width * 3;
      src += pitch;
    }
  }
  else
  {
    CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format");
    free(result);
    return false;
  }

  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = jpeg_error_exit;
  jpeg_create_compress(&cinfo);

  if (setjmp(jerr.setjmp_buffer))
  {
    jpeg_destroy_compress(&cinfo);
    free(result);
    if(format != XB_FMT_RGB8)
      delete [] rgbbuf;
    return false;
  }
  else
  {
#if JPEG_LIB_VERSION < 80
    x_jpeg_mem_dest(&cinfo, &result, &outBufSize);
#else
    jpeg_mem_dest(&cinfo, &result, &outBufSize);
#endif
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 90, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    while (cinfo.next_scanline < cinfo.image_height)
    {
      row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3];
      jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
  }
  if(format != XB_FMT_RGB8)
    delete [] rgbbuf;

  XFILE::CFile file;
  if (file.OpenForWrite(destFile, true))
  {
    file.Write(result, outBufSize);
    file.Close();
    free(result);
    return true;
  }
  free(result);
  return false;
}