/Src/Dependencies/Boost/boost/archive/iterators/transform_width.hpp

http://hadesmem.googlecode.com/ · C++ Header · 170 lines · 118 code · 22 blank · 30 comment · 11 complexity · 938012e31da627ba32264a55ce70badf MD5 · raw file

  1. #ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
  2. #define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  8. // transform_width.hpp
  9. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  10. // Use, modification and distribution is subject to the Boost Software
  11. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. // See http://www.boost.org for updates, documentation, and revision history.
  14. // iterator which takes elements of x bits and returns elements of y bits.
  15. // used to change streams of 8 bit characters into streams of 6 bit characters.
  16. // and vice-versa for implementing base64 encodeing/decoding. Be very careful
  17. // when using and end iterator. end is only reliable detected when the input
  18. // stream length is some common multiple of x and y. E.G. Base64 6 bit
  19. // character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
  20. // or 3 8 bit characters
  21. #include <algorithm>
  22. #include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
  23. #include <boost/serialization/pfto.hpp>
  24. #include <boost/iterator/iterator_adaptor.hpp>
  25. #include <boost/iterator/iterator_traits.hpp>
  26. namespace boost {
  27. namespace archive {
  28. namespace iterators {
  29. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  30. // class used by text archives to translate char strings to wchar_t
  31. // strings of the currently selected locale
  32. template<
  33. class Base,
  34. int BitsOut,
  35. int BitsIn,
  36. class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type // output character
  37. >
  38. class transform_width :
  39. public boost::iterator_adaptor<
  40. transform_width<Base, BitsOut, BitsIn, CharType>,
  41. Base,
  42. CharType,
  43. single_pass_traversal_tag,
  44. CharType
  45. >
  46. {
  47. friend class boost::iterator_core_access;
  48. typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
  49. transform_width<Base, BitsOut, BitsIn, CharType>,
  50. Base,
  51. CharType,
  52. single_pass_traversal_tag,
  53. CharType
  54. > super_t;
  55. typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
  56. typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;
  57. CharType fill();
  58. CharType dereference_impl(){
  59. if(! m_full){
  60. m_current_value = fill();
  61. m_full = true;
  62. }
  63. return m_current_value;
  64. }
  65. CharType dereference() const {
  66. return const_cast<this_t *>(this)->dereference_impl();
  67. }
  68. // test for iterator equality
  69. bool equal(const this_t & rhs) const {
  70. return
  71. this->base_reference() == rhs.base_reference();
  72. ;
  73. }
  74. void increment(){
  75. m_displacement += BitsOut;
  76. while(m_displacement >= BitsIn){
  77. m_displacement -= BitsIn;
  78. if(0 == m_displacement)
  79. m_bufferfull = false;
  80. if(! m_bufferfull){
  81. // note: suspect that this is not invoked for borland
  82. ++(this->base_reference());
  83. }
  84. }
  85. m_full = false;
  86. }
  87. CharType m_current_value;
  88. // number of bits left in current input character buffer
  89. unsigned int m_displacement;
  90. base_value_type m_buffer;
  91. // flag to current output character is ready - just used to save time
  92. bool m_full;
  93. // flag to indicate that m_buffer has data
  94. bool m_bufferfull;
  95. public:
  96. // make composible buy using templated constructor
  97. template<class T>
  98. transform_width(BOOST_PFTO_WRAPPER(T) start) :
  99. super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
  100. m_displacement(0),
  101. m_full(false),
  102. m_bufferfull(false)
  103. {}
  104. // intel 7.1 doesn't like default copy constructor
  105. transform_width(const transform_width & rhs) :
  106. super_t(rhs.base_reference()),
  107. m_current_value(rhs.m_current_value),
  108. m_displacement(rhs.m_displacement),
  109. m_buffer(rhs.m_buffer),
  110. m_full(rhs.m_full),
  111. m_bufferfull(rhs.m_bufferfull)
  112. {}
  113. };
  114. template<class Base, int BitsOut, int BitsIn, class CharType>
  115. CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
  116. CharType retval = 0;
  117. unsigned int missing_bits = BitsOut;
  118. for(;;){
  119. unsigned int bcount;
  120. if(! m_bufferfull){
  121. m_buffer = * this->base_reference();
  122. m_bufferfull = true;
  123. bcount = BitsIn;
  124. }
  125. else
  126. bcount = BitsIn - m_displacement;
  127. unsigned int i = (std::min)(bcount, missing_bits);
  128. // shift interesting bits to least significant position
  129. unsigned int j = m_buffer >> (bcount - i);
  130. // strip off uninteresting bits
  131. // (note presumption of two's complement arithmetic)
  132. j &= ~(-(1 << i));
  133. // append then interesting bits to the output value
  134. retval <<= i;
  135. retval |= j;
  136. missing_bits -= i;
  137. if(0 == missing_bits)
  138. break;
  139. // note: suspect that this is not invoked for borland 5.51
  140. ++(this->base_reference());
  141. m_bufferfull = false;
  142. }
  143. return retval;
  144. }
  145. } // namespace iterators
  146. } // namespace archive
  147. } // namespace boost
  148. #endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP