1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: chunk_collector.h,v 1.1 2008/08/25 16:20:04 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_CHUNK_COLLECTOR_H
22 #define SEQAN_HEADER_CHUNK_COLLECTOR_H
25 namespace SEQAN_NAMESPACE_MAIN
27 //////////////////////////////////////////////////////////////////////////////
30 .Internal._ChunkCollector:
32 ..summary:Reads piecewise from stream, collects pieces (chunks) in a vector.
33 ..signature:_ChunkCollector<Host>
34 ..param.Host:Type of host object that is used as allocator.
37 //////////////////////////////////////////////////////////////////////////////
42 enum { VALUE = 1024 };
45 //////////////////////////////////////////////////////////////////////////////
46 // _StreamChunkCollector class: collects content of a stream in chunks
47 //////////////////////////////////////////////////////////////////////////////
49 template <typename THost>
54 typename Size<THost>::Type data_length;
56 typedef ::std::vector<typename Value<THost>::Type *, ToStdAllocator<THost, typename Value<THost>::Type *> > Chunk_Holder;
57 Chunk_Holder data_chunks;
60 static int const CHUNK_LENGTH = ChunkLength<_ChunkCollector>::VALUE;
63 _ChunkCollector(THost & _host):
66 data_chunks(typename Chunk_Holder::allocator_type(_host))
78 clear(_ChunkCollector & me)
80 typename Chunk_Holder::iterator it = me.data_chunks.begin();
81 typename Chunk_Holder::iterator it_end = me.data_chunks.end();
83 for (; it != it_end; ++it)
85 deallocate(me.data_host, *it, CHUNK_LENGTH);
88 me.data_chunks.clear();
92 friend inline typename Size<THost>::Type
93 length(_ChunkCollector const & me)
95 return me.data_length;
99 _setLength(_ChunkCollector & me, typename Size<THost>::Type new_length)
101 me.data_length = new_length;
105 chunkCount(_ChunkCollector const & me)
107 return me.data_chunks.size();
110 friend inline typename Value<THost>::Type *
111 getChunk(_ChunkCollector const & me, int chunk_number)
113 return me.data_chunks[chunk_number];
116 friend inline typename Value<THost>::Type *
117 createChunk(_ChunkCollector & me)
119 typename Value<THost>::Type * new_chunk;
120 allocate(me.data_host, new_chunk, CHUNK_LENGTH);
121 me.data_chunks.push_back(new_chunk);
127 //////////////////////////////////////////////////////////////////////////////
129 template <typename THost>
130 struct Host<_ChunkCollector<THost> >
135 template <typename THost>
136 struct Host<_ChunkCollector<THost> const >
141 //////////////////////////////////////////////////////////////////////////////
143 template <typename THost>
144 struct Value<_ChunkCollector<THost> >
146 typedef typename Value<THost>::Type Type;
149 template <typename THost>
150 struct Value<_ChunkCollector<THost> const >
152 typedef typename Value<THost>::Type Type;
155 //////////////////////////////////////////////////////////////////////////////
157 template <typename THost>
158 struct GetValue<_ChunkCollector<THost> >
160 typedef typename GetValue<THost>::Type Type;
163 template <typename THost>
164 struct GetValue<_ChunkCollector<THost> const >
166 typedef typename GetValue<THost>::Type Type;
169 //////////////////////////////////////////////////////////////////////////////
171 template <typename THost>
172 struct Size<_ChunkCollector<THost> >
174 typedef typename Size<THost>::Type Type;
177 template <typename THost>
178 struct Size<_ChunkCollector<THost> const >
180 typedef typename Size<THost>::Type Type;
183 //////////////////////////////////////////////////////////////////////////////
185 struct _Assign_Stream_2_ChunkCollector
187 template <typename THost, typename TSource>
189 assign_(_ChunkCollector<THost> & target,
194 while (!_streamEOF(source))
196 typename Value<THost>::Type * chunk = createChunk(target);
197 typename Size<THost>::Type count = _streamRead(chunk, source, ChunkLength< _ChunkCollector<THost> >::VALUE);
198 _setLength(target, length(target) + count);
202 template <typename THost, typename TSource>
204 assign_(_ChunkCollector<THost> & target,
206 typename Size< _ChunkCollector<THost> >::Type limit)
210 while (!_streamEOF(source))
212 typename Value<THost>::Type * chunk = createChunk(target);
213 typename Size<THost>::Type count = _streamRead(chunk, source, ChunkLength< _ChunkCollector<THost> >::VALUE);
214 _setLength(target, length(target) + count);
216 if (length(target) >= limit)
218 _setLength(target, limit);
225 //////////////////////////////////////////////////////////////////////////////
227 template <typename THost, typename TSource>
229 assign(_ChunkCollector<THost> & target,
232 _Assign_Stream_2_ChunkCollector::assign_(target, source);
234 template <typename THost, typename TSource>
236 assign(_ChunkCollector<THost> & target,
237 TSource const & source)
239 _Assign_Stream_2_ChunkCollector::assign_(target, source);
242 template <typename THost, typename TSource, typename TSize>
244 assign(_ChunkCollector<THost> & target,
248 _Assign_Stream_2_ChunkCollector::assign_(target, source, limit);
250 template <typename THost, typename TSource, typename TSize>
252 assign(_ChunkCollector<THost> & target,
253 TSource const & source,
256 _Assign_Stream_2_ChunkCollector::assign_(target, source, limit);
259 //////////////////////////////////////////////////////////////////////////////
260 //////////////////////////////////////////////////////////////////////////////
262 template <typename TExpand>
263 struct _Assign_ChunkCollector_2_String
265 template <typename TTarget, typename TSource>
270 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), TExpand());
272 int i_end = chunkCount(source);
273 typename Value<TTarget>::Type * pos = begin(target);
274 for (int i = 0; i < i_end; ++i)
276 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
277 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : ChunkLength<TSource>::VALUE;
278 typename Value<TSource>::Type * chunk = getChunk(source, i);
280 arrayConstructCopy(chunk, chunk + chunk_length, pos);
281 if (is_last_chunk) break;
286 template <typename TTarget, typename TSource>
290 typename Size<TTarget>::Type limit)
292 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), limit, TExpand());
294 int i_end = chunkCount(source);
295 typename Value<TTarget>::Type * pos = begin(target);
296 for (int i = 0; i < i_end; ++i)
298 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
299 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : ChunkLength<TSource>::VALUE;
300 typename Value<TSource>::Type * chunk = getChunk(source, i);
302 arrayConstructCopy(chunk, chunk + chunk_length, pos);
303 if (is_last_chunk) break;
309 //////////////////////////////////////////////////////////////////////////////
311 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
313 assign(String<TTargetValue, TTargetSpec> & target,
314 _ChunkCollector<TSourceHost> const & source,
315 Tag<TExpand> const tag)
317 _Assign_ChunkCollector_2_String<Tag<TExpand> const>::assign_(target, source);
319 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
321 assign(String<TTargetValue, TTargetSpec> & target,
322 _ChunkCollector<TSourceHost> const & source,
323 typename Size< String<TTargetValue, TTargetSpec> >::Type limit,
324 Tag<TExpand> const tag)
326 _Assign_ChunkCollector_2_String<Tag<TExpand> const>::assign_(target, source, limit);
330 //////////////////////////////////////////////////////////////////////////////
332 template <typename TExpand>
333 struct _Append_ChunkCollector_2_String
335 template <typename TTarget, typename TSource>
340 typedef typename Size<TTarget>::Type TSize;
341 TSize target_length_old = length(target);
342 TSize part_length = _clearSpace(target, length(source), target_length_old, target_length_old, TExpand());
344 int i_end = chunkCount(source);
345 typename Value<TTarget>::Type * pos = begin(target) + target_length_old; //begin(target) was possibly changed by _clearSpace
346 for (int i = 0; i < i_end; ++i)
348 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
349 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : (TSize) ChunkLength<TSource>::VALUE;
350 typename Value<TSource>::Type * chunk = getChunk(source, i);
352 arrayConstructCopy(chunk, chunk + chunk_length, pos);
353 if (is_last_chunk) break;
358 template <typename TTarget, typename TSource>
362 typename Size<TTarget>::Type limit)
364 typedef typename Size<TTarget>::Type TSize;
365 TSize target_length_old = length(target);
366 TSize part_length = _clearSpace(target, length(source), target_length_old, target_length_old, limit, TExpand());
368 int i_end = chunkCount(source);
369 typename Value<TTarget>::Type * pos = begin(target) + target_length_old; //begin(target) was possibly changed by _clearSpace
370 for (int i = 0; i < i_end; ++i)
372 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
373 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : (TSize) ChunkLength<TSource>::VALUE;
374 typename Value<TSource>::Type * chunk = getChunk(source, i);
376 arrayConstructCopy(chunk, chunk + chunk_length, pos);
377 if (is_last_chunk) break;
383 //////////////////////////////////////////////////////////////////////////////
385 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
387 append(String<TTargetValue, TTargetSpec> & target,
388 _ChunkCollector<TSourceHost> const & source,
391 _Append_ChunkCollector_2_String<Tag<TExpand> const>::append_(target, source);
393 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
395 append(String<TTargetValue, TTargetSpec> & target,
396 _ChunkCollector<TSourceHost> const & source,
397 typename Size< String<TTargetValue, TTargetSpec> >::Type limit,
400 _Append_ChunkCollector_2_String<Tag<TExpand> const>::append_(target, source, limit);
403 //////////////////////////////////////////////////////////////////////////////
405 template <typename TExpand>
406 struct _Replace_ChunkCollector_2_String
408 template <typename TTarget, typename TSource>
409 static void replace_(
411 typename Size<TTarget>::Type pos_begin,
412 typename Size<TTarget>::Type pos_end,
415 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), pos_begin, pos_end, TExpand());
417 int i_end = chunkCount(source);
418 typename Value<TTarget>::Type * pos = begin(target) + pos_begin;
419 for (int i = 0; i < i_end; ++i)
421 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
422 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : ChunkLength<TSource>::VALUE;
423 typename Value<TSource>::Type * chunk = getChunk(source, i);
425 arrayConstructCopy(chunk, chunk + chunk_length, pos);
426 if (is_last_chunk) break;
431 template <typename TTarget, typename TSource>
432 static void replace_(
434 typename Size<TTarget>::Type pos_begin,
435 typename Size<TTarget>::Type pos_end,
437 typename Size<TTarget>::Type limit)
439 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), pos_begin, pos_end, limit, TExpand());
441 int i_end = chunkCount(source);
442 typename Value<TTarget>::Type * pos = begin(target) + pos_begin;
443 for (int i = 0; i < i_end; ++i)
445 bool is_last_chunk = ( part_length <= ChunkLength<TSource>::VALUE);
446 typename Size<TTarget>::Type chunk_length = (is_last_chunk) ? part_length : ChunkLength<TSource>::VALUE;
447 typename Value<TSource>::Type * chunk = getChunk(source, i);
449 arrayConstructCopy(chunk, chunk + chunk_length, pos);
450 if (is_last_chunk) break;
456 //////////////////////////////////////////////////////////////////////////////
458 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
460 replace(String<TTargetValue, TTargetSpec> & target,
461 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_begin,
462 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_end,
463 _ChunkCollector<TSourceHost> const & source,
464 Tag<TExpand> const tag)
466 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source);
469 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
471 replace(String<TTargetValue, TTargetSpec> & target,
472 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_begin,
473 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_end,
474 _ChunkCollector<TSourceHost> const & source,
475 typename Size< String<TTargetValue, TTargetSpec> >::Type limit,
476 Tag<TExpand> const tag)
478 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source, limit);
481 //////////////////////////////////////////////////////////////////////////////
483 template <typename TTargetValue, typename TSourceHost, typename TExpand>
485 replace(TTargetValue * target,
488 _ChunkCollector<TSourceHost> const & source,
489 Tag<TExpand> const tag)
491 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source);
494 template <typename TTargetValue, typename TSourceHost, typename TExpand>
496 replace(TTargetValue * target,
499 _ChunkCollector<TSourceHost> const & source,
501 Tag<TExpand> const tag)
503 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source, limit);
505 //____________________________________________________________________________
507 template <typename TTargetValue, typename TSourceHost, typename TExpand>
509 replace(TTargetValue * target,
512 _ChunkCollector<TSourceHost> const & source,
513 Tag<TExpand> const tag)
515 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source);
518 template <typename TTargetValue, typename TTargetSpec, typename TSourceHost, typename TExpand>
520 replace(String<TTargetValue, TTargetSpec> & target,
521 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_begin,
522 typename Size< String<TTargetValue, TTargetSpec> >::Type pos_end,
523 _ChunkCollector<TSourceHost> const & source,
524 typename Size< String<TTargetValue, TTargetSpec> >::Type limit,
525 Tag<TExpand> const tag)
527 _Replace_ChunkCollector_2_String<Tag<TExpand> const>::replace_(target, pos_begin, pos_end, source, limit);
530 //////////////////////////////////////////////////////////////////////////////
532 } //namespace SEQAN_NAMESPACE_MAIN
534 #endif //#ifndef SEQAN_HEADER_...