cddb_lookup: Cleanup.

* Use BNode::WriteAttrString() over WriteAttr().
* Use stderr for error output, print error codes when available.
* Use BObjectList instead of just a BList.
* No functional change intended.
This commit is contained in:
Axel Dörfler
2016-07-05 20:11:57 +02:00
parent 9be1b5a16f
commit 768544f677
3 changed files with 153 additions and 165 deletions
+54 -75
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2008-2015, Haiku, Inc. All Rights Reserved. * Copyright 2008-2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -35,11 +35,13 @@ public:
private: private:
bool _CanLookup(const dev_t device, uint32* cddbId, bool _CanLookup(const dev_t device, uint32* cddbId,
scsi_toc_toc* toc) const; scsi_toc_toc* toc) const;
QueryResponseData* _SelectResult(BList* response) const; const QueryResponseData*
_SelectResult(
const QueryResponseList& responses) const;
status_t _WriteCDData(dev_t device, status_t _WriteCDData(dev_t device,
QueryResponseData* diskData, const QueryResponseData& diskData,
ReadResponseData* readResponse); const ReadResponseData& readResponse);
}; };
@@ -83,57 +85,43 @@ CDDBLookup::Lookup(const dev_t device)
uint32 cddbId; uint32 cddbId;
if (!_CanLookup(device, &cddbId, toc)) { if (!_CanLookup(device, &cddbId, toc)) {
free(toc); free(toc);
printf("Skipping device with id %" B_PRId32 ".\n", device); fprintf(stderr, "Skipping device with id %" B_PRId32 ".\n", device);
return B_BAD_TYPE; return B_BAD_TYPE;
} }
printf("Looking up CD with CDDB Id %08" B_PRIx32 ".\n", cddbId); printf("Looking up CD with CDDB Id %08" B_PRIx32 ".\n", cddbId);
CDDBServer cddb_server("freedb.freedb.org:80"); CDDBServer cddbServer("freedb.freedb.org:80");
status_t result; BObjectList<QueryResponseData> queryResponses(10, true);
status_t result = cddbServer.Query(cddbId, toc, queryResponses);
BList queryResponse; if (result != B_OK) {
if ((result = cddb_server.Query(cddbId, toc, &queryResponse)) != B_OK) { fprintf(stderr, "Error when querying CD: %s\n", strerror(result));
printf("Error when querying CD.\n");
free(toc); free(toc);
return result; return result;
} }
free(toc); free(toc);
QueryResponseData* diskData = _SelectResult(&queryResponse); const QueryResponseData* diskData = _SelectResult(queryResponses);
if (diskData == NULL) { if (diskData == NULL) {
printf("Could not find any CD entries in query response.\n"); fprintf(stderr, "Could not find any CD entries in query response.\n");
return B_BAD_INDEX; return B_BAD_INDEX;
} }
ReadResponseData readResponse; ReadResponseData readResponse;
if ((result = cddb_server.Read(diskData, &readResponse)) != B_OK) { result = cddbServer.Read(*diskData, readResponse);
if (result != B_OK) {
fprintf(stderr, "Could not read detailed CD entry from server: %s\n",
strerror(result));
return result; return result;
} }
if (_WriteCDData(device, diskData, &readResponse) == B_OK) { result = _WriteCDData(device, *diskData, readResponse);
if (result == B_OK)
printf("CD data saved.\n"); printf("CD data saved.\n");
} else { else
printf("Error writting CD data.\n" ); fprintf(stderr, "Error writing CD data: %s\n", strerror(result));
}
// Delete itens in the query response BList;
int32 count = queryResponse.CountItems();
for (int32 i = 0; i < count; ++i) {
delete (QueryResponseData*)queryResponse.RemoveItem((int32)0);
}
queryResponse.MakeEmpty();
// Delete itens in the track data BList in the read response data;
count = readResponse.tracks.CountItems();
for (int32 i = 0; i < count; ++i) {
delete (TrackData*)readResponse.tracks.RemoveItem((int32)0);
}
readResponse.tracks.MakeEmpty();
return B_OK; return B_OK;
} }
@@ -176,29 +164,28 @@ CDDBLookup::_CanLookup(const dev_t device, uint32* cddbId,
} }
QueryResponseData* const QueryResponseData*
CDDBLookup::_SelectResult(BList* response) const CDDBLookup::_SelectResult(const QueryResponseList& responses) const
{ {
// Select a single CD match from the response and return it. // Select a single CD match from the response and return it.
// //
// TODO(bga):Right now it just picks the first entry on the list but // TODO(bga):Right now it just picks the first entry on the list but
// someday we may want to let the user choose one. // someday we may want to let the user choose one.
int32 numItems = response->CountItems(); int32 numItems = responses.CountItems();
if (numItems > 0) { if (numItems > 0) {
if (numItems > 1) { if (numItems > 1)
printf("Multiple matches found :\n"); printf("Multiple matches found :\n");
};
for (int32 i = 0; i < numItems; i++) {
QueryResponseData* data = (QueryResponseData*)response->ItemAt(i);
printf("* %s : %s - %s (%s)\n", (data->cddbId).String(),
(data->artist).String(), (data->title).String(),
(data->category).String());
}
if (numItems > 1) {
printf("Returning first entry.\n");
}
return (QueryResponseData*)response->ItemAt(0L); for (int32 i = 0; i < numItems; i++) {
QueryResponseData* data = responses.ItemAt(i);
printf("* %s : %s - %s (%s)\n", data->cddbId.String(),
data->artist.String(), data->title.String(),
data->category.String());
}
if (numItems > 1)
printf("Returning first entry.\n");
return responses.ItemAt(0);
} }
return NULL; return NULL;
@@ -206,15 +193,17 @@ CDDBLookup::_SelectResult(BList* response) const
status_t status_t
CDDBLookup::_WriteCDData(dev_t device, QueryResponseData* diskData, CDDBLookup::_WriteCDData(dev_t device, const QueryResponseData& diskData,
ReadResponseData* readResponse) const ReadResponseData& readResponse)
{ {
// Rename volume. // Rename volume.
BVolume volume(device); BVolume volume(device);
status_t error = B_OK; status_t error = B_OK;
BString name = diskData->artist << " - " << diskData->title; BString name = diskData.artist;
name += " - ";
name += diskData.title;
name.ReplaceSet("/", " "); name.ReplaceSet("/", " ");
status_t result = volume.SetName(name.String()); status_t result = volume.SetName(name.String());
@@ -230,11 +219,11 @@ CDDBLookup::_WriteCDData(dev_t device, QueryResponseData* diskData,
BEntry entry; BEntry entry;
int index = 0; int index = 0;
while (cddaRoot.GetNextEntry(&entry) == B_OK) { while (cddaRoot.GetNextEntry(&entry) == B_OK) {
TrackData* data = (TrackData*)((readResponse->tracks).ItemAt(index)); TrackData* track = readResponse.tracks.ItemAt(index);
// Update name. // Update name.
int trackNum = index + 1; // index=0 is actually Track 1 int trackNum = index + 1; // index=0 is actually Track 1
name.SetToFormat("%02d %s.wav", trackNum, data->title.String()); name.SetToFormat("%02d %s.wav", trackNum, track->title.String());
name.ReplaceSet("/", " "); name.ReplaceSet("/", " ");
result = entry.Rename(name.String()); result = entry.Rename(name.String());
@@ -248,29 +237,19 @@ CDDBLookup::_WriteCDData(dev_t device, QueryResponseData* diskData,
// Add relevant attributes. We consider an error here as non-fatal. // Add relevant attributes. We consider an error here as non-fatal.
BNode node(&entry); BNode node(&entry);
node.WriteAttr("Media:Title", B_STRING_TYPE, 0, data->title.String(), node.WriteAttrString("Media:Title", &track->title);
data->title.Length()); node.WriteAttrString("Audio:Album", &readResponse.title);
node.WriteAttr("Audio:Album", B_STRING_TYPE, 0, if (readResponse.genre.Length() != 0)
readResponse->title.String(), node.WriteAttrString("Media:Genre", &readResponse.genre);
readResponse->title.Length()); if (readResponse.year != 0) {
if (readResponse->genre.Length() != 0) {
node.WriteAttr("Media:Genre", B_STRING_TYPE, 0,
readResponse->genre.String(),
readResponse->genre.Length());
}
if (readResponse->year != 0) {
node.WriteAttr("Media:Year", B_INT32_TYPE, 0, node.WriteAttr("Media:Year", B_INT32_TYPE, 0,
&readResponse->year, sizeof(int32)); &readResponse.year, sizeof(int32));
} }
if (data->artist == "") { if (track->artist == "")
node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0, node.WriteAttrString("Audio:Artist", &readResponse.artist);
readResponse->artist.String(), else
readResponse->artist.Length()); node.WriteAttrString("Audio:Artist", &track->artist);
} else {
node.WriteAttr("Audio:Artist", B_STRING_TYPE, 0,
data->artist.String(), data->artist.Length());
}
index++; index++;
} }
+67 -70
View File
@@ -1,11 +1,11 @@
/* /*
* Copyright 2008-2015, Haiku, Inc. All Rights Reserved. * Copyright 2008-2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Bruno Albuquerque, [email protected] * Bruno Albuquerque, [email protected]
*/ */
#include "cddb_server.h" #include "cddb_server.h"
@@ -35,60 +35,58 @@ CDDBServer::CDDBServer(const BString& cddbServer)
} else { } else {
fLocalHostName = kDefaultLocalHostName; fLocalHostName = kDefaultLocalHostName;
} }
// Set up local user name. // Set up local user name.
char* user = getenv("USER"); char* user = getenv("USER");
if (user == NULL) { if (user == NULL)
fLocalUserName = "unknown"; fLocalUserName = "unknown";
} else { else
fLocalUserName = user; fLocalUserName = user;
}
// Set up server address; // Set up server address;
if (_ParseAddress(cddbServer) == B_OK) if (_ParseAddress(cddbServer) == B_OK)
fInitialized = true; fInitialized = true;
} }
status_t status_t
CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc, BList* queryResponse) CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc,
QueryResponseList& queryResponses)
{ {
if (_OpenConnection() != B_OK) if (_OpenConnection() != B_OK)
return B_ERROR; return B_ERROR;
// Convert CDDB id to hexadecimal format. // Convert CDDB id to hexadecimal format.
char hexCddbId[9]; char hexCddbId[9];
sprintf(hexCddbId, "%08" B_PRIx32 "", cddbId); sprintf(hexCddbId, "%08" B_PRIx32, cddbId);
// Assemble the Query command. // Assemble the Query command.
int32 numTracks = toc->last_track + 1 - toc->first_track; int32 numTracks = toc->last_track + 1 - toc->first_track;
BString cddbCommand("cddb query "); BString cddbCommand("cddb query ");
cddbCommand << hexCddbId << " " << numTracks << " "; cddbCommand << hexCddbId << " " << numTracks << " ";
// Add track offsets in frames. // Add track offsets in frames.
for (int32 i = 0; i < numTracks; ++i) { for (int32 i = 0; i < numTracks; ++i) {
const scsi_cd_msf& start = toc->tracks[i].start.time; const scsi_cd_msf& start = toc->tracks[i].start.time;
uint32 startFrameOffset = start.minute * kFramesPerMinute + uint32 startFrameOffset = start.minute * kFramesPerMinute +
start.second * kFramesPerSecond + start.frame; start.second * kFramesPerSecond + start.frame;
cddbCommand << startFrameOffset << " "; cddbCommand << startFrameOffset << " ";
} }
// Add total disc time in seconds. Last track is lead-out. // Add total disc time in seconds. Last track is lead-out.
const scsi_cd_msf& lastTrack = toc->tracks[numTracks].start.time; const scsi_cd_msf& lastTrack = toc->tracks[numTracks].start.time;
uint32 totalTimeInSeconds = lastTrack.minute * 60 + lastTrack.second; uint32 totalTimeInSeconds = lastTrack.minute * 60 + lastTrack.second;
cddbCommand << totalTimeInSeconds; cddbCommand << totalTimeInSeconds;
BString output; BString output;
status_t result; status_t result = _SendCommand(cddbCommand, output);
result = _SendCddbCommand(cddbCommand, &output);
if (result == B_OK) { if (result == B_OK) {
// Remove the header from the reply. // Remove the header from the reply.
output.Remove(0, output.FindFirst("\r\n\r\n") + 4); output.Remove(0, output.FindFirst("\r\n\r\n") + 4);
// Check status code. // Check status code.
BString statusCode; BString statusCode;
output.MoveInto(statusCode, 0, 3); output.MoveInto(statusCode, 0, 3);
@@ -107,7 +105,7 @@ CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc, BList* queryResponse)
} else if (statusCode == "202") { } else if (statusCode == "202") {
// No match found. // No match found.
printf("Error : CDDB entry for id %s not found.\n", hexCddbId); printf("Error : CDDB entry for id %s not found.\n", hexCddbId);
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} else { } else {
// Something bad happened. // Something bad happened.
@@ -120,26 +118,26 @@ CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc, BList* queryResponse)
return B_ERROR; return B_ERROR;
} }
// Process all entries. // Process all entries.
bool done = false; bool done = false;
while (!done) { while (!done) {
QueryResponseData* responseData = new QueryResponseData; QueryResponseData* responseData = new QueryResponseData;
output.MoveInto(responseData->category, 0, output.FindFirst(" ")); output.MoveInto(responseData->category, 0, output.FindFirst(" "));
output.Remove(0, 1); output.Remove(0, 1);
output.MoveInto(responseData->cddbId, 0, output.FindFirst(" ")); output.MoveInto(responseData->cddbId, 0, output.FindFirst(" "));
output.Remove(0, 1); output.Remove(0, 1);
output.MoveInto(responseData->artist, 0, output.FindFirst(" / ")); output.MoveInto(responseData->artist, 0, output.FindFirst(" / "));
output.Remove(0, 3); output.Remove(0, 3);
output.MoveInto(responseData->title, 0, output.FindFirst("\r\n")); output.MoveInto(responseData->title, 0, output.FindFirst("\r\n"));
output.Remove(0, 2); output.Remove(0, 2);
queryResponse->AddItem(responseData); queryResponses.AddItem(responseData);
if (output == "" || output == ".\r\n") { if (output == "" || output == ".\r\n") {
// All returned data was processed exit the loop. // All returned data was processed exit the loop.
done = true; done = true;
@@ -155,23 +153,22 @@ CDDBServer::Query(uint32 cddbId, const scsi_toc_toc* toc, BList* queryResponse)
status_t status_t
CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse) CDDBServer::Read(const QueryResponseData& diskData,
ReadResponseData& readResponse)
{ {
if (_OpenConnection() != B_OK) if (_OpenConnection() != B_OK)
return B_ERROR; return B_ERROR;
// Assemble the Read command. // Assemble the Read command.
BString cddbCommand("cddb read "); BString cddbCommand("cddb read ");
cddbCommand << diskData->category << " " << diskData->cddbId; cddbCommand << diskData.category << " " << diskData.cddbId;
BString output; BString output;
status_t result; status_t result = _SendCommand(cddbCommand, output);
result = _SendCddbCommand(cddbCommand, &output);
if (result == B_OK) { if (result == B_OK) {
// Remove the header from the reply. // Remove the header from the reply.
output.Remove(0, output.FindFirst("\r\n\r\n") + 4); output.Remove(0, output.FindFirst("\r\n\r\n") + 4);
// Check status code. // Check status code.
BString statusCode; BString statusCode;
output.MoveInto(statusCode, 0, 3); output.MoveInto(statusCode, 0, 3);
@@ -182,7 +179,7 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
// Something bad happened. // Something bad happened.
return B_ERROR; return B_ERROR;
} }
// Process all entries. // Process all entries.
bool done = false; bool done = false;
while (!done) { while (!done) {
@@ -191,7 +188,7 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
output.Remove(0, output.FindFirst("\r\n") + 2); output.Remove(0, output.FindFirst("\r\n") + 2);
continue; continue;
} }
// Extract one line to reduce the scope of processing to it. // Extract one line to reduce the scope of processing to it.
BString line; BString line;
output.MoveInto(line, 0, output.FindFirst("\r\n")); output.MoveInto(line, 0, output.FindFirst("\r\n"));
@@ -201,14 +198,14 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
BString prefix; BString prefix;
line.MoveInto(prefix, 0, line.FindFirst("=")); line.MoveInto(prefix, 0, line.FindFirst("="));
line.Remove(0, 1); line.Remove(0, 1);
if (prefix == "DTITLE") { if (prefix == "DTITLE") {
// Disk title. // Disk title.
BString artist; BString artist;
line.MoveInto(artist, 0, line.FindFirst(" / ")); line.MoveInto(artist, 0, line.FindFirst(" / "));
line.Remove(0, 3); line.Remove(0, 3);
readResponse->title = line; readResponse.title = line;
readResponse->artist = artist; readResponse.artist = artist;
} else if (prefix == "DYEAR") { } else if (prefix == "DYEAR") {
// Disk year. // Disk year.
char* firstInvalid; char* firstInvalid;
@@ -221,19 +218,19 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
printf("Year out of range: %s\n", line.String()); printf("Year out of range: %s\n", line.String());
year = 0; year = 0;
} }
if (firstInvalid == line.String()) { if (firstInvalid == line.String()) {
printf("Invalid year: %s\n", line.String()); printf("Invalid year: %s\n", line.String());
year = 0; year = 0;
} }
readResponse->year = year; readResponse.year = year;
} else if (prefix == "DGENRE") { } else if (prefix == "DGENRE") {
// Disk genre. // Disk genre.
readResponse->genre = line; readResponse.genre = line;
} else if (prefix.FindFirst("TTITLE") == 0) { } else if (prefix.FindFirst("TTITLE") == 0) {
// Track title. // Track title.
BString index; BString index;
prefix.MoveInto(index, 6, prefix.Length() - 6); prefix.MoveInto(index, 6, prefix.Length() - 6);
TrackData* trackData = new TrackData; TrackData* trackData = new TrackData;
@@ -249,17 +246,17 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
delete trackData; delete trackData;
return B_ERROR; return B_ERROR;
} }
if (firstInvalid == index.String()) { if (firstInvalid == index.String()) {
printf("Invalid track: %s\n", index.String()); printf("Invalid track: %s\n", index.String());
delete trackData; delete trackData;
return B_ERROR; return B_ERROR;
} }
trackData->trackNumber = track; trackData->trackNumber = track;
int32 pos = line.FindFirst(" / " ); int32 pos = line.FindFirst(" / ");
if (pos != B_ERROR && diskData->artist.ICompare("Various") == 0) { if (pos >= 0 && diskData.artist.ICompare("Various") == 0) {
// Disk is set to have a compilation artist and // Disk is set to have a compilation artist and
// we have track specific artist information. // we have track specific artist information.
BString artist; BString artist;
@@ -269,22 +266,22 @@ CDDBServer::Read(QueryResponseData* diskData, ReadResponseData* readResponse)
// Remove " / " from line. // Remove " / " from line.
trackData->artist = artist; trackData->artist = artist;
} else { } else {
trackData->artist = diskData->artist; trackData->artist = diskData.artist;
} }
trackData->title = line; trackData->title = line;
(readResponse->tracks).AddItem(trackData); readResponse.tracks.AddItem(trackData);
} }
if (output == "" || output == ".\r\n") { if (output == "" || output == ".\r\n") {
// All returned data was processed exit the loop. // All returned data was processed exit the loop.
done = true; done = true;
} }
} }
} else { } else {
printf("Error sending CDDB command : \"%s\".\n", cddbCommand.String()); printf("Error sending CDDB command : \"%s\".\n", cddbCommand.String());
} }
_CloseConnection(); _CloseConnection();
return B_OK; return B_OK;
@@ -298,8 +295,8 @@ CDDBServer::_ParseAddress(const BString& cddbServer)
int32 pos = cddbServer.FindFirst(":"); int32 pos = cddbServer.FindFirst(":");
if (pos == B_ERROR) { if (pos == B_ERROR) {
// It seems we do not have the address:port format. Use hostname as-is. // It seems we do not have the address:port format. Use hostname as-is.
fCddbServerAddr.SetTo(cddbServer.String(), kDefaultPortNumber); fServerAddress.SetTo(cddbServer.String(), kDefaultPortNumber);
if (fCddbServerAddr.InitCheck() == B_OK) if (fServerAddress.InitCheck() == B_OK)
return B_OK; return B_OK;
} else { } else {
// Parse address:port format. // Parse address:port format.
@@ -319,12 +316,12 @@ CDDBServer::_ParseAddress(const BString& cddbServer)
if (firstInvalid == portString.String()) { if (firstInvalid == portString.String()) {
return B_ERROR; return B_ERROR;
} }
newCddbServer.RemoveAll(":"); newCddbServer.RemoveAll(":");
fCddbServerAddr.SetTo(newCddbServer.String(), port); fServerAddress.SetTo(newCddbServer.String(), port);
if (fCddbServerAddr.InitCheck() == B_OK) if (fServerAddress.InitCheck() == B_OK)
return B_OK; return B_OK;
} }
} }
return B_ERROR; return B_ERROR;
@@ -340,11 +337,11 @@ CDDBServer::_OpenConnection()
if (fConnected) if (fConnected)
return B_OK; return B_OK;
if (fConnection.Connect(fCddbServerAddr) == B_OK) { if (fConnection.Connect(fServerAddress) == B_OK) {
fConnected = true; fConnected = true;
return B_OK; return B_OK;
} }
return B_ERROR; return B_ERROR;
} }
@@ -354,14 +351,14 @@ CDDBServer::_CloseConnection()
{ {
if (!fConnected) if (!fConnected)
return; return;
fConnection.Close(); fConnection.Close();
fConnected = false; fConnected = false;
} }
status_t status_t
CDDBServer::_SendCddbCommand(const BString& command, BString* output) CDDBServer::_SendCommand(const BString& command, BString& output)
{ {
if (!fConnected) if (!fConnected)
return B_ERROR; return B_ERROR;
@@ -374,10 +371,10 @@ CDDBServer::_SendCddbCommand(const BString& command, BString* output)
// Replace spaces by + signs. // Replace spaces by + signs.
fullCommand.ReplaceAll(" ", "+"); fullCommand.ReplaceAll(" ", "+");
// And now add command header and footer. // And now add command header and footer.
fullCommand.Prepend("GET /~cddb/cddb.cgi?cmd="); fullCommand.Prepend("GET /~cddb/cddb.cgi?cmd=");
fullCommand << " HTTP 1.0\n\n"; fullCommand << " HTTP 1.0\n\n";
int32 result = fConnection.Send((void*)fullCommand.String(), int32 result = fConnection.Send((void*)fullCommand.String(),
fullCommand.Length()); fullCommand.Length());
if (result == fullCommand.Length()) { if (result == fullCommand.Length()) {
@@ -385,11 +382,11 @@ CDDBServer::_SendCddbCommand(const BString& command, BString* output)
while (fConnection.Receive(netBuffer, 1024) != 0) { while (fConnection.Receive(netBuffer, 1024) != 0) {
// Do nothing. Data is automatically appended to the NetBuffer. // Do nothing. Data is automatically appended to the NetBuffer.
} }
// AppendString automatically adds the terminating \0. // AppendString automatically adds the terminating \0.
netBuffer.AppendString(""); netBuffer.AppendString("");
output->SetTo((char*)netBuffer.Data(), netBuffer.Size()); output.SetTo((char*)netBuffer.Data(), netBuffer.Size());
return B_OK; return B_OK;
} }
+32 -20
View File
@@ -1,17 +1,17 @@
/* /*
* Copyright 2008-2009, Haiku, Inc. All Rights Reserved. * Copyright 2008-2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Bruno Albuquerque, [email protected] * Bruno Albuquerque, [email protected]
*/ */
#ifndef _CDDB_SERVER_H #ifndef _CDDB_SERVER_H
#define _CDDB_SERVER_H #define _CDDB_SERVER_H
#include <List.h>
#include <NetAddress.h> #include <NetAddress.h>
#include <NetEndpoint.h> #include <NetEndpoint.h>
#include <ObjectList.h>
#include <String.h> #include <String.h>
#include <scsi_cmds.h> #include <scsi_cmds.h>
@@ -40,34 +40,46 @@ struct ReadResponseData {
BString artist; BString artist;
BString genre; BString genre;
uint32 year; uint32 year;
BList tracks; // TrackData items. BObjectList<TrackData> tracks;
ReadResponseData()
:
tracks(20, true)
{
}
}; };
typedef BObjectList<QueryResponseData> QueryResponseList;
class CDDBServer { class CDDBServer {
public: public:
CDDBServer(const BString& cddbServer); CDDBServer(const BString& cddbServer);
// CDDB commands interface. // CDDB commands interface.
status_t Query(uint32 cddbId, const scsi_toc_toc* toc, status_t Query(uint32 cddbId, const scsi_toc_toc* toc,
BList* queryResponse); QueryResponseList& queryResponses);
status_t Read(QueryResponseData* diskData, status_t Read(const QueryResponseData& diskData,
ReadResponseData* readResponse); ReadResponseData& readResponse);
private: private:
status_t _ParseAddress(const BString& cddbServer); status_t _ParseAddress(const BString& cddbServer);
status_t _OpenConnection(); status_t _OpenConnection();
void _CloseConnection(); void _CloseConnection();
status_t _SendCddbCommand(const BString& command, BString* output);
BString fLocalHostName; status_t _SendCommand(const BString& command,
BString fLocalUserName; BString& output);
BNetAddress fCddbServerAddr;
BNetEndpoint fConnection; private:
bool fInitialized; BString fLocalHostName;
bool fConnected; BString fLocalUserName;
BNetAddress fServerAddress;
BNetEndpoint fConnection;
bool fInitialized;
bool fConnected;
}; };
#endif // _CDDB_SERVER_H #endif // _CDDB_SERVER_H