Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/random/random_device.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.0 KB
Line 
1/* boost random_device.cpp implementation
2 *
3 * Copyright Jens Maurer 2000
4 * Distributed under the Boost Software License, Version 1.0. (See
5 * accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 * $Id: random_device.cpp,v 1.8 2004/07/27 03:43:34 dgregor Exp $
9 *
10 */
11
12#include <boost/nondet_random.hpp>
13#include <string>
14#include <cassert>
15
16
17#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
18//  A definition is required even for integral static constants
19const bool boost::random_device::has_fixed_range;
20const boost::random_device::result_type boost::random_device::min_value;
21const boost::random_device::result_type boost::random_device::max_value;
22#endif
23
24
25#ifdef __linux__
26
27// the default is the unlimited capacity device, using some secure hash
28// try "/dev/random" for blocking when the entropy pool has drained
29const char * const boost::random_device::default_token = "/dev/urandom";
30
31/*
32 * This uses the POSIX interface for unbuffered reading.
33 * Using buffered std::istream would consume entropy which may
34 * not actually be used.  Entropy is a precious good we avoid
35 * wasting.
36 */
37
38#if defined(__GNUC__) && defined(_CXXRT_STD_NAME)
39// I have severe difficulty to get the POSIX includes to work with
40// -fhonor-std and Dietmar Kühl's standard C++ library.  Hack around that
41// problem for now.
42extern "C" {
43static const int O_RDONLY = 0;
44extern int open(const char *__file, int __oflag, ...);
45extern int read(int __fd, __ptr_t __buf, size_t __nbytes);
46extern int close(int __fd);
47}
48#else
49#include <sys/types.h>
50#include <sys/stat.h>
51#include <fcntl.h>    // open
52#include <unistd.h>   // read, close
53#endif
54
55#include <errno.h>    // errno
56#include <string.h>   // strerror
57#include <stdexcept>  // std::invalid_argument
58
59
60class boost::random_device::impl
61{
62public:
63  impl(const std::string & token) : path(token) {
64    fd = open(token.c_str(), O_RDONLY);
65    if(fd < 0)
66      error("cannot open");
67  }
68
69  ~impl() { if(close(fd) < 0) error("could not close"); }
70
71  unsigned int next() {
72    unsigned int result;
73    long sz = read(fd, reinterpret_cast<char *>(&result), sizeof(result));
74    if(sz == -1)
75      error("error while reading");
76    else if(sz != sizeof(result)) {
77      errno = 0;
78      error("EOF while reading");
79    }
80    return result;
81  }
82
83private:
84  void error(const std::string & msg) {
85    throw std::invalid_argument("boost::random_device: " + msg + 
86                                " random-number pseudo-device " + path + 
87                                ": " + strerror(errno));
88  }
89  const std::string path;
90  int fd;
91};
92
93#endif // __linux__
94
95
96boost::random_device::random_device(const std::string& token)
97  : pimpl(new impl(token))
98{
99  assert((std::numeric_limits<result_type>::max)() == max_value);
100}
101
102boost::random_device::~random_device()
103{
104  // the complete class impl is now visible, so we're safe
105  // (see comment in random.hpp)
106  delete pimpl;
107}
108
109double boost::random_device::entropy() const
110{
111  return 10;
112}
113
114unsigned int boost::random_device::operator()()
115{
116  return pimpl->next();
117}
Note: See TracBrowser for help on using the repository browser.