Code:
typedef struct _fullrec {
TMRI_PARAMREC *p0, *p1;
TMRI_CHROMREC *c;
TMRI_ERRORREC *e;
} FULLREC;
void initfullrec(FULLREC *fr)
/*
Given: A pointer to a FULLREC struct.
Return: Nothing.
Task: Set everything to NULL.
*/
{
fr->p0 = NULL;
fr->p1 = NULL;
fr->c = NULL;
fr->e = NULL;
return;
}
FULLREC **loadfiles(char **filenames)
/*
Given: A list of strings.
Return: A list of FULLRECs.
Task: The given list of strings has a trailing NULL. Step through the list of filenames and load all the data
from the filenames into a buffer. Return that buffer.
*/
{
FULLREC **list = NULL;
int listlen = 0;
int i, next;
void *p, *e, *c;
FILE *file;
if (filenames == NULL){
return NULL;
}
for (i = 0; filenames[i] != NULL; i++){
if ((file = fopen(filenames[i], "rb")) == NULL){
continue;
}
next = 0;
while (!feof(file) && !next){
if (getnexttype(file) != TYPE_PARAMREC){
next++;
continue;
}
p = NULL; e = NULL; c = NULL;
switch(getnextversion(file)){
case 0:
p = malloc(sizeof(TMRI_PARAMREC_R0));
getnextchunk(p, file, TYPE_PARAMREC);
break;
default:
p = NULL;
break;
}
if (p == NULL){
next++;
break;
}
listlen++;
list = (FULLREC **) realloc(list, sizeof(FULLREC *) * (listlen + 1));
list[listlen - 1] = (FULLREC *) malloc(sizeof(FULLREC));
initfullrec(list[listlen - 1]);
list[listlen - 1]->p0 = (TMRI_PARAMREC *) p;
if ((getnexttype(file) == TYPE_PARAMREC) && (list[listlen - 1]->p0->bytes[BYTE_NUMAGENTS] == 1)){
continue;
}
p = NULL;
if (getnexttype(file) == TYPE_PARAMREC){
switch(getnextversion(file)){
case 0:
p = malloc(sizeof(TMRI_PARAMREC_R0));
getnextchunk(p, file, TYPE_PARAMREC);
break;
default:
p = NULL;
break;
}
if (p == NULL){
next++;
break;
}
}
list[listlen - 1]->p1 = (TMRI_PARAMREC *) p;
if (getnexttype(file) == TYPE_ERRORREC){
switch(getnextversion(file)){
case 0:
e = malloc(sizeof(TMRI_ERRORREC_R0));
getnextchunk(e, file, TYPE_ERRORREC);
break;
default:
e = NULL;
}
if (e == NULL){
next++;
break;
}
}
list[listlen - 1]->e = (TMRI_ERRORREC *) e;
if (getnexttype(file) == TYPE_CHROMREC){
switch(getnextversion(file)){
case 0:
c = malloc(sizeof(TMRI_CHROMREC_R0));
getnextchunk(c, file, TYPE_CHROMREC);
break;
default:
c = NULL;
}
if (c == NULL){
next++;
break;
}
}
list[listlen - 1]->c = (TMRI_CHROMREC *) c;
}
}
if (listlen){
list = (FULLREC **) realloc(list, sizeof(FULLREC *) * (listlen + 1));
list[listlen] = NULL;
}
return list;
}
void freefullrec(FULLREC *fr)
/*
Given: A pointer to a FULLREC struct.
Return: Nothing.
Task: fr may have nothing in it to free. If there is something, however, free the parts correctly.
Note: FULLREC.e and FULLREC.c may have malloced memory which will also need to be free'ed.
*/
{
if (fr->p0 != NULL){
free(fr->p0);
}
if (fr->p1 != NULL){
free(fr->p1);
}
if (fr->e != NULL){
free(fr->e->list);
free(fr->e);
}
if (fr->c != NULL){
free(fr->c->chrom);
free(fr->c->extrabits);
free(fr->c);
}
return;
}
int inreclist(FULLREC **list, FULLREC *node)
/*
Given: A FULLREC array and a FULLREC.
Return: 0 for not found, 1+offset for found and complete, -1-offset for found and not complete.
Task: Locate node in list and determine if it is more complete than what is in the list.
*/
{
int i;
if (list == NULL)
return 0;
for (i = 0; list[i] != NULL; i++){
if (cmp_PARAMREC(node->p0, list[i]->p0))
break;
}
if (list[i] != NULL){
if (((list[i]->p1 == NULL) && (node->p1 != NULL)) ||
((list[i]->e == NULL) && (node->e != NULL)) ||
((list[i]->c == NULL) && (node->c != NULL))){
i++;
return i;
}
if (((list[i]->p1 != NULL) && (node->p1 == NULL)) ||
((list[i]->e != NULL) && (node->e == NULL)) ||
((list[i]->c != NULL) && (node->c == NULL))){
i++;
i *= -1;
return i;
}
if (list[i]->p0->shorts[SHORT_POINTSLEN] > node->p0->shorts[SHORT_POINTSLEN]){
i++;
i *= -1;
return i;
}
if (list[i]->p1 != NULL){
if (list[i]->p1->shorts[SHORT_POINTSLEN] > node->p1->shorts[SHORT_POINTSLEN]){
i++;
i *= -1;
return i;
}
}
if (list[i]->c != NULL){
if (list[i]->c->shorts[CHROM_SHORTS_CHROMLEN] > node->c->shorts[CHROM_SHORTS_CHROMLEN]){
i++;
i *= -1;
return i;
}
}
if (list[i]->e != NULL){
if (list[i]->e->len > node->e->len){
i++;
i *= -1;
return i;
}
}
}
return 0;
}
char *importadf(char **infile, char *outfilepath)
/*
Given: Two strings.
Return: A filename that is the new file that should be the currentfile (this will be the last filename to which we output).
Task: The given infile is a fully qualified filename to an existing ADF outfilepath is the path to the current
store directory. The new file(s) will be located into the outfilepath directory. The import will be preformed
by using the outfilepath, unit ID, the year, the month, the day, and ".adf" as the new filename. It is possible, therefore,
that the file contain multiple dates within one file.
NOTE: No error checking is done on loading the files. If a file/filename fails, we ditch out and continue.
*/
{
char *outfile, *retval;
int infilelen, i, j, changed, curfilelen;
int start, end, year, month, day, unit, preunit, preyear, premonth, preday;
char **subfilelist;
FULLREC **list, **curfile;
FULLREC *fr;
FILE *file;
TMRI_PARAMREC *p;
if (infile == NULL){
return NULL;
}
infilelen = 0;
while (infile[infilelen] != NULL) infilelen++;
infilelen++;
qsort(infile, infilelen, sizeof(char *), strcmp);
start = 0;
outfile = (char *) malloc(sizeof(char) * 2048);
while (start < infilelen){
sscanf(infile[start], "%5u%4i%2u%2u", &preunit, &preyear, &premonth, &preday);
// Set the number files to import in this batch. We are only getting a single day's worth of data.
// e.g. 123452006010100.adf - 123452006010123.adf
for (i = start + 1; i < infilelen; i++){
sscanf(infile[i], "%5u%4i%2u%2u", &unit, &year, &premonth, &preday);
if (unit == preunit){
if (year == preyear){
if (month == premonth){
if (day == preday){
continue;
}
}
}
}
break;
}
if (i == infilelen)
i--;
end = i;
end++; // make the compare only <
subfilelist = (char **) malloc(sizeof(char *) * (end - start + 1));
subfilelist[end - start] = NULL;
for (i = start; i < end; i++){
subfilelist[i - start] = strdup(infile[i]);
}
list = loadfiles(subfilelist);
for (i = start; i < end; i++){
free(subfilelist[i - start]);
}
p = list[0]->p0;
sprintf(outfile, "%s\\%05i\\%i\\%02i\\%05i%i%02i%02i.adf", outfilepath, p->shorts[SHORT_UNITID],
p->dates[DATE_DATE].year, p->dates[DATE_DATE].month,
p->shorts[SHORT_UNITID], p->dates[DATE_DATE].year,
p->dates[DATE_DATE].month, p->dates[DATE_DATE].day);
createdirs(outfile);
subfilelist[1] = NULL;
subfilelist[0] = outfile;
curfile = loadfiles(subfilelist);
free(subfilelist);
// Now we have two lists (maybe) and need to move items from the list -> curfile. If we move ANYTHING, then
// we need to sort and remake this file.
changed = 0;
if (curfile == NULL){
curfile = list;
list = NULL;
changed = 1;
} else {
for (i = 0; curfile[i] != NULL; i++);
curfilelen = i;
for (i = 0; list[i] != NULL; i++){
j = inreclist(curfile, list[i]);
if (!j){
changed = 1;
curfilelen++;
curfile = (FULLREC **) realloc(curfile, sizeof(FULLREC *) * (curfilelen + 1));
curfile[curfilelen] = NULL;
curfile[curfilelen - 1] = list[i];
list[i] = NULL;
} else if (j < 0){
changed = 1;
j *= -1;
j--;
freefullrec(curfile[j]);
free(curfile[j]);
curfile[j] = list[i];
list[i] = NULL;
}
if (list[i] != NULL){
freefullrec(list[i]);
free(list[i]);
}
}
free(list);
}
if (changed){
file = fopen(outfile, "w");
fclose(file);
for (i = 0; curfile[i] != NULL; i++){
fr = curfile[i];
writetostore(outfile, fr->p0, TMRI_PARAMREC);
if (fr->p1 != NULL){
writetostore(outfile, fr->p1, TMRI_PARAMREC);
}
if (curfile[i]->e != NULL){
writetostore(outfile, fr->e, TMRI_ERRORREC);
}
if (curfile[i]->c != NULL){
writetostore(outfile, fr->c, TMRI_CHROMREC);
}
freefullrec(curfile[i]);
free(curfile[i]);
}
free(curfile);
}
start = end;
}
if (outfile[0] != '\0'){
retval = strdup(outfile);
} else {
retval = NULL;
}
free(outfile);
return retval;