Fixed a bug in the Latin-1 handling code in ReadLine

Replaced exception code with better error-handling code
If a lookup fails, we now fill CD info with basic (and barely useful) data :D


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14877 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2005-11-12 23:20:15 +00:00
parent 8b5934c975
commit bcf95670a2
2 changed files with 117 additions and 91 deletions
+113 -64
View File
@@ -407,32 +407,6 @@ CDDBData::TrackTimeAt(const int16 &index)
return (cdaudio_time *)fTimeList.ItemAt(index); return (cdaudio_time *)fTimeList.ItemAt(index);
} }
template <class InitCheckable>
void
InitCheck(InitCheckable *item)
{
if (!item)
throw B_ERROR;
status_t error = item->InitCheck();
if (error != B_OK)
throw error;
}
inline void
ThrowOnError(status_t error)
{
if (error != B_OK)
throw error;
}
inline void
ThrowIfNotSize(ssize_t size)
{
if (size < 0)
throw (status_t)size;
}
CDDBQuery::CDDBQuery(const char *server, int32 port) CDDBQuery::CDDBQuery(const char *server, int32 port)
: fServerName(server), : fServerName(server),
fPort(port), fPort(port),
@@ -522,22 +496,29 @@ CDDBQuery::GetToken(const char *stream, BString &result)
} }
void status_t
CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *latitude, CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *latitude,
const char *longitude, const char *description, void *state), void *passThru) const char *longitude, const char *description, void *state), void *passThru)
{ {
Connector connection(this); if(!IsConnected())
Connect();
BString tmp; BString tmp;
tmp = "sites\n"; tmp = "sites\n";
STRACE((">%s", tmp.String())); STRACE((">%s", tmp.String()));
ThrowIfNotSize( fSocket.Send(tmp.String(), tmp.Length()) ); if(fSocket.Send(tmp.String(), tmp.Length())==-1)
return B_ERROR;
ReadLine(tmp); ReadLine(tmp);
if (tmp.FindFirst("210") == -1) if(tmp.FindFirst("210") == -1)
throw (status_t)B_ERROR; {
Disconnect();
return B_ERROR;
}
for (;;) for (;;)
{ {
BString site; BString site;
@@ -563,6 +544,8 @@ CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *lat
description.String(), passThru)) description.String(), passThru))
break; break;
} }
Disconnect();
return B_OK;
} }
bool bool
@@ -689,14 +672,19 @@ CDDBQuery::ReadFromServer(BString &data)
int32 discLength = (fCDData.DiscTime()->minutes * 60) + fCDData.DiscTime()->seconds; int32 discLength = (fCDData.DiscTime()->minutes * 60) + fCDData.DiscTime()->seconds;
query << "cddb query " << idString << ' ' << trackCount << ' ' query << "cddb query " << idString << ' ' << trackCount << ' '
<< offsetString << ' ' << discLength << '\n'; << offsetString << ' ' << discLength << '\n';
STRACE((">%s", query.String())); STRACE((">%s", query.String()));
ThrowIfNotSize( fSocket.Send(query.String(), query.Length()) ); if(fSocket.Send(query.String(), query.Length())==-1)
{
Disconnect();
return B_ERROR;
}
BString tmp; BString tmp;
ReadLine(tmp); ReadLine(tmp);
STRACE(("<%s", tmp.String()));
BString category; BString category;
BString queryDiscID(idString); BString queryDiscID(idString);
@@ -739,18 +727,21 @@ CDDBQuery::ReadFromServer(BString &data)
{ {
GetToken(tmp.String() + 3, category); GetToken(tmp.String() + 3, category);
} }
STRACE(("CDDBQuery::ReadFromServer: Genre: %s\n",category.String())); STRACE(("CDDBQuery::ReadFromServer: Genre: %s\n",category.String()));
if(!category.Length()) if(!category.Length())
{ {
STRACE(("Set genre to 'misc'\n")); STRACE(("Set genre to 'misc'\n"));
category = "misc"; category = "misc";
} }
// Query for the disc's data - artist, album, tracks, etc. // Query for the disc's data - artist, album, tracks, etc.
query = ""; query = "";
query << "cddb read " << category << ' ' << queryDiscID << '\n' ; query << "cddb read " << category << ' ' << queryDiscID << '\n' ;
ThrowIfNotSize( fSocket.Send(query.String(), query.Length()) ); if(fSocket.Send(query.String(), query.Length())==-1)
{
Disconnect();
return B_ERROR;
}
while(true) while(true)
{ {
@@ -765,18 +756,29 @@ CDDBQuery::ReadFromServer(BString &data)
return B_OK; return B_OK;
} }
void status_t
CDDBQuery::Connect() CDDBQuery::Connect()
{ {
BNetAddress address(fServerName.String(), fPort); if(fConnected)
InitCheck(&address); Disconnect();
ThrowOnError( fSocket.Connect(address) ); BNetAddress address;
status_t status = address.SetTo(fServerName.String(), fPort);
if(status != B_OK)
return status;
status = fSocket.Connect(address);
if(status != B_OK)
return status;
fConnected = true; fConnected = true;
BString tmp; BString tmp;
ReadLine(tmp); ReadLine(tmp);
IdentifySelf(); IdentifySelf();
return B_OK;
} }
bool bool
@@ -788,8 +790,11 @@ CDDBQuery::IsConnected() const
void void
CDDBQuery::Disconnect() CDDBQuery::Disconnect()
{ {
fSocket.Close(); if(fConnected)
fConnected = false; {
fSocket.Close();
fConnected = false;
}
} }
void void
@@ -846,6 +851,7 @@ CDDBQuery::ReadLine(BString &buffer)
srcstr[1]='\0'; srcstr[1]='\0';
srclen = 1; srclen = 1;
destlen = 5; destlen = 5;
memset(deststr,0,5);
if(convert_to_utf8(B_ISO1_CONVERSION,srcstr,&srclen,deststr,&destlen,&state)==B_OK) if(convert_to_utf8(B_ISO1_CONVERSION,srcstr,&srclen,deststr,&destlen,&state)==B_OK)
{ {
@@ -856,7 +862,11 @@ CDDBQuery::ReadLine(BString &buffer)
stringindex = string + length; stringindex = string + length;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{
stringindex[i] = deststr[i]; stringindex[i] = deststr[i];
if(!deststr[i])
break;
}
buffer.UnlockBuffer(); buffer.UnlockBuffer();
} }
@@ -877,7 +887,7 @@ CDDBQuery::ReadLine(BString &buffer)
STRACE(("<%s", buffer.String())); STRACE(("<%s", buffer.String()));
} }
void status_t
CDDBQuery::IdentifySelf() CDDBQuery::IdentifySelf()
{ {
// TODO: Figure out a better way to do this for Zeta // TODO: Figure out a better way to do this for Zeta
@@ -886,7 +896,11 @@ CDDBQuery::IdentifySelf()
tmp << "cddb hello simplyvorbis svhost SimplyVorbis v0.1\n"; tmp << "cddb hello simplyvorbis svhost SimplyVorbis v0.1\n";
STRACE((">%s", tmp.String())); STRACE((">%s", tmp.String()));
ThrowIfNotSize( fSocket.Send(tmp.String(), tmp.Length()) ); if(fSocket.Send(tmp.String(), tmp.Length())==-1)
{
Disconnect();
return B_ERROR;
}
ReadLine(tmp); ReadLine(tmp);
#else #else
@@ -902,11 +916,15 @@ CDDBQuery::IdentifySelf()
tmp << "cddb hello " << username << " " << hostname << " SimplyVorbis v0.1\n"; tmp << "cddb hello " << username << " " << hostname << " SimplyVorbis v0.1\n";
STRACE((">%s", tmp.String())); STRACE((">%s", tmp.String()));
ThrowIfNotSize( fSocket.Send(tmp.String(), tmp.Length()) ); if(fSocket.Send(tmp.String(), tmp.Length())==-1)
{
Disconnect();
return B_ERROR;
}
ReadLine(tmp); ReadLine(tmp);
#endif #endif
return B_OK;
} }
status_t status_t
@@ -966,30 +984,33 @@ int32
CDDBQuery::QueryThread(void *owner) CDDBQuery::QueryThread(void *owner)
{ {
CDDBQuery *query = (CDDBQuery *)owner; CDDBQuery *query = (CDDBQuery *)owner;
try
signal(kTerminatingSignal, DoNothing);
if(query->OpenContentFile(query->fCDData.DiscID())!=B_OK)
{ {
signal(kTerminatingSignal, DoNothing); // new content file, read it in from the server
if(query->Connect()==B_OK)
if(query->OpenContentFile(query->fCDData.DiscID())!=B_OK)
{ {
// new content file, read it in from the server
Connector connection(query);
BString data; BString data;
query->ReadFromServer(data); query->ReadFromServer(data);
query->ParseData(data); query->ParseData(data);
query->WriteFile(); query->WriteFile();
} }
else
{
// We apparently couldn't connect to the server, so we'll need to handle
// creating tracknames. Note that we do not save to disk. This is because it should
// be up to the user what to do.
query->SetDefaultInfo();
}
}
query->fState = kDone;
query->fThread = -1;
query->fResult = B_OK;
query->fState = kDone;
query->fThread = -1;
query->fResult = B_OK;
}
catch (status_t error)
{
query->fState = kError;
query->fResult = error;
}
return 0; return 0;
} }
@@ -1012,6 +1033,34 @@ CDDBQuery::WriteFile(void)
fCDData.Save(filename.String()); fCDData.Save(filename.String());
} }
void
CDDBQuery::SetDefaultInfo(void)
{
for(int16 i = fCDData.CountTracks(); i>=0; i--)
fCDData.RemoveTrack(i);
vector<cdaudio_time> trackTimes;
GetTrackTimes(&fSCSIData,trackTimes);
int32 trackCount = GetTrackCount(&fSCSIData);
fCDData.SetArtist("Artist");
fCDData.SetAlbum("Audio CD");
fCDData.SetGenre("Misc");
for(int32 i=0; i<trackCount; i++)
{
BString trackname("Track ");
if(i<9)
trackname << "0";
trackname << i+1;
cdaudio_time time = trackTimes[i+1] - trackTimes[i];
fCDData.AddTrack(trackname.String(),time);
}
}
void void
CDDBQuery::ParseData(const BString &data) CDDBQuery::ParseData(const BString &data)
{ {
@@ -1031,7 +1080,7 @@ CDDBQuery::ParseData(const BString &data)
// the file ourselves. This is actually pretty easy. // the file ourselves. This is actually pretty easy.
fCDData.SetArtist("Artist"); fCDData.SetArtist("Artist");
fCDData.SetAlbum("Audio CD"); fCDData.SetAlbum("Audio CD");
fCDData.SetGenre("misc"); fCDData.SetGenre("Misc");
for(int32 i=0; i<trackCount; i++) for(int32 i=0; i<trackCount; i++)
{ {
+4 -27
View File
@@ -76,7 +76,7 @@ public:
CDDBQuery(const char *server, int32 port = 888); CDDBQuery(const char *server, int32 port = 888);
~CDDBQuery(void); ~CDDBQuery(void);
void SetToSite(const char *server, int32 port); void SetToSite(const char *server, int32 port);
void GetSites(bool (*)(const char *site, int port, status_t GetSites(bool (*)(const char *site, int port,
const char *latitude, const char *longitude, const char *latitude, const char *longitude,
const char *description, void *state), void *); const char *description, void *state), void *);
@@ -99,35 +99,12 @@ public:
static BString OffsetsToString(const scsi_toc *); static BString OffsetsToString(const scsi_toc *);
private: private:
void Connect(); status_t Connect();
void Disconnect(); void Disconnect();
bool IsConnected() const; bool IsConnected() const;
static int32 QueryThread(void *); static int32 QueryThread(void *);
class Connector
{
public:
Connector(CDDBQuery *client)
: client(client),
wasConnected(client->IsConnected())
{
if (!wasConnected)
client->Connect();
}
~Connector()
{
if (!wasConnected)
client->Disconnect();
}
private:
CDDBQuery *client;
bool wasConnected;
};
friend class Connector;
// cached retrieved data // cached retrieved data
enum State enum State
{ {
@@ -137,7 +114,7 @@ private:
kInterrupting, kInterrupting,
kError kError
}; };
void SetDefaultInfo(void);
status_t OpenContentFile(const int32 &discID); status_t OpenContentFile(const int32 &discID);
status_t ReadFromServer(BString &data); status_t ReadFromServer(BString &data);
@@ -145,7 +122,7 @@ private:
void WriteFile(void); void WriteFile(void);
void ReadLine(BString &); void ReadLine(BString &);
void IdentifySelf(); status_t IdentifySelf();
const char * GetToken(const char *, BString &); const char * GetToken(const char *, BString &);