📄 fileio.c
字号:
links[i] = ReadBinaryInt(finfo); if (CheckErrors() > 0) break; if (links[i] > max) max = links[i]; } return max;}/******************************************************************************Description: Auxilary function used to read num outlink information from file finfo. The information is stored in an array pointed to by links. The outlink section of the file is a sequence of positive integers which give the ID number of the child node. Missing children are identified by placeholders in the file which is any sequence of non-white space and non-digit characters. Missing children are stored with value -1 in the array.Return value: The maximum value of an ID number found in the link section, or -1 if there were no valid IDs.******************************************************************************/int ReadLinksAscII(int *links, UNSIGNED num, struct FileInfo *finfo){ char *cptr, *chead; int max = -1; UNSIGNED i; for (i = 0; i < num; i++){ chead = ReadWord(finfo); cptr = chead; if (cptr && isdigit((int)*cptr)){ links[i] = atoi(cptr); if (links[i] > max) max = links[i]; } else links[i] = -1; free(chead); if (CheckErrors() > 0) break; } return max;}/******************************************************************************Description: Auxilary function used to ensure that unique items are added to the data format array are added.Return value: 1 if everything went well, 0 if the was an error such as buffer overflow or duplicate item found.******************************************************************************/int AddUnique(UNSIGNED *array, UNSIGNED item){ UNSIGNED num; for (num = 0; num < MAXFIELDS && array[num] != 0 && array[num]!=item; num++); if (num < MAXFIELDS && array[num] == 0){ array[num] = item; return 1; } else{ AddError("Duplicate item in format string found."); return 0; }}/******************************************************************************Description: Auxilary function used to find whether a given integer item is in an array of integer values. The array is of a given size.Return value: 0 if the item was not found in the array, or a value greater than zero indicating the position (plus one) in which the item was found.******************************************************************************/int FindInt(UNSIGNED *array, UNSIGNED size, int item){ UNSIGNED num; for (num = 0; num < size; num++){ if (array[num] == item) return num+1; } return 0;}/******************************************************************************Description: Initialize nmemb elements of the float vector pointed to by fptr with value.Return value: This function does not return a value.******************************************************************************/void InitFloatVector(FLOAT *fptr, size_t nmemb, FLOAT value){ UNSIGNED i; for (i = 0; i < nmemb; i++) fptr[i] = value;}/******************************************************************************Description: An auxilary function used to extract file format information from a given text line pointed to by cptr. The text line is expected to contain a list of comma separated keywords which indicate the format of the file.Return value: The number of keywords found in the given line.******************************************************************************/int GetDataFormat(char *cptr, UNSIGNED *dformat){ UNSIGNED num = 0; if (cptr == NULL) /* No data given, return 0 */ return 0; memset(dformat, 0, sizeof(unsigned)*MAXFIELDS); /* Reset the format string */ while (cptr != NULL && CheckErrors() == 0){ num++; if (!strncasecmp(cptr, "nodelabel", 9)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+9, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, NODELABEL); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "childstate", 10)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+10, " ,:;+"), " ,:;+");/*Jump to next field*/ AddUnique(dformat, CHILDSTATE); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "parentstate", 11)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+11, " ,:;+"), " ,:;+");/*Jump to next field*/ AddUnique(dformat, PARENTSTATE); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "target", 6)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+6, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, TARGET); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "noden", 5)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+5, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, NODENO); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "depth", 5)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+5, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, DEPTH); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "links", 5)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+5, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, LINKS); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "label", 5)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+5, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, LABEL); /* Record occurence of keyword */ } else if (!strncasecmp(cptr, "state", 5)){ /*Check for keyword */ cptr = strnstr(strpbrk(cptr+5, " ,:;+"), " ,:;+");/*Jump to next field */ AddUnique(dformat, STATE); /* Record occurence of keyword */ } else AddError("Unrecognized item in format string found."); } return num;}/******************************************************************************Description: A helper function used to read a symbolic label from a binary stream. Return value: Pointer to the symbolic label or NULL if the label coult not be read successfully.******************************************************************************/char *ReadBinaryLabel(struct FileInfo *finfo){ UNSIGNED clen = 0; /* Length of the label */ char *cptr = NULL; /* Pointer to the label */ if (bo_fread(&clen, sizeof(UNSIGNED), 1, finfo) != 1)/*Read length of label*/ AddError("Unexpected end of file."); else if (clen != 0){ /* Read label if length is greater zero */ cptr = MyCalloc(clen+1, sizeof(char)); /* Allocate memory for label */ if (fread(cptr, sizeof(char), clen, finfo->fptr) != clen){ /* read label */ AddError("Unexpected end of file."); /* if we couldn't read the label */ free(cptr); /* free allocated memory and return NULL */ cptr = NULL; } } return cptr;}/******************************************************************************Description: Reads codebook entries from file finfo and stores them in the given map structure.Return value: The number of errors that occured while reading the codebooks.******************************************************************************/int ReadCodes(struct FileInfo *finfo, struct Map *map){ UNSIGNED x, y; FLOAT *fptr; char *label; size_t(*ReadVector)(FLOAT *, size_t, struct FileInfo *); char*(*ReadLabel)(struct FileInfo *); int(*CheckForTrailingData)(struct FileInfo *); map->codes = (struct Codebook*)MyCalloc(map->xdim*map->ydim, sizeof(struct Codebook)); if (finfo->byteorder != 0){ ReadVector = ReadBinaryVector; ReadLabel = ReadBinaryLabel; CheckForTrailingData = SetErrorIfAnyDataAvailable; } else{ ReadVector = ReadAscIIVector; ReadLabel = ReadWord; CheckForTrailingData = SetErrorIfDataAvailable; } for (y = 0; y < map->ydim; y++){ for (x = 0; x < map->xdim; x++){ fptr = (FLOAT*)MyMalloc(map->dim * sizeof(FLOAT)); ReadVector(fptr, map->dim, finfo); map->codes[y*map->xdim+x].points = fptr; map->codes[y*map->xdim+x].x = x; map->codes[y*map->xdim+x].y = y; label = ReadLabel(finfo); if (label != NULL){ map->codes[y*map->xdim+x].label = AddLabel(label); free(label); } if (finfo->byteorder == 0) /* In ASC-II mode... */ CheckForTrailingData(finfo); /* check for trailing data */ if (CheckErrors() > 0) return CheckErrors(); } } CheckForTrailingData(finfo); /* Check for unexpected trailing data */ return 0;}/******************************************************************************Description: Read a datafile header from file finfo. A header can occur at the start of the file or between any two graphs. Reading starts from the line pointed to by cptr, header information is stored in a prototype called prime, file format information is stored in dformat.Return value: Pointer to the first line of text which follows the header, or NULL if there is no more data in the file.******************************************************************************/char *ReadDataHeader(char *cptr, UNSIGNED *dformat, struct Graph *prime, struct FileInfo *finfo){ UNSIGNED numrecognized; while(cptr != NULL){ numrecognized = 0; cptr = strnspc(cptr); numrecognized+=satou(GetFileOption(cptr,"dim_target"),(uint*)&prime->tdim); numrecognized+=satou(GetFileOption(cptr,"indegree"), (uint*)&prime->FanIn); numrecognized+=satou(GetFileOption(cptr,"outdegree"),(uint*)&prime->FanOut); numrecognized+=satou(GetFileOption(cptr,"dim_label"), (uint*)&prime->ldim); numrecognized+=satou(GetFileOption(cptr, "byteorder"),&finfo->byteorder); numrecognized += GetDataFormat(GetFileOption(cptr, "format"), dformat); if (!strncmp(cptr, "graph", 5)) /* Graph data follows */ break; if (numrecognized == 0 && *cptr != '\0' && *cptr != '#'){ AddError("Unrecognized keyword found in header."); AddFileInfoOnError(finfo); /* Add file status info to error message */ break; } cptr = ReadLine(finfo); } /* Verify that header contained useful information */ if (finfo && finfo->byteorder > 0 && finfo->byteorder != LITTLE_ENDIAN && finfo->byteorder != BIG_ENDIAN && finfo->byteorder != PDP_ENDIAN) AddError("Invalid byteorder specified in file!"); if (prime->FanIn + prime->FanOut + prime->tdim + prime->ldim == 0) AddError("Overall dimension of data is zero!"); if (prime->ldim > 0 && !FindInt(dformat, MAXFIELDS, NODELABEL)) AddError("Dimension of node label is non-zero but no labels are given"); if (prime->tdim > 0 && !FindInt(dformat, MAXFIELDS, TARGET)) AddError("Dimension of target value is non-zero but no targets are given"); if (prime->FanIn > 0 && !FindInt(dformat, MAXFIELDS, LINKS)) AddError("FanIn must be zero when undirected links are specified"); if (FindInt(dformat, MAXFIELDS, STATE) && (FindInt(dformat, MAXFIELDS, PARENTSTATE) || FindInt(dformat, MAXFIELDS, CHILDSTATE))) AddError("Both directed and undirected links are specified. This is currently not supported."); return cptr;}/******************************************************************************Description: Connect the nodes stored in gptr according to information provided by links.Return value: This function does not return a value;******************************************************************************/void LinkNodes(struct Graph *gptr){ UNSIGNED i, j; struct Node *node, *child; static int nerror = 0; int *links; /* Array holding outlink information */ if (gptr->FanOut == 0) /* Graph has no offsprings (e.g. single node only) */ return; for (i = 0; i < gptr->numnodes; i++){ node = gptr->nodes[i]; links = (int*)node->children; /* Rectify a dirty hack in ReadNodes() */ node->children=(struct Node**)MyCalloc(gptr->FanOut, sizeof(struct Node*)); for (j = 0; j < gptr->FanOut; j++){ if (links[j] >= 0 && links[j] < gptr->numnodes){ node->children[j] = gptr->nodes[links[j]]; /* Set link to children */ child = gptr->nodes[links[j]]; /* Current node is parent of its */ child->numparents += 1;/* children, thus add node to list of parents */ child->parents = MyRealloc(child->parents, child->numparents * sizeof(struct Node*)); child->parents[child->numparents-1] = node; } else if (links[j] > 0){ /* Ignore links to a non-existing nodes */ char msg[256]; if (nerror < 10){ snprintf(msg, 256, "Warning: Ignoring link from node %d of graph '%s' to non-existing node %d.", node->nnum, gptr->gname, links[j]); AddMessage(msg); } else if (nerror == 10) AddMessage("These warnings occur more than 10 times...truncating."); nerror++; } } free(links); }}/******************************************************************************Description: Read the nodes of a graph from file finfo. Store the nodes which are expected to be available in the format given by dformat in the graph structure provided by gptr.Return value: 0 if no error, otherwise the number of errors occured while reading the nodes is returned.******************************************************************************/int ReadNodes(struct Graph *gptr, UNSIGNED *dformat, struct FileInfo *finfo){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -