⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfccddb.cpp

📁 MfcCDDB v1.11 A freeware MFC class to support access to CDDB servers Welcome to MfcCDDB, a collectio
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        bContinue = FALSE;

      //Parse each line
      CString sField;
      CString sValue;

      if (strcmp(pszCurLine, "Database entries by category:") == 0)
      {
        //Skip over the heading line  
        pszCurLine = pszNextLine;

        //Handle the database entries
        BOOL bMoreEntries = (pszCurLine != NULL);
        while (bMoreEntries)
        {
          //Get the next line before we parse the current one
          pszNextLine = GetNextLine(pszCurLine);
          if (pszNextLine == NULL)
            bMoreEntries = FALSE;

          //Parse the category info
          if (pszCurLine[0] = ' ')
          {
            if (SplitSemiColonLine(pszCurLine, sField, sValue))
            {
              status.m_Categories.Add(sField);
              int nValue = _ttoi(sValue);
              status.m_CategoryEntries.Add(nValue);
            }
          }
          else
            bMoreEntries = FALSE;

          pszCurLine = pszNextLine;
        }
      }
      else if (strcmp(pszCurLine, "Pending File transmissions:") == 0)
      {
        //Skip over the heading line  
        pszCurLine = pszNextLine;

        //Handle the database entries
        BOOL bMoreSites = (pszCurLine != NULL);
        while (bMoreSites)
        {
          //Get the next line before we parse the current one
          pszNextLine = GetNextLine(pszCurLine);
          if (pszNextLine == NULL)
            bMoreSites = FALSE;

          //Parse the pending sites info
          if (pszCurLine[0] = ' ')
          {
            if (SplitSemiColonLine(pszCurLine, sField, sValue))
            {
              status.m_PendingSites.Add(sField);
              int nValue = _ttoi(sValue);
              status.m_PendingEntries.Add(nValue);
            }
          }
          else
            bMoreSites = FALSE;

          pszCurLine = pszNextLine;
        }
      }

      //Parse out the other types of field
      if (pszCurLine)
      {
        if (SplitSemiColonLine(pszCurLine, sField, sValue))
        {
          if (sField == _T("current proto"))
            status.m_nCurrentProtocol = _ttoi(sValue);  
          else if (sField == _T("max proto"))
            status.m_nMaxProtocol = _ttoi(sValue);
          else if (sField == _T("gets"))
          {
            if (sValue == _T("yes"))
              status.m_bGetsAllowed = TRUE;
            else if (sValue == _T("no"))
              status.m_bGetsAllowed = FALSE;
            else
            {
              bContinue = FALSE;
              m_dwLastError = 0;
              SetLastError(WSAEPROTONOSUPPORT);
    		      TRACE(_T("CDDB server failed to return a valid gets response to the stat command\n"));
            }
          }
          else if (sField == _T("updates"))
          {
            if (sValue == _T("yes"))
              status.m_bUpdatesAllowed = TRUE;
            else if (sValue == _T("no"))
              status.m_bUpdatesAllowed = FALSE;
            else
            {
              bContinue = FALSE;
              m_dwLastError = 0;
              SetLastError(WSAEPROTONOSUPPORT);
    		      TRACE(_T("CDDB server failed to return a valid updates response to the stat command\n"));
            }
          }
          else if (sField == _T("posting"))
          {
            if (sValue == _T("yes"))
              status.m_bPostingAllowed = TRUE;
            else if (sValue == _T("no"))
              status.m_bPostingAllowed = FALSE;
            else
            {
              bContinue = FALSE;
              m_dwLastError = 0;
              SetLastError(WSAEPROTONOSUPPORT);
    		      TRACE(_T("CDDB server failed to return a valid posting response to the stat command\n"));
            }
          }
          else if (sField == _T("quotes"))
          {
            if (sValue == _T("yes"))
              status.m_bQuotes = TRUE;
            else if (sValue == _T("no"))
              status.m_bQuotes = FALSE;
            else
            {
              bContinue = FALSE;
              m_dwLastError = 0;
              SetLastError(WSAEPROTONOSUPPORT);
    		      TRACE(_T("CDDB server failed to return a valid quotes response to the stat command\n"));
            }
          }
          else if (sField == _T("current users"))
            status.m_nCurrentUsers = _ttoi(sValue);  
          else if (sField == _T("max users"))
            status.m_nMaxUsers = _ttoi(sValue);  
          else if (sField == _T("strip ext"))
          {
            if (sValue == _T("yes"))
              status.m_bStripExtended = TRUE;
            else if (sValue == _T("no"))
              status.m_bStripExtended = FALSE;
            else
            {
              bContinue = FALSE;
              m_dwLastError = 0;
              SetLastError(WSAEPROTONOSUPPORT);
    		      TRACE(_T("CDDB server failed to return a valid strip extended response to the stat command\n"));
            }
          }
          else if (sField == _T("Database entries"))
            status.m_nDatabaseEntries = _ttoi(sValue);  

          //Move to the next line 
          pszCurLine = pszNextLine;
        }
        else
          bContinue = FALSE;
      }
    }

    //Everything went ok ??
    if (bContinue)
    {
      bSuccess = TRUE;
      m_sLastCommandResponse.Empty();
    }
  }

  return bSuccess;
}

