~ubuntu-branches/ubuntu/quantal/genometools/quantal-backports

« back to all changes in this revision

Viewing changes to src/core/mapspec.c

  • Committer: Package Import Robot
  • Author(s): Sascha Steinbiss
  • Date: 2012-07-09 14:10:23 UTC
  • Revision ID: package-import@ubuntu.com-20120709141023-juuu4spm6chqsf9o
Tags: upstream-1.4.1
ImportĀ upstreamĀ versionĀ 1.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (c) 2007      Stefan Kurtz <kurtz@zbh.uni-hamburg.de>
 
3
  Copyright (c)      2011 Sascha Steinbiss <steinbiss@zbh.uni-hamburg.de>
 
4
  Copyright (c) 2007-2011 Center for Bioinformatics, University of Hamburg
 
5
 
 
6
  Permission to use, copy, modify, and distribute this software for any
 
7
  purpose with or without fee is hereby granted, provided that the above
 
8
  copyright notice and this permission notice appear in all copies.
 
9
 
 
10
  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 
11
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
12
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 
13
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
14
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
15
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 
16
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
17
*/
 
18
 
 
19
#include "core/error.h"
 
20
#include "core/fa.h"
 
21
#include "core/filelengthvalues.h"
 
22
#include "core/format64.h"
 
23
#include "core/intbits.h"
 
24
#include "core/types_api.h"
 
25
#include "core/mapspec.h"
 
26
#include "core/pairbwtidx.h"
 
27
#include "core/safecast-gen.h"
 
28
#include "core/str.h"
 
29
#include "core/ulongbound.h"
 
30
#include "core/xansi_api.h"
 
31
 
 
32
typedef enum
 
33
{
 
34
  GtCharType, /* \0 terminated string */
 
35
  GtFilelengthvaluesType,
 
36
  GtUcharType,
 
37
  Uint16Type,
 
38
  Uint32Type,
 
39
  Uint64Type,
 
40
  GtUlongType,
 
41
  GtUlongBoundType,
 
42
  GtBitsequenceType,
 
43
  GtPairBwtidxType,
 
44
  GtTwobitencodingType,
 
45
  GtSpecialcharinfoType,
 
46
  GtBitElemType
 
47
} GtTypespec;
 
48
 
 
49
typedef struct
 
50
{
 
51
  GtTypespec typespec;
 
52
  char *name;
 
53
  void *startptr;
 
54
  size_t sizeofunit;
 
55
  unsigned long numofunits;
 
56
} GtMapspecification;
 
57
 
 
58
GT_DECLAREARRAYSTRUCT(GtMapspecification);
 
59
 
 
60
#define ASSIGNPTR2STARTPTR(TYPE)\
 
61
        if (mapspec->numofunits == 0)\
 
62
        {\
 
63
          *((TYPE **) mapspec->startptr) = NULL;\
 
64
        } else\
 
65
        {\
 
66
          voidptr = (((char *) ptr) + byteoffset);\
 
67
          *((TYPE **) mapspec->startptr) = voidptr;\
 
68
        }
 
69
 
 
70
#define WRITEACTIONWITHTYPE(TYPE)\
 
71
        gt_xfwrite(*((TYPE **) mapspecptr->startptr),\
 
72
                   mapspecptr->sizeofunit,\
 
73
                   (size_t) mapspecptr->numofunits, fp);
 
74
 
 
75
static uint64_t detexpectedaccordingtomapspec(const GtArrayGtMapspecification
 
76
                                              *mapspectable)
 
77
{
 
78
  uint64_t sumup = 0;
 
79
  GtMapspecification *mapspecptr;
 
80
 
 
81
  for (mapspecptr = mapspectable->spaceGtMapspecification;
 
82
       mapspecptr < mapspectable->spaceGtMapspecification +
 
83
                    mapspectable->nextfreeGtMapspecification; mapspecptr++)
 
84
  {
 
85
    sumup += (uint64_t) mapspecptr->sizeofunit *
 
86
             (uint64_t) mapspecptr->numofunits;
 
87
    if (sumup % GT_WORDSIZE_INBYTES > 0)
 
88
    {
 
89
      sumup += (GT_WORDSIZE_INBYTES - (sumup % GT_WORDSIZE_INBYTES));
 
90
    }
 
91
  }
 
92
  return sumup;
 
93
}
 
