1 /*
2  * Copyright (c) 2005-2007, 2010, 2013 Genome Research Ltd.
3  * Author(s): James Bonfield
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *    1. Redistributions of source code must retain the above copyright notice,
9  *       this list of conditions and the following disclaimer.
10  *
11  *    2. Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *
16  *    3. Neither the names Genome Research Ltd and Wellcome Trust Sanger
17  *    Institute nor the names of its contributors may be used to endorse
18  *    or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY GENOME RESEARCH LTD AND CONTRIBUTORS "AS
22  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENOME RESEARCH
25  * LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Author(s): James Bonfield, Simon Dear, Rodger Staden,
36  *
37  * Copyright (c) 1994, 1997, 2001-2002 MEDICAL RESEARCH COUNCIL
38  * All rights reserved
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions are met:
42  *
43  *    1 Redistributions of source code must retain the above copyright notice,
44  *      this list of conditions and the following disclaimer.
45  *
46  *    2 Redistributions in binary form must reproduce the above copyright
47  *      notice, this list of conditions and the following disclaimer in
48  *      the documentation and/or other materials provided with the
49  *      distribution.
50  *
51  *    3 Neither the name of the MEDICAL RESEARCH COUNCIL, THE LABORATORY OF
52  *      MOLECULAR BIOLOGY nor the names of its contributors may be used
53  *      to endorse or promote products derived from this software without
54  *      specific prior written permission.
55  *
56  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
60  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66  * POSSIBILITY OF SUCH DAMAGE.
67  */
68 
69 /*
70  * Copyright (c) Medical Research Council 1994. All rights reserved.
71  *
72  * Permission to use, copy, modify and distribute this software and its
73  * documentation for any purpose is hereby granted without fee, provided that
74  * this copyright and notice appears in all copies.
75  *
76  * This file was written by James Bonfield, Simon Dear, Rodger Staden,
77  * as part of the Staden Package at the MRC Laboratory of Molecular
78  * Biology, Hills Road, Cambridge, CB2 2QH, United Kingdom.
79  *
80  * MRC disclaims all warranties with regard to this software.
81  */
82 
83 /*
84  * File: 	read_alloc.c
85  * Purpose:	Performs the allocation/freeing of Read structures
86  * Last update: 01/09/94
87  */
88 
89 
90 /*
91     The Read data type is designed so that it can hold a varying degree
92     of information about sequences, yet have a single set of calls
93     to access the data.
94 
95     There are plenty of assumptions around that both the number of
96     bases and the number of points will fit into an int_2, a short.
97 
98 */
99 
100 /* ---- Includes ---- */
101 
102 #ifdef HAVE_CONFIG_H
103 #include "io_lib_config.h"
104 #endif
105 
106 #include <stdlib.h>
107 #include <stdio.h>
108 #include <string.h>
109 #include <assert.h>
110 
111 #include "io_lib/misc.h"
112 #include "io_lib/Read.h"
113 #include "io_lib/xalloc.h"
114 
115 /*
116  * Allocate a new sequence, with the given sizes.
117  * Returns:
118  *   "Read *" for success
119  *   "NULLRead" for failure
120  */
read_allocate(int num_points,int num_bases)121 Read *read_allocate(int num_points, int num_bases) {
122     Read *seq = NULLRead;
123 
124     int sections = read_sections(0);
125 
126     /* Allocate the body of the sequence */
127     if ((seq = (Read *)xmalloc(sizeof(Read))) == NULL)
128 	return(NULLRead);
129 
130     seq->NPoints = num_points;
131     seq->NBases  = num_bases;
132 
133     /*
134      * Initialise the body, all pointers are set to NULL so we can
135      * happily call `read_deallocate()`.
136      */
137     seq->leftCutoff  = 0;
138     seq->rightCutoff = 0;
139     seq->maxTraceVal = 0;
140     seq->baseline = 0;
141 
142     seq->traceC    = NULL;
143     seq->traceA    = NULL;
144     seq->traceG    = NULL;
145     seq->traceT    = NULL;
146 
147     seq->base      = NULL;
148     seq->basePos   = NULL;
149 
150     seq->info = NULL;
151     seq->format = TT_ANY;
152     seq->trace_name = NULL;
153 
154     seq->prob_A = NULL;
155     seq->prob_C = NULL;
156     seq->prob_G = NULL;
157     seq->prob_T = NULL;
158 
159     seq->orig_trace_format = TT_ANY;
160     seq->orig_trace = NULL;
161     seq->orig_trace_free = NULL;
162 
163     seq->ident = NULL;
164 
165     /* Allocate space for the bases - 1 extra for the ->base field so
166      * that we can treat it as a NULL terminated string.
167      */
168     if (sections & READ_BASES &&
169 	(((seq->base	  = (char *)xcalloc(num_bases+1,1))   == NULL) ||
170 	 ((seq->basePos   = (uint_2 *)xcalloc(num_bases+1,2)) == NULL) ||
171 	 ((seq->prob_A    = (char *)xcalloc(num_bases+1,1))   == NULL) ||
172 	 ((seq->prob_C    = (char *)xcalloc(num_bases+1,1))   == NULL) ||
173 	 ((seq->prob_G    = (char *)xcalloc(num_bases+1,1))   == NULL) ||
174 	 ((seq->prob_T    = (char *)xcalloc(num_bases+1,1))   == NULL))
175 	)
176     {
177 	read_deallocate(seq);
178 	return NULLRead;
179     }
180 
181     if (sections & READ_SAMPLES &&
182 	(((seq->traceC   =(TRACE *)xcalloc(num_points+1, 2))  == NULL)||
183 	 ((seq->traceA   =(TRACE *)xcalloc(num_points+1, 2))  == NULL)||
184 	 ((seq->traceG   =(TRACE *)xcalloc(num_points+1, 2))  == NULL)||
185 	 ((seq->traceT   =(TRACE *)xcalloc(num_points+1, 2))  == NULL))
186 	)
187     {
188 	read_deallocate(seq);
189 	return NULLRead;
190     }
191 
192     seq->nflows = 0;
193     seq->flow_order = NULL;
194     seq->flow = NULL;
195     seq->flow_raw = NULL;
196 
197     seq->private_data = NULL;
198     seq->private_size = 0;
199 
200     return seq;
201 }
202 
203 
204 /*
205  * Free memory allocated to a sequence by read_allocate().
206  */
read_deallocate(Read * read)207 void read_deallocate(Read *read)
208 {
209     if (read == NULLRead)
210 	return;
211 
212     if (read->traceC  != NULL)  xfree(read->traceC);
213     if (read->traceA  != NULL)  xfree(read->traceA);
214     if (read->traceG  != NULL)  xfree(read->traceG);
215     if (read->traceT  != NULL)  xfree(read->traceT);
216 
217     if (read->base    != NULL)  xfree(read->base);
218     if (read->basePos != NULL)  xfree(read->basePos);
219 
220     if (read->info    != NULL)  xfree(read->info);
221 
222     if (read->prob_A  != NULL)  xfree(read->prob_A);
223     if (read->prob_C  != NULL)  xfree(read->prob_C);
224     if (read->prob_G  != NULL)  xfree(read->prob_G);
225     if (read->prob_T  != NULL)  xfree(read->prob_T);
226 
227     if (read->trace_name != NULL) xfree(read->trace_name);
228 
229     if (read->orig_trace != NULL) {
230 	if (read->orig_trace_free)
231 	    read->orig_trace_free(read->orig_trace);
232 	else
233 	    xfree(read->orig_trace);
234     }
235 
236     if (read->ident != NULL)
237 	xfree(read->ident);
238 
239     if (read->flow_order)
240 	xfree(read->flow_order);
241     if (read->flow)
242 	xfree(read->flow);
243     if (read->flow_raw)
244 	xfree(read->flow_raw);
245 
246     if (read->private_data)
247 	xfree(read->private_data);
248 
249     xfree(read);
250 }
251 
252 
253 
254 
255 /*
256  * Duplicates the read structure and optionally gives it a new filename.
257  * The following fields are not duplicated:
258  *
259  *  int  orig_trace_format;
260  *  void (*orig_trace_free)(void *ptr);
261  *  void *orig_trace;
262  *  char *ident;
263  *
264  * Returns:
265  *   "Read *" for success
266  *   "NULLRead" for failure
267  */
read_dup(Read * src,const char * new_name)268 Read* read_dup( Read* src, const char* new_name )
269 {
270     int   n;
271     Read* dst;
272     assert(src);
273 
274     /* Allocate storage and initialise */
275     dst = read_allocate( src->NPoints, src->NBases );
276     if( dst == NULLRead )
277 	return 0;
278     dst->info       = 0;
279     dst->trace_name = 0;
280 
281 
282     /* Copy over possibly new name */
283     if( new_name )
284 	n = strlen(new_name);
285     else if( src->trace_name )
286 	n = strlen(src->trace_name);
287     else
288 	n = 0;
289     if( n > 0 )	{
290 	dst->trace_name = (char*) xmalloc(n+1);
291 	if( !dst->trace_name )
292 	    goto error;
293 
294 	if(new_name)
295 	    strcpy( dst->trace_name, new_name );
296 	else
297 	    strcpy( dst->trace_name, src->trace_name );
298     }
299 
300 
301     /* Copy over info */
302     if( src->info ) {
303 	dst->info = strdup(src->info);
304     }
305 
306 
307     /* Copy single fields */
308     dst->format      = src->format;
309     dst->maxTraceVal = src->maxTraceVal;
310     dst->leftCutoff  = src->leftCutoff;
311     dst->rightCutoff = src->rightCutoff;
312     dst->baseline    = src->baseline;
313 
314 
315     /* Copy NPoints fields if they exist */
316     if( src->traceA )
317 	{
318 	    for( n=0; n<src->NPoints; n++ )
319 		{
320 		    dst->traceA[n] = src->traceA[n];
321 		    dst->traceC[n] = src->traceC[n];
322 		    dst->traceG[n] = src->traceG[n];
323 		    dst->traceT[n] = src->traceT[n];
324 		}
325 	}
326 
327 
328     /* Copy NBases fields if they exist */
329     if( src->base && src->base[0] )
330 	{
331 	    for( n=0; n<src->NBases; n++ )
332 		{
333 		    dst->base[n]    = src->base[n];
334 		    dst->basePos[n] = src->basePos[n];
335 		    if( src->prob_A )
336 			{
337 			    dst->prob_A[n] = src->prob_A[n];
338 			    dst->prob_C[n] = src->prob_C[n];
339 			    dst->prob_G[n] = src->prob_G[n];
340 			    dst->prob_T[n] = src->prob_T[n];
341 			}
342 		}
343 	}
344 
345 
346     /* Success */
347     return dst;
348 
349  error:
350     /* Failure */
351     read_deallocate(dst);
352     return NULLRead;
353 }
354