1 /*------------------------------------------------------------------------------
2 
3    Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
4 
5    Tyrell DarkIce
6 
7    File     : CastSink.h
8    Version  : $Revision$
9    Author   : $Author$
10    Location : $HeadURL$
11 
12    Copyright notice:
13 
14     This program is free software; you can redistribute it and/or
15     modify it under the terms of the GNU General Public License
16     as published by the Free Software Foundation; either version 3
17     of the License, or (at your option) any later version.
18 
19     This program is distributed in the hope that it will be useful,
20     but WITHOUT ANY WARRANTY; without even the implied warranty of
21     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22     GNU General Public License for more details.
23 
24     You should have received a copy of the GNU General Public License
25     along with this program; if not, write to the Free Software
26     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 
28 ------------------------------------------------------------------------------*/
29 #ifndef CAST_SINK_H
30 #define CAST_SINK_H
31 
32 #ifndef __cplusplus
33 #error This is a C++ include file
34 #endif
35 
36 
37 /* ============================================================ include files */
38 
39 #include "Ref.h"
40 #include "Reporter.h"
41 #include "Sink.h"
42 #include "TcpSocket.h"
43 #include "BufferedSink.h"
44 
45 
46 /* ================================================================ constants */
47 
48 
49 /* =================================================================== macros */
50 
51 
52 /* =============================================================== data types */
53 
54 /**
55  *  Data output to a ShoutCast / IceCast / etc. server
56  *  This is an abstract class. A subclass should override at least
57  *  the sendLogin() function.
58  *
59  *  @author  $Author$
60  *  @version $Revision$
61  */
62 class CastSink : public Sink, public virtual Reporter
63 {
64     private:
65 
66         /**
67          *  The socket connection to the server.
68          */
69         Ref<TcpSocket>      socket;
70 
71         /**
72          *  An optional Sink to enable stream dumps.
73          */
74         Ref<Sink>           streamDump;
75 
76         /**
77          *  Password to the server.
78          */
79         char              * password;
80 
81         /**
82          *  Name of the stream.
83          */
84         char              * name;
85 
86         /**
87          *  URL associated with the stream.
88          */
89         char              * url;
90 
91         /**
92          *  Genre of the stream.
93          */
94         char              * genre;
95 
96         /**
97          *  Bitrate of the stream (e.g. mp3 bitrate).
98          */
99         unsigned int        bitRate;
100 
101         /**
102          *  Is the stream public?
103          */
104         bool                isPublic;
105 
106         /**
107          *  Initalize the object.
108          *
109          *  @param socket socket connection to the server.
110          *  @param password password to the server.
111          *  @param name name of the stream.
112          *  @param url URL associated with the stream.
113          *  @param genre genre of the stream.
114          *  @param bitRate bitrate of the stream (e.g. mp3 bitrate).
115          *  @param isPublic is the stream public?
116          *  @exception Exception
117          */
118         void
119         init (  TcpSocket             * socket,
120                 Sink                  * streamDump,
121                 const char            * password,
122                 unsigned int            bitRate,
123                 const char            * name,
124                 const char            * url,
125                 const char            * genre,
126                 bool                    isPublic)
127                                                     throw ( Exception );
128 
129         /**
130          *  De-initalize the object.
131          *
132          *  @exception Exception
133          */
134         void
135         strip ( void )                              throw ( Exception );
136 
137 
138     protected:
139 
140         /**
141          *  Default constructor. Always throws an Exception.
142          *
143          *  @exception Exception
144          */
145         inline
CastSink(void)146         CastSink ( void )                           throw ( Exception )
147         {
148             throw Exception( __FILE__, __LINE__);
149         }
150 
151         /**
152          *  Log in to the server using the socket avialable.
153          *
154          *  @return true if login was successful, false otherwise.
155          *  @exception Exception
156          */
157         virtual bool
158         sendLogin ( void )              throw ( Exception )         = 0;
159 
160         /**
161          *  Get the Sink underneath this CastSink.
162          *
163          *  @return pointer to the Sink underneath this CastSink.
164          */
165         inline Sink *
getSink(void)166         getSink ( void ) const                      throw ()
167         {
168             return getSocket();
169         }
170 
171         /**
172          *  Get the TcpSocket underneath this CastSink.
173          *
174          *  @return pointer to the TcpSocket underneath this CastSink.
175          */
176         inline TcpSocket *
getSocket(void)177         getSocket ( void ) const                    throw ()
178         {
179             return socket.get();
180         }
181 
182 
183     public:
184 
185         /**
186          *  Constructor.
187          *
188          *  @param socket socket connection to the server.
189          *  @param password password to the server.
190          *  @param name name of the stream.
191          *  @param url URL associated with the stream.
192          *  @param genre genre of the stream.
193          *  @param bitRate bitrate of the stream (e.g. mp3 bitrate).
194          *  @param isPublic is the stream public?
195          *  @param streamDump a Sink to dump the streamed binary data to
196          *
197          *  @exception Exception
198          */
199         inline
200         CastSink (  TcpSocket         * socket,
201                     const char        * password,
202                     unsigned int        bitRate,
203                     const char        * name           = 0,
204                     const char        * url            = 0,
205                     const char        * genre          = 0,
206                     bool                isPublic       = false,
207                     Sink              * streamDump     = 0)
throw(Exception)208                                                         throw ( Exception )
209         {
210             init( socket,
211                   streamDump,
212                   password,
213                   bitRate,
214                   name,
215                   url,
216                   genre,
217                   isPublic );
218         }
219 
220         /**
221          *  Copy constructor.
222          *
223          *  @param cs the CastSink to copy.
224          */
225         inline
throw(Exception)226         CastSink(   const CastSink &    cs )        throw ( Exception )
227                 : Sink( cs )
228         {
229             init( cs.socket.get(),
230                   cs.streamDump.get(),
231                   cs.password,
232                   cs.bitRate,
233                   cs.name,
234                   cs.url,
235                   cs.genre,
236                   cs.isPublic );
237         }
238 
239         /**
240          *  Destructor.
241          *
242          *  @exception Exception
243          */
244         inline virtual
~CastSink(void)245         ~CastSink( void )                           throw ( Exception )
246         {
247             strip();
248         }
249 
250         /**
251          *  Assignment operator.
252          *
253          *  @param cs the CastSink to assign this to.
254          *  @return a reference to this CastSink.
255          *  @exception Exception
256          */
257         inline virtual CastSink &
throw(Exception)258         operator= ( const CastSink &    cs )        throw ( Exception )
259         {
260             if ( this != &cs ) {
261                 strip();
262                 Sink::operator=( cs );
263                 init( cs.socket.get(),
264                       cs.streamDump.get(),
265                       cs.password,
266                       cs.bitRate,
267                       cs.name,
268                       cs.url,
269                       cs.genre,
270                       cs.isPublic );
271             }
272             return *this;
273         }
274 
275         /**
276          *  Open the CastSink.
277          *  Logs in to the server.
278          *
279          *  @return true if opening was successfull, false otherwise.
280          *  @exception Exception
281          */
282         virtual bool
283         open ( void )                               throw ( Exception );
284 
285         /**
286          *  Check if the CastSink is open.
287          *
288          *  @return true if the CastSink is open, false otherwise.
289          */
290         inline virtual bool
isOpen(void)291         isOpen ( void ) const                       throw ()
292         {
293 	    if( !getSink() ) {
294 		return false;
295 	    }
296 	    return getSink()->isOpen();
297         }
298 
299         /**
300          *  Check if the CastSink is ready to accept data.
301          *  Blocks until the specified time for data to be available.
302          *
303          *  @param sec the maximum seconds to block.
304          *  @param usec micro seconds to block after the full seconds.
305          *  @return true if the CastSink is ready to accept data,
306          *          false otherwise.
307          *  @exception Exception
308          */
309         inline virtual bool
canWrite(unsigned int sec,unsigned int usec)310         canWrite (     unsigned int    sec,
311                        unsigned int    usec )       throw ( Exception )
312         {
313             return getSink()->canWrite( sec, usec);
314         }
315 
316         /**
317          *  Write data to the CastSink.
318          *
319          *  @param buf the data to write.
320          *  @param len number of bytes to write from buf.
321          *  @return the number of bytes written (may be less than len).
322          *  @exception Exception
323          */
324         inline virtual unsigned int
write(const void * buf,unsigned int len)325         write (        const void    * buf,
326                        unsigned int    len )        throw ( Exception )
327         {
328             if ( streamDump != 0 ) {
329                 streamDump->write( buf, len);
330             }
331 
332             return getSink()->write( buf, len);
333         }
334 
335         /**
336          *  Flush all data that was written to the CastSink to the server.
337          *
338          *  @exception Exception
339          */
340         inline virtual void
flush(void)341         flush ( void )                              throw ( Exception )
342         {
343             if ( streamDump != 0 ) {
344                 streamDump->flush();
345             }
346 
347             return getSink()->flush();
348         }
349 
350         /**
351          *  Cut what the sink has been doing so far, and start anew.
352          *  This usually means separating the data sent to the sink up
353          *  until now, and start saving a new chunk of data.
354          */
355         inline virtual void
cut(void)356         cut ( void )                                    throw ()
357         {
358             if ( streamDump != 0 ) {
359                 streamDump->cut();
360             }
361         }
362 
363         /**
364          *  Close the CastSink.
365          *
366          *  @exception Exception
367          */
368         inline virtual void
close(void)369         close ( void )                              throw ( Exception )
370         {
371             if ( streamDump != 0 ) {
372                 streamDump->close();
373             }
374 
375             return getSink()->close();
376         }
377 
378         /**
379          *  Get the password to the server.
380          *
381          *  @return the password to the server.
382          */
383         inline const char *
getPassword(void)384         getPassword ( void ) const                  throw ()
385         {
386             return password;
387         }
388 
389         /**
390          *  Get the name of the stream.
391          *
392          *  @return the name of the stream.
393          */
394         inline const char *
getName(void)395         getName ( void ) const                      throw ()
396         {
397             return name;
398         }
399 
400         /**
401          *  Get the URL associated with the stream.
402          *
403          *  @return the URL associated with the stream.
404          */
405         inline const char *
getUrl(void)406         getUrl ( void ) const                       throw ()
407         {
408             return url;
409         }
410 
411         /**
412          *  Get the genre of the stream.
413          *
414          *  @return the genre of the stream.
415          */
416         inline const char *
getGenre(void)417         getGenre ( void ) const                     throw ()
418         {
419             return genre;
420         }
421 
422         /**
423          *  Get the bitrate of the stream (e.g. mp3 bitrate).
424          *
425          *  @return the bitrate of the stream (e.g. mp3 bitrate).
426          */
427         inline unsigned int
getBitRate(void)428         getBitRate ( void ) const                   throw ()
429         {
430             return bitRate;
431         }
432 
433         /**
434          *  Get whether this stream is public.
435          *
436          *  @return true if the stream is public, false otherwise.
437          */
438         inline bool
getIsPublic(void)439         getIsPublic ( void ) const                  throw ()
440         {
441             return isPublic;
442         }
443 };
444 
445 
446 /* ================================================= external data structures */
447 
448 
449 /* ====================================================== function prototypes */
450 
451 
452 
453 #endif  /* CAST_SINK_H */
454 
455