94
 
 
95
#undef SKDEBUG
 
96
#ifdef SKDEBUG
 
97
static void showmapspec(const GtMapspecification *mapspec)
 
98
{
 
99
  printf("(%s,size=%lu,elems=%lu)",
 
100
           mapspec->name,
 
101
           (unsigned long) mapspec->sizeofunit,
 
102
           mapspec->numofunits);
 
103
}
 
104
#endif
 
105
 
 
106
static int assigncorrecttype(GtMapspecification *mapspec,
 
107
                             void *ptr,
 
108
                             unsigned long byteoffset,
 
109
                             GtError *err)
 
110
{
 
111
  void *voidptr;
 
112
  int had_err = 0;
 
113
 
 
114
  gt_error_check(err);
 
115
  switch (mapspec->typespec)
 
116
  {
 
117
    case GtCharType:
 
118
      ASSIGNPTR2STARTPTR(char);
 
119
      break;
 
120
    case GtFilelengthvaluesType:
 
121
      ASSIGNPTR2STARTPTR(GtFilelengthvalues);
 
122
      break;
 
123
    case GtUcharType:
 
124
      ASSIGNPTR2STARTPTR(GtUchar);
 
125
      break;
 
126
    case Uint16Type:
 
127
      ASSIGNPTR2STARTPTR(uint16_t);
 
128
      break;
 
129
    case Uint32Type:
 
130
      ASSIGNPTR2STARTPTR(uint32_t);
 
131
      break;
 
132
    case GtUlongType:
 
133
      ASSIGNPTR2STARTPTR(unsigned long);
 
134
      break;
 
135
    case Uint64Type:
 
136
      ASSIGNPTR2STARTPTR(uint64_t);
 
137
      break;
 
138
    case GtBitsequenceType:
 
139
      ASSIGNPTR2STARTPTR(GtBitsequence);
 
140
      break;
 
141
    case GtUlongBoundType:
 
142
      ASSIGNPTR2STARTPTR(GtUlongBound);
 
143
      break;
 
144
    case GtPairBwtidxType:
 
145
      ASSIGNPTR2STARTPTR(GtPairBwtidx);
 
146
      break;
 
147
    case GtTwobitencodingType:
 
148
      ASSIGNPTR2STARTPTR(GtTwobitencoding);
 
149
      break;
 
150
    case GtSpecialcharinfoType:
 
151
      ASSIGNPTR2STARTPTR(GtSpecialcharinfo);
 
152
      break;
 
153
    case GtBitElemType:
 
154
      ASSIGNPTR2STARTPTR(BitElem);
 
155
      break;
 
156
    default:
 
157
      gt_error_set(err,"no assignment specification for size %lu",
 
158
                    (unsigned long) mapspec->sizeofunit);
 
159
      had_err = -1;
 
160
  }
 
161
  return had_err;
 
162
}
 
163
 
 
164
struct GtMapspec {
 
165
  GtArrayGtMapspecification mapspectable;
 
166
};
 
167
 
 
168
int  gt_mapspec_read(GtMapspecSetupFunc setup, void *data,
 
169
                     const GtStr *filename, unsigned long expectedsize,
 
170
                     void **mapped, GtError *err)
 
