00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_OLN_UTILS_BUFFER_HXX
00029 # define OLENA_OLN_UTILS_BUFFER_HXX
00030
00031
00032 inline
00033 buffer::buffer(): current_bit_(0),
00034 data_(),
00035 len1_(ntg_zero_val(value_type)),
00036 len2_(ntg_zero_val(value_type)),
00037 padding_appended_(false),
00038 length_appended_(false)
00039 {
00040 data_.reserve(length_);
00041 data_.push_back(ntg_zero_val(value_type));
00042 };
00043
00044
00045 template <class E>
00046 inline
00047 void buffer::add(const E &e, bool count)
00048 {
00049 ntg_storage_type(E) mask = 1 << (ntg_nbits(E) - 1);
00050 ntg_storage_type(E) e_cast = e;
00051
00052 while (mask)
00053 {
00054 push_back(e_cast & mask, !count);
00055 mask >>= 1;
00056 }
00057 };
00058
00059
00060 inline
00061 void buffer::push_back(bool bit, bool is_padding)
00062 {
00063 precondition(current_bit_ < 32);
00064
00065 current_bit_ += 1;
00066 data_.back() *= 2;
00067 if (bit)
00068 data_.back() += ntg_unit_val(value_type);
00069 if (current_bit_ == 32)
00070 {
00071 if (data_.size() == data_.capacity())
00072 data_.reserve(data_.capacity() + length_);
00073 current_bit_ = 0;
00074 data_.push_back(ntg_zero_val(value_type));
00075 }
00076 if (!is_padding)
00077 {
00078 if (len1_ == ntg_max_val(value_type))
00079 {
00080 if (len2_ == ntg_max_val(value_type))
00081 len2_ = ntg_unit_val(value_type);
00082 else
00083 len2_ += ntg_unit_val(value_type);
00084 }
00085 len1_ += ntg_unit_val(value_type);
00086 }
00087 }
00088
00089
00090 inline
00091 buffer::value_type buffer::reorder(value_type x) const
00092 {
00093 ntg_storage_type_(value_type) r = 0;
00094 ntg_storage_type_(value_type) mask = 0xFF;
00095
00096 for (unsigned i = 0; i < (sizeof(ntg_storage_type_(value_type))); ++i)
00097 {
00098 r <<= 8;
00099 r |= (mask & ntg_storage_type_(value_type)(x)) >> (i * 8);
00100 mask <<= 8;
00101 }
00102 return r;
00103 }
00104
00105
00106 inline
00107 ntg::int_u32 buffer::operator[] (unsigned n) const
00108 {
00109 precondition(n < data_.size());
00110
00111 return reorder(data_[n]);
00112 };
00113
00114
00115 inline
00116 void buffer::append_padding()
00117 {
00118 push_back(true, true);
00119 while (((data_.size() * 32) % 512) != 448)
00120 push_back(false, true);
00121 padding_appended_ = true;
00122 };
00123
00124
00125 inline
00126 void buffer::append_length()
00127 {
00128 precondition(padding_appended_);
00129
00130 add(reorder(len2_), false);
00131 add(reorder(len1_), false);
00132 length_appended_ = true;
00133 };
00134
00135
00136 inline
00137 unsigned buffer::size() const
00138 {
00139 return data_.size();
00140 };
00141
00142
00143 inline
00144 unsigned buffer::bit_len() const
00145 {
00146 return data_.size() * 32;
00147 }
00148
00149
00150 inline
00151 bool buffer::is_append_padding() const
00152 {
00153 return padding_appended_;
00154 }
00155
00156
00157 inline
00158 bool buffer::is_append_length() const
00159 {
00160 return length_appended_;
00161 }
00162
00163 #endif // !OLENA_OLN_UTILS_BUFFER_HXX