rng.h

00001 
00002 /* Copyright (c) 2007-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #ifndef EQBASE_RNG_H
00019 #define EQBASE_RNG_H
00020 
00021 #include <eq/base/debug.h> // for EQASSERT
00022 #include <eq/base/nonCopyable.h>
00023 
00024 #include <fcntl.h>
00025 
00026 namespace eq
00027 {
00028 namespace base
00029 {
00036     class RNG : public NonCopyable
00037     {
00038     public:
00040         RNG()
00041         {
00042 #ifdef Linux
00043             _fd = ::open( "/dev/urandom", O_RDONLY );
00044             EQASSERT( _fd != -1 );
00045 #endif
00046             reseed();
00047         }
00048 
00050         ~RNG()
00051         {
00052 #ifdef Linux
00053             if( _fd > 0 )
00054                 close( _fd );
00055 #endif
00056         }
00057 
00059         void reseed()
00060         {
00061 #ifdef Linux
00062             // NOP
00063 #elif defined (WIN32)
00064             LARGE_INTEGER seed;
00065             QueryPerformanceCounter( &seed );
00066             srand( seed.LowPart );
00067 #else // Darwin
00068             srandomdev();
00069 #endif
00070         }
00071 
00073         template< typename T >
00074         T get()
00075         {
00076             T              value;
00077 #ifdef Linux
00078             int read = ::read( _fd, &value, sizeof( T ));
00079             EQASSERT( read == sizeof( T ));
00080             if( read != sizeof( T ))
00081             {
00082                 EQERROR << "random number generator not working" << std::endl;
00083                 return 0;
00084             }
00085 
00086 #elif defined (WIN32)
00087 
00088             EQASSERTINFO( RAND_MAX >= 32767, RAND_MAX );
00089 
00090             uint8_t* bytes = reinterpret_cast< uint8_t* >( &value );
00091             for( size_t i=0; i<sizeof( T ); ++i )
00092                 bytes[i] = ( rand() & 255 );
00093 #else // Darwin
00094             uint8_t* bytes = reinterpret_cast< uint8_t* >( &value );
00095             for( size_t i=0; i<sizeof( T ); ++i )
00096                 bytes[i] = ( random() & 255 );
00097 #endif
00098             return value;
00099         }
00100 
00101     private:
00102 #ifdef Linux
00103         int _fd;
00104 #endif
00105     };
00106 }
00107 }
00108 #endif  // EQBASE_RNG_H
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8