BOOL CCDDB::Query(const CCDDBSite& server, DWORD dwDiscID, const CArray<CCDDBTrackPosition, CCDDBTrackPosition&>& tracks, 
                  CArray<CCDDBQueryResult, CCDDBQueryResult&>& results)
{
	//For correct operation of the T2A macro, see MFC Tech Note 59
	USES_CONVERSION;

  BOOL bSuccess = FALSE;

  //Create the socket
  CHTTPSocket socket;
  if (!socket.Create())
  {
    m_dwLastError = 0;
    TRACE(_T("Failed to create client socket for query command, GetLastError:%d, %s\n"), GetLastError(), GetErrorMessage());
    return FALSE;
  }

  //Connect to the host on the specified port
  if (!socket.Connect(server.m_sSite, server.m_nPort))
  {
    m_dwLastError = 0;
    TRACE(_T("Could not connect to the CDDB HTTP server %s, GetLastError:%d, %s\n"), server.m_sSite, GetLastError(), GetErrorMessage());
    return FALSE;
  }
  else
  {
    //Form the specialized HTTP request to retrieve the query data
    CString sDiscID;
    sDiscID.Format(_T("%08x"), dwDiscID);

    int nTracks = tracks.GetSize() - 1; //Number of tracks is 1 less than the size
                                        //of the array as it also contains the lead 
                                        //out position

    CString sTracks;
    sTracks.Format(_T("%d"), nTracks);

    CString sOffsets;
    for (int i=0; i<nTracks; i++)
    {
      //Form the frame number
      CString sFrame;
      sFrame.Format(_T("%d"), tracks[i].m_nMinute*60*75 + tracks[i].m_nSecond*75 + tracks[i].m_nFrame);

      //Accumulate the frame number into the string
      sOffsets += sFrame;

      //Add a space between each offset
      if (i<(nTracks-1))
       sOffsets += _T("+");
    }

    //Compute the playing length in seconds by using the lead out position
    int nCDlength = tracks[nTracks].m_nMinute*60 + tracks[nTracks].m_nSecond - tracks[0].m_nMinute - tracks[0].m_nSecond;
    CString sLength;
    sLength.Format(_T("%d"), nCDlength);

    //Form the full request string
    CString sRequest;
    sRequest.Format(_T("GET %s?cmd=cddb+query+%s+%s+%s+%s&%s HTTP/1.0\r\n\r\n"), server.m_sAddress, sDiscID, sTracks, sOffsets, sLength, GetHelloCommand());

    //Send the request through the socket
    LPCSTR pszRequest = T2A((LPTSTR) (LPCTSTR) sRequest);
    int nCmdLength = strlen(pszRequest);
    if (!socket.Send(pszRequest, nCmdLength))
    {
      m_dwLastError = 0;
      TRACE(_T("An unexpected error occurred while sending the HTTP query request, GetLastError:%d, %s\n"), GetLastError(), GetErrorMessage());
      return FALSE;
    }
    
    //Read the response back through the socket
    LPSTR pszOverFlowBuffer = NULL;
    if (ReadResponse(socket, NULL, 0, "\r\n.\r\n", &pszOverFlowBuffer, 4096, READ_RESPONSE_QUERY))
    {
      ASSERT(pszOverFlowBuffer);

      //Extract the HTTP body from the response;
      LPSTR pszBody = FindHTTPBody(pszOverFlowBuffer);

      //Parse out the query info from the body
      bSuccess = ParseQueryBody(pszBody, sDiscID, results);
    }
    else
    {
      //Reponse could not be retrieved
      m_dwLastError = 0;
      SetLastError(WSAEPROTONOSUPPORT);
    	TRACE(_T("CDDB server did not respond correctly to the query command\n"));
    }

    //Don't forget to delete the allocated buffer
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

    return bSuccess;
  }
}

BOOL CCDDB::ParseQueryBody(LPSTR pszBody, const CString& sDiscID, CArray<CCDDBQueryResult, CCDDBQueryResult&>& results)
{
  //setup return value
  BOOL bSuccess = FALSE;

  //Hive away the last reponse until everything is ok
  m_sLastCommandResponse = pszBody;

  //From the HTTP body get the CDDB response code
  int nResponseCode = GetCDDBReponseCode(pszBody);

  //Remove any entries which are in the query array
  results.RemoveAll();

  //If the response is in the expected range (21x) then parse the query data line by line
  if (nResponseCode >= 210 && nResponseCode <= 219)
  {
    //Get the query data and then iterate through all the lines
    LPSTR pszLine = SkipToNextLine(pszBody);
    while (pszLine)
    {
      //Get the next line before we parse the current line
      LPSTR pszNextLine = GetNextLine(pszLine);

      //If we can parse the current line then add it 
      //to the query array
      CCDDBQueryResult result;
      if (result.Parse(pszLine))
      {
        results.Add(result);
        bSuccess = TRUE;
      }
      
      //Move on to the next line  
      pszLine = pszNextLine;
    }

    //Everything is successful, empty out the last command reponse string
    m_sLastCommandResponse.Empty();
  }
  else if (nResponseCode == 200 && strlen(pszBody) > 5)
  {
    //found an exact match, If we can parse the 
    //current line then add it to the query array
    CCDDBQueryResult result;
    if (result.Parse(pszBody+4))
    {
      results.Add(result);
      bSuccess = TRUE;
    }

    //Everything is successful, empty out the last command reponse string
    m_sLastCommandResponse.Empty();
  }
  else if (nResponseCode == 202)
  {
    //Deliberately do nothing other than a trace
    TRACE(_T("CDDB server does not contain the specifed album with DISCID:%s in its database\n"), sDiscID);
  }
  else
  {
    //An unexpected response was retrieved
    m_dwLastError = 0;
    SetLastError(WSAEPROTONOSUPPORT);
    TRACE(_T("CDDB server failed to return a valid query response code\n"));
  }

  return bSuccess;
}

