1
//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
3
//Distributed under the Boost Software License, Version 1.0. (See accompanying
4
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
//This program simulates errors on copying simple data files. It demonstrates
7
//typical Boost Exception usage.
9
//The output from this program can vary depending on the platform.
11
#include <boost/throw_exception.hpp>
12
#include <boost/exception/info.hpp>
13
#include <boost/exception/get_error_info.hpp>
14
#include <boost/exception/diagnostic_information.hpp>
15
#include <boost/exception/errinfo_file_open_mode.hpp>
16
#include <boost/exception/errinfo_file_handle.hpp>
17
#include <boost/exception/errinfo_file_name.hpp>
18
#include <boost/exception/errinfo_api_function.hpp>
19
#include <boost/exception/errinfo_errno.hpp>
20
#include <boost/shared_ptr.hpp>
21
#include <boost/weak_ptr.hpp>
24
typedef boost::error_info<struct tag_file_name_src,std::string> errinfo_src_file_name;
25
typedef boost::error_info<struct tag_file_name_dst,std::string> errinfo_dst_file_name;
27
char const data[] = "example";
28
size_t const data_size = sizeof(data);
31
error: //Base for all exception objects we throw.
32
public virtual std::exception,
33
public virtual boost::exception
40
return "example_io error";
50
struct open_error: virtual error { };
51
struct read_error: virtual error { };
52
struct write_error: virtual error { };
53
struct fopen_error: virtual open_error { };
54
struct fread_error: virtual read_error { };
55
struct fwrite_error: virtual write_error { };
57
boost::shared_ptr<FILE>
58
my_fopen( char const * name, char const * mode )
60
if( FILE * f = ::fopen(name,mode) )
61
return boost::shared_ptr<FILE>(f,fclose);
63
BOOST_THROW_EXCEPTION(fopen_error() <<
64
boost::errinfo_errno (errno) <<
65
boost::errinfo_file_name(name) <<
66
boost::errinfo_file_open_mode(mode) <<
67
boost::errinfo_api_function("fopen"));
71
my_fread( void * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream )
74
if( count!=fread(buffer,size,count,stream.get()) || ferror(stream.get()) )
75
BOOST_THROW_EXCEPTION(fread_error() <<
76
boost::errinfo_api_function("fread") <<
77
boost::errinfo_errno(errno) <<
78
boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream)));
82
my_fwrite( void const * buffer, size_t size, size_t count, boost::shared_ptr<FILE> const & stream )
85
if( count!=fwrite(buffer,size,count,stream.get()) || ferror(stream.get()) )
86
BOOST_THROW_EXCEPTION(fwrite_error() <<
87
boost::errinfo_api_function("fwrite") <<
88
boost::errinfo_errno(errno) <<
89
boost::errinfo_file_handle(boost::weak_ptr<FILE>(stream)));
93
reset_file( char const * file_name )
95
(void) my_fopen(file_name,"wb");
99
create_data( char const * file_name )
101
boost::shared_ptr<FILE> f = my_fopen(file_name,"wb");
102
my_fwrite( data, 1, data_size, f );
106
copy_data( char const * src_file_name, char const * dst_file_name )
108
boost::shared_ptr<FILE> src = my_fopen(src_file_name,"rb");
109
boost::shared_ptr<FILE> dst = my_fopen(dst_file_name,"wb");
112
char buffer[data_size];
113
my_fread( buffer, 1, data_size, src );
114
my_fwrite( buffer, 1, data_size, dst );
117
boost::exception & x )
119
if( boost::weak_ptr<FILE> const * f=boost::get_error_info<boost::errinfo_file_handle>(x) )
120
if( boost::shared_ptr<FILE> fs = f->lock() )
123
x << boost::errinfo_file_name(src_file_name);
125
x << boost::errinfo_file_name(dst_file_name);
128
errinfo_src_file_name(src_file_name) <<
129
errinfo_dst_file_name(dst_file_name);
135
dump_copy_info( boost::exception const & x )
137
if( std::string const * src = boost::get_error_info<errinfo_src_file_name>(x) )
138
std::cerr << "Source file name: " << *src << "\n";
139
if( std::string const * dst = boost::get_error_info<errinfo_dst_file_name>(x) )
140
std::cerr << "Destination file name: " << *dst << "\n";
144
dump_file_info( boost::exception const & x )
146
if( std::string const * fn = boost::get_error_info<boost::errinfo_file_name>(x) )
147
std::cerr << "File name: " << *fn << "\n";
151
dump_clib_info( boost::exception const & x )
153
if( int const * err=boost::get_error_info<boost::errinfo_errno>(x) )
154
std::cerr << "OS error: " << *err << "\n";
155
if( char const * const * fn=boost::get_error_info<boost::errinfo_api_function>(x) )
156
std::cerr << "Failed function: " << *fn << "\n";
160
dump_all_info( boost::exception const & x )
162
std::cerr << "-------------------------------------------------\n";
166
std::cerr << "\nOutput from diagnostic_information():\n";
167
std::cerr << diagnostic_information(x);
175
create_data( "tmp1.txt" );
176
copy_data( "tmp1.txt", "tmp2.txt" ); //This should succeed.
178
reset_file( "tmp1.txt" ); //Creates empty file.
181
copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt is empty.
186
std::cerr << "\nCaught 'read_error' exception.\n";
190
remove( "tmp1.txt" );
191
remove( "tmp2.txt" );
194
copy_data( "tmp1.txt", "tmp2.txt" ); //This should fail, tmp1.txt does not exist.
199
std::cerr << "\nCaught 'open_error' exception.\n";
206
std::cerr << "\nCaught unexpected exception!\n";
207
std::cerr << boost::current_exception_diagnostic_information();