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

📄 mfccddb.cpp

📁 MfcCDDB v1.11 A freeware MFC class to support access to CDDB servers Welcome to MfcCDDB, a collectio
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
Module : MfcCDDB.CPP
Purpose: Defines the implementation for an MFC class to wrap access to CDDB
Created: PJN / 24-02-1999
History: PJN / 19-05-1999 1. Added support for MOTD (Message of the Day)
                          2. Added support for submit
                          3. Fixed a number of places where calling the TRACE
                          function was causing an access violation
                          4. Fixed a bug in GetErrorMessage which was causing
                          SDK errors to return the string "The operation completed successfully"
         PJN / 14-07-1999 1. Fixed two potential access violations in the CCDDB::ReadResponse function.

Copyright (c) 1999 by PJ Naughter.  
All rights reserved.

*/



/////////////////////////////////  Includes  //////////////////////////////////

#include "stdafx.h"
#include <afxpriv.h>
#include <mmsystem.h>
#include "MfcCDDB.h"




//////////////////////////////// Statics / Macros /////////////////////////////

const DWORD READ_RESPONSE_QUERY = 1;
const DWORD READ_RESPONSE_SUBMIT = 2;

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif




////////////////////////////////// Implementation /////////////////////////////

CCDDBSite::CCDDBSite(BOOL bRetrieve)
{
  m_nPort = 80;
  m_bNorthing = TRUE;
  m_nLatitudeMinutes = 0;
  m_bEasting = TRUE;
  m_nLongitudeMinutes = 0;
  if (bRetrieve)
    m_sAddress = _T("/~cddb/cddb.cgi");
  else
    m_sAddress = _T("/~cddb/submit.cgi");
}

CCDDBSite::CCDDBSite(const CCDDBSite& site)
{
  *this = site;
}

CCDDBSite& CCDDBSite::operator=(const CCDDBSite& site)
{
  m_sSite = site.m_sSite;
  m_nPort = site.m_nPort;
  m_sAddress = site.m_sAddress;
  m_bNorthing = site.m_bNorthing;
  m_nLatitudeMinutes = site.m_nLatitudeMinutes;
  m_bEasting = site.m_bEasting;
  m_nLongitudeMinutes = site.m_nLongitudeMinutes;
  m_sDescription = site.m_sDescription;
  return *this;
}

BOOL CCDDBSite::Parse(LPSTR pszLine)
{
  LPSTR pszField = pszLine;

  //Get the site name
  LPSTR pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  m_sSite = pszField;
  
  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the protocol
  pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  CString sProtocol = pszField;
    
  //If the protocol is not http, then ignore it
  if (sProtocol.CompareNoCase(_T("http")) != 0)
    return FALSE;

  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the port number
  pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  m_nPort = ::atoi(pszField);

  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the address
  pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  m_sAddress = pszField;
  
  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the latitude  
  pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  
  //Latitude field must be 7 characters long
  if (strlen(pszField) != 7)
    return FALSE;

  //Parse out the northing field
  if (pszField[0] == 'N')
    m_bNorthing = TRUE;
  else if (pszField[0] == 'S')
    m_bNorthing = FALSE;
  else
    return FALSE;

  //Parse out the Latitude degrees
  char sNum[4];
  sNum[0] = pszField[1];
  sNum[1] = pszField[2];
  sNum[2] = pszField[3];
  sNum[3] = '\0';
  int nLatDeg = ::atoi(sNum);

  //Parse out the Latitude minutes
  sNum[0] = pszField[5];
  sNum[1] = pszField[6];
  sNum[2] = '\0';
  int nLatMin = ::atoi(sNum);
  m_nLatitudeMinutes = nLatMin + 60*nLatDeg;
  
  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the longitude  
  pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  
  //Longitude field must be 7 characters long
  if (strlen(pszField) != 7)
    return FALSE;

  //Parse out the easting field
  if (pszField[0] == 'E')
    m_bEasting = TRUE;
  else if (pszField[0] == 'W')
    m_bEasting = FALSE;
  else
    return FALSE;

  //Parse out the Longitude degrees
  sNum[0] = pszField[1];
  sNum[1] = pszField[2];
  sNum[2] = pszField[3];
  sNum[3] = '\0';
  int nLongDeg = ::atoi(sNum);

  //Parse out the Longitude minutes
  sNum[0] = pszField[5];
  sNum[1] = pszField[6];
  sNum[2] = '\0';
  int nLongMin = ::atoi(sNum);
  m_nLongitudeMinutes = nLongMin + 60*nLongDeg;

  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Whats left is put into the description field
  m_sDescription = pszField;

  //Everything has been parsed correctly
  return TRUE;
}





CCDDBQueryResult::CCDDBQueryResult()
{
  m_dwDiscID = 0;
}

CCDDBQueryResult::CCDDBQueryResult(const CCDDBQueryResult& result)
{
  *this = result;
}

