📄 fileio.c
字号:
int maxid, cval; /* cval is a read-ahead character */ UNSIGNED i; UNSIGNED nodeno = 0; /* Number of nodes read from file */ UNSIGNED numnodes = 0; /* Number of nodes for which we allocated memory */ UNSIGNED maxnodes = MAX_UNSIGNED;/* Max number of nodes for current graph */ UNSIGNED dimension; /* Total data dimension of the nodes */ UNSIGNED coff = 0, poff = 0, toff = 0;/*Offset values for vector components*/ struct Node **nodes = NULL; /* The array of nodes */ struct Node *node; /* Pointer to current node */ int *links; /* Array holding outlink information */ char *label; size_t(*ReadVector)(FLOAT *, size_t, struct FileInfo *); int(*ReadInt)(struct FileInfo *); int(*ReadLinks)(int *links, UNSIGNED size, struct FileInfo *); char*(*ReadLabel)(struct FileInfo *); /* Set pointers to the right functions depending on whether the data is in binary or in ASC-II format */ if (finfo->byteorder != 0){ /* If in binary format */ ReadVector = ReadBinaryVector; ReadInt = ReadBinaryInt; ReadLinks = ReadLinksBinary; ReadLabel = ReadBinaryLabel; if (bo_fread(&numnodes, sizeof(UNSIGNED), 1, finfo) != 1){ AddError("Unexpected end of file."); return 1; } nodes = (struct Node **)MyCalloc(numnodes, sizeof(struct Node *)); maxnodes = numnodes;/* read no more nodes than numnodes in binary mode */ } else{ /* otherwise data are assumed to be in ASC-II format */ ReadVector = ReadAscIIVector; ReadInt = ReadAscIIInt; ReadLinks = ReadLinksAscII; ReadLabel = ReadWord; nodes = (struct Node **)MyCalloc(127, sizeof(struct Node *)); numnodes = 127; } /* Compute total dimension of data label, and the offset values of its elements. */ dimension = 0; dimension += gptr->ldim; coff = dimension; /* offset value of child state vector */ dimension += 2 * gptr->FanOut; poff = dimension; /* offset value of parent state vector */ dimension += 2 * gptr->FanIn; toff = dimension; /* offset value of target vector */ dimension += gptr->tdim; /* Loop to read one node at a time */ while(maxnodes > nodeno && CheckErrors() == 0){ if (finfo->byteorder == 0){ /* In ASC-II mode only, */ cval = zgetc(finfo); /* Find start of data */ while (cval != EOF && (isspace(cval) || cval == '#')){ if (cval == '\n') finfo->lineno++; /* Keep track of line numbers */ else if (cval == '#') GotoEndOfLine(finfo); cval = zgetc(finfo); } if (cval == EOF) /* There is no more data */ break; zungetc(cval, finfo); /* Put read-ahead character back into stream */ if (isalpha(cval)) /* check if the read-ahead was alphabetic, as */ break; /* this indicates start of a new header */ } /* ...end ASC-II mode only */ /* Allocate memory for new node and its data vector */ node = (struct Node *)MyCalloc(1, sizeof(struct Node)); node->points = (FLOAT*)MyCalloc(dimension, sizeof(FLOAT)); /* Read node in given file format */ for (i = 0; dformat[i] != 0 && CheckErrors() == 0; i++){ if (dformat[i] == NODELABEL) ReadVector(node->points, gptr->ldim, finfo); /* Read node label */ else if (dformat[i] == CHILDSTATE) ReadVector(&node->points[coff], 2 * gptr->FanOut, finfo); /* c-state */ else if (dformat[i] == PARENTSTATE) ReadVector(&node->points[poff], 2 * gptr->FanIn, finfo); /* p-state */ else if (dformat[i] == TARGET) ReadVector(&node->points[toff], gptr->tdim, finfo); /* target vector */ else if (dformat[i] == NODENO) node->nnum = ReadInt(finfo); /* Read node number */ else if (dformat[i] == DEPTH) node->depth = ReadInt(finfo); /* Read node depth */ else if (dformat[i] == LINKS){ /* To convert outlinks to pointers use */ links = MyCalloc(gptr->FanOut, sizeof(int));/* this dirty hack which */ node->children = (struct Node**)links; /* is set right in LinkNodes()*/ ReadLinks(links, gptr->FanOut, finfo); } else if (dformat[i] == LABEL){ label = ReadLabel(finfo); node->label = AddLabel(label); /* Read the symbolic data label */ free(label); } } if (!FindInt(dformat, MAXFIELDS, NODENO)) /* If node number not available*/ node->nnum = nodeno; /* set a node's default logical number */ if (numnodes <= nodeno){ numnodes += 128; nodes = (struct Node**)MyRealloc(nodes, numnodes*sizeof(struct Node*)); memset(&nodes[numnodes-128], 0, 128*sizeof(struct Node*)); } nodes[nodeno] = node; /* Add node to array */ nodeno++; /* Increase node counter */ if (CheckErrors() == 0 && finfo->byteorder == 0) /* In ASC-II mode */ SetErrorIfDataAvailable(finfo); /*No further data expected in this line*/ if (CheckErrors() > 0){ finfo->lineno++; /* Adjust line number as it is off by one */ AddFileInfoOnError(finfo); /* Add file status info on error */ } } maxid = 0; for (i = 0; i < nodeno; i++){ if (nodes[i]->nnum > maxid) maxid = nodes[i]->nnum; /* Find greatest node ID */ } gptr->nodes = (struct Node **)MyCalloc(maxid+1, sizeof(struct Node *)); gptr->numnodes = maxid+1; for (i = 0; i < nodeno; i++) gptr->nodes[nodes[i]->nnum] = nodes[i]; /* Assign nodes to graph */ free(nodes); nodes = gptr->nodes; gptr->dimension = dimension; /* */ /* What follows here are post-analysis and post-initializations */ /* */ if (CheckErrors() > 0) return CheckErrors(); else if (maxid+1 != nodeno){/*Highest node-id must equal number of nodes*/ AddError("Inconsistency with node numbers."); AddFileInfoOnError(finfo); /* Add file status info on error */ } else{ /* No errors */ if (FindInt(dformat, MAXFIELDS, LINKS)) LinkNodes(gptr); /* Set internal links to parents and offsprings */ /* Initialize child states if they were not specified in the file */ if (gptr->FanOut > 0 && !FindInt(dformat, MAXFIELDS, CHILDSTATE)){ for (i = 0; i < maxid+1; i++) InitFloatVector(&nodes[i]->points[coff], 2*gptr->FanOut, -1.0); } /* Initialize parent states if they were not specified in the file */ if (gptr->FanIn > 0 && !FindInt(dformat, MAXFIELDS, PARENTSTATE)){ for (i = 0; i < maxid+1; i++) InitFloatVector(&nodes[i]->points[poff], 2*gptr->FanIn, -1.0); } } if (CheckMessages()){ fputc('\n', stderr); PrintMessages(); } return CheckErrors();}/******************************************************************************Description: Read a single graph structure from file pointed to by finfo. The graph is stored in the structure provided by gptr, it's nodes are expected to be available on file in the format defined by dformat. The pointer cptr points to the line which indicates the start of the graph structure (it starts with the keyword 'graph') and may contain a name of the graph.Return value: Pointer to the first line of text in the file after the graph structure which either points to the start of a new graph, the start of a new header, or NULL if there are no further graphs.******************************************************************************/char *ReadGraph(char *cptr, UNSIGNED *dformat, struct Graph *gptr, struct FileInfo *finfo){ if (!((cptr = strchr(cptr, ':')) == NULL || (cptr = strnspc(cptr+1))== '\0')) gptr->gname = strdup(cptr); /* Get the name of the graph */ ReadNodes(gptr, dformat, finfo); /* Now read the graph's nodes */ cptr = ReadLine(finfo); /* read next line of data */ return cptr;}/******************************************************************************Description: Read graph definitions from a file named fname, and return a pointer to a linked list of graphs (read from the given file).Return value: Pointer to a linked list of graphs, or NULL if there were no graphs read.******************************************************************************/struct Graph* LoadData(char *fname){ UNSIGNED dformat[MAXFIELDS+1] = {NODELABEL,CHILDSTATE,LINKS,LABEL,0}; UNSIGNED gnum = 0; /* Provides a unique number to each graph */ UNSIGNED numnodes = 0; /* Counts the total number of nodes */ char *cptr; struct FileInfo *finfo; /* Structure to hold file status info */ struct Graph prime; /* Used as a prototype for all graphs */ struct Graph *head = NULL, *prev = NULL, *gptr; /* Handle the graph-list */ fprint(stderr, "Reading data......."); /* Print what is being done */ if ((finfo = OpenFile(fname, "rb")) == NULL) /* Try to open data stream */ AddError("No file name given."); if (CheckErrors()){ /* Any errors so far? */ fprintf(stderr, "%55s\n", "[FAILED]"); return NULL; } memset(&prime, 0, sizeof(struct Graph)); /* Initialize primal graph */ InitProgressMeter(-1); /* Initialize the progress meter */ /* Read the header */ cptr = ReadLine(finfo); /* Read first line of data */ cptr = ReadDataHeader(cptr, dformat, &prime, finfo); if (cptr == NULL) /* Obligatory keyword "graph" not found */ AddError("This doesn't seem to be a valid data file."); while (cptr != NULL && CheckErrors() == 0){ gptr = MyMalloc(sizeof(struct Graph)); memcpy(gptr, &prime, sizeof(struct Graph)); gptr->gnum = gnum++; /* Give this graph a logical number */ cptr = ReadGraph(cptr, dformat, gptr, finfo); /* Read graph */ if (prev != NULL) /* Attach to list of graph */ prev->next = gptr; else head = gptr; prev = gptr; numnodes += gptr->numnodes; PrintProgress(gnum); /* Print progress */ if (CheckErrors() == 0) cptr = ReadDataHeader(cptr, dformat, &prime, finfo); } CloseFile(finfo); /* Close data stream */ if (CheckErrors() == 0) SetNodeDepth(head); /* Ensure that depth value of nodes is initialized */ StopProgressMeter(); /* Stop the progress meter */ if (!CheckErrors()) /* If no errors... */ fprintf(stderr, "%d nodes%*s\n", (int)numnodes, 48-(int)(log10(numnodes)), "[OK]"); else fprintf(stderr, "%55s\n", "[FAILED]"); return head;}/******************************************************************************Description: Return value: ******************************************************************************/void SaveData(FILE *ofile, struct Graph *gptr){ UNSIGNED i, n; UNSIGNED ldim, tdim, FanIn, FanOut; UNSIGNED soff, coff, poff; struct Node *node; if (gptr == NULL) return; ldim = INT_MAX; /* Initialize graph properties with illegal values to */ tdim = INT_MAX; /* enforce the writing of a data header for the first */ FanIn = INT_MAX; /* graph. Any successife graph will have an own header */ FanOut = INT_MAX;/* if a property differs from an earlier graph. */ fprintf(ofile, "format=nodenumber,nodelabel,target,links,label\n"); for(; gptr != NULL; gptr = gptr->next){ /* Compute max indegree of graph */ for (n = 0; n < gptr->numnodes; n++){ if (gptr->FanIn < gptr->nodes[n]->numparents) gptr->FanIn = gptr->nodes[n]->numparents; } if (ldim != gptr->ldim){ ldim = gptr->ldim; fprintf(ofile, "dim_label=%d\n", ldim); } if (tdim != gptr->tdim){ tdim = gptr->tdim; fprintf(ofile, "dim_target=%d\n", tdim); } if (FanOut != gptr->FanOut){ FanOut = gptr->FanOut; fprintf(ofile, "outdegree=%d\n", FanOut); } if (gptr->gname != NULL) fprintf(ofile, "graph:%s\n", gptr->gname); else fprintf(ofile, "graph\n"); for (n = 0; n < gptr->numnodes; n++){ node = gptr->nodes[n]; soff = gptr->ldim + 2*gptr->FanOut; poff = soff + 2*node->numparents; coff = poff + gptr->tdim; fprintf(ofile, "%u ", node->nnum); /* Print node number */ for (i = 0; i < gptr->ldim; i++){ if (node->points[i] == (int)node->points[i]) fprintf(ofile, "%3d ", (int)node->points[i]);/* Print node label */ else fprintf(ofile, "%f ", node->points[i]); /* Print node label */ } for (i = poff; i < coff; i++) fprintf(ofile, "%f ", node->points[i]); /* Print target vector */ for (i = 0; i < gptr->FanOut; i++){ /* Print links */ if (node->children[i] == NULL) fprintf(ofile, "- "); else fprintf(ofile, "%u ", node->children[i]->nnum); } if (GetLabel(node->label) != NULL) /* Print node label */ fprintf(ofile, "%s\n", GetLabel(node->label)); else fprintf(ofile, "\n"); } } /* UNSIGNED n, i; struct Graph *gptr; UNSIGNED ldim, tdim, FanIn, FanOut; printf("format=nodenumber,nodelabel,childstate,parentstate,target,depth,links,label\n"); ldim = INT_MAX; tdim = INT_MAX; FanIn = INT_MAX; FanOut = INT_MAX; for(gptr = graph; gptr != NULL; gptr = gptr->next){ if (ldim != gptr->ldim){ ldim = gptr->ldim; printf("dim_label=%d\n", ldim); } if (tdim != gptr->tdim){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -