Untabifying, widening, nixed wacky client version parsing.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2728 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -28,10 +28,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CDDB class provides access to the information provided by servers
|
* The CDDB class provides access to the information provided by servers compliant with the
|
||||||
* compliant with the
|
* <a href="http://www.freedb.org/software/old/CDDBPROTO">CDDB protocol</a>.
|
||||||
* <a href="http://www.freedb.org/software/old/CDDBPROTO">CDDB
|
|
||||||
* protocol</a>.
|
|
||||||
*/
|
*/
|
||||||
public class CDDB
|
public class CDDB
|
||||||
{
|
{
|
||||||
@@ -48,149 +46,134 @@ public class CDDB
|
|||||||
/**
|
/**
|
||||||
* The client version reported to the CDDB server.
|
* The client version reported to the CDDB server.
|
||||||
*/
|
*/
|
||||||
public static String CLIENT_VERSION; // assigned during static init
|
public static final String CLIENT_VERSION = "1.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates the information needed to look up a full
|
* This class encapsulates the information needed to look up a full CDDB record for a
|
||||||
* CDDB record for a particular disc. An array of them are returned in
|
* particular disc. An array of them are returned in response to a CDDB query.
|
||||||
* response to a CDDB query.
|
|
||||||
*/
|
*/
|
||||||
public static class Entry
|
public static class Entry
|
||||||
{
|
{
|
||||||
/** The category to which this entry belongs. */
|
/** The category to which this entry belongs. */
|
||||||
public String category;
|
public String category;
|
||||||
|
|
||||||
/** The unique identifier for this entry. */
|
/** The unique identifier for this entry. */
|
||||||
public String cdid;
|
public String cdid;
|
||||||
|
|
||||||
/** The human readable title of this entry. */
|
/** The human readable title of this entry. */
|
||||||
public String title;
|
public String title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses values for this entry from the supplied source
|
* Parses values for this entry from the supplied source string. The source string should
|
||||||
* string. The source string should contain an entry description
|
* contain an entry description as formatted by the CDDB server.
|
||||||
* as formatted by the CDDB server.
|
*
|
||||||
*
|
* @exception CDDBException Thrown if the entry is not properly formatted.
|
||||||
* @exception CDDBException Thrown if the entry is not properly
|
*/
|
||||||
* formatted.
|
public void parse (String source)
|
||||||
*/
|
throws CDDBException
|
||||||
public void parse (String source)
|
{
|
||||||
throws CDDBException
|
int sidx1 = source.indexOf(" ");
|
||||||
{
|
int sidx2 = source.indexOf(" ", sidx1+1);
|
||||||
int sidx1 = source.indexOf(" ");
|
|
||||||
int sidx2 = source.indexOf(" ", sidx1+1);
|
|
||||||
|
|
||||||
if (sidx1 == -1 || sidx2 == -1) {
|
if (sidx1 == -1 || sidx2 == -1) {
|
||||||
throw new CDDBException(499, "Malformed entry '" +
|
throw new CDDBException(499, "Malformed entry '" + source + "'");
|
||||||
source + "'");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
category = source.substring(0, sidx1);
|
category = source.substring(0, sidx1);
|
||||||
cdid = source.substring(sidx1+1, sidx2);
|
cdid = source.substring(sidx1+1, sidx2);
|
||||||
title = source.substring(sidx2+1);
|
title = source.substring(sidx2+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects this CDDB instance to the CDDB server running on the
|
* Connects this CDDB instance to the CDDB server running on the supplied host using the
|
||||||
* supplied host using the standard port.
|
* standard port.
|
||||||
*
|
*
|
||||||
* <p> <b>Note well:</b> you must close a CDDB connection once you are
|
* <p> <b>Note well:</b> you must close a CDDB connection once you are done with it, otherwise
|
||||||
* done with it, otherwise the socket connection will remain open and
|
* the socket connection will remain open and pointlessly consume machine resources.
|
||||||
* pointlessly consume machine resources.
|
|
||||||
*
|
*
|
||||||
* @param hostname The host to which to connect.
|
* @param hostname The host to which to connect.
|
||||||
*
|
*
|
||||||
* @exception IOException Thrown if a network error occurs attempting
|
* @exception IOException Thrown if a network error occurs attempting to connect to the host.
|
||||||
* to connect to the host.
|
* @exception CDDBException Thrown if an error occurs after identifying ourselves to the host.
|
||||||
* @exception CDDBException Thrown if an error occurs after
|
|
||||||
* identifying ourselves to the host.
|
|
||||||
*
|
*
|
||||||
* @return The message supplied with the succesful connection
|
* @return The message supplied with the succesful connection response.
|
||||||
* response.
|
|
||||||
*
|
*
|
||||||
* @see #STANDARD_PORT
|
* @see #STANDARD_PORT
|
||||||
* @see #close
|
* @see #close
|
||||||
*/
|
*/
|
||||||
public String connect (String hostname)
|
public String connect (String hostname)
|
||||||
throws IOException, CDDBException
|
throws IOException, CDDBException
|
||||||
{
|
{
|
||||||
return connect(hostname, STANDARD_PORT);
|
return connect(hostname, STANDARD_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects this CDDB instance to the CDDB server running on the
|
* Connects this CDDB instance to the CDDB server running on the supplied host using the
|
||||||
* supplied host using the specified port.
|
* specified port.
|
||||||
*
|
*
|
||||||
* <p> <b>Note well:</b> you must close a CDDB connection once you are
|
* <p> <b>Note well:</b> you must close a CDDB connection once you are done with it, otherwise
|
||||||
* done with it, otherwise the socket connection will remain open and
|
* the socket connection will remain open and pointlessly consume machine resources.
|
||||||
* pointlessly consume machine resources.
|
|
||||||
*
|
*
|
||||||
* @param hostname The host to which to connect.
|
* @param hostname The host to which to connect.
|
||||||
* @param port The port number on which to connect to the host.
|
* @param port The port number on which to connect to the host.
|
||||||
*
|
*
|
||||||
* @exception IOException Thrown if a network error occurs attempting
|
* @exception IOException Thrown if a network error occurs attempting to connect to the host.
|
||||||
* to connect to the host.
|
* @exception CDDBException Thrown if an error occurs after identifying ourselves to the host.
|
||||||
* @exception CDDBException Thrown if an error occurs after
|
|
||||||
* identifying ourselves to the host.
|
|
||||||
*
|
*
|
||||||
* @return The message supplied with the succesful connection
|
* @return The message supplied with the succesful connection response.
|
||||||
* response.
|
|
||||||
*
|
*
|
||||||
* @see #close
|
* @see #close
|
||||||
*/
|
*/
|
||||||
public String connect (String hostname, int port)
|
public String connect (String hostname, int port)
|
||||||
throws IOException, CDDBException
|
throws IOException, CDDBException
|
||||||
{
|
{
|
||||||
// obtain the necessary information we'll need to identify
|
// obtain the necessary information we'll need to identify
|
||||||
// ourselves to the CDDB server
|
// ourselves to the CDDB server
|
||||||
String localhost = InetAddress.getLocalHost().getHostName();
|
String localhost = InetAddress.getLocalHost().getHostName();
|
||||||
String username = System.getProperty("user.name");
|
String username = System.getProperty("user.name");
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
username = "anonymous";
|
username = "anonymous";
|
||||||
}
|
}
|
||||||
|
|
||||||
// establish our socket connection and IO streams
|
// establish our socket connection and IO streams
|
||||||
InetAddress addr = InetAddress.getByName(hostname);
|
InetAddress addr = InetAddress.getByName(hostname);
|
||||||
_sock = new Socket(addr, port);
|
_sock = new Socket(addr, port);
|
||||||
_in = new BufferedReader(
|
_in = new BufferedReader(new InputStreamReader(_sock.getInputStream()));
|
||||||
new InputStreamReader(_sock.getInputStream()));
|
_out = new PrintStream(new BufferedOutputStream(_sock.getOutputStream()));
|
||||||
_out = new PrintStream(
|
|
||||||
new BufferedOutputStream(_sock.getOutputStream()));
|
|
||||||
|
|
||||||
// first read (and discard) the banner string
|
// first read (and discard) the banner string
|
||||||
_in.readLine();
|
_in.readLine();
|
||||||
|
|
||||||
// send a hello request
|
// send a hello request
|
||||||
StringBuilder req = new StringBuilder("cddb hello ");
|
StringBuilder req = new StringBuilder("cddb hello ");
|
||||||
req.append(username).append(" ");
|
req.append(username).append(" ");
|
||||||
req.append(localhost).append(" ");
|
req.append(localhost).append(" ");
|
||||||
req.append(CLIENT_NAME).append(" ");
|
req.append(CLIENT_NAME).append(" ");
|
||||||
req.append(CLIENT_VERSION);
|
req.append(CLIENT_VERSION);
|
||||||
|
|
||||||
Response rsp = request(req.toString());
|
Response rsp = request(req.toString());
|
||||||
|
|
||||||
// confirm that the response was a successful one
|
// confirm that the response was a successful one
|
||||||
if (CDDBProtocol.codeFamily(rsp.code) != CDDBProtocol.OK &&
|
if (CDDBProtocol.codeFamily(rsp.code) != CDDBProtocol.OK &&
|
||||||
rsp.code != 402 /* already shook hands */) {
|
rsp.code != 402 /* already shook hands */) {
|
||||||
throw new CDDBException(rsp.code, rsp.message);
|
throw new CDDBException(rsp.code, rsp.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rsp.message;
|
return rsp.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the number of milliseconds that the client should wait
|
* Specifies the number of milliseconds that the client should wait for a response from the
|
||||||
* for a response from the server before aborting. This must be called
|
* server before aborting. This must be called <em>after</em> a successful call to connect,
|
||||||
* <em>after</em> a successful call to connect, otherwise the timeout
|
* otherwise the timeout will not be set.
|
||||||
* will not be set.
|
|
||||||
*/
|
*/
|
||||||
public void setTimeout (int timeout)
|
public void setTimeout (int timeout)
|
||||||
throws SocketException
|
throws SocketException
|
||||||
{
|
{
|
||||||
if (_sock != null) {
|
if (_sock != null) {
|
||||||
_sock.setSoTimeout(timeout);
|
_sock.setSoTimeout(timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,255 +181,280 @@ public class CDDB
|
|||||||
*/
|
*/
|
||||||
public boolean connected ()
|
public boolean connected ()
|
||||||
{
|
{
|
||||||
return _sock != null;
|
return _sock != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connection to the CDDB server previously opened with a
|
* Closes the connection to the CDDB server previously opened with a call to {@link #connect}.
|
||||||
* call to <code>connect()</code>. If the connection was not
|
* If the connection was not previously established, this member function does nothing.
|
||||||
* previously established, this member function does nothing.
|
|
||||||
*
|
|
||||||
* @see #connect
|
|
||||||
*/
|
*/
|
||||||
public void close ()
|
public void close ()
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
if (_sock != null) {
|
if (_sock != null) {
|
||||||
_sock.close();
|
_sock.close();
|
||||||
|
|
||||||
// clear out our references
|
// clear out our references
|
||||||
_sock = null;
|
_sock = null;
|
||||||
_in = null;
|
_in = null;
|
||||||
_out = null;
|
_out = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issues a query to the CDDB server using the supplied CD identifying
|
* Issues a query to the CDDB server using the supplied CD identifying information.
|
||||||
* information.
|
|
||||||
*
|
*
|
||||||
* @param discid The disc identifier (information on how to compute
|
* @param discid The disc identifier (information on how to compute the disc ID is available <a
|
||||||
* the disc ID is available
|
* href="http://www.freedb.org/sections.php?op=viewarticle&artid=6"> here</a>.
|
||||||
* <a href="http://www.freedb.org/sections.php?op=viewarticle&artid=6">
|
* @param frameOffsets The frame offset of each track. The length of this array is assumed to
|
||||||
* here</a>.
|
* be the number of tracks on the CD and is used in the query.
|
||||||
* @param frameOffsets The frame offset of each track. The length of
|
|
||||||
* this array is assumed to be the number of tracks on the CD and is
|
|
||||||
* used in the query.
|
|
||||||
* @param length The length (in seconds) of the CD.
|
* @param length The length (in seconds) of the CD.
|
||||||
*
|
*
|
||||||
* @return If no entry matches the query, null is returned. Otherwise
|
* @return If no entry matches the query, null is returned. Otherwise one or more entries is
|
||||||
* one or more entries is returned that matched the query parameters.
|
* returned that matched the query parameters.
|
||||||
*/
|
*/
|
||||||
public Entry[] query (String discid, int[] frameOffsets, int length)
|
public Entry[] query (String discid, int[] frameOffsets, int length)
|
||||||
throws IOException, CDDBException
|
throws IOException, CDDBException
|
||||||
{
|
{
|
||||||
// sanity check
|
// sanity check
|
||||||
if (_sock == null) {
|
if (_sock == null) {
|
||||||
throw new CDDBException(500, "Not connected");
|
throw new CDDBException(500, "Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the query parameter
|
// construct the query parameter
|
||||||
StringBuilder req = new StringBuilder("cddb query ");
|
StringBuilder req = new StringBuilder("cddb query ");
|
||||||
req.append(discid).append(" ");
|
req.append(discid).append(" ");
|
||||||
req.append(frameOffsets.length).append(" ");
|
req.append(frameOffsets.length).append(" ");
|
||||||
for (int i = 0; i < frameOffsets.length; i++) {
|
for (int i = 0; i < frameOffsets.length; i++) {
|
||||||
req.append(frameOffsets[i]).append(" ");
|
req.append(frameOffsets[i]).append(" ");
|
||||||
}
|
}
|
||||||
req.append(length);
|
req.append(length);
|
||||||
|
|
||||||
// make the request
|
// make the request
|
||||||
Response rsp = request(req.toString());
|
Response rsp = request(req.toString());
|
||||||
Entry[] entries = null;
|
Entry[] entries = null;
|
||||||
|
|
||||||
// if this is an exact match, parse the entry and return it
|
// if this is an exact match, parse the entry and return it
|
||||||
if (rsp.code == 200 /* exact match */) {
|
if (rsp.code == 200 /* exact match */) {
|
||||||
entries = new Entry[1];
|
entries = new Entry[1];
|
||||||
entries[0] = new Entry();
|
entries[0] = new Entry();
|
||||||
entries[0].parse(rsp.message);
|
entries[0].parse(rsp.message);
|
||||||
|
|
||||||
} else if (rsp.code == 211 /* inexact matches */) {
|
} else if (rsp.code == 211 /* inexact matches */) {
|
||||||
// read the matches from the server
|
// read the matches from the server
|
||||||
ArrayList<Entry> list = new ArrayList<Entry>();
|
ArrayList<Entry> list = new ArrayList<Entry>();
|
||||||
String input = _in.readLine();
|
String input = _in.readLine();
|
||||||
System.out.println("...: " + input);
|
System.out.println("...: " + input);
|
||||||
while (!input.equals(CDDBProtocol.TERMINATOR)) {
|
while (!input.equals(CDDBProtocol.TERMINATOR)) {
|
||||||
Entry e = new Entry();
|
Entry e = new Entry();
|
||||||
e.parse(input);
|
e.parse(input);
|
||||||
list.add(e);
|
list.add(e);
|
||||||
input = _in.readLine();
|
input = _in.readLine();
|
||||||
System.out.println("...: " + input);
|
System.out.println("...: " + input);
|
||||||
}
|
}
|
||||||
entries = new Entry[list.size()];
|
entries = new Entry[list.size()];
|
||||||
list.toArray(entries);
|
list.toArray(entries);
|
||||||
|
|
||||||
} else if (CDDBProtocol.codeFamily(rsp.code) != CDDBProtocol.OK) {
|
} else if (CDDBProtocol.codeFamily(rsp.code) != CDDBProtocol.OK) {
|
||||||
throw new CDDBException(rsp.code, rsp.message);
|
throw new CDDBException(rsp.code, rsp.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A detail object contains all of the detailed information about a
|
* A detail object contains all of the detailed information about a particular CD as retrieved
|
||||||
* particular CD as retrieved from the CDDB server.
|
* from the CDDB server.
|
||||||
*/
|
*/
|
||||||
public static class Detail
|
public static class Detail
|
||||||
{
|
{
|
||||||
/** The unique identifier for this CD. */
|
/** The unique identifier for this CD. */
|
||||||
public String discid;
|
public String discid;
|
||||||
|
|
||||||
/** The category to which this CD belongs. */
|
/** The category to which this CD belongs. */
|
||||||
public String category;
|
public String category;
|
||||||
|
|
||||||
/** The title of this CD. */
|
/** The title of this CD. */
|
||||||
public String title;
|
public String title;
|
||||||
|
|
||||||
/** The track names. */
|
/** The track names. */
|
||||||
public String[] trackNames;
|
public String[] trackNames;
|
||||||
|
|
||||||
/** The extended data for the CD. */
|
/** The extended data for the CD. */
|
||||||
public String extendedData;
|
public String extendedData;
|
||||||
|
|
||||||
/** The extended data for each track. */
|
/** The extended data for each track. */
|
||||||
public String[] extendedTrackData;
|
public String[] extendedTrackData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the detail information for a particular disc in a
|
* Requests the detail information for a particular disc in a particular category from the CDDB
|
||||||
* particular category from the CDDB server.
|
* server.
|
||||||
*
|
*
|
||||||
* @return A detail instance filled with the information for the
|
* @return A detail instance filled with the information for the requested CD.
|
||||||
* requested CD.
|
|
||||||
*/
|
*/
|
||||||
public Detail read (String category, String discid)
|
public Detail read (String category, String discid)
|
||||||
throws IOException, CDDBException
|
throws IOException, CDDBException
|
||||||
{
|
{
|
||||||
// sanity check
|
// sanity check
|
||||||
if (_sock == null) {
|
if (_sock == null) {
|
||||||
throw new CDDBException(500, "Not connected");
|
throw new CDDBException(500, "Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the query
|
// construct the query
|
||||||
StringBuilder req = new StringBuilder("cddb read ");
|
StringBuilder req = new StringBuilder("cddb read ");
|
||||||
req.append(category).append(" ");
|
req.append(category).append(" ");
|
||||||
req.append(discid);
|
req.append(discid);
|
||||||
|
|
||||||
// make the request
|
// make the request
|
||||||
Response rsp = request(req.toString());
|
Response rsp = request(req.toString());
|
||||||
// anything other than an OK response earns an exception
|
// anything other than an OK response earns an exception
|
||||||
if (rsp.code != 210 /* OK, entry follows */) {
|
if (rsp.code != 210 /* OK, entry follows */) {
|
||||||
throw new CDDBException(rsp.code, rsp.message);
|
throw new CDDBException(rsp.code, rsp.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Detail detail = new Detail();
|
Detail detail = new Detail();
|
||||||
|
|
||||||
// parse the category and discid from the response string
|
// parse the category and discid from the response string
|
||||||
int sidx = rsp.message.indexOf(" ");
|
int sidx = rsp.message.indexOf(" ");
|
||||||
if (sidx == -1) {
|
if (sidx == -1) {
|
||||||
throw new CDDBException(500, "Malformed read response: " +
|
throw new CDDBException(500, "Malformed read response: " +
|
||||||
rsp.message);
|
rsp.message);
|
||||||
}
|
}
|
||||||
detail.category = rsp.message.substring(0, sidx);
|
detail.category = rsp.message.substring(0, sidx);
|
||||||
detail.discid = rsp.message.substring(sidx+1);
|
detail.discid = rsp.message.substring(sidx+1);
|
||||||
|
|
||||||
ArrayList<String> tnames = new ArrayList<String>();
|
ArrayList<String> tnames = new ArrayList<String>();
|
||||||
ArrayList<String> texts = new ArrayList<String>();
|
ArrayList<String> texts = new ArrayList<String>();
|
||||||
|
|
||||||
// now parse the contents
|
// now parse the contents
|
||||||
String input = _in.readLine();
|
String input = _in.readLine();
|
||||||
for (int lno = 0; !input.equals(CDDBProtocol.TERMINATOR); lno++) {
|
for (int lno = 0; !input.equals(CDDBProtocol.TERMINATOR); lno++) {
|
||||||
|
if (input.startsWith("#")) {
|
||||||
|
// skip comments
|
||||||
|
|
||||||
if (input.startsWith("#")) {
|
} else if (input.startsWith("DTITLE")) {
|
||||||
// skip comments
|
if (detail.title == null) {
|
||||||
|
detail.title = contents(input, lno);
|
||||||
|
} else {
|
||||||
|
detail.title += contents(input, lno);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (input.startsWith("DTITLE")) {
|
} else if (input.startsWith("EXTD")) {
|
||||||
if (detail.title == null) {
|
if (detail.extendedData == null) {
|
||||||
detail.title = contents(input, lno);
|
detail.extendedData = contents(input, lno);
|
||||||
} else {
|
} else {
|
||||||
detail.title += contents(input, lno);
|
detail.extendedData += contents(input, lno);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (input.startsWith("EXTD")) {
|
} else if (input.startsWith("TTITLE")) {
|
||||||
if (detail.extendedData == null) {
|
append(tnames, index(input, "TTITLE", lno), contents(input, lno));
|
||||||
detail.extendedData = contents(input, lno);
|
|
||||||
} else {
|
|
||||||
detail.extendedData += contents(input, lno);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (input.startsWith("TTITLE")) {
|
} else if (input.startsWith("EXTT")) {
|
||||||
append(tnames, index(input, "TTITLE", lno),
|
append(texts, index(input, "EXTT", lno), contents(input, lno));
|
||||||
contents(input, lno));
|
}
|
||||||
|
|
||||||
} else if (input.startsWith("EXTT")) {
|
// read in the next line of input
|
||||||
append(texts, index(input, "EXTT", lno),
|
input = _in.readLine();
|
||||||
contents(input, lno));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// read in the next line of input
|
// convert the lists into arrays
|
||||||
input = _in.readLine();
|
detail.trackNames = new String[tnames.size()];
|
||||||
}
|
tnames.toArray(detail.trackNames);
|
||||||
|
detail.extendedTrackData = new String[texts.size()];
|
||||||
|
texts.toArray(detail.extendedTrackData);
|
||||||
|
|
||||||
// convert the lists into arrays
|
return detail;
|
||||||
detail.trackNames = new String[tnames.size()];
|
|
||||||
tnames.toArray(detail.trackNames);
|
|
||||||
detail.extendedTrackData = new String[texts.size()];
|
|
||||||
texts.toArray(detail.extendedTrackData);
|
|
||||||
|
|
||||||
return detail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the track index of the supplied line (the number
|
* Extracts the track index of the supplied line (the number immediately following the supplied
|
||||||
* immediately following the supplied prefix and preceding the equals
|
* prefix and preceding the equals sign) or throws a CDDBException if the line contains no
|
||||||
* sign) or throws a CDDBException if the line contains no equals sign
|
* equals sign or track index.
|
||||||
* or track index.
|
|
||||||
*/
|
*/
|
||||||
protected final int index (String source, String prefix, int lineno)
|
protected final int index (String source, String prefix, int lineno)
|
||||||
throws CDDBException
|
throws CDDBException
|
||||||
{
|
{
|
||||||
int eidx = source.indexOf("=", prefix.length());
|
int eidx = source.indexOf("=", prefix.length());
|
||||||
if (eidx == -1) {
|
if (eidx == -1) {
|
||||||
throw new CDDBException(500, "Malformed line '" + source +
|
throw new CDDBException(500, "Malformed line '" + source + "' number " + lineno);
|
||||||
"' number " + lineno);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(source.substring(prefix.length(), eidx));
|
return Integer.parseInt(source.substring(prefix.length(), eidx));
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
throw new CDDBException(500, "Malformed line '" + source +
|
throw new CDDBException(500, "Malformed line '" + source + "' number " + lineno);
|
||||||
"' number " + lineno);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the contents of the supplied line (everything after the
|
* Extracts the contents of the supplied line (everything after the equals sign) or throws a
|
||||||
* equals sign) or throws a CDDBException if the line contains no
|
* CDDBException if the line contains no equals sign.
|
||||||
* equals sign.
|
|
||||||
*/
|
*/
|
||||||
protected final String contents (String source, int lineno)
|
protected final String contents (String source, int lineno)
|
||||||
throws CDDBException
|
throws CDDBException
|
||||||
{
|
{
|
||||||
int eidx = source.indexOf("=");
|
int eidx = source.indexOf("=");
|
||||||
if (eidx == -1) {
|
if (eidx == -1) {
|
||||||
throw new CDDBException(500, "Malformed line '" + source +
|
throw new CDDBException(500, "Malformed line '" + source + "' number " + lineno);
|
||||||
"' number " + lineno);
|
}
|
||||||
}
|
return source.substring(eidx+1);
|
||||||
return source.substring(eidx+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends the supplied string to the contents of the list at the
|
* Appends the supplied string to the contents of the list at the supplied index. If the list
|
||||||
* supplied index. If the list has no contents at the supplied
|
* has no contents at the supplied index, the supplied value becomes the contents at that
|
||||||
* index, the supplied value becomes the contents at that index.
|
* index.
|
||||||
*/
|
*/
|
||||||
protected final void append (
|
protected final void append (
|
||||||
ArrayList<String> list, int index, String value)
|
ArrayList<String> list, int index, String value)
|
||||||
{
|
{
|
||||||
// expand the list as necessary
|
// expand the list as necessary
|
||||||
while (list.size() <= index) {
|
while (list.size() <= index) {
|
||||||
list.add("");
|
list.add("");
|
||||||
}
|
}
|
||||||
list.set(index, list.get(index) + value);
|
list.set(index, list.get(index) + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issues a request to the CDDB server and parses the response.
|
||||||
|
*/
|
||||||
|
protected Response request (String req)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
System.err.println("REQ:" + req);
|
||||||
|
|
||||||
|
// send the request to the server
|
||||||
|
_out.println(req);
|
||||||
|
_out.flush();
|
||||||
|
|
||||||
|
// now read the response
|
||||||
|
String rspstr = _in.readLine();
|
||||||
|
// if they closed the connection on us, we should deal
|
||||||
|
if (rspstr == null) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
System.err.println("RSP:" + rspstr);
|
||||||
|
|
||||||
|
// parse the response
|
||||||
|
Response rsp = new Response();
|
||||||
|
String codestr = rspstr;
|
||||||
|
|
||||||
|
// assume the response is just a code unless we see a space
|
||||||
|
int sidx = rspstr.indexOf(" ");
|
||||||
|
if (sidx != -1) {
|
||||||
|
codestr = rspstr.substring(0, sidx);
|
||||||
|
rsp.message = rspstr.substring(sidx+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
rsp.code = Integer.parseInt(codestr);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
rsp.code = 599;
|
||||||
|
rsp.message = "Unparseable response";
|
||||||
|
}
|
||||||
|
|
||||||
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -454,61 +462,8 @@ public class CDDB
|
|||||||
*/
|
*/
|
||||||
protected class Response
|
protected class Response
|
||||||
{
|
{
|
||||||
public int code;
|
public int code;
|
||||||
public String message;
|
public String message;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Issues a request to the CDDB server and parses the response.
|
|
||||||
*/
|
|
||||||
protected Response request (String req)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
System.err.println("REQ:" + req);
|
|
||||||
|
|
||||||
// send the request to the server
|
|
||||||
_out.println(req);
|
|
||||||
_out.flush();
|
|
||||||
|
|
||||||
// now read the response
|
|
||||||
String rspstr = _in.readLine();
|
|
||||||
// if they closed the connection on us, we should deal
|
|
||||||
if (rspstr == null) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
System.err.println("RSP:" + rspstr);
|
|
||||||
|
|
||||||
// parse the response
|
|
||||||
Response rsp = new Response();
|
|
||||||
String codestr = rspstr;
|
|
||||||
|
|
||||||
// assume the response is just a code unless we see a space
|
|
||||||
int sidx = rspstr.indexOf(" ");
|
|
||||||
if (sidx != -1) {
|
|
||||||
codestr = rspstr.substring(0, sidx);
|
|
||||||
rsp.message = rspstr.substring(sidx+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
rsp.code = Integer.parseInt(codestr);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
rsp.code = 599;
|
|
||||||
rsp.message = "Unparseable response";
|
|
||||||
}
|
|
||||||
|
|
||||||
return rsp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The client version number is extracted from the version control
|
|
||||||
* revision of this file from a string that is managed by the version
|
|
||||||
* control system.
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
{
|
|
||||||
StringTokenizer tok = new StringTokenizer("$Revision: 1.8 $");
|
|
||||||
tok.nextToken();
|
|
||||||
CLIENT_VERSION = tok.nextToken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Socket _sock;
|
protected Socket _sock;
|
||||||
|
|||||||
Reference in New Issue
Block a user