CCDDBQueryResult& CCDDBQueryResult::operator=(const CCDDBQueryResult& result)
{
  m_sCategory = result.m_sCategory;
  m_dwDiscID  = result.m_dwDiscID;
  m_sArtist   = result.m_sArtist;
  m_sTitle    = result.m_sTitle;

  return *this;
}

BOOL CCDDBQueryResult::Parse(LPSTR pszLine)
{
  LPSTR pszField = pszLine;

  //Get the category
  LPSTR pszEnd = pszField;
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  m_sCategory = pszField;

  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get over the CDDB DISCID
  while (pszEnd[0] != ' ' && pszEnd[0] != '\0')
    ++pszEnd;
  if (pszEnd[0] == '\0')
    return FALSE;
  pszEnd[0] = '\0';
  sscanf(pszField, "%x", &m_dwDiscID);

  //skip over the whitespace
  pszField = ++pszEnd;
  while (pszField[0] == ' ' && pszField[0] != '\0')
    ++pszField;
  if (pszField[0] == '\0')
    return FALSE;

  //Get the Artist and Title  
  m_sTitle = pszField;

  //Remove any EOL if it is on the end
  int nEOLPos = m_sTitle.Find(_T("\r\n"));
  if (nEOLPos == -1)
    nEOLPos = m_sTitle.Find(_T("\n"));
  if (nEOLPos != -1)
    m_sTitle = m_sTitle.Left(nEOLPos);
  
  //Split into the artist and title
  int nSlashPos = m_sTitle.Find(_T('/'));
  if (nSlashPos != -1)
  {
    m_sArtist = m_sTitle.Left(nSlashPos);
    m_sTitle = m_sTitle.Right(m_sTitle.GetLength() - nSlashPos - 1);

    //Remove any trailing or leading spaces
    m_sArtist.TrimLeft();
    m_sArtist.TrimRight();
    m_sTitle.TrimLeft();
    m_sTitle.TrimRight();
  }

  return TRUE;
}





CCDDBTrackPosition::CCDDBTrackPosition()
{
  m_nMinute = 0;
  m_nSecond = 0;
  m_nFrame  = 0;
}

CCDDBTrackPosition::CCDDBTrackPosition(const CCDDBTrackPosition& position)
{
  *this = position;
}

CCDDBTrackPosition& CCDDBTrackPosition::operator=(const CCDDBTrackPosition& position)
{
  m_nMinute = position.m_nMinute;
  m_nSecond = position.m_nSecond;
  m_nFrame  = position.m_nFrame;

  return *this;
}





CHTTPSocket::CHTTPSocket()
{
  m_hSocket = INVALID_SOCKET; //default to an invalid scoket descriptor
}

CHTTPSocket::~CHTTPSocket()
{
  Close();
}

BOOL CHTTPSocket::Create()
{
  m_hSocket = socket(AF_INET, SOCK_STREAM, 0);
  return (m_hSocket != INVALID_SOCKET);
}

BOOL CHTTPSocket::Connect(LPCTSTR pszHostAddress, int nPort)
{
	//For correct operation of the T2A macro, see MFC Tech Note 59
	USES_CONVERSION;

  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);
  
	LPSTR lpszAscii = T2A((LPTSTR)pszHostAddress);

	//Determine if the address is in dotted notation
	SOCKADDR_IN sockAddr;
	ZeroMemory(&sockAddr, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons((u_short)nPort);
	sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);

	//If the address is not dotted notation, then do a DNS 
	//lookup of it.
	if (sockAddr.sin_addr.s_addr == INADDR_NONE)
	{
		LPHOSTENT lphost;
		lphost = gethostbyname(lpszAscii);
		if (lphost != NULL)
			sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
		else
		{
      WSASetLastError(WSAEINVAL); 
			return FALSE;
		}
	}

	//Call the protected version which takes an address 
	//in the form of a standard C style struct.
	return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}

BOOL CHTTPSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
	return (connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR);
}

BOOL CHTTPSocket::Send(LPCSTR pszBuf, int nBuf)
{
  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);

  return (send(m_hSocket, pszBuf, nBuf, 0) != SOCKET_ERROR);
}

int CHTTPSocket::Receive(LPSTR pszBuf, int nBuf)
{
  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);

  return recv(m_hSocket, pszBuf, nBuf, 0); 
}

void CHTTPSocket::Close()
{
	if (m_hSocket != INVALID_SOCKET)
	{
		VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
		m_hSocket = INVALID_SOCKET;
	}
}

BOOL CHTTPSocket::IsReadible(BOOL& bReadible)
{
  timeval timeout = {0, 0};
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(m_hSocket, &fds);
  int nStatus = select(0, &fds, NULL, NULL, &timeout);
  if (nStatus == SOCKET_ERROR)
  {
    return FALSE;
  }
  else
  {
    bReadible = !(nStatus == 0);
    return TRUE;
  }
}

⌨️ 快捷键说明

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