Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

Util.cpp

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002 
00003    Copyright (c) 2000 Tyrell Corporation. All rights reserved.
00004 
00005    Tyrell DarkIce
00006 
00007    File     : Util.cpp
00008    Version  : $Revision: 1.13 $
00009    Author   : $Author: darkeye $
00010    Location : $Source: /cvsroot/darkice/darkice/src/Util.cpp,v $
00011    
00012    Copyright notice:
00013 
00014     This program is free software; you can redistribute it and/or
00015     modify it under the terms of the GNU General Public License  
00016     as published by the Free Software Foundation; either version 2
00017     of the License, or (at your option) any later version.
00018    
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00022     GNU General Public License for more details.
00023    
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ------------------------------------------------------------------------------*/
00029 
00030 /* ============================================================ include files */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035 
00036 #ifdef HAVE_STRING_H
00037 #include <string.h>
00038 #else
00039 #error need string.h
00040 #endif
00041 
00042 #ifdef HAVE_STDLIB_H
00043 #include <stdlib.h>
00044 #else
00045 #error need stdlib.h
00046 #endif
00047 
00048 #ifdef HAVE_LIMITS_H
00049 #include <limits.h>
00050 #else
00051 #error need limits.h
00052 #endif
00053 
00054 #ifdef HAVE_MATH_H
00055 #include <math.h>
00056 #else
00057 #error need math.h
00058 #endif
00059 
00060 #ifdef HAVE_TIME_H
00061 #include <time.h>
00062 #else
00063 #error need time.h
00064 #endif
00065 
00066 
00067 #include "Util.h"
00068 
00069 
00070 /* ===================================================  local data structures */
00071 
00072 
00073 /* ================================================  local constants & macros */
00074 
00075 /*------------------------------------------------------------------------------
00076  *  File identity
00077  *----------------------------------------------------------------------------*/
00078 static const char fileid[] = "$Id: Util.cpp,v 1.13 2004/02/15 12:06:30 darkeye Exp $";
00079 
00080 
00081 /* ===============================================  local function prototypes */
00082 
00083 
00084 /* =============================================================  module code */
00085 
00086 char
00087 Util :: base64Table[] = {
00088     'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
00089     'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
00090     'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
00091     'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
00092 };
00093 
00094 
00095 /*------------------------------------------------------------------------------
00096  *  Calculate the length of a zero-terminated C string,
00097  *  w/o the zero-termination
00098  *----------------------------------------------------------------------------*/
00099 unsigned int
00100 Util :: strLen( const char    * str )                   throw ( Exception )
00101 {
00102     size_t      len;
00103 
00104     if ( !str ) {
00105         throw Exception( __FILE__, __LINE__, "no str");
00106     }
00107 
00108     len = strlen( str);
00109 
00110     return len;
00111 }
00112 
00113 
00114 /*------------------------------------------------------------------------------
00115  *  Copy the contents of a string into another
00116  *----------------------------------------------------------------------------*/
00117 void
00118 Util :: strCpy (    char          * dest,
00119                     const char    * src )               throw ( Exception )
00120 {
00121     if ( !dest || !src ) {
00122         throw Exception( __FILE__, __LINE__, "no src or dest");
00123     }
00124 
00125     strcpy( dest, src);
00126 }
00127 
00128 
00129 /*------------------------------------------------------------------------------
00130  *  Concatenate the contents of a string onto another
00131  *----------------------------------------------------------------------------*/
00132 void
00133 Util :: strCat (    char          * dest,
00134                     const char    * src )               throw ( Exception )
00135 {
00136     if ( !dest || !src ) {
00137         throw Exception( __FILE__, __LINE__, "no src or dest");
00138     }
00139 
00140     strcat( dest, src);
00141 }
00142 
00143 
00144 /*------------------------------------------------------------------------------
00145  *  Duplicate a string by allocating space with new[]
00146  *  The returned string must be freed with delete[]
00147  *----------------------------------------------------------------------------*/
00148 char *
00149 Util :: strDup( const char    * str )                   throw ( Exception )
00150 {
00151     size_t      len;
00152     char      * s;
00153 
00154     if ( !str ) {
00155         throw Exception( __FILE__, __LINE__, "no str");
00156     }
00157 
00158     len = strlen( str) + 1;
00159     s   = new char[len];
00160     memcpy( s, str, len);
00161 
00162     return s;
00163 }
00164 
00165 
00166 /*------------------------------------------------------------------------------
00167  *  Convert a string into base64 encoding.
00168  *----------------------------------------------------------------------------*/
00169 char *
00170 Util :: base64Encode( const char  * str )               throw ( Exception )
00171 {
00172     if ( !str ) {
00173         throw Exception( __FILE__, __LINE__, "no str");
00174     }
00175 
00176     const char    * data    = str;
00177     size_t          len     = strlen( data);
00178     char          * out     = new char[len * 4 / 3 + 4];
00179     char          * result  = out;
00180     unsigned        chunk;
00181 
00182     while ( len > 0 ) {
00183         chunk = (len > 3) ? 3 : len;
00184         *out++ = base64Table[(*data & 0xfc) >> 2];
00185         *out++ = base64Table[((*data & 0x03) << 4) | ((*(data+1) & 0xf0) >> 4)];
00186         switch ( chunk ) {
00187             case 3:
00188                 *out++ = base64Table[((*(data+1) & 0x0f) << 2) |
00189                                      ((*(data+2) & 0xc0) >> 6)];
00190                 *out++ = base64Table[(*(data+2)) & 0x3f];
00191                 break;
00192             case 2:
00193                 *out++ = base64Table[((*(data+1) & 0x0f) << 2)];
00194                 *out++ = '=';
00195                 break;
00196             case 1:
00197                 *out++ = '=';
00198                 *out++ = '=';
00199                 break;
00200         }
00201         data += chunk;
00202         len  -= chunk;
00203     }
00204     *out = 0;
00205 
00206     return result;
00207 }
00208 
00209 
00210 /*------------------------------------------------------------------------------
00211  *  Check wether two strings are equal
00212  *----------------------------------------------------------------------------*/
00213 bool
00214 Util :: strEq( const char    * str1,
00215                const char    * str2,
00216                unsigned int    len )                    throw ( Exception )
00217 {
00218     if ( !str1 || !str2 ) {
00219         throw Exception( __FILE__, __LINE__, "no str1 or no str2");
00220     }
00221 
00222     return len == 0 ? !strcmp( str1, str2) : !strncmp( str1, str2, len);
00223 }
00224 
00225 
00226 /*------------------------------------------------------------------------------
00227  *  Convert a string to a long integer
00228  *----------------------------------------------------------------------------*/
00229 long int
00230 Util :: strToL( const char    * str,
00231                 int             base )                  throw ( Exception )
00232 {
00233     long int    val;
00234     char      * s;
00235 
00236     if ( !str ) {
00237         throw Exception( __FILE__, __LINE__, "no str");
00238     }
00239 
00240     val = strtol( str, &s, base);
00241     if ( s == str || val == LONG_MIN || val == LONG_MAX ) {
00242         throw Exception( __FILE__, __LINE__, "number conversion error");
00243     }
00244 
00245     return val;
00246 }
00247 
00248 
00249 /*------------------------------------------------------------------------------
00250  *  Convert a string to a double
00251  *----------------------------------------------------------------------------*/
00252 double
00253 Util :: strToD( const char    * str )                   throw ( Exception )
00254 {
00255     double      val;
00256     char      * s;
00257 
00258     if ( !str ) {
00259         throw Exception( __FILE__, __LINE__, "no str");
00260     }
00261 
00262     val = strtod( str, &s);
00263     if ( s == str || val == HUGE_VAL ) {
00264         throw Exception( __FILE__, __LINE__, "number conversion error");
00265     }
00266 
00267     return val;
00268 }
00269 
00270 /*------------------------------------------------------------------------------
00271  *  add current date to a file name, before the file extension (if any)
00272  *----------------------------------------------------------------------------*/
00273 char * 
00274 Util :: fileAddDate ( const char * str )                    throw ( Exception )
00275 {
00276     unsigned int    size;
00277     char          * s;
00278     char          * strdate;
00279     char          * last;
00280     time_t          now;
00281     
00282     if ( !str ) {
00283         throw Exception( __FILE__, __LINE__, "no str");
00284     }
00285 
00286     strdate = new char[128];
00287     now     = time(NULL);    
00288     strftime( strdate, 128, "[%m-%d-%Y-%H-%M-%S]", localtime (&now));
00289 
00290     // search for the part before the extension of the file name
00291     if ( !(last = strrchr( str, '.')) ) {
00292         last = (char *) str + strlen( str);
00293     }
00294 
00295     size = strlen( str) + strlen( strdate) + 1;
00296     s    = new char [size];
00297 
00298     memcpy( s, str, strlen (str)-strlen(last));
00299     memcpy( s + strlen(str) -  strlen(last), strdate, strlen (strdate));
00300     memcpy( s + strlen(str) -  strlen(last) + strlen(strdate),
00301             last,
00302             strlen(last));
00303     s[size-1] = '\0';
00304 
00305     delete[] strdate;   
00306     return s;
00307 }
00308 
00309 /*------------------------------------------------------------------------------
00310  *  Convert an unsigned char buffer holding 8 or 16 bit PCM values with
00311  *  channels interleaved to a short int buffer, still with channels interleaved
00312  *----------------------------------------------------------------------------*/
00313 void
00314 Util :: conv (  unsigned int        bitsPerSample,
00315                 unsigned char     * pcmBuffer,
00316                 unsigned int        lenPcmBuffer,
00317                 short int         * outBuffer,
00318                 bool                isBigEndian )           throw ( Exception )
00319 {
00320     if ( bitsPerSample == 8 ) {
00321         unsigned int    i, j;
00322 
00323         for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00324             outBuffer[j] = pcmBuffer[i++];
00325             ++j;
00326         }
00327     } else if ( bitsPerSample == 16 ) {
00328 
00329         if ( isBigEndian ) {
00330             unsigned int    i, j;
00331 
00332             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00333                 short int       value;
00334 
00335                 value         = pcmBuffer[i++] << 8;
00336                 value        |= pcmBuffer[i++];
00337                 outBuffer[j]  = value;
00338                 ++j;
00339             }
00340         } else {
00341             unsigned int    i, j;
00342 
00343             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00344                 short int       value;
00345 
00346                 value         = pcmBuffer[i++];
00347                 value        |= pcmBuffer[i++] << 8;
00348                 outBuffer[j]  = value;
00349                 ++j;
00350             }
00351         }
00352     } else {
00353         throw Exception( __FILE__, __LINE__,
00354                          "this number of bits per sample not supported",
00355                          bitsPerSample);
00356     }
00357 }
00358 
00359 
00360 /*------------------------------------------------------------------------------
00361  *  Convert a short buffer holding PCM values with channels interleaved
00362  *  to one or more float buffers, one for each channel
00363  *----------------------------------------------------------------------------*/
00364 void
00365 Util :: conv (  short int         * shortBuffer,
00366                 unsigned int        lenShortBuffer,
00367                 float            ** floatBuffers,
00368                 unsigned int        channels )              throw ( Exception )
00369 {
00370     unsigned int    i, j;
00371 
00372     for ( i = 0, j = 0; i < lenShortBuffer; ) {
00373         for ( unsigned int c = 0; c < channels; ++c ) {
00374             floatBuffers[c][j] = ((float) shortBuffer[i++]) / 32768.f;
00375         }
00376         ++j;
00377     }
00378 }
00379 
00380 
00381 /*------------------------------------------------------------------------------
00382  *  Convert an unsigned char buffer holding 8 bit PCM values with channels
00383  *  interleaved to two short int buffers (one for each channel)
00384  *----------------------------------------------------------------------------*/
00385 void
00386 Util :: conv8 (     unsigned char     * pcmBuffer,
00387                     unsigned int        lenPcmBuffer,
00388                     short int         * leftBuffer,
00389                     short int         * rightBuffer,
00390                     unsigned int        channels )          throw ( Exception )
00391 {
00392     if ( channels == 1 ) {
00393         unsigned int    i, j;
00394 
00395         for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00396             unsigned short int  value;
00397 
00398             value         = pcmBuffer[i++];
00399             leftBuffer[j] = (short int) value;
00400             ++j;
00401         }
00402     } else if ( channels == 2 ) {
00403         unsigned int    i, j;
00404 
00405         for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00406             unsigned short int  value;
00407 
00408             value          = pcmBuffer[i++];
00409             leftBuffer[j]  = (short int) value;
00410             value          = pcmBuffer[i++];
00411             rightBuffer[j] = (short int) value;
00412             ++j;
00413         }
00414     } else {
00415         throw Exception( __FILE__, __LINE__,
00416                          "this number of channels not supported", channels);
00417     }
00418 }
00419 
00420 
00421 /*------------------------------------------------------------------------------
00422  *  Convert an unsigned char buffer holding 16 bit PCM values with channels
00423  *  interleaved to two short int buffers (one for each channel)
00424  *----------------------------------------------------------------------------*/
00425 void
00426 Util :: conv16 (    unsigned char     * pcmBuffer,
00427                     unsigned int        lenPcmBuffer,
00428                     short int         * leftBuffer,
00429                     short int         * rightBuffer,
00430                     unsigned int        channels,
00431                     bool                isBigEndian )       throw ( Exception )
00432 {
00433     if ( isBigEndian ) {
00434         if ( channels == 1 ) {
00435             unsigned int    i, j;
00436 
00437             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00438                 unsigned short int   value;
00439 
00440                 value           = pcmBuffer[i++] << 8;
00441                 value          |= pcmBuffer[i++];
00442                 leftBuffer[j]  = (short int) value;
00443                 ++j;
00444             }
00445         } else {
00446             unsigned int    i, j;
00447 
00448             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00449                 unsigned short int   value;
00450 
00451                 value           = pcmBuffer[i++] << 8;
00452                 value          |= pcmBuffer[i++];
00453                 leftBuffer[j]   = (short int) value;
00454                 value           = pcmBuffer[i++] << 8;
00455                 value          |= pcmBuffer[i++];
00456                 rightBuffer[j]  = (short int) value;
00457                 ++j;
00458             }
00459         }
00460     } else {
00461         if ( channels == 1 ) {
00462             unsigned int    i, j;
00463 
00464             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00465                 unsigned short int   value;
00466 
00467                 value          = pcmBuffer[i++];
00468                 value         |= pcmBuffer[i++] << 8;
00469                 leftBuffer[j]  = (short int) value;
00470                 ++j;
00471             }
00472         } else {
00473             unsigned int    i, j;
00474 
00475             for ( i = 0, j = 0; i < lenPcmBuffer; ) {
00476                 unsigned short int   value;
00477 
00478                 value           = pcmBuffer[i++];
00479                 value          |= pcmBuffer[i++] << 8;
00480                 leftBuffer[j]   = (short int) value;
00481                 value           = pcmBuffer[i++];
00482                 value          |= pcmBuffer[i++] << 8;
00483                 rightBuffer[j]  = (short int) value;
00484                 ++j;
00485             }
00486         }
00487     }
00488 }
00489 
00490 
00491 
00492 /*------------------------------------------------------------------------------
00493  
00494   $Source: /cvsroot/darkice/darkice/src/Util.cpp,v $
00495 
00496   $Log: Util.cpp,v $
00497   Revision 1.13  2004/02/15 12:06:30  darkeye
00498   added ALSA support, thanks to Christian Forster
00499 
00500   Revision 1.12  2003/02/09 12:57:36  darkeye
00501   cosmetic changes to the fileAddDate option
00502 
00503   Revision 1.11  2002/12/22 01:20:32  darkeye
00504   time.h include file was missing
00505 
00506   Revision 1.10  2002/11/20 16:52:07  wandereq
00507   added fileAddDate function
00508 
00509   Revision 1.9  2002/08/20 18:39:14  darkeye
00510   added HTTP Basic authentication for icecast2 logins
00511 
00512   Revision 1.8  2002/07/21 08:47:06  darkeye
00513   some exception cleanup (throw clauses in function declarations)
00514 
00515   Revision 1.7  2002/03/28 16:45:46  darkeye
00516   added functions strToD(), conv8(), conv16() and conv()
00517 
00518   Revision 1.6  2001/08/30 17:25:56  darkeye
00519   renamed configure.h to config.h
00520 
00521   Revision 1.5  2000/11/12 13:31:40  darkeye
00522   added kdoc-style documentation comments
00523 
00524   Revision 1.4  2000/11/09 22:04:33  darkeye
00525   added functions strLen strCpy and strCat
00526 
00527   Revision 1.3  2000/11/09 06:44:21  darkeye
00528   added strEq and strToL functions
00529 
00530   Revision 1.2  2000/11/05 14:08:28  darkeye
00531   changed builting to an automake / autoconf environment
00532 
00533   Revision 1.1.1.1  2000/11/05 10:05:55  darkeye
00534   initial version
00535 
00536   
00537 ------------------------------------------------------------------------------*/
00538 

Generated on Fri May 19 15:36:48 2006 for DarkIce by  doxygen 1.4.4