22 #include <Rinternals.h>
37 if(total_size<1)total_size=1;
41 Rprintf(
"libMVL: *** INTERNAL ERROR: Could not allocate %llu chunks of %llu bytes each because of overflow %llu total)\n",a,b,a*b);
43 fprintf(stderr,
"libMVL: *** INTERNAL ERROR: Could not allocate %llu chunks of %llu bytes each because of overflow %llu total\n",a,b,a*b);
51 Rprintf(
"libMVL: Could not allocate %llu chunks of %llu bytes each (%llu bytes total)\n",a,b,a*b);
53 fprintf(stderr,
"libMVL: Could not allocate %llu chunks of %llu bytes each (%llu bytes total)\n",a,b,a*b);
68 p=do_malloc(len+1, 1);
69 for(i=0;i<len;i++)p[i]=s[i];
82 off_t do_ftello(FILE *f)
89 return(lseek(fileno(f), 0, SEEK_CUR));
93 #ifndef HAVE_POSIX_FALLOCATE
95 #if _POSIX_C_SOURCE >= 200112L
96 #define HAVE_POSIX_FALLOCATE 1
98 #define HAVE_POSIX_FALLOCATE 0
105 #if HAVE_POSIX_FALLOCATE
107 return(posix_fallocate(fileno(f), offset, len));
113 #ifndef FALLOCATE_BUF_SIZE
114 #define FALLOCATE_BUF_SIZE 512
116 char buf[FALLOCATE_BUF_SIZE];
119 if(cur<0)
return(cur);
121 if((err=fseeko(f, 0, SEEK_END))<0) {
126 if(end<0)
return(end);
128 if(end>=(offset+len))
return(0);
130 memset(buf, 0, FALLOCATE_BUF_SIZE);
132 for(i=end;i<offset+len;i+=FALLOCATE_BUF_SIZE) {
133 size_t cnt=offset+len-i;
134 if(cnt>FALLOCATE_BUF_SIZE)cnt=FALLOCATE_BUF_SIZE;
135 fwrite(buf, 1, cnt, f);
138 if((err=fseeko(f, cur, SEEK_SET))<0) {
154 ctx=do_malloc(1,
sizeof(*ctx));
155 if(ctx==NULL)
return(ctx);
157 memset(ctx, 0,
sizeof(*ctx));
160 ctx->abort_on_error=1;
166 ctx->directory_offset=-1;
170 ctx->character_class_offset=0;
176 #ifdef HAVE_POSIX_FALLOCATE
177 ctx->flags|=LIBMVL_CTX_FLAG_HAVE_POSIX_FALLOCATE;
181 ctx->flags|=LIBMVL_CTX_FLAG_HAVE_FTELLO;
203 if(ctx->abort_on_error) {
205 Rprintf(
"*** ERROR: libMVL code %d: %s\n", error,
mvl_strerror(ctx));
207 fprintf(stderr,
"*** ERROR: libMVL code %d: %s\n", error,
mvl_strerror(ctx));
222 case LIBMVL_ERR_FAIL_PREAMBLE:
223 return(
"invalid preamble");
224 case LIBMVL_ERR_FAIL_POSTAMBLE:
225 return(
"invalid postamble");
226 case LIBMVL_ERR_UNKNOWN_TYPE :
227 return(
"unknown type");
228 case LIBMVL_ERR_FAIL_VECTOR:
229 return(
"unknown type");
230 case LIBMVL_ERR_INCOMPLETE_WRITE:
231 return(
"incomplete write");
232 case LIBMVL_ERR_INVALID_SIGNATURE:
233 return(
"invalid signature");
234 case LIBMVL_ERR_WRONG_ENDIANNESS:
235 return(
"wrong endianness");
236 case LIBMVL_ERR_EMPTY_DIRECTORY:
237 return(
"empty MVL directory");
238 case LIBMVL_ERR_INVALID_DIRECTORY:
239 return(
"invalid MVL directory");
240 case LIBMVL_ERR_FTELL:
241 return(
"call to ftell() failed");
242 case LIBMVL_ERR_CORRUPT_POSTAMBLE:
243 return(
"corrupt postamble");
244 case LIBMVL_ERR_INVALID_ATTR_LIST:
245 return(
"invalid attribute list");
246 case LIBMVL_ERR_INVALID_OFFSET:
247 return(
"invalid offset");
248 case LIBMVL_ERR_INVALID_ATTR:
249 return(
"invalid attributes");
250 case LIBMVL_ERR_CANNOT_SEEK:
251 return(
"seek() call failed");
252 case LIBMVL_ERR_INVALID_PARAMETER:
253 return(
"invalid parameter");
254 case LIBMVL_ERR_INVALID_LENGTH:
255 return(
"invalid length");
256 case LIBMVL_ERR_INVALID_EXTENT_INDEX:
257 return(
"invalid extent index");
258 case LIBMVL_ERR_UNALIGNED_POINTER:
259 return(
"pointer is not properly aligned");
260 case LIBMVL_ERR_UNALIGNED_OFFSET:
261 return(
"an offset or size parameter is not properly aligned");
262 case LIBMVL_ERR_INVALID_HEADER:
263 return(
"invalid or inappropriate vector header");
264 case LIBMVL_ERR_UNKNOWN_CHECKSUM_ALGORITHM:
265 return(
"unknown checksum algorithm");
266 case LIBMVL_ERR_CHECKSUM_FAILED:
267 return(
"checksum did not match, corrupt data likely");
268 case LIBMVL_ERR_NO_CHECKSUMS:
269 return(
"no checksums found, cannot verify");
270 case LIBMVL_ERR_NO_DATA:
271 return(
"data is NULL and mvl_load_image() has not been called on MVL context");
272 case LIBMVL_ERR_MVL_FILE_TOO_SHORT:
273 return(
"MVL file length is too short, indicating a corrupt or wrong file");
275 return(
"unknown error");
283 n=fwrite(data, 1, length, ctx->f);
284 if(n<length)mvl_set_error(ctx, LIBMVL_ERR_INCOMPLETE_WRITE);
291 cur=do_ftello(ctx->f);
293 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
296 if(fseeko(ctx->f, offset, SEEK_SET)<0) {
297 mvl_set_error(ctx, LIBMVL_ERR_CANNOT_SEEK);
300 n=fwrite(data, 1, length, ctx->f);
301 if(n<length)mvl_set_error(ctx, LIBMVL_ERR_INCOMPLETE_WRITE);
302 if(fseeko(ctx->f, cur, SEEK_SET)<0) {
303 mvl_set_error(ctx, LIBMVL_ERR_CANNOT_SEEK);
310 memset(&(ctx->tmp_preamble), 0,
sizeof(ctx->tmp_preamble));
311 memcpy(ctx->tmp_preamble.signature, LIBMVL_SIGNATURE, 4);
312 ctx->tmp_preamble.endianness=LIBMVL_ENDIANNESS_FLAG;
313 ctx->tmp_preamble.alignment=ctx->alignment;
314 mvl_write(ctx,
sizeof(ctx->tmp_preamble), &ctx->tmp_preamble);
319 memset(&(ctx->tmp_postamble), 0,
sizeof(ctx->tmp_postamble));
320 ctx->tmp_postamble.directory=ctx->directory_offset;
321 #ifdef MVL_OLD_DIRECTORY
322 ctx->tmp_postamble.type=LIBMVL_VECTOR_POSTAMBLE1;
324 ctx->tmp_postamble.type=LIBMVL_VECTOR_POSTAMBLE2;
326 mvl_write(ctx,
sizeof(ctx->tmp_postamble), &ctx->tmp_postamble);
341 unsigned char *zeros;
344 memset(&(ctx->tmp_vh), 0,
sizeof(ctx->tmp_vh));
348 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
351 padding=ctx->alignment-((byte_length+
sizeof(ctx->tmp_vh)) & (ctx->alignment-1));
352 padding=padding & (ctx->alignment-1);
354 ctx->tmp_vh.length=length;
355 ctx->tmp_vh.type=type;
356 ctx->tmp_vh.metadata=metadata;
358 offset=do_ftello(ctx->f);
361 perror(
"mvl_write_vector");
362 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
366 mvl_write(ctx,
sizeof(ctx->tmp_vh), &ctx->tmp_vh);
367 mvl_write(ctx, byte_length, data);
370 zeros=alloca(padding);
371 memset(zeros, 0, padding);
372 mvl_write(ctx, padding, zeros);
391 unsigned char *zeros;
394 if(length>expected_length) {
395 mvl_set_error(ctx, LIBMVL_ERR_INVALID_PARAMETER);
400 memset(&(ctx->tmp_vh), 0,
sizeof(ctx->tmp_vh));
406 total_byte_length=expected_length;
410 byte_length=length*4;
411 total_byte_length=expected_length*4;
417 byte_length=length*8;
418 total_byte_length=expected_length*8;
421 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
424 padding=ctx->alignment-((total_byte_length+
sizeof(ctx->tmp_vh)) & (ctx->alignment-1));
425 padding=padding & (ctx->alignment-1);
427 ctx->tmp_vh.length=expected_length;
428 ctx->tmp_vh.type=type;
429 ctx->tmp_vh.metadata=metadata;
431 offset=do_ftello(ctx->f);
434 perror(
"mvl_write_vector");
435 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
439 if(do_fallocate(ctx->f, offset,
sizeof(ctx->tmp_vh)+total_byte_length+padding)) {
440 mvl_set_error(ctx, LIBMVL_ERR_INCOMPLETE_WRITE);
444 mvl_write(ctx,
sizeof(ctx->tmp_vh), &ctx->tmp_vh);
445 if(byte_length>0)mvl_write(ctx, byte_length, data);
446 if(total_byte_length>byte_length) {
447 if(fseeko(ctx->f, total_byte_length-byte_length, SEEK_CUR)<0) {
448 mvl_set_error(ctx, LIBMVL_ERR_CANNOT_SEEK);
454 zeros=alloca(padding);
455 memset(zeros, 0, padding);
456 mvl_write(ctx, padding, zeros);
475 byte_length=length*elt_size;
477 if(byte_length>0)mvl_rewrite(ctx, base_offset+elt_size*idx+
sizeof(ctx->tmp_vh), byte_length, data);
493 LIBMVL_OFFSET64 char_length, vec_length, i, m, k, i_start, char_start, char_buf_length, vec_buf_length, N;
495 unsigned char *char_buffer;
500 vec_length=index_count+1;
502 for(i=0;i<index_count;i++) {
504 mvl_set_error(ctx, LIBMVL_ERR_CORRUPT_PACKED_LIST);
511 vec_length=index_count;
515 vec_buf_length=vec_length;
519 if(vec_buf_length<50)vec_buf_length=50;
525 char_buf_length=char_length;
526 if(char_buf_length>max_buffer)char_buf_length=max_buffer;
527 if(char_buf_length<100)char_buf_length=100;
528 char_buffer=do_malloc(char_buf_length, 1);
539 while(i_start<index_count) {
545 if(i>=char_buf_length) {
555 if(i>char_buf_length)N--;
579 unsigned char *pb=(
unsigned char *)vec_buffer;
580 N=index_count-i_start;
581 if(N>vec_buf_length)N=vec_buf_length;
590 int *pi=(
int *)vec_buffer;
591 N=index_count-i_start;
592 if(N>vec_buf_length)N=vec_buf_length;
601 long long *pi=(
long long *)vec_buffer;
602 N=index_count-i_start;
603 if(N>vec_buf_length)N=vec_buf_length;
612 float *pf=(
float *)vec_buffer;
613 N=index_count-i_start;
614 if(N>vec_buf_length)N=vec_buf_length;
623 double *pd=(
double *)vec_buffer;
624 N=index_count-i_start;
625 if(N>vec_buf_length)N=vec_buf_length;
635 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
657 int padding, item_size;
658 unsigned char *zeros;
663 for(i=0;i<nvec;i++)length+=lengths[i];
665 memset(&(ctx->tmp_vh), 0,
sizeof(ctx->tmp_vh));
669 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
672 byte_length=length*item_size;
673 padding=ctx->alignment-((byte_length+
sizeof(ctx->tmp_vh)) & (ctx->alignment-1));
674 padding=padding & (ctx->alignment-1);
676 ctx->tmp_vh.length=length;
677 ctx->tmp_vh.type=type;
678 ctx->tmp_vh.metadata=metadata;
680 offset=do_ftello(ctx->f);
682 if((
long long)offset<0) {
683 perror(
"mvl_write_vector");
684 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
687 mvl_write(ctx,
sizeof(ctx->tmp_vh), &ctx->tmp_vh);
689 mvl_write(ctx, lengths[i]*item_size, data[i]);
692 zeros=alloca(padding);
693 memset(zeros, 0, padding);
694 mvl_write(ctx, padding, zeros);
709 if(length<0)length=strlen(data);
722 if(length<0)length=strlen(data);
736 va_start(ap, metadata);
743 for(i=0;i<count;i++)data[i]=va_arg(ap,
int);
750 data=alloca(count*
sizeof(*data));
751 for(i=0;i<count;i++)data[i]=va_arg(ap,
int);
758 data=alloca(count*
sizeof(*data));
759 for(i=0;i<count;i++)data[i]=va_arg(ap,
double);
766 data=alloca(count*
sizeof(*data));
767 for(i=0;i<count;i++)data[i]=va_arg(ap,
long long);
774 data=alloca(count*
sizeof(*data));
775 for(i=0;i<count;i++)data[i]=va_arg(ap,
double);
782 data=alloca(count*
sizeof(*data));
789 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
808 ofsv=do_malloc(count+1,
sizeof(*ofsv));
809 str_size2=do_malloc(count,
sizeof(*str_size2));
812 for(i=0;i<count;i++) {
813 if((str_size==NULL) || (str_size[i]<0)) {
814 str_size2[i]=strlen((
char *)str[i]);
816 str_size2[i]=str_size[i];
823 for(i=0;i<count;i++) {
824 ofsv[i+1]=ofsv[i]+str_size2[i];
839 #ifndef LIBMVL_INTERNAL1_HASH64_BLOCKSIZE
840 #define LIBMVL_INTERNAL1_HASH64_BLOCKSIZE 65536
860 unsigned char *data8;
861 unsigned char *zeros;
868 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
872 data8=(
unsigned char *)data;
875 mvl_set_error(ctx, LIBMVL_ERR_UNALIGNED_POINTER);
879 if((checksum_area_start & 0x7) || (checksum_block_size & 0x7) || (checksum_area_stop & 0x7)) {
880 mvl_set_error(ctx, LIBMVL_ERR_UNALIGNED_OFFSET);
884 memset(hdr, 0,
sizeof(*hdr));
885 hdr->type=LIBMVL_VECTOR_CHECKSUM;
887 hdr->checksum_area_start=checksum_area_start;
888 hdr->checksum_area_stop=checksum_area_stop;
889 hdr->checksum_block_size=checksum_block_size;
890 hdr->length=(checksum_area_stop-checksum_area_start+checksum_block_size-1)/checksum_block_size;
893 byte_length=hdr->length*8;
894 padding=ctx->alignment-((byte_length+
sizeof(ctx->tmp_vh)) & (ctx->alignment-1));
895 padding=padding & (ctx->alignment-1);
898 buffer=do_malloc(LIBMVL_INTERNAL1_HASH64_BLOCKSIZE,
sizeof(*buffer));
900 offset=do_ftello(ctx->f);
902 if((
long long)offset<0) {
903 perror(
"mvl_write_vector");
904 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
907 mvl_write(ctx,
sizeof(ctx->tmp_vh), &ctx->tmp_vh);
910 for(block=checksum_area_start;block<checksum_area_stop;block+=checksum_block_size) {
911 block_stop=block+checksum_block_size;
912 if(block_stop>checksum_area_stop)block_stop=checksum_area_stop;
918 buffer[buffer_idx]=hash;
921 if(buffer_idx>=LIBMVL_INTERNAL1_HASH64_BLOCKSIZE) {
922 mvl_write(ctx, buffer_idx*
sizeof(*buffer), buffer);
928 mvl_write(ctx, buffer_idx*
sizeof(*buffer), buffer);
933 zeros=alloca(padding);
934 memset(zeros, 0, padding);
935 mvl_write(ctx, padding, zeros);
955 unsigned char *data8;
960 data_size=ctx->data_size;
964 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
968 data8=(
unsigned char *)data;
970 if(checksum_vector==NULL) {
972 mvl_set_error(ctx, LIBMVL_ERR_NO_CHECKSUMS);
975 checksum_vector=(
LIBMVL_VECTOR *) &(data8[ctx->full_checksums_offset]);
981 if(hdr->type!=LIBMVL_VECTOR_CHECKSUM) {
982 mvl_set_error(ctx, LIBMVL_ERR_INVALID_HEADER);
987 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_CHECKSUM_ALGORITHM);
992 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1001 if(start<hdr->checksum_area_start || stop>hdr->checksum_area_stop) {
1002 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1006 if(hdr->length < ((hdr->checksum_area_stop-hdr->checksum_area_start+hdr->checksum_block_size-1) / hdr->checksum_block_size)) {
1007 mvl_set_error(ctx, LIBMVL_ERR_INVALID_HEADER);
1011 start2=start-((start-hdr->checksum_area_start) % hdr->checksum_block_size);
1013 block=(stop-hdr->checksum_area_start) % hdr->checksum_block_size;
1015 if(block>0)stop2+=hdr->checksum_block_size-block;
1017 if(stop2>hdr->checksum_area_stop)stop2=hdr->checksum_area_stop;
1019 if(stop2>data_size) {
1020 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1024 buffer_idx=(start2-hdr->checksum_area_start) / hdr->checksum_block_size;
1026 for(block=start2;block<stop2;block+=hdr->checksum_block_size) {
1028 block_stop=block+hdr->checksum_block_size;
1029 if(block_stop>hdr->checksum_area_stop)block_stop=hdr->checksum_area_stop;
1035 if(buffer[buffer_idx]!=hash) {
1036 mvl_set_error(ctx, LIBMVL_ERR_CHECKSUM_FAILED);
1055 unsigned char *data8;
1059 data_size=ctx->data_size;
1063 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
1067 data8=(
unsigned char *)data;
1069 if(checksum_vector==NULL) {
1071 mvl_set_error(ctx, LIBMVL_ERR_NO_CHECKSUMS);
1074 checksum_vector=(
LIBMVL_VECTOR *) &(data8[ctx->full_checksums_offset]);
1079 if(hdr->type!=LIBMVL_VECTOR_CHECKSUM) {
1080 mvl_set_error(ctx, LIBMVL_ERR_INVALID_HEADER);
1084 return(
mvl_verify_checksum_vector(ctx, checksum_vector, data, data_size, hdr->checksum_area_start, hdr->checksum_area_stop));
1106 data_size=ctx->data_size;
1110 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
1117 mvl_set_error(ctx, err);
1121 if(checksum_vector==NULL) {
1123 mvl_set_error(ctx, LIBMVL_ERR_NO_CHECKSUMS);
1126 checksum_vector=(
LIBMVL_VECTOR *) &(data8[ctx->full_checksums_offset]);
1134 mvl_set_error(ctx, LIBMVL_ERR_UNKNOWN_TYPE);
1140 if((a=
mvl_verify_checksum_vector(ctx, checksum_vector, data, data_size, vector_offset, vector_offset+byte_length+
sizeof(*vec))))
return(a);
1161 char *start8=(
char *)start;
1162 char *stop8=(
char *)stop;
1166 data_size=ctx->data_size;
1170 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
1176 if( (start8-data8 < 0) || (start8-data8>data_size) || (stop8-data8<0) || (stop8-data8>data_size)) {
1177 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1190 if(ctx->character_class_offset==0) {
1195 return(ctx->character_class_offset);
1254 if(ctx->directory->free<1) {
1255 mvl_set_error(ctx, LIBMVL_ERR_EMPTY_DIRECTORY);
1259 #ifdef MVL_OLD_DIRECTORY
1261 p=do_malloc(ctx->directory->free*2,
sizeof(*p));
1262 for(
int i=0;i<ctx->directory->free;i++) {
1266 p[i+ctx->directory->free]=ctx->directory->offset[i];
1270 cur=do_ftello(ctx->f);
1272 if((
long long)cur<0) {
1273 perror(
"mvl_write_directory");
1274 mvl_set_error(ctx, LIBMVL_ERR_FTELL);
1286 ctx->directory_offset=offset;
1298 L=do_malloc(1,
sizeof(*L));
1301 if(L->size<10)L->size=10;
1303 L->offset=do_malloc(L->size,
sizeof(*L->offset));
1304 L->tag_length=do_malloc(L->size,
sizeof(*L->tag_length));
1305 L->tag=do_malloc(L->size,
sizeof(*L->tag));
1320 for(i=0;i<L->free;i++)free(L->tag[i]);
1322 free(L->first_item);
1325 free(L->tag_length);
1335 if(L->hash_size<L->size) {
1338 while(hs<L->size && hs)hs=hs<<1;
1342 free(L->first_item);
1350 L->next_item=do_malloc(L->hash_size,
sizeof(*L->next_item));
1351 L->first_item=do_malloc(L->hash_size,
sizeof(*L->first_item));
1353 mask=L->hash_size-1;
1357 L->next_item[i]=L->first_item[h];
1373 if(L->free>=L->size) {
1374 L->size=2*L->size+10;
1376 p=do_malloc(L->size,
sizeof(*L->offset));
1377 if(L->free>0)memcpy(p, L->offset, L->free*
sizeof(*L->offset));
1381 p=do_malloc(L->size,
sizeof(*L->tag_length));
1382 if(L->free>0)memcpy(p, L->tag_length, L->free*
sizeof(*L->tag_length));
1383 free(L->tag_length);
1386 p=do_malloc(L->size,
sizeof(*L->tag));
1387 if(L->free>0)memcpy(p, L->tag, L->free*
sizeof(*L->tag));
1396 L->offset[k]=offset;
1397 if(tag_length<0)tag_length=strlen(tag);
1398 L->tag_length[k]=tag_length;
1399 L->tag[k]=(
unsigned char*)memndup(tag, tag_length);
1401 if(L->hash_size>0) {
1404 L->next_item[k]=L->first_item[h];
1420 if(tl<0)tl=strlen(tag);
1422 if(L->hash_size>0) {
1426 for(i=L->first_item[h]; i>=0; i=L->next_item[i]) {
1427 if(L->tag_length[i]!=tl)
continue;
1428 if(!memcmp(L->tag[i], tag, tl)) {
1429 return(L->offset[i]);
1435 for(i=0;i<L->free;i++) {
1436 if(L->tag_length[i]!=tl)
continue;
1437 if(!memcmp(L->tag[i], tag, tl)) {
1438 return(L->offset[i]);
1468 offsets=do_malloc(2*L->free,
sizeof(*offsets));
1470 for(i=0;i<L->free;i++) {
1473 memcpy(&(offsets[L->free]), L->offset, L->free*
sizeof(*offsets));
1479 return(attr_offset);
1500 return(list_offset);
1522 return(list_offset);
1548 return(list_offset);
1570 data_size=ctx->data_size;
1574 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
1579 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1586 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1590 p=&(d[metadata_offset]);
1593 if(nattr==0)
return(NULL);
1594 if((nattr<0) || (nattr & 1)) {
1595 mvl_set_error(ctx, LIBMVL_ERR_INVALID_ATTR_LIST);
1601 for(i=0;i<nattr;i++) {
1603 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1640 data_size=ctx->data_size;
1644 mvl_set_error(ctx, LIBMVL_ERR_NO_DATA);
1649 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1656 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1661 if(Lattr==NULL)
return(NULL);
1665 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1678 mvl_set_error(ctx, LIBMVL_ERR_INVALID_ATTR);
1681 for(i=0;i<nelem;i++) {
1685 mvl_set_error(ctx, LIBMVL_ERR_INVALID_OFFSET);
1697 mvl_set_error(ctx, LIBMVL_ERR_INVALID_ATTR);
1700 for(i=0;i<nelem;i++) {
1702 mvl_set_error(ctx, LIBMVL_ERR_CORRUPT_PACKED_LIST);
1712 mvl_set_error(ctx, LIBMVL_ERR_INVALID_ATTR);
1729 mvl_write_preamble(ctx);
1738 mvl_write_postamble(ctx);
1752 return(p->length>>1);
1796 if(strncmp(pr->signature, LIBMVL_SIGNATURE, 4)) {
1797 mvl_set_error(ctx, LIBMVL_ERR_INVALID_SIGNATURE);
1801 if(pr->endianness!=LIBMVL_ENDIANNESS_FLAG) {
1802 mvl_set_error(ctx, LIBMVL_ERR_WRONG_ENDIANNESS);
1807 mvl_set_error(ctx, LIBMVL_ERR_MVL_FILE_TOO_SHORT);
1813 ctx->data=(
unsigned char *)data;
1814 ctx->data_size=length;
1819 case LIBMVL_VECTOR_POSTAMBLE2:
1822 mvl_set_error(ctx, LIBMVL_ERR_CORRUPT_POSTAMBLE);
1827 if(ctx->directory==NULL)
1830 #ifdef MVL_READ_OLD_DIRECTORY
1831 case LIBMVL_VECTOR_POSTAMBLE1:
1832 dir=(
LIBMVL_VECTOR *)&(((
unsigned char *)data)[pa->directory]);
1833 k=dir->header.length>>1;
1866 mvl_set_error(ctx, LIBMVL_ERR_CORRUPT_POSTAMBLE);
1872 mvl_set_error(ctx, err);
1886 MVL_SORT_INFO *info;
1890 int mvl_equals(MVL_SORT_UNIT *a, MVL_SORT_UNIT *b)
1898 avec=a->info->vec[i];
1899 bvec=b->info->vec[i];
1904 unsigned char ad, bd;
1968 if((
double)ad!=bd)
return 0;
2009 const unsigned char *ad, *bd;
2020 if(ad[j]!=bd[j])
return 0;
2038 int mvl_lexicographic_cmp(MVL_SORT_UNIT *a, MVL_SORT_UNIT *b)
2046 vec=a->info->vec[i];
2051 unsigned char ad, bd;
2100 const unsigned char *ad, *bd;
2108 if(ad[j]<bd[j])
return -1;
2109 if(ad[j]>bd[j])
return 1;
2126 int mvl_lexicographic_desc_cmp(MVL_SORT_UNIT *a, MVL_SORT_UNIT *b)
2134 vec=a->info->vec[i];
2139 unsigned char ad, bd;
2188 const unsigned char *ad, *bd;
2196 if(ad[j]<bd[j])
return 1;
2197 if(ad[j]>bd[j])
return -1;
2227 MVL_SORT_UNIT *units;
2231 if(vec_count<1)
return 0;
2234 info.data_length=vec_data_length;
2236 info.nvec=vec_count;
2238 units=do_malloc(indices_count,
sizeof(*units));
2242 for(i=1;i<vec_count;i++) {
2245 if(vec_data==NULL)
return -1;
2246 if(vec_data[i]==NULL)
return -1;
2252 for(i=0;i<indices_count;i++) {
2253 units[i].info=&info;
2254 if(indices[i]>=N)
return -1;
2255 units[i].index=indices[i];
2258 switch(sort_function) {
2260 qsort(units, indices_count,
sizeof(*units), (
int (*)(
const void *,
const void *))mvl_lexicographic_cmp);
2263 qsort(units, indices_count,
sizeof(*units), (
int (*)(
const void *,
const void *))mvl_lexicographic_desc_cmp);
2268 for(i=0;i<indices_count;i++) {
2269 indices[i]=units[i].index;
2298 for(i=0;i<indices_count;i++) {
2303 if(vec_count<1)
return 0;
2308 for(i=1;i<vec_count;i++) {
2311 if(vec_data==NULL)
return -2;
2312 if(vec_data[i]==NULL)
return -3;
2318 for(i=0;i<indices_count;i++) {
2319 if(indices[i]>=N)
return -5;
2322 for(j=0;j<vec_count;j++) {
2326 for(i=0;i<indices_count;i++) {
2331 for(i=0;i<indices_count;i++) {
2336 for(i=0;i<indices_count;i++) {
2341 for(i=0;i<indices_count;i++) {
2346 for(i=0;i<indices_count;i++) {
2351 for(i=0;i<indices_count;i++) {
2356 if(vec_data==NULL)
return -6;
2357 if(vec_data[j]==NULL)
return -7;
2358 for(i=0;i<indices_count;i++) {
2371 for(i=0;i<indices_count;i++) {
2399 indices_count=i1-i0;
2402 for(i=0;i<indices_count;i++) {
2407 if(vec_count<1 || (i1<=i0))
return 0;
2412 for(i=1;i<vec_count;i++) {
2415 if(vec_data==NULL)
return -2;
2416 if(vec_data[i]==NULL)
return -3;
2422 if(i0>=N || i1>=N)
return(-5);
2424 for(j=0;j<vec_count;j++) {
2428 for(i=0;i<indices_count;i++) {
2433 for(i=0;i<indices_count;i++) {
2438 for(i=0;i<indices_count;i++) {
2443 for(i=0;i<indices_count;i++) {
2448 for(i=0;i<indices_count;i++) {
2453 for(i=0;i<indices_count;i++) {
2458 if(vec_data==NULL)
return -6;
2459 if(vec_data[j]==NULL)
return -7;
2460 for(i=0;i<indices_count;i++) {
2473 for(i=0;i<indices_count;i++) {
2490 if(hash_count & (1LLU<<63))
return 0;
2493 while(hash_map_size<hash_count) {
2494 hash_map_size=hash_map_size<<1;
2496 return(hash_map_size);
2509 hm=do_malloc(1,
sizeof(*hm));
2535 if(hash_map->
flags & MVL_FLAG_OWN_VEC_TYPES)free(hash_map->
vec_types);
2559 hash_mask=hash_map_size-1;
2561 for(i=0;i<hash_map_size;i++) {
2565 if(hash_mask & hash_map_size) {
2567 for(i=0;i<hash_count;i++) {
2568 k=hash[i] % hash_map_size;
2569 if(hash_map[k]==~0LLU) {
2576 next[i]=hash_map[k];
2579 for(i=0;i<N_first;i++) {
2580 k=hash[first[i]] % hash_map_size;
2581 first[i]=hash_map[k];
2585 for(i=0;i<hash_count;i++) {
2586 k=hash[i] & hash_mask;
2587 if(hash_map[k]==~0LLU) {
2594 next[i]=hash_map[k];
2597 for(i=0;i<N_first;i++) {
2598 k=hash[first[i]] & hash_mask;
2599 first[i]=hash_map[k];
2625 hash_mask=hash_map_size-1;
2628 if(hash_map_size & hash_mask) {
2629 for(i=0;i<key_count;i++) {
2630 k=hash_map[key_hash[i] % hash_map_size];
2632 if(hash[k]==key_hash[i])match_count++;
2637 for(i=0;i<key_count;i++) {
2638 k=hash_map[key_hash[i] & hash_mask];
2640 if(hash[k]==key_hash[i])match_count++;
2645 return(match_count);
2663 hash_mask=hash_map_size-1;
2665 if(hash_map_size & hash_mask) {
2666 for(i=0;i<key_count;i++) {
2667 k=hash_map[key_hash[i] % hash_map_size];
2669 if(hash[k]==key_hash[i])
break;
2675 for(i=0;i<key_count;i++) {
2676 k=hash_map[key_hash[i] & hash_mask];
2678 if(hash[k]==key_hash[i])
break;
2725 MVL_SORT_INFO key_si, si;
2726 MVL_SORT_UNIT key_su, su;
2729 key_si.data=key_vec_data;
2730 key_si.data_length=key_vec_data_length;
2731 key_si.nvec=key_vec_count;
2735 si.data_length=vec_data_length;
2738 key_su.info=&key_si;
2742 hash_mask=hash_map_size-1;
2749 if(hash_map_size & hash_mask) {
2750 for(i=0;i<key_indices_count;i++) {
2751 k=hash_map[key_hash[i] % hash_map_size];
2752 key_su.index=key_indices[i];
2754 su.index=indices[k];
2755 if((hash[k]==key_hash[i]) && mvl_equals(&key_su, &su) ) {
2756 if(N_matches>=pairs_size)
return(-1000);
2757 key_match_indices[N_matches]=key_indices[i];
2758 match_indices[N_matches]=indices[k];
2763 key_last[i]=N_matches;
2766 for(i=0;i<key_indices_count;i++) {
2767 k=hash_map[key_hash[i] & hash_mask];
2768 key_su.index=key_indices[i];
2770 su.index=indices[k];
2771 if((hash[k]==key_hash[i]) && mvl_equals(&key_su, &su) ) {
2772 if(N_matches>=pairs_size)
return(-1000);
2773 key_match_indices[N_matches]=key_indices[i];
2774 match_indices[N_matches]=indices[k];
2779 key_last[i]=N_matches;
2803 MVL_SORT_UNIT su1, su2;
2807 si.data_length=vec_data_length;
2820 for(i=0;i<first_count;i++) {
2831 su1.index=indices[tmp[0]];
2833 su2.index=indices[tmp[l]];
2834 if(hash[tmp[0]]!=hash[tmp[l]] || !mvl_equals(&su1, &su2)) {
2844 for(m=1;m<l;m++)next[tmp[m]]=tmp[m-1];
2846 hm->
first[i]=tmp[l-1];
2849 hm->
first[group_count]=tmp[l-1];
2851 memmove(tmp, &(tmp[l]), (j-l)*
sizeof(*tmp));
2852 hm->
first[i]=tmp[0];
2853 hm->
next[tmp[0]]=~0LLU;
2871 new_size=2*el->
size+nelem;
2873 p=do_malloc(new_size,
sizeof(*p));
2915 info.data_length=data_length;
2924 if(mvl_equals(&a, &b))
continue;
2945 memset(el, 0,
sizeof(*el));
2966 memset(el, 0,
sizeof(*el));
2967 el->
size=LIBMVL_EXTENT_INLINE_SIZE;
2968 el->
start=el->start_inline;
2969 el->
stop=el->stop_inline;
2978 if(el->
size>LIBMVL_EXTENT_INLINE_SIZE) {
2997 new_size=2*el->
size+nelem;
2999 p=do_malloc(new_size,
sizeof(*p));
3001 if(el->
size>LIBMVL_EXTENT_INLINE_SIZE) {
3006 p=do_malloc(new_size,
sizeof(*p));
3008 if(el->
size>LIBMVL_EXTENT_INLINE_SIZE) {
3022 memset(ei, 0,
sizeof(*ei));
3035 free(ei->hash_map.
first);
3038 free(ei->hash_map.
hash);
3041 free(ei->hash_map.
next);
3046 if(ei->hash_map.
flags & MVL_FLAG_OWN_VEC_TYPES)
3049 ei->hash_map.
flags=0;
3067 ei->partition.
count=0;
3075 free(ei->hash_map.
hash);
3077 free(ei->hash_map.
first);
3079 free(ei->hash_map.
next);
3083 ei->hash_map.
hash=do_malloc(ei->hash_map.
hash_size,
sizeof(*ei->hash_map.
hash));
3085 ei->hash_map.
next=do_malloc(ei->hash_map.
hash_size,
sizeof(*ei->hash_map.
next));
3098 if(ei->hash_map.
flags & MVL_FLAG_OWN_VEC_TYPES)
3101 ei->hash_map.
flags|=MVL_FLAG_OWN_VEC_TYPES;
3142 ei->partition.
count=0;
3147 ei->partition.
count=0;
3150 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3155 ei->partition.
count=0;
3158 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3161 ei->partition.
size=0;
3167 ei->partition.
count=0;
3170 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3179 ei->partition.
count=0;
3182 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3187 ei->hash_map.
first=NULL;
3193 ei->partition.
count=0;
3196 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3202 ei->partition.
count=0;
3205 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3212 ei->partition.
count=0;
3215 return(LIBMVL_ERR_INVALID_EXTENT_INDEX);
3263 stats->
center=(a0+a1)*0.5;
3265 stats->
scale=2/(a1-a0);
3293 stats->
center=(a0+a1)*0.5;
3295 stats->
scale=2/(a1-a0);
3323 stats->
center=(a0*1.0+a1*1.0)*0.5;
3325 stats->
scale=2/(a1-a0);
3331 long long int a0, a1, b;
3353 stats->
center=(a0*1.0+a1*1.0)*0.5;
3355 stats->
scale=2/(a1-a0);
3381 double scale, center;
3382 scale=0.5*stats->
scale;
3383 center=1.5-stats->
center*scale;
3388 for(;i<i1;i++)out[i-i0]=0.0;
3397 out[i-i0]=pd[i]*scale+center;
3404 out[i-i0]=pd[i]*scale+center;
3411 out[i-i0]=pd[i]*scale+center;
3418 out[i-i0]=pd[i]*scale+center;