docprop.c
上传用户:qin5330
上传日期:2007-01-05
资源大小:114k
文件大小:8k
- /*
- ** DocProperties.c, DocProperties.h
- **
- ** Functions to manage the index's Document Properties
- **
- ** File Created.
- ** Mark Gaulin 11/24/98
- */
- #include "swish.h"
- #include "file.h"
- #include "hash.h"
- #include "mem.h"
- #include "merge.h"
- #include "error.h"
- #include "search.h"
- #include "string.h"
- #include "docprop.h"
- #ifdef SUPPORT_DOC_PROPERTIES
- void freeDocProperties(docProperties)
- struct docPropertyEntry **docProperties;
- {
- /* delete the linked list of doc properties */
- struct docPropertyEntry *prop = NULL;
- prop = *docProperties;
- while (prop != NULL)
- {
- struct docPropertyEntry *nextOne = prop->next;
- free(prop->propValue);
- free(prop);
- prop = nextOne;
- }
- /* replace the ptr to the head of the list with a NULL */
- *docProperties = NULL;
- }
- void addDocProperty(docProperties, metaName, propValue)
- struct docPropertyEntry **docProperties;
- int metaName;
- char* propValue;
- {
- /* Add the given file/metaName/propValue data to the File object */
- struct docPropertyEntry *docProp = NULL;
- /*printf("File#: %s %03d %sn", thisFileEntry->filename, metaName, propValue);*/
- /* new prop object */
- docProp = (struct docPropertyEntry *) emalloc(sizeof(struct docPropertyEntry));
- docProp->metaName = metaName;
- docProp->propValue = (char *) mystrdup(propValue);
- /* insert at head of file objects list of properties */
- docProp->next = *docProperties; /* "*docProperties" is the ptr to the head of the list */
- *docProperties = docProp; /* update head-of-list ptr */
- }
- void storeDocProperties(docProperties, fp)
- struct docPropertyEntry *docProperties;
- FILE *fp;
- {
- /*
- * Dump the document properties into the index file
- * The format is:
- * <PropID:int><PropValueLen:int><PropValue:null-terminated>
- * ...
- * <PropID:int><PropValueLen:int><PropValue:null-terminated>
- * <EndofList:int>
- *
- * The list is terminated with a PropID with a value of zero
- */
- short int propID;
- short int len;
- while (docProperties != NULL)
- {
- /* the length of the property value */
- len = (short int) strlen(docProperties->propValue);
- if (len > 0)
- {
- /* the ID of the property */
- propID = (short int) docProperties->metaName;
- fwrite(&propID, sizeof(propID), 1, fp);
- /* including the length will make retrieval faster */
- fwrite(&len, sizeof(len), 1, fp);
- fwrite(docProperties->propValue, len+1, 1, fp);
- }
- docProperties = docProperties->next;
- }
- /* set is terminated by a "zero" ID */
- propID = 0;
- fwrite(&propID, sizeof(propID), 1, fp);
- }
- static char* readNextDocPropEntry(fp, metaName, targetMetaName)
- FILE* fp;
- int* metaName;
- int targetMetaName;
- {
- /* read one entry and return it; also set the metaName.
- * if targetMetaName is zero then return values for all entries.
- * if targetMetaName is non-zero than only return the value
- * for the property matching that value.
- * In all cases, metaName will be zero when the end of the
- * set is reached.
- */
- static char* propValueBuf = NULL;
- static int propValueBufLen = 0;
- short int tempPropID;
- short int len;
- long propPos; /* file pos */
- fread(&tempPropID, sizeof(tempPropID), 1, fp);
- *metaName = (int) tempPropID;
- if (tempPropID == 0)
- return NULL; /* end of list */
- /* grab the string length */
- fread(&len, sizeof(len), 1, fp);
- if ((targetMetaName != 0) && (tempPropID != (short int) targetMetaName))
- {
- /* we were looking for something specific, and this is not it */
- /* move to the next property */
- propPos = ftell(fp);
- fseek(fp, propPos+len+1, 0);
- return "";
- }
- else
- {
- /* return the value */
- if (propValueBufLen < len+1)
- {
- /* allocate buffer for prop value */
- /* the buffer will be reused on the next call */
- propValueBufLen = len+100;
- propValueBuf = (char *) emalloc(propValueBufLen);
- }
- fread(propValueBuf, len+1, 1, fp);
- return propValueBuf;
- }
- }
- void fetchDocProperties(docProperties, fp)
- struct docPropertyEntry **docProperties;
- FILE *fp;
- {
- /*
- * Read the docProperties section that the file pointer is
- * currently pointing to.
- * If docProperties is NULL then throw away the results,
- * which has the desired side effect of moving the file
- * pointer to the next file entry in the index
- */
- char* tempPropValue;
- int tempMetaName;
- int targetMetaName = 0; /* 0 = no target; return all data */
- if (docProperties == NULL)
- {
- targetMetaName = -1; /* invalid target; matches nothing */
- }
- else
- {
- *docProperties = NULL; /* initialize linked list - empty */
- }
- /* read all of the properties */
- tempPropValue = readNextDocPropEntry(fp, &tempMetaName, targetMetaName);
- while (tempMetaName > 0)
- {
- if (docProperties != NULL)
- {
- /* add the entry to the list of properties */
- addDocProperty(docProperties, tempMetaName, tempPropValue);
- }
- tempPropValue = readNextDocPropEntry(fp, &tempMetaName, targetMetaName);
- }
- }
- char* lookupDocPropertyValue(metaName, propPos, fp)
- int metaName;
- long propPos; /* from struct sortresult.propPos */
- FILE *fp;
- {
- /*
- * Returns the string containing the document's
- * property value, or an empty string if it was not found.
- */
- char* tempPropValue;
- int tempMetaName;
- fseek(fp, propPos, 0);
- tempPropValue = readNextDocPropEntry(fp, &tempMetaName, metaName);
- while (tempMetaName > 0)
- {
- /* a match? */
- if (tempMetaName == metaName)
- return tempPropValue;
- tempPropValue = readNextDocPropEntry(fp, &tempMetaName, metaName);
- }
- return "";
- }
- #define MAX_PROPS_TO_DISPLAY 50
- static int numPropertiesToDisplay = 0;
- static char* propNameToDisplay[MAX_PROPS_TO_DISPLAY];
- static int propIDToDisplay[MAX_PROPS_TO_DISPLAY];
- void addSearchResultDisplayProperty(propName)
- char* propName;
- {
- /* add a property to the list of properties that will be displayed */
- if (numPropertiesToDisplay < MAX_PROPS_TO_DISPLAY)
- {
- propNameToDisplay[numPropertiesToDisplay++] = propName;
- }
- else
- {
- progerr("Too many properties to display.");
- }
- }
- void initSearchResultProperties()
- {
- /* lookup selected property names */
- int i;
- if (numPropertiesToDisplay == 0)
- return;
- for (i = 0; i<numPropertiesToDisplay; i++)
- {
- printf("# DocProperty %d: %sn", i+1, propNameToDisplay[i]);
- /*strlwr(propNameToDisplay[i]);*/
- makeItLow(propNameToDisplay[i]);
- propIDToDisplay[i] = getMetaName(propNameToDisplay[i]);
- if (propIDToDisplay[i] == 1)
- {
- char buf[200];
- sprintf(buf, "Unknown property name "%s"", propNameToDisplay[i]);
- progerr(buf);
- return;
- }
- }
- }
- void printSearchResultProperties(propPos, fp)
- long propPos; /* from struct sortresult.propPos */
- FILE *fp;
- {
- int i;
- if (numPropertiesToDisplay == 0)
- return;
- for (i = 0; i<numPropertiesToDisplay; i++)
- {
- char* propValue;
- propValue = lookupDocPropertyValue(propIDToDisplay[i], propPos, fp);
-
- if (useCustomOutputDelimiter)
- printf("%s", customOutputDelimiter);
- else
- printf(" ""); /* default is to quote the string, with leading space */
- /* print value, handling newlines and quotes */
- while (*propValue)
- {
- if (*propValue == 'n')
- printf(" ");
- else if (*propValue == '"') /* should not happen */
- printf(""");
- else
- printf("%c", *propValue);
- propValue++;
- }
- printf("%s", propValue);
- if (!useCustomOutputDelimiter)
- printf("""); /* default is to quote the string */
- }
- }
- void swapDocPropertyMetaNames(docProperties, metaFile)
- struct docPropertyEntry *docProperties;
- struct metaMergeEntry* metaFile;
- {
- /* swap metaName values for properties */
- while (docProperties)
- {
- struct metaMergeEntry* metaFileTemp;
- /* scan the metaFile list to get the new metaName value */
- metaFileTemp = metaFile;
- while (metaFileTemp)
- {
- if (docProperties->metaName == metaFileTemp->oldIndex)
- {
- docProperties->metaName = metaFileTemp->newIndex;
- break;
- }
- metaFileTemp = metaFileTemp->next;
- }
- docProperties = docProperties->next;
- }
- }
- #endif