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
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.
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.
19
#include "core/error.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"
29
#include "core/ulongbound.h"
30
#include "core/xansi_api.h"
34
GtCharType, /* \0 terminated string */
35
GtFilelengthvaluesType,
45
GtSpecialcharinfoType,
55
unsigned long numofunits;
58
GT_DECLAREARRAYSTRUCT(GtMapspecification);
60
#define ASSIGNPTR2STARTPTR(TYPE)\
61
if (mapspec->numofunits == 0)\
63
*((TYPE **) mapspec->startptr) = NULL;\
66
voidptr = (((char *) ptr) + byteoffset);\
67
*((TYPE **) mapspec->startptr) = voidptr;\
70
#define WRITEACTIONWITHTYPE(TYPE)\
71
gt_xfwrite(*((TYPE **) mapspecptr->startptr),\
72
mapspecptr->sizeofunit,\
73
(size_t) mapspecptr->numofunits, fp);
75
static uint64_t detexpectedaccordingtomapspec(const GtArrayGtMapspecification
79
GtMapspecification *mapspecptr;
81
for (mapspecptr = mapspectable->spaceGtMapspecification;
82
mapspecptr < mapspectable->spaceGtMapspecification +
83
mapspectable->nextfreeGtMapspecification; mapspecptr++)
85
sumup += (uint64_t) mapspecptr->sizeofunit *
86
(uint64_t) mapspecptr->numofunits;
87
if (sumup % GT_WORDSIZE_INBYTES > 0)
89
sumup += (GT_WORDSIZE_INBYTES - (sumup % GT_WORDSIZE_INBYTES));
97
static void showmapspec(const GtMapspecification *mapspec)
99
printf("(%s,size=%lu,elems=%lu)",
101
(unsigned long) mapspec->sizeofunit,
102
mapspec->numofunits);
106
static int assigncorrecttype(GtMapspecification *mapspec,
108
unsigned long byteoffset,
115
switch (mapspec->typespec)
118
ASSIGNPTR2STARTPTR(char);
120
case GtFilelengthvaluesType:
121
ASSIGNPTR2STARTPTR(GtFilelengthvalues);
124
ASSIGNPTR2STARTPTR(GtUchar);
127
ASSIGNPTR2STARTPTR(uint16_t);
130
ASSIGNPTR2STARTPTR(uint32_t);
133
ASSIGNPTR2STARTPTR(unsigned long);
136
ASSIGNPTR2STARTPTR(uint64_t);
138
case GtBitsequenceType:
139
ASSIGNPTR2STARTPTR(GtBitsequence);
141
case GtUlongBoundType:
142
ASSIGNPTR2STARTPTR(GtUlongBound);
144
case GtPairBwtidxType:
145
ASSIGNPTR2STARTPTR(GtPairBwtidx);
147
case GtTwobitencodingType:
148
ASSIGNPTR2STARTPTR(GtTwobitencoding);
150
case GtSpecialcharinfoType:
151
ASSIGNPTR2STARTPTR(GtSpecialcharinfo);
154
ASSIGNPTR2STARTPTR(BitElem);
157
gt_error_set(err,"no assignment specification for size %lu",
158
(unsigned long) mapspec->sizeofunit);
165
GtArrayGtMapspecification mapspectable;
168
int gt_mapspec_read(GtMapspecSetupFunc setup, void *data,
169
const GtStr *filename, unsigned long expectedsize,
170
void **mapped, GtError *err)
173
uint64_t expectedaccordingtomapspec;
174
unsigned long byteoffset = 0;
176
GtMapspec *ms = gt_malloc(sizeof (GtMapspec));
177
GtMapspecification *mapspecptr;
179
unsigned long totalpadunits = 0;
182
GT_INITARRAY(&ms->mapspectable, GtMapspecification);
183
setup(ms, data, false);
185
mapptr = gt_fa_mmap_read(gt_str_get(filename), &numofbytes, err);
193
if (assigncorrecttype(ms->mapspectable.spaceGtMapspecification,
201
expectedaccordingtomapspec =
202
detexpectedaccordingtomapspec(&ms->mapspectable);
203
if (expectedaccordingtomapspec != (uint64_t) numofbytes)
205
gt_error_set(err,"%lu bytes read from %s, but " Formatuint64_t
207
(unsigned long) numofbytes,
208
gt_str_get(filename),
209
PRINTuint64_tcast(expectedaccordingtomapspec));
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)
223
= GT_WORDSIZE_INBYTES - (byteoffset % GT_WORDSIZE_INBYTES);
224
byteoffset += (unsigned long) padunits;
225
totalpadunits += (unsigned long) padunits;
228
mapspecptr < ms->mapspectable.spaceGtMapspecification +
229
ms->mapspectable.nextfreeGtMapspecification; mapspecptr++)
231
if (assigncorrecttype(mapspecptr,mapptr,byteoffset,err) != 0)
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)
243
= GT_WORDSIZE_INBYTES - (byteoffset % GT_WORDSIZE_INBYTES);
244
byteoffset += (unsigned long) padunits;
245
totalpadunits += (unsigned long) padunits;
251
if (expectedsize + totalpadunits != byteoffset)
253
gt_error_set(err,"mapping: expected file size is %lu bytes, "
254
"but file has %lu bytes",
255
expectedsize,byteoffset);
259
GT_FREEARRAY(&ms->mapspectable,GtMapspecification);
264
int gt_mapspec_pad(FILE *fp, unsigned long *bytes_written,
265
unsigned long byteoffset, GT_UNUSED GtError *err)
267
if (byteoffset % (unsigned long) GT_WORDSIZE_INBYTES > 0)
269
GtUchar padbuffer[GT_WORDSIZE_INBYTES-1] = {0};
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;
281
int gt_mapspec_write(GtMapspecSetupFunc setup, FILE *fp,
282
void *data, unsigned long expectedsize, GtError *err)
284
GtMapspecification *mapspecptr;
285
unsigned long byteoffset = 0;
287
unsigned long totalpadunits = 0;
288
unsigned long byteswritten;
289
GtMapspec *ms = gt_malloc(sizeof (GtMapspec));
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;
301
printf("# gt_mapspec_flushtheindex2file");
302
showmapspec(mapspecptr);
303
printf(" at byteoffset %lu\n",byteoffset);
305
if (mapspecptr->numofunits > 0)
307
switch (mapspecptr->typespec)
310
WRITEACTIONWITHTYPE(char);
312
case GtFilelengthvaluesType:
313
WRITEACTIONWITHTYPE(GtFilelengthvalues);
316
WRITEACTIONWITHTYPE(GtUchar);
319
WRITEACTIONWITHTYPE(uint16_t);
322
WRITEACTIONWITHTYPE(uint32_t);
325
WRITEACTIONWITHTYPE(GtUlong);
328
WRITEACTIONWITHTYPE(uint64_t);
330
case GtBitsequenceType:
331
WRITEACTIONWITHTYPE(GtBitsequence);
333
case GtUlongBoundType:
334
WRITEACTIONWITHTYPE(GtUlongBound);
336
case GtPairBwtidxType:
337
WRITEACTIONWITHTYPE(GtPairBwtidx);
339
case GtTwobitencodingType:
340
WRITEACTIONWITHTYPE(GtTwobitencoding);
342
case GtSpecialcharinfoType:
343
WRITEACTIONWITHTYPE(GtSpecialcharinfo);
346
WRITEACTIONWITHTYPE(BitElem);
349
gt_error_set(err,"no map specification for size %lu",
350
(unsigned long) mapspecptr->sizeofunit);
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)
366
byteoffset += byteswritten;
367
totalpadunits += byteswritten;
371
if (expectedsize + totalpadunits != byteoffset)
373
gt_error_set(err,"expected file size is %lu bytes, "
374
"but file has %lu bytes",
380
GT_FREEARRAY(&ms->mapspectable,GtMapspecification);
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
394
void gt_mapspec_add_char_ptr(GtMapspec *mapspec, char **ptr, unsigned long n)
396
GtMapspecification *mapspecptr;
397
gt_assert(mapspec && ptr);
398
NEWMAPSPEC(mapspec, ptr, GtCharType, sizeof (char), n);
401
void gt_mapspec_add_uchar_ptr(GtMapspec *mapspec, GtUchar **ptr,
404
GtMapspecification *mapspecptr;
405
gt_assert(mapspec && ptr);
406
NEWMAPSPEC(mapspec, ptr, GtUcharType, sizeof (GtUchar), n);
409
void gt_mapspec_add_uint16_ptr(GtMapspec *mapspec, uint16_t **ptr,
412
GtMapspecification *mapspecptr;
413
gt_assert(mapspec && ptr);
414
NEWMAPSPEC(mapspec, ptr, Uint16Type, sizeof (uint16_t), n);
417
void gt_mapspec_add_ulong_ptr(GtMapspec *mapspec, unsigned long **ptr,
420
GtMapspecification *mapspecptr;
421
gt_assert(mapspec && ptr);
422
NEWMAPSPEC(mapspec, ptr, GtUlongType, sizeof (unsigned long), n);
425
void gt_mapspec_add_ulongbound_ptr(GtMapspec *mapspec, GtUlongBound **ptr,
428
GtMapspecification *mapspecptr;
429
gt_assert(mapspec && ptr);
430
NEWMAPSPEC(mapspec, ptr, GtUlongBoundType, sizeof (GtUlongBound), n);
433
void gt_mapspec_add_uint32_ptr(GtMapspec *mapspec, uint32_t **ptr,
436
GtMapspecification *mapspecptr;
437
gt_assert(mapspec && ptr);
438
NEWMAPSPEC(mapspec, ptr, Uint32Type, sizeof (uint32_t), n);
441
void gt_mapspec_add_uint64_ptr(GtMapspec *mapspec, uint64_t **ptr,
444
GtMapspecification *mapspecptr;
445
gt_assert(mapspec && ptr);
446
NEWMAPSPEC(mapspec, ptr, Uint64Type, sizeof (uint64_t), n);
449
void gt_mapspec_add_bitsequence_ptr(GtMapspec *mapspec, GtBitsequence **ptr,
452
GtMapspecification *mapspecptr;
453
gt_assert(mapspec && ptr);
454
NEWMAPSPEC(mapspec, ptr, GtBitsequenceType, sizeof (GtBitsequence), n);
456
void gt_mapspec_add_twobitencoding_ptr(GtMapspec *mapspec,
457
GtTwobitencoding **ptr, unsigned long n)
459
GtMapspecification *mapspecptr;
460
gt_assert(mapspec && ptr);
461
NEWMAPSPEC(mapspec, ptr, GtTwobitencodingType, sizeof (GtTwobitencoding), n);
464
void gt_mapspec_add_specialcharinfo_ptr(GtMapspec *mapspec,
465
GtSpecialcharinfo **ptr,
468
GtMapspecification *mapspecptr;
469
gt_assert(mapspec && ptr);
470
NEWMAPSPEC(mapspec, ptr, GtSpecialcharinfoType, sizeof (GtSpecialcharinfo),
474
void gt_mapspec_add_bitelem_ptr(GtMapspec *mapspec, BitElem **ptr,
477
GtMapspecification *mapspecptr;
478
gt_assert(mapspec && ptr);
479
NEWMAPSPEC(mapspec, ptr, GtBitElemType, sizeof (BitElem), n);
482
void gt_mapspec_add_filelengthvalues_ptr(GtMapspec *mapspec,
483
GtFilelengthvalues **ptr,
486
GtMapspecification *mapspecptr;
487
gt_assert(mapspec && ptr);
488
NEWMAPSPEC(mapspec, ptr, GtFilelengthvaluesType,
489
sizeof (GtFilelengthvalues), n);
492
void gt_mapspec_add_pairbwtindex_ptr(GtMapspec *mapspec, GtPairBwtidx **ptr,
495
GtMapspecification *mapspecptr;
496
gt_assert(mapspec && ptr);
497
NEWMAPSPEC(mapspec, ptr, GtPairBwtidxType, sizeof (GtPairBwtidx), n);