Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

freedb.hxx

00001 /*
00002     \todo Setup a sourceforge account.
00003 
00004     \todo Application layer errors (6xx), e.g. "need connection first"
00005 
00006     \todo Connection checker guard
00007 
00008     \todo Central error handling for general errors
00009 */
00010 
00011 #ifndef FREEDB_HXX
00012 #define FREEDB_HXX
00013 
00014 #include <assert.h>
00015 
00016 #include <sys/types.h>
00017 #include <sys/socket.h>
00018 #include <netinet/in.h>
00019 #include <arpa/inet.h>
00020 #include <netdb.h>
00021 #include <unistd.h> //close()
00022 #include <errno.h>
00023 #include <linux/cdrom.h>
00024 
00025 #include <string.h> //strerror()
00026 
00027 #include <iostream>
00028 #include <sstream>
00029 #include <string>
00030 #include <vector>
00031 
00041 inline int stoi(const string s)
00042 {
00043     istringstream in(s);
00044     int i;
00045 
00046     in >> i;
00047 
00048     return(i);
00049 }
00050 
00056 inline string itos(int i)
00057 {
00058     ostringstream out;
00059 
00060     out << i;
00061 
00062     return(out.str());
00063 }
00064 
00073 const unsigned short CDDBP_PORT = 8880;
00074 
00075 
00076 typedef struct
00077 {
00078     string leading;
00079     string version_number;
00080     string release_type;
00081     string level;
00082 } ClientVersion;
00083 
00084 typedef struct
00085 {
00086     string name;
00087     ClientVersion version;
00088     string comments;
00089 } ClientInfo;
00090 
00093 typedef struct
00094 {
00095     long discid;                    
00096     string dartist;                 
00097     string dtitle;                  
00098     string dyear;                   
00099     string dgenre;                  
00100     string dextinfo;                
00101     int revision;                   
00102     vector<int> trackoffsets;       
00103     vector<string> tracktitles;     
00104     vector<int> playorder;          
00105 } CDInfo;
00106 
00109 typedef struct
00110 {
00111     long discid;
00112     string category;
00113     string dartist;
00114     string dtitle;
00115 } SearchResult;
00116 
00119 typedef struct
00120 {
00121     string compassdirection;
00122     short degrees;
00123     short minutes;
00124 } GeoCoords;
00125 
00128 typedef struct
00129 {
00130     string site;
00131     unsigned short port;
00132     GeoCoords latitude;
00133     GeoCoords longitude;
00134     string description;
00135 } ServerInfo;
00136 
00137 typedef struct
00138 {
00139     int min;
00140     int sec;
00141     int frame;
00142 } TrackPosition;
00143 
00149 typedef struct
00150 {
00151     int errcode;
00152     string errmsg;
00153     int errcode_sys;
00154     string errmsg_sys;
00155     string extinfo;
00156 } Error;
00157 
00164 class Freedb
00165 {
00166     public:
00167 
00168         virtual vector<SearchResult> search() const = 0;
00169 
00170         static string createEntry(CDInfo info);
00171         static CDInfo parseEntry(string entry);
00172 
00173         static vector<TrackPosition> getTrackOffsets(string device = "/dev/cdrom");
00174 
00175         static unsigned long generateDiscID(const vector<TrackPosition> offsets, const int num_tracks);
00176         static unsigned long getDiscID(string device = "/dev/cdrom");
00177 
00178         static void createDefaultDirectories();
00179 
00180     private:
00181         static int generateDiscSum(int n);
00182 };
00183 
00190 class FreedbRemote : public Freedb
00191 {
00192     public:
00193         FreedbRemote(string servername = "freedb.freedb.org");
00194         ~FreedbRemote();
00195 
00196         vector<SearchResult> search() const;
00197 
00198         void doHandshake(string username, string clientname, string version) const;
00199 
00200         vector<ServerInfo> getServerList() const;
00201 
00202         vector<string> getCategories() const;
00203 
00204         void submitDiscInfo(CDInfo info) const;
00205 
00206         inline string getGreeting() const
00207         {
00208             return(_greeting);
00209         }
00210 
00211     protected:
00212         void connect(string servername = "freedb.freedb.org");
00213         void disconnect();
00214 
00215         void sendCommand(string command) const;
00216         string getResponseLine(bool stripcr = true) const;
00217         static ServerInfo parseServerInfoLine(string line);
00218 
00219         int _sockfd;
00220         string _greeting;
00221 };
00222 
00229 class FreedbLocal : public Freedb
00230 {
00231     public:
00232         FreedbLocal(string dbfilename = "~/.freedb/db");
00233         ~FreedbLocal();
00234 
00235         vector<SearchResult> search() const;
00236 
00237     protected:
00238         int _dbfd;
00239 };
00240 
00241 #endif
00242 
00243 
00244 
00245 /*
00246 General errors:
00247 ---------------
00248 
00249 Server response:
00250 <- code error
00251     code:
00252 402Server error.
00253 408CGI environment error.
00254 500Command syntax error, command unknown, command unimplemented.
00255 530Server error, server timeout.
00256 
00257 freedb query:
00258 -----------
00259 Client command:
00260 -> freedb query discid ntrks off1 off2 ... nsecs
00261 
00262     discid:
00263 CD disc ID number.  Example: f50a3b13
00264     ntrks:
00265 Total number of tracks on CD.
00266     off1, off2, ...:
00267 Frame offset of the starting location of each track.
00268     nsecs:
00269 Total playing length of CD in seconds (calculated by dividing the lead
00270 out offset in frames by 75 (discarding the remainder)).
00271 
00272 Server response:
00273 <- code categ discid dtitle
00274 or
00275 <- code close matches found
00276 <- categ discid dtitle
00277 <- categ discid dtitle
00278 <- (more matches...)
00279 <- .
00280 
00281     code:
00282 200 Found exact match
00283 211 Found inexact matches, list follows (until terminating marker)
00284 202 No match found
00285 403 Database entry is corrupt
00286 409 No handshake
00287     categ:
00288 CD category.  Example: rock
00289     discid:
00290 CD disc ID number of the found entry.  Example: f50a3b13
00291     dtitle:
00292 The Disc Artist and Disc Title (The DTITLE line).  For example:
00293 Pink Floyd / The Dark Side of the Moon
00294 
00295 
00296 freedb read:
00297 ----------
00298 Client command:
00299 -> freedb read categ discid
00300 
00301     categ:
00302 CD category.  Example: rock
00303     discid:
00304 CD disc ID number.  Example: f50a3b13
00305 
00306 Server response:
00307 <- code categ discid
00308 <- # xmcd 2.0 CD database file
00309 <- # ...
00310 <- (freedb data...)
00311 <- .
00312 or
00313 <- code categ discid No such CD entry in database
00314 
00315     code:
00316 210 OK, freedb database entry follows (until terminating marker)
00317 401 Specified freedb entry not found.
00318 402 Server error.
00319 403 Database entry is corrupt.
00320 409 No handshake.
00321     categ:
00322 CD category.  Example: rock
00323     discid:
00324 CD disc ID number.  Example: f50a3b13
00325 
00326 
00327 freedb write:
00328 -----------
00329 Client command:
00330 -> freedb write categ discid
00331 
00332     categ:
00333 CD category.  Example: rock
00334     discid:
00335 CD disc ID number.  Example: f50a3b13
00336 
00337 Server response:
00338 <- code categ discid
00339 
00340     code:
00341 320OK, input freedb data (until terminating marker)
00342 401Permission denied.
00343 402Server file system full/file access failed.
00344 409No handshake.
00345 501Entry rejected: reason for rejection.
00346     categ:
00347 CD category.  Example: rock
00348     discid:
00349 CD disc ID number.  Example: f50a3b13
00350 
00351 Client data:
00352 -> # xmcd 2.0 CD database file
00353 -> # ...
00354 -> (freedb data)
00355 -> .
00356 
00357 Server response:
00358 <- code message
00359 
00360     code:
00361 200 freedb entry accepted
00362 401 freedb entry rejected: reason why
00363     message:
00364 Message string to indicate write status:
00365 freedb entry accepted, or freedb entry rejected.
00366 */

Generated on Wed Nov 6 17:32:02 2002 for libfreedb by doxygen1.2.18