?? mfccddb.cpp
字號:
/*
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 + -