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