171
{
 
172
  void *mapptr;
 
173
  uint64_t expectedaccordingtomapspec;
 
174
  unsigned long byteoffset = 0;
 
175
  size_t numofbytes;
 
176
  GtMapspec *ms = gt_malloc(sizeof (GtMapspec));
 
177
  GtMapspecification *mapspecptr;
 
178
  int had_err = 0;
 
179
  unsigned long totalpadunits = 0;
 
180
 
 
181
  gt_error_check(err);
 
182
  GT_INITARRAY(&ms->mapspectable, GtMapspecification);
 
183
  setup(ms, data, false);
 
184
 
 
185
  mapptr = gt_fa_mmap_read(gt_str_get(filename), &numofbytes, err);
 
186
  if (mapptr == NULL)
 
187
  {
 
188
    had_err = -1;
 
189
  }
 
190
  *mapped = mapptr;
 
191
  if (!had_err)
 
192
  {
 
193
    if (assigncorrecttype(ms->mapspectable.spaceGtMapspecification,
 
194
                          mapptr,0,err) != 0)
 
195
    {
 
196
      had_err = -1;
 
197
    }
 
198
  }
 
199
  if (!had_err)
 
200
  {
 
201
    expectedaccordingtomapspec =
 
202
                               detexpectedaccordingtomapspec(&ms->mapspectable);
 
203
    if (expectedaccordingtomapspec != (uint64_t) numofbytes)
 
204
    {
 
205
      gt_error_set(err,"%lu bytes read from %s, but " Formatuint64_t
 
206
                         " expected",
 
207
                         (unsigned long) numofbytes,
 
208
                         gt_str_get(filename),
 
209
                         PRINTuint64_tcast(expectedaccordingtomapspec));
 
210
      had_err = -1;
 
211
    }
 
212
  }
 
213
  if (!had_err)
 
214
  {
 
215
    mapspecptr = ms->mapspectable.spaceGtMapspecification;
 
216
    gt_assert(mapspecptr != NULL);
 
217
    byteoffset = CALLCASTFUNC(uint64_t,unsigned_long,
 
218
                              (uint64_t) (mapspecptr->sizeofunit *
 
219
                                          mapspecptr->numofunits));
 
220
    if (byteoffset % (unsigned long) GT_WORDSIZE_INBYTES > 0)
 
221
    {
 
222
      size_t padunits
 
223
        = GT_WORDSIZE_INBYTES - (byteoffset % GT_WORDSIZE_INBYTES);
 
224
      byteoffset += (unsigned long) padunits;
 
225
      totalpadunits += (unsigned long) padunits;
 
226
    }
 
227
    for (mapspecptr++;
 
228
         mapspecptr < ms->mapspectable.spaceGtMapspecification +
 
229
                      ms->mapspectable.nextfreeGtMapspecification; mapspecptr++)
 
230
    {
 
231
      if (assigncorrecttype(mapspecptr,mapptr,byteoffset,err) != 0)
 
232
      {
 
233
        had_err = -1;
 
234
        break;
 
235
      }
 
236
      byteoffset = CALLCASTFUNC(uint64_t,unsigned_long,
 
237
                                (uint64_t) (byteoffset +
 
238
                                            mapspecptr->sizeofunit *
 
239
                                            mapspecptr->numofunits));
 
240
      if (byteoffset % (unsigned long) GT_WORDSIZE_INBYTES > 0)
 
241
      {
 
242
        size_t padunits
 
243
          = GT_WORDSIZE_INBYTES - (byteoffset % GT_WORDSIZE_INBYTES);
 
244
        byteoffset += (unsigned long) padunits;
 
245
        totalpadunits += (unsigned long) padunits;
 
246
      }
 
247
    }
 
248
  }
 
249
  if (!had_err)
 
250
  {
 
251
    if (expectedsize + totalpadunits != byteoffset)
 
252
    {
 
253
      gt_error_set(err,"mapping: expected file size is %lu bytes, "
 
254
                       "but file has %lu bytes",
 
255
                       expectedsize,byteoffset);
 
256
      had_err = -1;
 
257
    }
 
258
  }
 
259
  GT_FREEARRAY(&ms->mapspectable,GtMapspecification);
 
260
  gt_free(ms);
 
261
  return had_err;
 
262
}
 
