Chris@16
|
1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
Chris@16
|
2 // basic_text_iprimitive.ipp:
|
Chris@16
|
3
|
Chris@16
|
4 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 // See http://www.boost.org for updates, documentation, and revision history.
|
Chris@16
|
10
|
Chris@16
|
11 #include <cstddef> // size_t
|
Chris@16
|
12 #include <cstddef> // NULL
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/config.hpp>
|
Chris@16
|
15 #if defined(BOOST_NO_STDC_NAMESPACE)
|
Chris@16
|
16 namespace std{
|
Chris@16
|
17 using ::size_t;
|
Chris@16
|
18 } // namespace std
|
Chris@16
|
19 #endif
|
Chris@16
|
20
|
Chris@16
|
21 #include <boost/serialization/throw_exception.hpp>
|
Chris@16
|
22 #include <boost/serialization/pfto.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/archive/basic_text_iprimitive.hpp>
|
Chris@16
|
25 #include <boost/archive/codecvt_null.hpp>
|
Chris@16
|
26 #include <boost/archive/add_facet.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 #include <boost/archive/iterators/remove_whitespace.hpp>
|
Chris@16
|
29 #include <boost/archive/iterators/istream_iterator.hpp>
|
Chris@16
|
30 #include <boost/archive/iterators/binary_from_base64.hpp>
|
Chris@16
|
31 #include <boost/archive/iterators/transform_width.hpp>
|
Chris@16
|
32
|
Chris@101
|
33 namespace boost {
|
Chris@16
|
34 namespace archive {
|
Chris@16
|
35
|
Chris@101
|
36 namespace detail {
|
Chris@16
|
37 template<class CharType>
|
Chris@101
|
38 static inline bool is_whitespace(CharType c);
|
Chris@16
|
39
|
Chris@16
|
40 template<>
|
Chris@101
|
41 inline bool is_whitespace(char t){
|
Chris@16
|
42 return 0 != std::isspace(t);
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 #ifndef BOOST_NO_CWCHAR
|
Chris@16
|
46 template<>
|
Chris@101
|
47 inline bool is_whitespace(wchar_t t){
|
Chris@16
|
48 return 0 != std::iswspace(t);
|
Chris@16
|
49 }
|
Chris@16
|
50 #endif
|
Chris@101
|
51 } // detail
|
Chris@16
|
52
|
Chris@16
|
53 // translate base64 text into binary and copy into buffer
|
Chris@16
|
54 // until buffer is full.
|
Chris@16
|
55 template<class IStream>
|
Chris@16
|
56 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
57 basic_text_iprimitive<IStream>::load_binary(
|
Chris@16
|
58 void *address,
|
Chris@16
|
59 std::size_t count
|
Chris@16
|
60 ){
|
Chris@101
|
61 typedef typename IStream::char_type CharType;
|
Chris@16
|
62
|
Chris@16
|
63 if(0 == count)
|
Chris@16
|
64 return;
|
Chris@16
|
65
|
Chris@16
|
66 BOOST_ASSERT(
|
Chris@16
|
67 static_cast<std::size_t>((std::numeric_limits<std::streamsize>::max)())
|
Chris@16
|
68 > (count + sizeof(CharType) - 1)/sizeof(CharType)
|
Chris@16
|
69 );
|
Chris@16
|
70
|
Chris@16
|
71 if(is.fail())
|
Chris@16
|
72 boost::serialization::throw_exception(
|
Chris@16
|
73 archive_exception(archive_exception::input_stream_error)
|
Chris@16
|
74 );
|
Chris@16
|
75 // convert from base64 to binary
|
Chris@101
|
76 typedef typename
|
Chris@16
|
77 iterators::transform_width<
|
Chris@16
|
78 iterators::binary_from_base64<
|
Chris@16
|
79 iterators::remove_whitespace<
|
Chris@16
|
80 iterators::istream_iterator<CharType>
|
Chris@16
|
81 >
|
Chris@16
|
82 ,CharType
|
Chris@16
|
83 >
|
Chris@16
|
84 ,8
|
Chris@16
|
85 ,6
|
Chris@16
|
86 ,CharType
|
Chris@16
|
87 >
|
Chris@16
|
88 binary;
|
Chris@16
|
89
|
Chris@16
|
90 binary i = binary(
|
Chris@16
|
91 BOOST_MAKE_PFTO_WRAPPER(
|
Chris@16
|
92 iterators::istream_iterator<CharType>(is)
|
Chris@16
|
93 )
|
Chris@16
|
94 );
|
Chris@16
|
95
|
Chris@16
|
96 char * caddr = static_cast<char *>(address);
|
Chris@16
|
97
|
Chris@16
|
98 // take care that we don't increment anymore than necessary
|
Chris@16
|
99 while(count-- > 0){
|
Chris@16
|
100 *caddr++ = static_cast<char>(*i++);
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 // skip over any excess input
|
Chris@16
|
104 for(;;){
|
Chris@101
|
105 typename IStream::int_type r;
|
Chris@16
|
106 r = is.get();
|
Chris@16
|
107 if(is.eof())
|
Chris@16
|
108 break;
|
Chris@101
|
109 if(detail::is_whitespace(static_cast<CharType>(r)))
|
Chris@16
|
110 break;
|
Chris@16
|
111 }
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 template<class IStream>
|
Chris@16
|
115 BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
Chris@16
|
116 basic_text_iprimitive<IStream>::basic_text_iprimitive(
|
Chris@16
|
117 IStream &is_,
|
Chris@16
|
118 bool no_codecvt
|
Chris@16
|
119 ) :
|
Chris@16
|
120 #ifndef BOOST_NO_STD_LOCALE
|
Chris@16
|
121 is(is_),
|
Chris@16
|
122 flags_saver(is_),
|
Chris@16
|
123 precision_saver(is_),
|
Chris@16
|
124 locale_saver(* is_.rdbuf())
|
Chris@16
|
125 {
|
Chris@16
|
126 if(! no_codecvt){
|
Chris@16
|
127 archive_locale.reset(
|
Chris@16
|
128 add_facet(
|
Chris@101
|
129 std::locale::classic(),
|
Chris@101
|
130 new boost::archive::codecvt_null<typename IStream::char_type>
|
Chris@16
|
131 )
|
Chris@16
|
132 );
|
Chris@101
|
133 //is.imbue(* archive_locale);
|
Chris@16
|
134 }
|
Chris@16
|
135 is >> std::noboolalpha;
|
Chris@16
|
136 }
|
Chris@16
|
137 #else
|
Chris@16
|
138 is(is_),
|
Chris@16
|
139 flags_saver(is_),
|
Chris@16
|
140 precision_saver(is_)
|
Chris@16
|
141 {}
|
Chris@16
|
142 #endif
|
Chris@16
|
143
|
Chris@16
|
144 template<class IStream>
|
Chris@16
|
145 BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
Chris@16
|
146 basic_text_iprimitive<IStream>::~basic_text_iprimitive(){
|
Chris@16
|
147 is.sync();
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 } // namespace archive
|
Chris@16
|
151 } // namespace boost
|