static char rcsver[] = "$Id: convert.c,v 1.3 2000/07/07 17:15:22 saadat Exp $"; /** ** $Source: /tes/cvs/vanilla/convert.c,v $ ** ** $Log: convert.c,v $ ** Revision 1.3 2000/07/07 17:15:22 saadat ** Added support for Windows MS Visual C++ memory-mapped file support. ** Removed some unused variables from various files. ** ** Revision 1.2 1999/11/19 21:19:42 gorelick ** Version 3.1, post PDS delivery of 3.0 ** ** Revision 1.1.1.1 1999/10/15 19:30:35 gorelick ** Version 3.0 ** ** Revision 2.2 1999/07/12 23:14:08 gorelick ** *** empty log message *** ** ** Revision 2.1 1999/02/10 04:00:50 gorelick ** *** empty log message *** ** ** Revision 2.0 1998/12/22 22:47:04 gorelick ** release version ** ** Revision 2.0 1998/12/18 01:26:03 gorelick ** release version ** ** Revision 1.10 1998/12/18 01:04:48 gorelick ** *** empty log message *** ** ** Revision 1.9 1998/12/01 22:42:06 gorelick ** *** empty log message *** ** ** Revision 1.8 1998/11/12 22:58:55 gorelick ** first release version ** **/ #include #include "header.h" #include "proto.h" #ifndef BITS /* Compute the number of bits in a specified type */ #define BITS(x) (sizeof(x) * 8) #endif void write_index(FIELD *f, int n ,void *ptr); int has_index(LIST *list, FIELD *f); /** ** Convert an ascii representation of a field into a DATA **/ DATA ConvertASCIItoData(char *ascii, int i) { DATA d; switch (i) { case INT: d.i = strtol(ascii, NULL, 10); break; case UINT: i = strtol(ascii, NULL, 10); if (i < 0) d.ui = 0; else d.ui = strtoul(ascii, NULL, 10); break; case REAL: d.r = strtod(ascii, NULL); break; case STRING: d.str = ascii; break; default: exit(fprintf(stderr, "__FILE__ %s __LINE__ %d\n", __FILE__, __LINE__)); } return (d); } /** ** Convert data at into a DATA using types specified by field ** ( is not row pointer) **/ DATA ConvertFieldData(PTR ptr, FIELD * f) { /* debug */ if (f == NULL) { fprintf(stderr, "FIELD: NULL PTR: %p\n", ptr); } if (!((long) ptr & 0xffff0000)) { fprintf(stderr, "PTR: %p FIELD: %s\n", ptr, f->name); } return (ConvertData(ptr + f->start, f)); } DATA ConvertData(PTR ptr, FIELD * f) { DATA d; char buf[128]; int shifts; uint mask; int bits; uint v; switch (f->eformat) { case MSB_BIT_FIELD: { if (f->bitfield){ shifts = f->bitfield->shifts; mask = f->bitfield->mask; bits = f->bitfield->bits; } else { shifts = 0; mask = 0; mask--; bits = BITS(int); } memcpy(buf, ptr, f->size); switch (f->size) { case 1: d.ui = (((uchar *) buf)[0] >> shifts) & mask; break; case 2: d.ui = (((ushort *) MSB2(buf))[0] >> shifts) & mask; break; case 4: d.ui = (((uint *) MSB4(buf))[0] >> shifts) & mask; break; } /* sign-extend if hi-bit is 1 */ if ((f->iformat == INT) && (d.ui & (1 << (bits-1)))){ v = 0; v--; v <<= bits - 1; d.ui |= v; } break; } case MSB_INTEGER: { memcpy(buf, ptr, f->size); switch (f->size) { case 1: d.i = ((char *) buf)[0]; break; case 2: d.i = ((short *) MSB2(buf))[0]; break; case 4: d.i = ((int *) MSB4(buf))[0]; break; } break; } case MSB_UNSIGNED_INTEGER: { memcpy(buf, ptr, f->size); switch (f->size) { case 1: d.ui = ((uchar *) buf)[0]; break; case 2: d.ui = ((ushort *) MSB2(buf))[0]; break; case 4: d.ui = ((uint *) MSB4(buf))[0]; break; } break; } case IEEE_REAL: { memcpy(buf, ptr, f->size); switch (f->size) { case 4: d.r = ((float *) MSB4(buf))[0]; break; case 8: d.r = ((double *) MSB8(buf))[0]; break; } break; } case ASCII_INTEGER: { if (f->size >= sizeof(buf)){ fprintf(stderr, "Internal Error! Reason: field-size > buffer-size for %s\n", f->name); abort(); } memcpy(buf, ptr, f->size); buf[f->size] = '\0'; d.i = atoi(buf); break; } case ASCII_REAL: { if (f->size >= sizeof(buf)){ fprintf(stderr, "Internal Error! Reason: field-size > buffer-size for %s\n", f->name); abort(); } memcpy(buf, ptr, f->size); buf[f->size] = '\0'; d.r = atof(buf); break; } case CHARACTER: { d.str = (char *) ptr; break; } default: exit(fprintf(stderr, "__FILE__ %s __LINE__ %d\n", __FILE__, __LINE__)); } return (d); } double ConvertAndScaleData(PTR raw, FIELD * field) { DATA d = ConvertData(raw, field); switch (field->iformat) { case INT: return (((double) d.i) * field->scale + field->offset); case UINT: return (((double) d.ui) * field->scale + field->offset); case REAL: return (((double) d.r) * field->scale + field->offset); case STRING: return (0); } assert(!"Implemented."); return 0; } /** ** Convert data at to DATA using types specified by **/ DATA ConvertVarData(PTR ptr, VARDATA * v) { DATA d; char buf[16]; switch (v->eformat) { case MSB_INTEGER:{ memcpy(buf, ptr, v->size); switch (v->size) { case 1: d.i = ((char *) buf)[0]; break; case 2: d.i = ((short *) MSB2(buf))[0]; break; case 4: d.i = ((int *) MSB4(buf))[0]; break; } } break; case MSB_UNSIGNED_INTEGER:{ memcpy(buf, ptr, v->size); switch (v->size) { case 1: d.ui = ((uchar *) buf)[0]; break; case 2: d.ui = ((ushort *) MSB2(buf))[0]; break; case 4: d.ui = ((uint *) MSB4(buf))[0]; break; } } break; case IEEE_REAL:{ memcpy(buf, ptr, v->size); switch (v->size) { case 4: d.r = ((float *) MSB4(buf))[0]; break; case 8: d.r = ((double *) MSB8(buf))[0]; break; } } break; case ASCII_INTEGER:{ memcpy(buf, ptr, v->size); buf[v->size] = '\0'; d.i = atoi(buf); } break; case ASCII_REAL:{ memcpy(buf, ptr, v->size); buf[v->size] = '\0'; d.r = atof(buf); } break; case CHARACTER:{ d.str = ptr; } break; default: exit(fprintf(stderr, "__FILE__ %s __LINE__ %d\n", __FILE__, __LINE__)); } return (d); } int EquivalentData(DATA d1, DATA d2, FIELD * f) { switch (f->iformat) { case INT: return (d1.i == d2.i); case UINT: return (d1.ui == d2.ui); case REAL: return (d1.r == d2.r); case STRING: return (strncmp(d1.str, d2.str, f->size)); } exit(fprintf(stderr, "__FILE__ %s __LINE__ %d\n", __FILE__, __LINE__)); return 0; } int CompareData(DATA d1, DATA d2, FIELD * f) { switch (f->iformat) { case INT: return ((d1.i < d2.i) ? -1 : ((d1.i == d2.i) ? 0 : 1)); case UINT: return ((d1.ui < d2.ui) ? -1 : ((d1.ui == d2.ui) ? 0 : 1)); case REAL: return ((d1.r < d2.r) ? -1 : ((d1.r == d2.r) ? 0 : 1)); case STRING: return (strncmp(d1.str, d2.str, f->size)); } exit(fprintf(stderr, "__FILE__ %s __LINE__ %d\n", __FILE__, __LINE__)); return 0; } #if 0 #define cmp(type,a,b) int cmp_##type(type *a, type *b) { \ return ((*a < *b) ? -1 : ((*a > *b) ? 1 : b-a)); } cmp(char, a, b) cmp(uchar, a, b) cmp(short, a, b) cmp(ushort, a, b) cmp(int, a, b) cmp(uint, a, b) cmp(float, a, b) cmp(double, a, b) #endif int cmp_char(char *a, char *b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_uchar(uchar * a, uchar * b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_short(short *a, short *b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_ushort(ushort * a, ushort * b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_int(int *a, int *b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_uint(uint * a, uint * b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_float(float *a, float *b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } int cmp_double(double *a, double *b) { return ((*a < *b) ? -1 : ((*a > *b) ? 1 : 0)); } FuncPtr select_cmp(FIELD *f) { switch(f->iformat) { case INT: switch (f->size) { case 1: return((FuncPtr)cmp_char); case 2: return((FuncPtr)cmp_short); case 4: return((FuncPtr)cmp_int); } case UINT: switch (f->size) { case 1: return((FuncPtr)cmp_uchar); case 2: return((FuncPtr)cmp_ushort); case 4: return((FuncPtr)cmp_uint); } case REAL: switch (f->size) { case 4: return((FuncPtr)cmp_float); case 8: return((FuncPtr)cmp_double); } default: return(NULL); } } LIST * LoadIndex(char *filename); int make_index(FIELD *f) { TABLE *table; int j, nrows, nbytes, reclen; uchar *ptr, *q; nbytes = f->size; table = f->label->table; table->buff = NewTblBuff(table); do { nrows = table->buff->frag->nrows; reclen = table->label->reclen; q = (uchar *)(table->buff->buf + table->buff->frag->offset + f->start); ptr = (uchar *)calloc(nrows, nbytes + 4); for (j = 0 ; j < nrows ; j++) { memcpy(ptr + j*(nbytes+4), q + j*reclen, nbytes); memcpy(ptr+nbytes+j*(nbytes+4), &j, 4); } qsort(ptr, nrows, nbytes + 4, (int (*)(const void *, const void *))select_cmp(f)); write_index(f, nrows, ptr); fprintf(stderr, "%s\n", ((char **)table->files->ptr)[table->buff->fileidx]); } while (RefillTblBuff(table->buff)); return 1; } LIST * Make_Index(char *fields_str, LIST *tables) { char buf[1024]; char *q, *p; FIELD *f; LIST *output = new_list(); if (fields_str == NULL) return output; strcpy(buf, fields_str); q = buf; while ((p = strtok(q, " \t\n")) != NULL) { q = NULL; if ((f = FindField(p, tables)) == NULL) { fprintf(stderr, "Unable to find specified field: %s\n", p); continue; } make_index(f); } return output; /* Saadat - I think! */ } void write_index(FIELD *f, int n ,void *ptr) { struct stat sbuf; char buf[256], *p; TABLE *t = f->label->table; int fd, i, rc; LIST *index_list; p = strdup(ListElement(char *, t->files, t->buff->fileidx)); strcpy(p + strlen(p) - 3, "idx"); rc = stat(p, &sbuf); if (rc == 0) { index_list = LoadIndex(p); if (has_index(index_list, f)) { fprintf(stderr, "Index exists.\n"); return; } } fd = open(p, O_RDWR | O_CREAT, 0777); i = n*(f->size+4) + 4 + 32; sprintf(buf, "%s%c%*s", f->name, 0, 32, " "); write(fd, &i, 4); write(fd, buf, 32); write(fd, ptr, n*(f->size+4)); close(fd); } typedef struct _index { int len; char *name; char *ptr; } INDEX; int has_index(LIST *list, FIELD *f) { INDEX *idx; int i; for (i = 0; i < list->number ; i++) { idx = ListElement(INDEX *, list, i); if (!strcmp(idx->name, f->name)) return(1); } return(0); } /* LoadIndex() should not be here */ #include "mem.h" LIST * LoadIndex(char *filename) { struct stat sbuf; LIST *list = new_list(); int rc, count = 0, i; uchar *address; INDEX *idx; rc = stat(filename, &sbuf); /* fd = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); */ /* fd = open(filename, O_RDWR | O_CREAT, 0777); */ /* address = (uchar *)mmap(NULL, sbuf.st_size, (PROT_READ | PROT_WRITE), MAP_PRIVATE, fd, 0); */ address = MemMapFile(NULL, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, filename, O_RDWR|O_CREAT, 0); if (address == NULL){ fprintf(stderr, "vanilla: Memory Mapping of %s failed. ", filename?filename:"(null)"); perror("Reason"); abort(); } for (i = 0 ; i < sbuf.st_size ; i+= *((int *)(address+i))) { idx = calloc(1, sizeof(INDEX)); idx->len = *((int *)(address+i)); idx->name = (char *)(address+i+4); idx->ptr = (char *)(address+i+4+32); list_add(list, idx); } return(list); }