263
 
 
264
int gt_mapspec_pad(FILE *fp, unsigned long *bytes_written,
 
265
                   unsigned long byteoffset, GT_UNUSED GtError *err)
 
266
{
 
267
  if (byteoffset % (unsigned long) GT_WORDSIZE_INBYTES > 0)
 
268
  {
 
269
    GtUchar padbuffer[GT_WORDSIZE_INBYTES-1] = {0};
 
270
 
 
271
    size_t padunits = GT_WORDSIZE_INBYTES - (byteoffset % GT_WORDSIZE_INBYTES);
 
272
    gt_xfwrite(padbuffer,sizeof (GtUchar),padunits,fp);
 
273
    *bytes_written = (unsigned long) padunits;
 
274
  } else
 
275
  {
 
276
    *bytes_written = 0;
 
277
  }
 
278
  return 0;
 
279
}
 
280
 
 
281
int gt_mapspec_write(GtMapspecSetupFunc setup, FILE *fp,
 
282
                     void *data, unsigned long expectedsize, GtError *err)
 
283
{
 
284
  GtMapspecification *mapspecptr;
 
285
  unsigned long byteoffset = 0;
 
286
  int had_err = 0;
 
287
  unsigned long totalpadunits = 0;
 
288
  unsigned long byteswritten;
 
289
  GtMapspec *ms = gt_malloc(sizeof (GtMapspec));
 
290
 
 
291
  gt_error_check(err);
 
292
  GT_INITARRAY(&ms->mapspectable,GtMapspecification);
 
293
  setup(ms, data, true);
 
294
  gt_assert(ms->mapspectable.spaceGtMapspecification != NULL);
 
295
  for (mapspecptr = ms->mapspectable.spaceGtMapspecification;
 
296
       mapspecptr < ms->mapspectable.spaceGtMapspecification +
 
297
                    ms->mapspectable.nextfreeGtMapspecification;
 
298
       mapspecptr++)
 
299
  {
 
300
#ifdef SKDEBUG
 
301
    printf("# gt_mapspec_flushtheindex2file");
 
302
    showmapspec(mapspecptr);
 
303
    printf(" at byteoffset %lu\n",byteoffset);
 
304
#endif
 
305
    if (mapspecptr->numofunits > 0)
 
306
    {
 
307
      switch (mapspecptr->typespec)
 
308
      {
 
309
        case GtCharType:
 
310
          WRITEACTIONWITHTYPE(char);
 
311
          break;
 
312
        case GtFilelengthvaluesType:
 
313
          WRITEACTIONWITHTYPE(GtFilelengthvalues);
 
314
          break;
 
315
        case GtUcharType:
 
316
          WRITEACTIONWITHTYPE(GtUchar);
 
317
          break;
 
318
        case Uint16Type:
 
319
          WRITEACTIONWITHTYPE(uint16_t);
 
320
          break;
 
321
        case Uint32Type:
 
322
          WRITEACTIONWITHTYPE(uint32_t);
 
323
          break;
 
324
        case GtUlongType:
 
325
          WRITEACTIONWITHTYPE(GtUlong);
 
326
          break;
 
327
        case Uint64Type:
 
328
          WRITEACTIONWITHTYPE(uint64_t);
 
329
          break;
 
330
        case GtBitsequenceType:
 
331
          WRITEACTIONWITHTYPE(GtBitsequence);
 
332
          break;
 
333
        case GtUlongBoundType:
 
334
          WRITEACTIONWITHTYPE(GtUlongBound);
 
335
          break;
 
336
        case GtPairBwtidxType:
 
337
          WRITEACTIONWITHTYPE(GtPairBwtidx);
 
338
          break;
 
339
        case GtTwobitencodingType:
 
340
          WRITEACTIONWITHTYPE(GtTwobitencoding);
 
341
          break;
 
342
        case GtSpecialcharinfoType:
 
343
          WRITEACTIONWITHTYPE(GtSpecialcharinfo);
 
344
          break;
 
345
        case GtBitElemType:
 
346
          WRITEACTIONWITHTYPE(BitElem);
 
347
          break;
 
348
        default:
 
349
           gt_error_set(err,"no map specification for size %lu",
 
350
                         (unsigned long) mapspecptr->sizeofunit);
 
351
           had_err = -1;
 
352
      }
 
353
    }
 
354
    if (had_err)
 
355
    {
 
356
      break;
 
357
    }
 
358
    byteoffset = CALLCASTFUNC(uint64_t,unsigned_long,
 
359
                              (uint64_t) (byteoffset +
 
360
                                          mapspecptr->sizeofunit *
 
361
                                          mapspecptr->numofunits));
 
362
    if (gt_mapspec_pad(fp,&byteswritten,byteoffset,err) != 0)
 
363
    {
 
364
      had_err = -1;
 
365
    }
 
366
    byteoffset += byteswritten;
 
367
    totalpadunits += byteswritten;
 
368
  }
 
369
  if (!had_err)
 
370
  {
 
371
    if (expectedsize + totalpadunits != byteoffset)
 
372
    {
 
373
      gt_error_set(err,"expected file size is %lu bytes, "
 
374
                       "but file has %lu bytes",
 
375
                       expectedsize,
 
376
                       byteoffset);
 
377
      had_err = -1;
 
378
    }
 
379
  }
 
380
  GT_FREEARRAY(&ms->mapspectable,GtMapspecification);
 
381
  gt_free(ms);
 
382
  return had_err;
 
383
}
 
