docprop.c
上传用户:qin5330
上传日期:2007-01-05
资源大小:114k
文件大小:8k
源码类别:

搜索引擎

开发平台:

Perl

  1. /*
  2. ** DocProperties.c, DocProperties.h
  3. **
  4. ** Functions to manage the index's Document Properties 
  5. **
  6. ** File Created.
  7. ** Mark Gaulin 11/24/98
  8. */
  9. #include "swish.h"
  10. #include "file.h"
  11. #include "hash.h"
  12. #include "mem.h"
  13. #include "merge.h"
  14. #include "error.h"
  15. #include "search.h"
  16. #include "string.h"
  17. #include "docprop.h"
  18. #ifdef SUPPORT_DOC_PROPERTIES
  19. void freeDocProperties(docProperties)
  20.      struct docPropertyEntry **docProperties;
  21. {
  22. /* delete the linked list of doc properties */
  23. struct docPropertyEntry *prop = NULL;
  24. prop = *docProperties;
  25. while (prop != NULL)
  26. {
  27. struct docPropertyEntry *nextOne = prop->next;
  28. free(prop->propValue);
  29. free(prop);
  30. prop = nextOne;
  31. }
  32. /* replace the ptr to the head of the list with a NULL */
  33. *docProperties = NULL;
  34. }
  35. void addDocProperty(docProperties, metaName, propValue)
  36.      struct docPropertyEntry **docProperties;
  37.      int metaName;
  38.      char* propValue;
  39. {
  40. /* Add the given file/metaName/propValue data to the File object */
  41. struct docPropertyEntry *docProp = NULL;
  42. /*printf("File#: %s %03d %sn", thisFileEntry->filename, metaName, propValue);*/
  43. /* new prop object */
  44. docProp = (struct docPropertyEntry *) emalloc(sizeof(struct docPropertyEntry));
  45. docProp->metaName = metaName;
  46. docProp->propValue = (char *) mystrdup(propValue);
  47. /* insert at head of file objects list of properties */
  48. docProp->next = *docProperties; /* "*docProperties" is the ptr to the head of the list */
  49. *docProperties = docProp; /* update head-of-list ptr */
  50. }
  51. void storeDocProperties(docProperties, fp)
  52.      struct docPropertyEntry *docProperties;
  53.      FILE *fp;
  54. {
  55. /*
  56.  * Dump the document properties into the index file 
  57.  * The format is:
  58.  * <PropID:int><PropValueLen:int><PropValue:null-terminated>
  59.  *   ...
  60.  * <PropID:int><PropValueLen:int><PropValue:null-terminated>
  61.  * <EndofList:int>
  62.  *
  63.  * The list is terminated with a PropID with a value of zero
  64.  */
  65. short int propID;
  66. short int len;
  67. while (docProperties != NULL)
  68. {
  69. /* the length of the property value */
  70. len = (short int) strlen(docProperties->propValue);
  71. if (len > 0)
  72. {
  73. /* the ID of the property */
  74. propID = (short int) docProperties->metaName;
  75. fwrite(&propID, sizeof(propID), 1, fp);
  76. /* including the length will make retrieval faster */
  77. fwrite(&len, sizeof(len), 1, fp);
  78. fwrite(docProperties->propValue, len+1, 1, fp);
  79. }
  80. docProperties = docProperties->next;
  81. }
  82. /* set is terminated by a "zero" ID  */
  83. propID = 0;
  84. fwrite(&propID, sizeof(propID), 1, fp);
  85. }
  86. static char* readNextDocPropEntry(fp, metaName, targetMetaName)
  87.       FILE* fp;
  88.       int* metaName;
  89.       int targetMetaName;
  90. {
  91. /* read one entry and return it; also set the metaName.
  92.    * if targetMetaName is zero then return values for all entries.
  93.  * if targetMetaName is non-zero than only return the value
  94.  * for the property matching that value.
  95.  * In all cases, metaName will be zero when the end of the
  96.  * set is reached.
  97.  */
  98. static char* propValueBuf = NULL;
  99. static int propValueBufLen = 0;
  100. short int tempPropID;
  101. short int len;
  102. long propPos; /* file pos */
  103. fread(&tempPropID, sizeof(tempPropID), 1, fp);
  104. *metaName = (int) tempPropID;
  105. if (tempPropID == 0)
  106. return NULL; /* end of list */
  107. /* grab the string length */
  108. fread(&len, sizeof(len), 1, fp);
  109. if ((targetMetaName != 0) && (tempPropID != (short int) targetMetaName))
  110. {
  111. /* we were looking for something specific, and this is not it */
  112. /* move to the next property */
  113. propPos = ftell(fp);
  114. fseek(fp, propPos+len+1, 0);
  115. return "";
  116. }
  117. else
  118. {
  119. /* return the value */
  120. if (propValueBufLen < len+1)
  121. {
  122. /* allocate buffer for prop value */
  123. /* the buffer will be reused on the next call */
  124. propValueBufLen = len+100;
  125. propValueBuf = (char *) emalloc(propValueBufLen);
  126. }
  127. fread(propValueBuf, len+1, 1, fp);
  128. return propValueBuf;
  129. }
  130. }
  131. void fetchDocProperties(docProperties, fp)
  132.      struct docPropertyEntry **docProperties;
  133.      FILE *fp;
  134. {
  135. /*
  136.  * Read the docProperties section that the file pointer is
  137.  * currently pointing to.
  138.  * If docProperties is NULL then throw away the results,
  139.  * which has the desired side effect of moving the file
  140.  * pointer to the next file entry in the index
  141.  */
  142. char* tempPropValue;
  143. int tempMetaName;
  144. int targetMetaName = 0; /* 0 = no target; return all data */
  145. if (docProperties == NULL)
  146. {
  147. targetMetaName = -1; /* invalid target; matches nothing */
  148. }
  149. else
  150. {
  151. *docProperties = NULL; /* initialize linked list - empty */
  152. }
  153. /* read all of the properties */
  154. tempPropValue = readNextDocPropEntry(fp, &tempMetaName, targetMetaName);
  155. while (tempMetaName > 0)
  156. {
  157. if (docProperties != NULL)
  158. {
  159. /* add the entry to the list of properties */
  160. addDocProperty(docProperties, tempMetaName, tempPropValue);
  161. }
  162. tempPropValue = readNextDocPropEntry(fp, &tempMetaName, targetMetaName);
  163. }
  164. }
  165. char* lookupDocPropertyValue(metaName, propPos, fp)
  166.      int metaName;
  167.      long propPos; /* from struct sortresult.propPos */
  168.      FILE *fp;
  169. {
  170. /*
  171.  * Returns the string containing the document's
  172.  * property value, or an empty string if it was not found.
  173.  */
  174. char* tempPropValue;
  175. int tempMetaName;
  176. fseek(fp, propPos, 0);
  177. tempPropValue = readNextDocPropEntry(fp, &tempMetaName, metaName);
  178. while (tempMetaName > 0)
  179. {
  180. /* a match? */
  181. if (tempMetaName == metaName)
  182. return tempPropValue;
  183. tempPropValue = readNextDocPropEntry(fp, &tempMetaName, metaName);
  184. }
  185. return "";
  186. }
  187. #define MAX_PROPS_TO_DISPLAY 50
  188. static int numPropertiesToDisplay = 0;
  189. static char* propNameToDisplay[MAX_PROPS_TO_DISPLAY];
  190. static int propIDToDisplay[MAX_PROPS_TO_DISPLAY];
  191. void addSearchResultDisplayProperty(propName)
  192.      char* propName;
  193. {
  194. /* add a property to the list of properties that will be displayed */
  195. if (numPropertiesToDisplay < MAX_PROPS_TO_DISPLAY)
  196. {
  197. propNameToDisplay[numPropertiesToDisplay++] = propName;
  198. }
  199. else
  200. {
  201. progerr("Too many properties to display.");
  202. }
  203. }
  204. void initSearchResultProperties()
  205. {
  206. /* lookup selected property names */
  207. int i;
  208. if (numPropertiesToDisplay == 0)
  209. return;
  210. for (i = 0; i<numPropertiesToDisplay; i++)
  211. {
  212. printf("# DocProperty %d: %sn", i+1, propNameToDisplay[i]);
  213. /*strlwr(propNameToDisplay[i]);*/
  214. makeItLow(propNameToDisplay[i]);
  215. propIDToDisplay[i] = getMetaName(propNameToDisplay[i]);
  216. if (propIDToDisplay[i] == 1)
  217. {
  218. char buf[200];
  219. sprintf(buf, "Unknown property name "%s"", propNameToDisplay[i]);
  220. progerr(buf);
  221. return;
  222. }
  223. }
  224. }
  225. void printSearchResultProperties(propPos, fp)
  226.      long propPos; /* from struct sortresult.propPos */
  227.      FILE *fp;
  228. {
  229. int i;
  230. if (numPropertiesToDisplay == 0)
  231. return;
  232. for (i = 0; i<numPropertiesToDisplay; i++)
  233. {
  234. char* propValue;
  235. propValue = lookupDocPropertyValue(propIDToDisplay[i], propPos, fp);
  236. if (useCustomOutputDelimiter)
  237. printf("%s", customOutputDelimiter);
  238. else
  239. printf(" ""); /* default is to quote the string, with leading space */
  240. /* print value, handling newlines and quotes */
  241. while (*propValue)
  242. {
  243. if (*propValue == 'n')
  244. printf(" ");
  245. else if (*propValue == '"') /* should not happen */
  246. printf("&quot;");
  247. else
  248. printf("%c", *propValue);
  249. propValue++;
  250. }
  251. printf("%s", propValue);
  252. if (!useCustomOutputDelimiter)
  253. printf("""); /* default is to quote the string */
  254. }
  255. }
  256. void swapDocPropertyMetaNames(docProperties, metaFile)
  257.      struct docPropertyEntry *docProperties;
  258.      struct metaMergeEntry* metaFile;
  259. {
  260. /* swap metaName values for properties */
  261. while (docProperties)
  262. {
  263. struct metaMergeEntry* metaFileTemp;
  264. /* scan the metaFile list to get the new metaName value */
  265. metaFileTemp = metaFile;
  266. while (metaFileTemp)
  267. {
  268. if (docProperties->metaName == metaFileTemp->oldIndex)
  269. {
  270. docProperties->metaName = metaFileTemp->newIndex;
  271. break;
  272. }
  273. metaFileTemp = metaFileTemp->next;
  274. }
  275. docProperties = docProperties->next;
  276. }
  277. }
  278. #endif