1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 #include "join_results.h"
27 #include "helper.h"
28 #include <klib/vector.h>
29 #include <klib/printf.h>
30 #include <kfs/buffile.h>
31
32 typedef struct join_printer
33 {
34 struct KFile * f;
35 uint64_t file_pos;
36 } join_printer;
37
38 typedef rc_t ( * print_v1 )( struct join_results * self,
39 int64_t row_id,
40 uint32_t dst_id,
41 uint32_t read_id,
42 const String * name,
43 const String * read,
44 const String * quality );
45
46 typedef rc_t ( * print_v2 )( struct join_results * self,
47 int64_t row_id,
48 uint32_t dst_id,
49 uint32_t read_id,
50 const String * name,
51 const String * read_1,
52 const String * read_2,
53 const String * quality );
54
55 typedef struct join_results
56 {
57 KDirectory * dir;
58 struct temp_registry * registry;
59 const char * output_base;
60 const char * accession_short;
61 struct Buf2NA * buf2na;
62 print_v1 v1_print_name_null;
63 print_v1 v1_print_name_not_null;
64 print_v2 v2_print_name_null;
65 print_v2 v2_print_name_not_null;
66 SBuffer print_buffer; /* we have only one print_buffer... */
67 Vector printers;
68 size_t buffer_size;
69 bool print_frag_nr, print_name;
70 } join_results;
71
destroy_join_printer(void * item,void * data)72 static void CC destroy_join_printer( void * item, void * data )
73 {
74 if ( NULL != item )
75 {
76 join_printer * p = item;
77 if ( NULL != p -> f )
78 {
79 rc_t rc = KFileRelease( p -> f );
80 if ( 0 != rc )
81 {
82 ErrMsg( "destroy_join_printer().KFileRelease() -> %R", rc );
83 }
84 }
85 free( item );
86 }
87 }
88
destroy_join_results(join_results * self)89 void destroy_join_results( join_results * self )
90 {
91 if ( NULL != self )
92 {
93 VectorWhack ( &self -> printers, destroy_join_printer, NULL );
94 release_SBuffer( &self -> print_buffer );
95 if ( NULL != self -> buf2na )
96 {
97 release_Buf2NA( self -> buf2na );
98 }
99 free( ( void * ) self );
100 }
101 }
102
103 static const char * fmt_fastq_v1_no_name_no_frag_nr = "@%s.%ld length=%u\n%S\n+%s.%ld length=%u\n%S\n";
print_v1_no_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)104 static rc_t print_v1_no_name_no_frag_nr( join_results * self,
105 int64_t row_id,
106 uint32_t dst_id,
107 uint32_t read_id,
108 const String * name,
109 const String * read,
110 const String * quality )
111 {
112 return join_results_print( self,
113 dst_id,
114 fmt_fastq_v1_no_name_no_frag_nr,
115 /* READ... */
116 self -> accession_short, row_id,
117 read -> len, read,
118 /* QUALITY... */
119 self -> accession_short, row_id,
120 quality -> len, quality );
121 }
122
123 static const char * fmt_fastq_v1_no_name_frag_nr = "@%s.%ld/%u length=%u\n%S\n+%s.%ld/%u length=%u\n%S\n";
print_v1_no_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)124 static rc_t print_v1_no_name_frag_nr( join_results * self,
125 int64_t row_id,
126 uint32_t dst_id,
127 uint32_t read_id,
128 const String * name,
129 const String * read,
130 const String * quality )
131 {
132 return join_results_print( self,
133 dst_id,
134 fmt_fastq_v1_no_name_frag_nr,
135 /* READ... */
136 self -> accession_short, row_id, read_id,
137 read -> len, read,
138 /* QUALITY... */
139 self -> accession_short, row_id, read_id,
140 quality -> len, quality );
141 }
142
143 static const char * fmt_fastq_v1_syn_name_no_frag_nr = "@%s.%ld %ld length=%u\n%S\n+%s.%ld %ld length=%u\n%S\n";
print_v1_syn_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)144 static rc_t print_v1_syn_name_no_frag_nr( join_results * self,
145 int64_t row_id,
146 uint32_t dst_id,
147 uint32_t read_id,
148 const String * name,
149 const String * read,
150 const String * quality )
151 {
152 return join_results_print( self,
153 dst_id,
154 fmt_fastq_v1_syn_name_no_frag_nr,
155 /* READ... */
156 self -> accession_short, row_id,
157 row_id,
158 read -> len, read,
159 /* QUALITY... */
160 self -> accession_short, row_id,
161 row_id,
162 quality -> len, quality );
163 }
164
165 static const char * fmt_fastq_v1_syn_name_frag_nr = "@%s.%ld/%u %ld length=%u\n%S\n+%s.%ld/%u %ld length=%u\n%S\n";
print_v1_syn_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)166 static rc_t print_v1_syn_name_frag_nr( join_results * self,
167 int64_t row_id,
168 uint32_t dst_id,
169 uint32_t read_id,
170 const String * name,
171 const String * read,
172 const String * quality )
173 {
174 return join_results_print( self,
175 dst_id,
176 fmt_fastq_v1_syn_name_frag_nr,
177 /* READ... */
178 self -> accession_short, row_id, read_id,
179 row_id,
180 read -> len, read,
181 /* QUALITY... */
182 self -> accession_short, row_id, read_id,
183 row_id,
184 quality -> len, quality );
185 }
186
187 static const char * fmt_fastq_v1_real_name_no_frag_nr = "@%s.%ld %S length=%u\n%S\n+%s.%ld %S length=%u\n%S\n";
188 static const char * fmt_fastq_v1_empty_name_no_frag_nr = "@%s.%ld length=%u\n%S\n+%s.%ld length=%u\n%S\n";
print_v1_real_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)189 static rc_t print_v1_real_name_no_frag_nr( join_results * self,
190 int64_t row_id,
191 uint32_t dst_id,
192 uint32_t read_id,
193 const String * name,
194 const String * read,
195 const String * quality )
196 {
197 if ( name -> len > 0 )
198 {
199 return join_results_print( self,
200 dst_id,
201 fmt_fastq_v1_real_name_no_frag_nr,
202 /* READ... */
203 self -> accession_short, row_id,
204 name,
205 read -> len, read,
206 /* QUALITY... */
207 self -> accession_short, row_id,
208 name,
209 quality -> len, quality );
210 }
211
212 return join_results_print( self,
213 dst_id,
214 fmt_fastq_v1_empty_name_no_frag_nr,
215 /* READ... */
216 self -> accession_short, row_id,
217 read -> len, read,
218 /* QUALITY... */
219 self -> accession_short, row_id,
220 quality -> len, quality );
221 }
222
223 static const char * fmt_fastq_v1_real_name_frag_nr = "@%s.%ld/%u %S length=%u\n%S\n+%s.%ld/%u %S length=%u\n%S\n";
224 static const char * fmt_fastq_v1_empty_name_frag_nr = "@%s.%ld/%u length=%u\n%S\n+%s.%ld/%u length=%u\n%S\n";
print_v1_real_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)225 static rc_t print_v1_real_name_frag_nr( join_results * self,
226 int64_t row_id,
227 uint32_t dst_id,
228 uint32_t read_id,
229 const String * name,
230 const String * read,
231 const String * quality )
232 {
233 if ( name -> len > 0 )
234 {
235 return join_results_print( self,
236 dst_id,
237 fmt_fastq_v1_real_name_frag_nr,
238 /* READ... */
239 self -> accession_short, row_id, read_id,
240 name,
241 read -> len, read,
242 /* QUALITY... */
243 self -> accession_short, row_id, read_id,
244 name,
245 quality -> len, quality );
246 }
247
248 return join_results_print( self,
249 dst_id,
250 fmt_fastq_v1_empty_name_frag_nr,
251 /* READ... */
252 self -> accession_short, row_id, read_id,
253 read -> len, read,
254 /* QUALITY... */
255 self -> accession_short, row_id, read_id,
256 quality -> len, quality );
257 }
258
259 static const char * fmt_fastq_v2_no_name_no_frag_nr = "@%s.%ld length=%u\n%S%S\n+%s.%ld length=%u\n%S\n";
print_v2_no_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)260 static rc_t print_v2_no_name_no_frag_nr( join_results * self,
261 int64_t row_id,
262 uint32_t dst_id,
263 uint32_t read_id,
264 const String * name,
265 const String * read1,
266 const String * read2,
267 const String * quality )
268 {
269 return join_results_print( self,
270 dst_id,
271 fmt_fastq_v2_no_name_no_frag_nr,
272 /* READ... */
273 self -> accession_short, row_id,
274 read1 -> len + read2 -> len, read1, read2,
275 /* QUALITY... */
276 self -> accession_short, row_id,
277 quality -> len, quality );
278 }
279
280 static const char * fmt_fastq_v2_no_name_frag_nr = "@%s.%ld/%u length=%u\n%S%S\n+%s.%ld/%u %length=%u\n%S\n";
print_v2_no_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)281 static rc_t print_v2_no_name_frag_nr( join_results * self,
282 int64_t row_id,
283 uint32_t dst_id,
284 uint32_t read_id,
285 const String * name,
286 const String * read1,
287 const String * read2,
288 const String * quality )
289 {
290 return join_results_print( self,
291 dst_id,
292 fmt_fastq_v2_no_name_frag_nr,
293 /* READ... */
294 self -> accession_short, row_id, read_id,
295 read1 -> len + read2 -> len, read1, read2,
296 /* QUALITY... */
297 self -> accession_short, row_id, read_id,
298 quality -> len, quality );
299 }
300
301 static const char * fmt_fastq_v2_syn_name_no_frag_nr = "@%s.%ld %ld length=%u\n%S%S\n+%s.%ld %ld length=%u\n%S\n";
print_v2_syn_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)302 static rc_t print_v2_syn_name_no_frag_nr( join_results * self,
303 int64_t row_id,
304 uint32_t dst_id,
305 uint32_t read_id,
306 const String * name,
307 const String * read1,
308 const String * read2,
309 const String * quality )
310 {
311 return join_results_print( self,
312 dst_id,
313 fmt_fastq_v2_syn_name_no_frag_nr,
314 /* READ... */
315 self -> accession_short, row_id,
316 row_id,
317 read1 -> len + read2 -> len, read1, read2,
318 /* QUALITY... */
319 self -> accession_short, row_id,
320 row_id,
321 quality -> len, quality );
322 }
323
324 static const char * fmt_fastq_v2_syn_name_frag_nr = "@%s.%ld/%u %ld length=%u\n%S%S\n+%s.%ld/%u %ld length=%u\n%S\n";
print_v2_syn_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)325 static rc_t print_v2_syn_name_frag_nr( join_results * self,
326 int64_t row_id,
327 uint32_t dst_id,
328 uint32_t read_id,
329 const String * name,
330 const String * read1,
331 const String * read2,
332 const String * quality )
333 {
334 return join_results_print( self,
335 dst_id,
336 fmt_fastq_v2_syn_name_frag_nr,
337 /* READ... */
338 self -> accession_short, row_id, read_id,
339 row_id,
340 read1 -> len + read2 -> len, read1, read2,
341 /* QUALITY... */
342 self -> accession_short, row_id, read_id,
343 row_id,
344 quality -> len, quality );
345 }
346
347 static const char * fmt_fastq_v2_real_name_no_frag_nr = "@%s.%ld %S length=%u\n%S%S\n+%s.%ld %S length=%u\n%S\n";
348 static const char * fmt_fastq_v2_empty_name_no_frag_nr = "@%s.%ld length=%u\n%S%S\n+%s.%ld length=%u\n%S\n";
print_v2_real_name_no_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)349 static rc_t print_v2_real_name_no_frag_nr( join_results * self,
350 int64_t row_id,
351 uint32_t dst_id,
352 uint32_t read_id,
353 const String * name,
354 const String * read1,
355 const String * read2,
356 const String * quality )
357 {
358 if ( name -> len > 0 )
359 {
360 return join_results_print( self,
361 dst_id,
362 fmt_fastq_v2_real_name_no_frag_nr,
363 /* READ... */
364 self -> accession_short, row_id,
365 name,
366 read1 -> len + read2 -> len, read1, read2,
367 /* QUALITY... */
368 self -> accession_short, row_id,
369 name,
370 quality -> len, quality );
371 }
372
373 return join_results_print( self,
374 dst_id,
375 fmt_fastq_v2_empty_name_no_frag_nr,
376 /* READ... */
377 self -> accession_short, row_id,
378 read1 -> len + read2 -> len, read1, read2,
379 /* QUALITY... */
380 self -> accession_short, row_id,
381 quality -> len, quality );
382 }
383
384 static const char * fmt_fastq_v2_real_name_frag_nr = "@%s.%ld/%u %S length=%u\n%S%S\n+%s.%ld/%u %S length=%u\n%S\n";
385 static const char * fmt_fastq_v2_empty_name_frag_nr = "@%s.%ld/%u length=%u\n%S%S\n+%s.%ld/%u length=%u\n%S\n";
print_v2_real_name_frag_nr(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)386 static rc_t print_v2_real_name_frag_nr( join_results * self,
387 int64_t row_id,
388 uint32_t dst_id,
389 uint32_t read_id,
390 const String * name,
391 const String * read1,
392 const String * read2,
393 const String * quality )
394 {
395 if ( name -> len > 0 )
396 {
397 return join_results_print( self,
398 dst_id,
399 fmt_fastq_v2_real_name_frag_nr,
400 /* READ... */
401 self -> accession_short, row_id, read_id,
402 name,
403 read1 -> len + read2 -> len, read1, read2,
404 /* QUALITY... */
405 self -> accession_short, row_id, read_id,
406 name,
407 quality -> len, quality );
408 }
409
410 return join_results_print( self,
411 dst_id,
412 fmt_fastq_v2_empty_name_frag_nr,
413 /* READ... */
414 self -> accession_short, row_id, read_id,
415 read1 -> len + read2 -> len, read1, read2,
416 /* QUALITY... */
417 self -> accession_short, row_id, read_id,
418 quality -> len, quality );
419 }
420
make_join_results(struct KDirectory * dir,join_results ** results,struct temp_registry * registry,const char * output_base,const char * accession_short,size_t file_buffer_size,size_t print_buffer_size,bool print_frag_nr,bool print_name,const char * filter_bases)421 rc_t make_join_results( struct KDirectory * dir,
422 join_results ** results,
423 struct temp_registry * registry,
424 const char * output_base,
425 const char * accession_short,
426 size_t file_buffer_size,
427 size_t print_buffer_size,
428 bool print_frag_nr,
429 bool print_name,
430 const char * filter_bases )
431 {
432 rc_t rc = 0;
433 struct Buf2NA * buf2na = NULL;
434 if ( filter_bases != NULL )
435 {
436 rc = make_Buf2NA( &buf2na, 512, filter_bases );
437 if ( 0 != rc )
438 {
439 ErrMsg( "make_join_results().error creating nucstrstr-filter from ( %s ) -> %R", filter_bases, rc );
440 }
441 }
442 if ( rc == 0 )
443 {
444 join_results * p = calloc( 1, sizeof * p );
445 *results = NULL;
446 if ( NULL == p )
447 {
448 rc = RC( rcVDB, rcNoTarg, rcConstructing, rcMemory, rcExhausted );
449 ErrMsg( "make_join_results().calloc( %d ) -> %R", ( sizeof * p ), rc );
450 }
451 else
452 {
453 p -> dir = dir;
454 p -> output_base = output_base;
455 p -> accession_short = accession_short;
456 p -> buffer_size = file_buffer_size;
457 p -> registry = registry;
458 p -> print_frag_nr = print_frag_nr;
459 p -> print_name = print_name;
460 p -> buf2na = buf2na;
461
462 /* available:
463 print_v1_no_name_no_frag_nr() print_v2_no_name_no_frag_nr()
464 print_v1_no_name_frag_nr() print_v2_no_name_frag_nr()
465 print_v1_syn_name_no_frag_nr() print_v2_syn_name_no_frag_nr()
466 print_v1_syn_name_frag_nr() print_v2_syn_name_frag_nr()
467 print_v1_real_name_no_frag_nr() print_v2_real_name_no_frag_nr()
468 print_v1_real_name_frag_nr() print_v2_real_name_frag_nr()
469 */
470 if ( print_frag_nr )
471 {
472 if ( print_name )
473 {
474 p -> v1_print_name_null = print_v1_syn_name_frag_nr;
475 p -> v1_print_name_not_null = print_v1_real_name_frag_nr;
476 p -> v2_print_name_null = print_v2_syn_name_frag_nr;
477 p -> v2_print_name_not_null = print_v2_real_name_frag_nr;
478 }
479 else
480 {
481 p -> v1_print_name_null = print_v1_no_name_frag_nr;
482 p -> v1_print_name_not_null = print_v1_no_name_frag_nr;
483 p -> v2_print_name_null = print_v2_no_name_frag_nr;
484 p -> v2_print_name_not_null = print_v2_no_name_frag_nr;
485 }
486 }
487 else
488 {
489 if ( print_name )
490 {
491 p -> v1_print_name_null = print_v1_syn_name_no_frag_nr;
492 p -> v1_print_name_not_null = print_v1_real_name_no_frag_nr;
493 p -> v2_print_name_null = print_v2_syn_name_no_frag_nr;
494 p -> v2_print_name_not_null = print_v2_real_name_no_frag_nr;
495 }
496 else
497 {
498 p -> v1_print_name_null = print_v1_no_name_no_frag_nr;
499 p -> v1_print_name_not_null = print_v1_no_name_no_frag_nr;
500 p -> v2_print_name_null = print_v2_no_name_no_frag_nr;
501 p -> v2_print_name_not_null = print_v2_no_name_no_frag_nr;
502 }
503 }
504
505 rc = make_SBuffer( &( p -> print_buffer ), print_buffer_size ); /* helper.c */
506 if ( 0 == rc )
507 {
508 VectorInit ( &p -> printers, 0, 4 );
509 *results = p;
510 }
511 }
512 }
513 if ( 0 != rc && NULL != buf2na )
514 {
515 release_Buf2NA( buf2na );
516 }
517 return rc;
518 }
519
join_results_match(join_results * self,const String * bases)520 bool join_results_match( join_results * self, const String * bases )
521 {
522 bool res = true;
523 if ( NULL != self && NULL != bases && NULL != self -> buf2na )
524 {
525 res = match_Buf2NA( self -> buf2na, bases ); /* helper.c */
526 }
527 return res;
528 }
529
join_results_match2(struct join_results * self,const String * bases1,const String * bases2)530 bool join_results_match2( struct join_results * self, const String * bases1, const String * bases2 )
531 {
532 bool res = true;
533 if ( NULL != self && NULL != bases1 && NULL != bases2 && NULL != self -> buf2na )
534 {
535 res = ( match_Buf2NA( self -> buf2na, bases1 ) || match_Buf2NA( self -> buf2na, bases2 ) ); /* helper.c */
536 }
537 return res;
538 }
539
make_join_printer(join_results * self,uint32_t read_id,join_printer ** printer)540 static rc_t make_join_printer( join_results * self, uint32_t read_id, join_printer ** printer )
541 {
542 char filename[ 4096 ];
543 size_t num_writ;
544
545 rc_t rc = string_printf( filename, sizeof filename, &num_writ, "%s.%u", self -> output_base, read_id );
546 *printer = NULL;
547 if ( 0 != rc )
548 {
549 ErrMsg( "make_join_printer().string_vprintf() -> %R", rc );
550 }
551 else
552 {
553 struct KFile * f;
554 rc = KDirectoryCreateFile( self -> dir, &f, false, 0664, kcmInit, "%s", filename );
555 if ( 0 != rc )
556 {
557 ErrMsg( "make_join_printer().KDirectoryVCreateFile() -> %R", rc );
558 }
559 else
560 {
561 if ( self -> buffer_size > 0 )
562 {
563 struct KFile * temp_file = f;
564 rc = KBufFileMakeWrite( &temp_file, f, false, self -> buffer_size );
565 if ( 0 != rc )
566 {
567 ErrMsg( "make_join_printer().KBufFileMakeWrite() -> %R", rc );
568 }
569 {
570 rc_t rc2 = KFileRelease( f );
571 if ( 0 != rc2 )
572 {
573 ErrMsg( "make_join_printer().KFileRelease().1 -> %R", rc2 );
574 rc = ( 0 == rc ) ? rc2 : rc;
575 }
576 }
577 f = temp_file;
578 }
579 if ( 0 == rc )
580 {
581 join_printer * p = calloc( 1, sizeof * p );
582 if ( NULL == p )
583 {
584 rc = RC( rcVDB, rcNoTarg, rcConstructing, rcMemory, rcExhausted );
585 ErrMsg( "make_join_printer().calloc( %d ) -> %R", ( sizeof * p ), rc );
586 {
587 rc_t rc2 = KFileRelease( f );
588 if ( 0 != rc2 )
589 {
590 ErrMsg( "make_join_printer().KFileRelease().2 -> %R", rc2 );
591 }
592 }
593 }
594 else
595 {
596 rc = register_temp_file( self -> registry, read_id, filename );
597 if ( rc != 0 )
598 {
599 free( p );
600 {
601 rc_t rc2 = KFileRelease( f );
602 if ( 0 != rc2 )
603 {
604 ErrMsg( "make_join_printer().KFileRelease().3 -> %R", rc2 );
605 }
606 }
607 }
608 else
609 {
610 p -> f = f;
611 *printer = p;
612 }
613 }
614 }
615 }
616 }
617 return rc;
618 }
619
join_results_print(struct join_results * self,uint32_t read_id,const char * fmt,...)620 rc_t join_results_print( struct join_results * self, uint32_t read_id, const char * fmt, ... )
621 {
622 rc_t rc = 0;
623 if ( NULL == self )
624 {
625 rc = RC( rcVDB, rcNoTarg, rcWriting, rcSelf, rcNull );
626 ErrMsg( "join_results_print() -> %R", rc );
627 }
628 else if ( NULL == fmt )
629 {
630 rc = RC( rcVDB, rcNoTarg, rcWriting, rcParam, rcNull );
631 ErrMsg( "join_results_print() -> %R", rc );
632 }
633 else
634 {
635 join_printer * p = VectorGet ( &self -> printers, read_id );
636 if ( NULL == p )
637 {
638 rc = make_join_printer( self, read_id, &p );
639 if ( 0 == rc )
640 {
641 rc = VectorSet ( &self -> printers, read_id, p );
642 if ( 0 != rc )
643 {
644 destroy_join_printer( p, NULL );
645 }
646 }
647 }
648
649 if ( 0 == rc && NULL != p )
650 {
651 bool done = false;
652 uint32_t cnt = 4;
653
654 while ( 0 == rc && !done && cnt-- > 0 )
655 {
656 va_list args;
657 va_start ( args, fmt );
658 rc = print_to_SBufferV( & self -> print_buffer, fmt, args );
659 /* do not print failed rc, because it is used to increase the buffer */
660 va_end ( args );
661
662 done = ( 0 == rc );
663 if ( !done )
664 {
665 rc = try_to_enlarge_SBuffer( & self -> print_buffer, rc );
666 }
667 }
668
669 if ( 0 != rc )
670 {
671 ErrMsg( "join_results_print().failed to enlarge buffer -> %R", rc );
672 }
673 else
674 {
675 size_t num_writ, to_write;
676 to_write = self -> print_buffer . S . size;
677 const char * src = self -> print_buffer . S . addr;
678 rc = KFileWriteAll( p -> f, p -> file_pos, src, to_write, &num_writ );
679 if ( 0 != rc )
680 {
681 ErrMsg( "join_results_print().KFileWriteAll( at %lu ) -> %R", p -> file_pos, rc );
682 }
683 else if ( num_writ != to_write )
684 {
685 rc = RC( rcVDB, rcNoTarg, rcWriting, rcFormat, rcInvalid );
686 ErrMsg( "join_results_print().KFileWriteAll( at %lu ) ( %d vs %d ) -> %R", p -> file_pos, to_write, num_writ, rc );
687 }
688 else
689 {
690 p -> file_pos += num_writ;
691 }
692 }
693 }
694 }
695 return rc;
696 }
697
join_results_print_fastq_v1(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read,const String * quality)698 rc_t join_results_print_fastq_v1( join_results * self,
699 int64_t row_id,
700 uint32_t dst_id,
701 uint32_t read_id,
702 const String * name,
703 const String * read,
704 const String * quality )
705 {
706 if ( NULL == name )
707 {
708 return self -> v1_print_name_null( self, row_id, dst_id, read_id, name, read, quality );
709 }
710 return self -> v1_print_name_not_null( self, row_id, dst_id, read_id, name, read, quality );
711 }
712
join_results_print_fastq_v2(join_results * self,int64_t row_id,uint32_t dst_id,uint32_t read_id,const String * name,const String * read1,const String * read2,const String * quality)713 rc_t join_results_print_fastq_v2( join_results * self,
714 int64_t row_id,
715 uint32_t dst_id,
716 uint32_t read_id,
717 const String * name,
718 const String * read1,
719 const String * read2,
720 const String * quality )
721 {
722 if ( NULL == name )
723 {
724 return self -> v2_print_name_null( self, row_id, dst_id, read_id, name, read1, read2, quality );
725 }
726 return self -> v2_print_name_not_null( self, row_id, dst_id, read_id, name, read1, read2, quality );
727 }
728