384
 
 
385
#define NEWMAPSPEC(MS,PTR,TYPE,SIZE,ELEMS)\
 
386
        GT_GETNEXTFREEINARRAY(mapspecptr,&MS->mapspectable, \
 
387
                              GtMapspecification,10);\
 
388
        mapspecptr->typespec = TYPE;\
 
389
        mapspecptr->startptr = PTR;\
 
390
        mapspecptr->sizeofunit = SIZE;\
 
391
        mapspecptr->numofunits = ELEMS;\
 
392
        mapspecptr->name = #PTR
 
393
 
 
394
void gt_mapspec_add_char_ptr(GtMapspec *mapspec, char **ptr, unsigned long n)
 
395
{
 
396
  GtMapspecification *mapspecptr;
 
397
  gt_assert(mapspec && ptr);
 
398
  NEWMAPSPEC(mapspec, ptr, GtCharType, sizeof (char), n);
 
399
}
 
400
 
 
401
void gt_mapspec_add_uchar_ptr(GtMapspec *mapspec, GtUchar **ptr,
 
402
                              unsigned long n)
 
403
{
 
404
  GtMapspecification *mapspecptr;
 
405
  gt_assert(mapspec && ptr);
 
406
  NEWMAPSPEC(mapspec, ptr, GtUcharType, sizeof (GtUchar), n);
 
407
}
 
408
 
 
409
void gt_mapspec_add_uint16_ptr(GtMapspec *mapspec, uint16_t **ptr,
 
410
                               unsigned long n)
 
411
{
 
412
  GtMapspecification *mapspecptr;
 
413
  gt_assert(mapspec && ptr);
 
414
  NEWMAPSPEC(mapspec, ptr, Uint16Type, sizeof (uint16_t), n);
 
415
}
 
416
 
 
417
void gt_mapspec_add_ulong_ptr(GtMapspec *mapspec, unsigned long **ptr,
 
418
                              unsigned long n)
 
419
{
 
420
  GtMapspecification *mapspecptr;
 
421
  gt_assert(mapspec && ptr);
 
422
  NEWMAPSPEC(mapspec, ptr, GtUlongType, sizeof (unsigned long), n);
 
423
}
 
424
 
 
425
void gt_mapspec_add_ulongbound_ptr(GtMapspec *mapspec, GtUlongBound **ptr,
 
426
                                   unsigned long n)
 
