void TestVector(const Hasher &h, const In &in, const Out &out) { Out hash; BOOST_CHECK(out.size() == h.OUTPUT_SIZE); hash.resize(out.size()); { // Test that writing the whole input string at once works. Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]); BOOST_CHECK(hash == out); } for (int i=0; i<32; i++) { // Test that writing the string broken up in random pieces works. Hasher hasher(h); size_t pos = 0; while (pos < in.size()) { size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1); hasher.Write((unsigned char*)&in[pos], len); pos += len; if (pos > 0 && pos + 2 * out.size() > in.size()) { // Test that writing the rest at once to a copy of a hasher works. Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]); BOOST_CHECK(hash == out); } } hasher.Finalize(&hash[0]); BOOST_CHECK(hash == out); } }
inline void copy( In const& a, Out& b , HDI const& , HDO const& , cudaStream_t stream = 0) { using T = typename Out::value_type; //TODO CUDA_ERROR(cudaMemcpyAsync( (T*)b.data() , a.data() , a.size()* sizeof(T) , copy_<HDI,HDO>::mode() , stream )); }
Out iconvert(const In& in) { if (in.empty()) return Out(); const size_t bufferLen = 128; typedef typename In::value_type InElem; typedef typename Out::value_type OutElem; static iconv_t cd = iconv_open(to, from); Out result; OutElem buffer[bufferLen]; char* inbuf = const_cast<char*>(reinterpret_cast<const char*>(&in[0])); size_t inbytesleft = in.size() * sizeof(InElem); char* outbuf = reinterpret_cast<char*>(buffer); size_t outbytesleft = sizeof buffer; for (;;) { size_t ret = ::iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (ret == static_cast<size_t>(-1) && errno == EILSEQ) { // Skip illegal sequence part, repeat loop. // TODO: Or retry w/ different encoding? ++inbuf; --inbytesleft; } else if (ret == static_cast<size_t>(-1) && errno == E2BIG) { // Append new characters, reset out buffer, then repeat loop. result.insert(result.end(), buffer, buffer + bufferLen); outbuf = reinterpret_cast<char*>(buffer); outbytesleft = sizeof buffer; } else { // Append what's new in the buffer, then LEAVE loop. result.insert(result.end(), buffer, buffer + bufferLen - outbytesleft / sizeof(OutElem)); return result; } } }
/* todo: concepts... In, Out are "container-like" classes that support: ::value_type, ::size(void), ::resize(size_t), ::operator[](size_t), &::value_type (i.e. addressable ::value_type) */ Out make_copy( const In&in ) { const size_t n_ival( sizeof( typename In::value_type ) ), n_oval( sizeof( typename Out::value_type ) ); const size_t b_total( in.size() * n_ival ); const size_t size_out ( b_total / n_oval + ( ( b_total % n_oval ) ? 1 : 0 ) ); Out out; out.resize( size_out, typename Out::value_type( 0 ) ); assert ( b_total == out.size() * n_oval + ( b_total % n_oval ? 1 : 0 ) ); memcpy( &out[0], &in[0], b_total ); return out; }