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:
@@ -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++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user