427
{
 
428
  GtMapspecification *mapspecptr;
 
429
  gt_assert(mapspec && ptr);
 
430
  NEWMAPSPEC(mapspec, ptr, GtUlongBoundType, sizeof (GtUlongBound), n);
 
431
}
 
432
 
 
433
void gt_mapspec_add_uint32_ptr(GtMapspec *mapspec, uint32_t **ptr,
 
434
                               unsigned long n)
 
435
{
 
436
  GtMapspecification *mapspecptr;
 
437
  gt_assert(mapspec && ptr);
 
438
  NEWMAPSPEC(mapspec, ptr, Uint32Type, sizeof (uint32_t), n);
 
439
}
 
440
 
 
441
void gt_mapspec_add_uint64_ptr(GtMapspec *mapspec, uint64_t **ptr,
 
442
                               unsigned long n)
 
443
{
 
444
  GtMapspecification *mapspecptr;
 
445
  gt_assert(mapspec && ptr);
 
446
  NEWMAPSPEC(mapspec, ptr, Uint64Type, sizeof (uint64_t), n);
 
447
}
 
448
 
 
449
void gt_mapspec_add_bitsequence_ptr(GtMapspec *mapspec, GtBitsequence **ptr,
 
450
                                    unsigned long n)
 
451
{
 
452
  GtMapspecification *mapspecptr;
 
453
  gt_assert(mapspec && ptr);
 
454
  NEWMAPSPEC(mapspec, ptr, GtBitsequenceType, sizeof (GtBitsequence), n);
 
455
}
 
456
void gt_mapspec_add_twobitencoding_ptr(GtMapspec *mapspec,
 
457
                                       GtTwobitencoding **ptr, unsigned long n)
 
458
{
 
459
  GtMapspecification *mapspecptr;
 
460
  gt_assert(mapspec && ptr);
 
461
  NEWMAPSPEC(mapspec, ptr, GtTwobitencodingType, sizeof (GtTwobitencoding), n);
 
462
}
 
463
 
 
464
void gt_mapspec_add_specialcharinfo_ptr(GtMapspec *mapspec,
 
465
                                        GtSpecialcharinfo **ptr,
 
466
                                        unsigned long n)
 
467
{
 
468
  GtMapspecification *mapspecptr;
 
469
  gt_assert(mapspec && ptr);
 
470
  NEWMAPSPEC(mapspec, ptr, GtSpecialcharinfoType, sizeof (GtSpecialcharinfo),
 
471
             n);
 
472
}
 
473
 
 
474
void gt_mapspec_add_bitelem_ptr(GtMapspec *mapspec, BitElem **ptr,
 
475
                                unsigned long n)
 
476
{
 
477
  GtMapspecification *mapspecptr;
 
478
  gt_assert(mapspec && ptr);
 
479
  NEWMAPSPEC(mapspec, ptr, GtBitElemType, sizeof (BitElem), n);
 
480
}
 
481
 
 
482
void gt_mapspec_add_filelengthvalues_ptr(GtMapspec *mapspec,
 
483
                                         GtFilelengthvalues **ptr,
 
484
                                         unsigned long n)
 
485
{
 
486
  GtMapspecification *mapspecptr;
 
487
  gt_assert(mapspec && ptr);
 
488
  NEWMAPSPEC(mapspec, ptr, GtFilelengthvaluesType,
 
489
             sizeof (GtFilelengthvalues), n);
 
490
}
 
491
 
 
492
void gt_mapspec_add_pairbwtindex_ptr(GtMapspec *mapspec, GtPairBwtidx **ptr,
 
493
                                     unsigned long n)
 
494
{
 
495
  GtMapspecification *mapspecptr;
 
496
  gt_assert(mapspec && ptr);
 
497
  NEWMAPSPEC(mapspec, ptr, GtPairBwtidxType, sizeof (GtPairBwtidx), n);
 
498
}