BOOL CCDDB::Read(const CCDDBSite& server, DWORD dwDiscID, const CString& sCategory, CCDDBRecord& record)
{
	//For correct operation of the T2A macro, see MFC Tech Note 59
	USES_CONVERSION;

  BOOL bSuccess = FALSE;

  //Create the socket
  CHTTPSocket socket;
  if (!socket.Create())
  {
    m_dwLastError = 0;
    TRACE(_T("Failed to create client socket for read command, GetLastError:%d, %s\n"), GetLastError(), GetErrorMessage());
    return FALSE;
  }

  //Connect to the host on the specified port
  if (!socket.Connect(server.m_sSite, server.m_nPort))
  {
    m_dwLastError = 0;
    TRACE(_T("Could not connect to the CDDB HTTP server %s, GetLastError:%d, %s\n"), server.m_sSite, GetLastError(), GetErrorMessage());
    return FALSE;
  }
  else
  {
    //Form the full request string
    CString sDiscID;
    sDiscID.Format(_T("%08x"), dwDiscID);

    CString sRequest;
    sRequest.Format(_T("GET %s?cmd=cddb+read+%s+%s&%s HTTP/1.0\r\n\r\n"), server.m_sAddress, sCategory, sDiscID, GetHelloCommand());

    //Send the request through the socket
    LPCSTR pszRequest = T2A((LPTSTR) (LPCTSTR) sRequest);
    int nCmdLength = strlen(pszRequest);
    if (!socket.Send(pszRequest, nCmdLength))
    {
      m_dwLastError = 0;
      TRACE(_T("An unexpected error occurred while sending the HTTP stat request, GetLastError:%d, %s\n"), GetLastError(), GetErrorMessage());
      return FALSE;
    }

    //Read the response back through the socket
    LPSTR pszOverFlowBuffer = NULL;
    if (ReadResponse(socket, NULL, 0, "\r\n.\r\n", &pszOverFlowBuffer))
    {
      ASSERT(pszOverFlowBuffer);

      //Hive away the last reponse until everything is ok
      m_sLastCommandResponse = pszOverFlowBuffer;

      //Extract the HTTP body from the response;
      LPSTR pszBody = FindHTTPBody(pszOverFlowBuffer);

      //Parse the CDDB record
      bSuccess = ParseRecordBody(pszBody, record);

      if (record.m_dwDiscID != dwDiscID)
      {
        TRACE(_T("Returned DiscID from CDDB read (%x) is different than the computed value (%x), using the computed value\n"), record.m_dwDiscID, dwDiscID);
        record.m_dwDiscID = dwDiscID;      
      }
    }
    else
    {
      //Reponse could not be Retrieved
      m_dwLastError = 0;
      SetLastError(WSAEPROTONOSUPPORT);
    	TRACE(_T("CDDB server did not respond correctly to the stat command\n"));
    }

    //Don't forget to delete the allocated buffer
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

    return bSuccess;
  }
}

void CCDDB::ReplaceSubString(CString& sText, const CString& sFind, const CString& sReplacement)
{
  int nFindLength = sFind.GetLength();
  int nFind = sText.Find(sFind);
  while (nFind != -1)
  {
    CString sTemp = sText.Left(nFind);
    sTemp += sReplacement;
    sTemp += sText.Right(sText.GetLength() - nFind - nFindLength);
    sText = sTemp;

    //Look for any more strings to replace prior to looping around
    nFind = sText.Find(sFind);
  }
}

BOOL CCDDB::ParseKeywordLine(LPCSTR pszLine, CString& sKeyword, CString& sValue)
{
  //Validate out parameters
  ASSERT(pszLine);
  
  //Duplicate the string into a local variable 
  int nLength = strlen(pszLine);
  LPSTR pszData = new char[nLength + 1];
  strcpy(pszData, pszLine);

  //Do the actual parsing
  BOOL bSuccess = FALSE;
  char* pszToken = strstr(pszData, "=");
  if (pszData)
  {
    pszToken[0] = '\0';
    sKeyword = pszData;
    sValue = pszToken+1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -