12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468 |
- /* HTVMS_WAISProt.c
- *
- * Adaptation for Lynx by F.Macrides (macrides@sci.wfeb.edu)
- *
- * 31-May-1994 FM Initial version.
- *
- *----------------------------------------------------------------------*/
- /*
- * Routines originally from WProt.c -- FM
- *
- *----------------------------------------------------------------------*/
- /* WIDE AREA INFORMATION SERVER SOFTWARE:
- * No guarantees or restrictions. See the readme file for the full standard
- * disclaimer.
- * 3.26.90 Harry Morris, morris@think.com
- * 3.30.90 Harry Morris
- * - removed chunk code from WAISSearchAPDU,
- * - added makeWAISQueryType1Query() and readWAISType1Query() which replace
- * makeWAISQueryTerms() and makeWAISQueryDocs().
- * 4.11.90 HWM - generalized conditional includes (see c-dialect.h)
- * - renamed makeWAISType1Query() to makeWAISTextQuery()
- * renamed readWAISType1Query() to readWAISTextQuery()
- * 5.29.90 TS - fixed bug in makeWAISQueryDocs
- * added CSTFreeWAISFoo functions
- */
- #define _C_WAIS_protocol_
- /* This file implements the Z39.50 extensions required for WAIS
- */
- #include <HTUtils.h>
- #include <HTVMS_WaisUI.h>
- #include <HTVMS_WaisProt.h>
- #include <LYLeaks.h>
- /* very rough estimates of the size of an object */
- #define DefWAISInitResponseSize (size_t)200
- #define DefWAISSearchSize (size_t)3000
- #define DefWAISSearchResponseSize (size_t)6000
- #define DefWAISPresentSize (size_t)1000
- #define DefWAISPresentResponseSize (size_t)6000
- #define DefWAISDocHeaderSize (size_t)500
- #define DefWAISShortHeaderSize (size_t)200
- #define DefWAISLongHeaderSize (size_t)800
- #define DefWAISDocTextSize (size_t)6000
- #define DefWAISDocHeadlineSize (size_t)500
- #define DefWAISDocCodeSize (size_t)500
- #define RESERVE_SPACE_FOR_WAIS_HEADER(len) \
- if (*len > 0) \
- *len -= header_len;
- #define S_MALLOC(type) (type*)s_malloc(sizeof(type))
- #define S_MALLOC2(type) (type*)s_malloc(sizeof(type) * 2)
- #define S_REALLOC2(type, ptr, num) (type*)s_realloc((char*)ptr, (sizeof(type) * (num + 2)))
- /*----------------------------------------------------------------------*/
- static unsigned long userInfoTagSize(data_tag tag,
- unsigned long length)
- /* return the number of bytes required to write the user info tag and
- length
- */
- {
- unsigned long size;
- /* calculate bytes required to represent tag. max tag is 16K */
- size = writtenCompressedIntSize(tag);
- size += writtenCompressedIntSize(length);
- return (size);
- }
- /*----------------------------------------------------------------------*/
- static char *writeUserInfoHeader(data_tag tag,
- long infoSize,
- long estHeaderSize,
- char *buffer,
- long *len)
- /* write the tag and size, making sure the info fits. return the true end
- of the info (after adjustment) note that the argument infoSize includes
- estHeaderSize. Note that the argument len is the number of bytes remaining
- in the buffer. Since we write the tag and size at the begining of the
- buffer (in space that we reserved) we don't want to pass len the calls which
- do that writing.
- */
- {
- long dummyLen = 100; /* plenty of space for a tag and size */
- char *buf = buffer;
- long realSize = infoSize - estHeaderSize;
- long realHeaderSize = userInfoTagSize(tag, realSize);
- if (buffer == NULL || *len == 0)
- return (NULL);
- /* write the tag */
- buf = writeTag(tag, buf, &dummyLen);
- /* see if the if the header size was correct. if not,
- we have to shift the info to fit the real header size */
- if (estHeaderSize != realHeaderSize) { /* make sure there is enough space */
- CHECK_FOR_SPACE_LEFT(realHeaderSize - estHeaderSize, len);
- memmove(buffer + realHeaderSize, buffer + estHeaderSize, (size_t) (realSize));
- }
- /* write the size */
- writeCompressedInteger(realSize, buf, &dummyLen);
- /* return the true end of buffer */
- return (buffer + realHeaderSize + realSize);
- }
- /*----------------------------------------------------------------------*/
- static char *readUserInfoHeader(data_tag *tag,
- unsigned long *num,
- char *buffer)
- /* read the tag and size */
- {
- char *buf = buffer;
- buf = readTag(tag, buf);
- buf = readCompressedInteger(num, buf);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISInitResponse *makeWAISInitResponse(long chunkCode,
- long chunkIDLen,
- char *chunkMarker,
- char *highlightMarker,
- char *deHighlightMarker,
- char *newLineChars)
- /* create a WAIS init response object */
- {
- WAISInitResponse *init = S_MALLOC(WAISInitResponse);
- init->ChunkCode = chunkCode; /* note: none are copied! */
- init->ChunkIDLength = chunkIDLen;
- init->ChunkMarker = chunkMarker;
- init->HighlightMarker = highlightMarker;
- init->DeHighlightMarker = deHighlightMarker;
- init->NewlineCharacters = newLineChars;
- return (init);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISInitResponse(WAISInitResponse *init)
- /* free an object made with makeWAISInitResponse */
- {
- s_free(init->ChunkMarker);
- s_free(init->HighlightMarker);
- s_free(init->DeHighlightMarker);
- s_free(init->NewlineCharacters);
- s_free(init);
- }
- /*----------------------------------------------------------------------*/
- char *writeInitResponseInfo(InitResponseAPDU *init,
- char *buffer,
- long *len)
- /* write an init response object */
- {
- unsigned long header_len = userInfoTagSize(DT_UserInformationLength,
- DefWAISInitResponseSize);
- char *buf = buffer + header_len;
- WAISInitResponse *info = (WAISInitResponse *) init->UserInformationField;
- unsigned long size;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeNum(info->ChunkCode, DT_ChunkCode, buf, len);
- buf = writeNum(info->ChunkIDLength, DT_ChunkIDLength, buf, len);
- buf = writeString(info->ChunkMarker, DT_ChunkMarker, buf, len);
- buf = writeString(info->HighlightMarker, DT_HighlightMarker, buf, len);
- buf = writeString(info->DeHighlightMarker, DT_DeHighlightMarker, buf, len);
- buf = writeString(info->NewlineCharacters, DT_NewlineCharacters, buf, len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_UserInformationLength,
- size,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readInitResponseInfo(void **info,
- char *buffer)
- /* read an init response object */
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- long chunkCode, chunkIDLen;
- data_tag tag1;
- char *chunkMarker = NULL;
- char *highlightMarker = NULL;
- char *deHighlightMarker = NULL;
- char *newLineChars = NULL;
- chunkCode = chunkIDLen = UNUSED;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_ChunkCode:
- buf = readNum(&chunkCode, buf);
- break;
- case DT_ChunkIDLength:
- buf = readNum(&chunkIDLen, buf);
- break;
- case DT_ChunkMarker:
- buf = readString(&chunkMarker, buf);
- break;
- case DT_HighlightMarker:
- buf = readString(&highlightMarker, buf);
- break;
- case DT_DeHighlightMarker:
- buf = readString(&deHighlightMarker, buf);
- break;
- case DT_NewlineCharacters:
- buf = readString(&newLineChars, buf);
- break;
- default:
- s_free(highlightMarker);
- s_free(deHighlightMarker);
- s_free(newLineChars);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *info = (void *) makeWAISInitResponse(chunkCode, chunkIDLen, chunkMarker,
- highlightMarker, deHighlightMarker,
- newLineChars);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISSearch *makeWAISSearch(char *seedWords,
- DocObj **docs,
- char **textList,
- long dateFactor,
- char *beginDateRange,
- char *endDateRange,
- long maxDocsRetrieved)
- /* create a type 3 query object */
- {
- WAISSearch *query = S_MALLOC(WAISSearch);
- query->SeedWords = seedWords; /* not copied! */
- query->Docs = docs; /* not copied! */
- query->TextList = textList; /* not copied! */
- query->DateFactor = dateFactor;
- query->BeginDateRange = beginDateRange;
- query->EndDateRange = endDateRange;
- query->MaxDocumentsRetrieved = maxDocsRetrieved;
- return (query);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISSearch(WAISSearch *query)
- /* destroy an object made with makeWAISSearch() */
- {
- void *ptr = NULL;
- long i;
- s_free(query->SeedWords);
- if (query->Docs != NULL)
- for (i = 0, ptr = (void *) query->Docs[i];
- ptr != NULL;
- ptr = (void *) query->Docs[++i])
- freeDocObj((DocObj *) ptr);
- s_free(query->Docs);
- if (query->TextList != NULL) /* XXX revisit when textlist is fully defined */
- for (i = 0, ptr = (void *) query->TextList[i];
- ptr != NULL;
- ptr = (void *) query->TextList[++i])
- s_free(ptr);
- s_free(query->TextList);
- s_free(query->BeginDateRange);
- s_free(query->EndDateRange);
- s_free(query);
- }
- /*----------------------------------------------------------------------*/
- DocObj *makeDocObjUsingWholeDocument(any *docID,
- char *type)
- /* construct a document object using byte chunks - only for use by
- servers */
- {
- DocObj *doc = S_MALLOC(DocObj);
- doc->DocumentID = docID; /* not copied! */
- doc->Type = type; /* not copied! */
- doc->ChunkCode = CT_document;
- return (doc);
- }
- /*----------------------------------------------------------------------*/
- DocObj *makeDocObjUsingLines(any *docID,
- char *type,
- long start,
- long end)
- /* construct a document object using line chunks - only for use by
- servers */
- {
- DocObj *doc = S_MALLOC(DocObj);
- doc->ChunkCode = CT_line;
- doc->DocumentID = docID; /* not copied */
- doc->Type = type; /* not copied! */
- doc->ChunkStart.Pos = start;
- doc->ChunkEnd.Pos = end;
- return (doc);
- }
- /*----------------------------------------------------------------------*/
- DocObj *makeDocObjUsingBytes(any *docID,
- char *type,
- long start,
- long end)
- /* construct a document object using byte chunks - only for use by
- servers */
- {
- DocObj *doc = S_MALLOC(DocObj);
- doc->ChunkCode = CT_byte;
- doc->DocumentID = docID; /* not copied */
- doc->Type = type; /* not copied! */
- doc->ChunkStart.Pos = start;
- doc->ChunkEnd.Pos = end;
- return (doc);
- }
- /*----------------------------------------------------------------------*/
- DocObj *makeDocObjUsingParagraphs(any *docID,
- char *type,
- any *start,
- any *end)
- /* construct a document object using byte chunks - only for use by
- servers */
- {
- DocObj *doc = S_MALLOC(DocObj);
- doc->ChunkCode = CT_paragraph;
- doc->DocumentID = docID; /* not copied */
- doc->Type = type;
- doc->ChunkStart.ID = start;
- doc->ChunkEnd.ID = end;
- return (doc);
- }
- /*----------------------------------------------------------------------*/
- void freeDocObj(DocObj *doc)
- /* free a docObj */
- {
- freeAny(doc->DocumentID);
- s_free(doc->Type);
- if (doc->ChunkCode == CT_paragraph) {
- freeAny(doc->ChunkStart.ID);
- freeAny(doc->ChunkEnd.ID);
- }
- s_free(doc);
- }
- /*----------------------------------------------------------------------*/
- static char *writeDocObj(DocObj *doc,
- char *buffer,
- long *len)
- /* write as little as we can about the doc obj */
- {
- char *buf = buffer;
- /* we alwasy have to write the id, but its tag depends on if its a chunk */
- if (doc->ChunkCode == CT_document)
- buf = writeAny(doc->DocumentID, DT_DocumentID, buf, len);
- else
- buf = writeAny(doc->DocumentID, DT_DocumentIDChunk, buf, len);
- if (doc->Type != NULL)
- buf = writeString(doc->Type, DT_TYPE, buf, len);
- switch (doc->ChunkCode) {
- case CT_document:
- /* do nothing - there is no chunk data */
- break;
- case CT_byte:
- case CT_line:
- buf = writeNum(doc->ChunkCode, DT_ChunkCode, buf, len);
- buf = writeNum(doc->ChunkStart.Pos, DT_ChunkStartID, buf, len);
- buf = writeNum(doc->ChunkEnd.Pos, DT_ChunkEndID, buf, len);
- break;
- case CT_paragraph:
- buf = writeNum(doc->ChunkCode, DT_ChunkCode, buf, len);
- buf = writeAny(doc->ChunkStart.ID, DT_ChunkStartID, buf, len);
- buf = writeAny(doc->ChunkEnd.ID, DT_ChunkEndID, buf, len);
- break;
- default:
- panic("Implementation error: unknown chuck type %ld",
- doc->ChunkCode);
- break;
- }
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- static char *readDocObj(DocObj **doc,
- char *buffer)
- /* read whatever we have about the new document */
- {
- char *buf = buffer;
- data_tag tag;
- *doc = S_MALLOC(DocObj);
- tag = peekTag(buf);
- buf = readAny(&((*doc)->DocumentID), buf);
- if (tag == DT_DocumentID) {
- (*doc)->ChunkCode = CT_document;
- tag = peekTag(buf);
- if (tag == DT_TYPE) /* XXX depends on DT_TYPE != what comes next */
- buf = readString(&((*doc)->Type), buf);
- /* ChunkStart and ChunkEnd are undefined */
- } else if (tag == DT_DocumentIDChunk) {
- boolean readParagraphs = false; /* for cleanup */
- tag = peekTag(buf);
- if (tag == DT_TYPE) /* XXX depends on DT_TYPE != CT_FOO */
- buf = readString(&((*doc)->Type), buf);
- buf = readNum(&((*doc)->ChunkCode), buf);
- switch ((*doc)->ChunkCode) {
- case CT_byte:
- case CT_line:
- buf = readNum(&((*doc)->ChunkStart.Pos), buf);
- buf = readNum(&((*doc)->ChunkEnd.Pos), buf);
- break;
- case CT_paragraph:
- readParagraphs = true;
- buf = readAny(&((*doc)->ChunkStart.ID), buf);
- buf = readAny(&((*doc)->ChunkEnd.ID), buf);
- break;
- default:
- freeAny((*doc)->DocumentID);
- if (readParagraphs) {
- freeAny((*doc)->ChunkStart.ID);
- freeAny((*doc)->ChunkEnd.ID);
- }
- s_free(doc);
- REPORT_READ_ERROR(buf);
- break;
- }
- } else {
- freeAny((*doc)->DocumentID);
- s_free(*doc);
- REPORT_READ_ERROR(buf);
- }
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *writeSearchInfo(SearchAPDU *query,
- char *buffer,
- long *len)
- /* write out a WAIS query (type 1 or 3) */
- {
- if (strcmp(query->QueryType, QT_TextRetrievalQuery) == 0) {
- return (writeAny((any *) query->Query, DT_Query, buffer, len));
- } else {
- unsigned long header_len = userInfoTagSize(DT_UserInformationLength,
- DefWAISSearchSize);
- char *buf = buffer + header_len;
- WAISSearch *info = (WAISSearch *) query->Query;
- unsigned long size;
- long i;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeString(info->SeedWords, DT_SeedWords, buf, len);
- if (info->Docs != NULL) {
- for (i = 0; info->Docs[i] != NULL; i++) {
- buf = writeDocObj(info->Docs[i], buf, len);
- }
- }
- /* XXX text list */
- buf = writeNum(info->DateFactor,
- DT_DateFactor,
- buf,
- len);
- buf = writeString(info->BeginDateRange,
- DT_BeginDateRange,
- buf,
- len);
- buf = writeString(info->EndDateRange,
- DT_EndDateRange,
- buf,
- len);
- buf = writeNum(info->MaxDocumentsRetrieved,
- DT_MaxDocumentsRetrieved,
- buf,
- len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_UserInformationLength,
- size,
- header_len,
- buffer,
- len);
- return (buf);
- }
- }
- /*----------------------------------------------------------------------*/
- char *readSearchInfo(void **info,
- char *buffer)
- /* read a WAIS query (type 1 or 3) */
- {
- data_tag type = peekTag(buffer);
- if (type == DT_Query) /* this is a type 1 query */
- {
- char *buf = buffer;
- any *query = NULL;
- buf = readAny(&query, buf);
- *info = (void *) query;
- return (buf);
- } else { /* a type 3 query */
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- char *seedWords = NULL;
- char *beginDateRange = NULL;
- char *endDateRange = NULL;
- long dateFactor, maxDocsRetrieved;
- char **textList = NULL;
- DocObj **docIDs = NULL;
- DocObj *doc = NULL;
- long docs = 0;
- long i;
- void *ptr = NULL;
- dateFactor = maxDocsRetrieved = UNUSED;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_SeedWords:
- buf = readString(&seedWords, buf);
- break;
- case DT_DocumentID:
- case DT_DocumentIDChunk:
- if (docIDs == NULL) /* create a new doc list */
- {
- docIDs = S_MALLOC2(DocObj *);
- } else { /* grow the doc list */
- docIDs = S_REALLOC2(DocObj *, docIDs, docs);
- }
- buf = readDocObj(&doc, buf);
- if (buf == NULL) {
- s_free(seedWords);
- s_free(beginDateRange);
- s_free(endDateRange);
- if (docIDs != NULL)
- for (i = 0, ptr = (void *) docIDs[i];
- ptr != NULL;
- ptr = (void *) docIDs[++i])
- freeDocObj((DocObj *) ptr);
- s_free(docIDs);
- /* XXX should also free textlist when it is fully defined */
- }
- RETURN_ON_NULL(buf);
- docIDs[docs++] = doc; /* put it in the list */
- docIDs[docs] = NULL;
- break;
- case DT_TextList:
- /* XXX */
- break;
- case DT_DateFactor:
- buf = readNum(&dateFactor, buf);
- break;
- case DT_BeginDateRange:
- buf = readString(&beginDateRange, buf);
- break;
- case DT_EndDateRange:
- buf = readString(&endDateRange, buf);
- break;
- case DT_MaxDocumentsRetrieved:
- buf = readNum(&maxDocsRetrieved, buf);
- break;
- default:
- s_free(seedWords);
- s_free(beginDateRange);
- s_free(endDateRange);
- if (docIDs != NULL)
- for (i = 0, ptr = (void *) docIDs[i];
- ptr != NULL;
- ptr = (void *) docIDs[++i])
- freeDocObj((DocObj *) ptr);
- s_free(docIDs);
- /* XXX should also free textlist when it is fully defined */
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *info = (void *) makeWAISSearch(seedWords, docIDs, textList,
- dateFactor, beginDateRange, endDateRange,
- maxDocsRetrieved);
- return (buf);
- }
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentHeader *makeWAISDocumentHeader(any *docID,
- long versionNumber,
- long score,
- long bestMatch,
- long docLen,
- long lines,
- char **types,
- char *source,
- char *date,
- char *headline,
- char *originCity)
- /* construct a standard document header, note that no fields are copied!
- if the application needs to save these fields, it should copy them,
- or set the field in this object to NULL before freeing it.
- */
- {
- WAISDocumentHeader *header = S_MALLOC(WAISDocumentHeader);
- header->DocumentID = docID;
- header->VersionNumber = versionNumber;
- header->Score = score;
- header->BestMatch = bestMatch;
- header->DocumentLength = docLen;
- header->Lines = lines;
- header->Types = types;
- header->Source = source;
- header->Date = date;
- header->Headline = headline;
- header->OriginCity = originCity;
- return (header);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentHeader(WAISDocumentHeader *header)
- {
- freeAny(header->DocumentID);
- doList((void **) header->Types, fs_free); /* can't use the macro here ! */
- s_free(header->Types);
- s_free(header->Source);
- s_free(header->Date);
- s_free(header->Headline);
- s_free(header->OriginCity);
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentHeader(WAISDocumentHeader *header, char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentHeaderGroup,
- DefWAISDocHeaderSize);
- char *buf = buffer + header_len;
- unsigned long size1;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(header->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(header->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeNum(header->Score, DT_Score, buf, len);
- buf = writeNum(header->BestMatch, DT_BestMatch, buf, len);
- buf = writeNum(header->DocumentLength, DT_DocumentLength, buf, len);
- buf = writeNum(header->Lines, DT_Lines, buf, len);
- if (header->Types != NULL) {
- long size;
- char *ptr = NULL;
- long i;
- buf = writeTag(DT_TYPE_BLOCK, buf, len);
- for (i = 0, size = 0, ptr = header->Types[i];
- ptr != NULL;
- ptr = header->Types[++i]) {
- long typeSize = strlen(ptr);
- size += writtenTagSize(DT_TYPE);
- size += writtenCompressedIntSize(typeSize);
- size += typeSize;
- }
- buf = writeCompressedInteger((unsigned long) size, buf, len);
- for (i = 0, ptr = header->Types[i]; ptr != NULL; ptr = header->Types[++i])
- buf = writeString(ptr, DT_TYPE, buf, len);
- }
- buf = writeString(header->Source, DT_Source, buf, len);
- buf = writeString(header->Date, DT_Date, buf, len);
- buf = writeString(header->Headline, DT_Headline, buf, len);
- buf = writeString(header->OriginCity, DT_OriginCity, buf, len);
- /* now write the header and size */
- size1 = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentHeaderGroup,
- size1,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentHeader(WAISDocumentHeader **header, char *buffer)
- {
- char *buf = buffer;
- unsigned long size1;
- unsigned long headerSize;
- data_tag tag1;
- any *docID = NULL;
- long versionNumber, score, bestMatch, docLength, lines;
- char **types = NULL;
- char *source = NULL;
- char *date = NULL;
- char *headline = NULL;
- char *originCity = NULL;
- versionNumber = score = bestMatch = docLength = lines = UNUSED;
- buf = readUserInfoHeader(&tag1, &size1, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size1 + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_Score:
- buf = readNum(&score, buf);
- break;
- case DT_BestMatch:
- buf = readNum(&bestMatch, buf);
- break;
- case DT_DocumentLength:
- buf = readNum(&docLength, buf);
- break;
- case DT_Lines:
- buf = readNum(&lines, buf);
- break;
- case DT_TYPE_BLOCK:
- {
- unsigned long size = -1;
- long numTypes = 0;
- buf = readTag(&tag, buf);
- buf = readCompressedInteger(&size, buf);
- while (size > 0) {
- char *type = NULL;
- char *originalBuf = buf;
- buf = readString(&type, buf);
- types = S_REALLOC2(char *, types, numTypes);
- types[numTypes++] = type;
- types[numTypes] = NULL;
- size -= (buf - originalBuf);
- }
- }
- /* FALLTHRU */
- case DT_Source:
- buf = readString(&source, buf);
- break;
- case DT_Date:
- buf = readString(&date, buf);
- break;
- case DT_Headline:
- buf = readString(&headline, buf);
- break;
- case DT_OriginCity:
- buf = readString(&originCity, buf);
- break;
- default:
- freeAny(docID);
- s_free(source);
- s_free(date);
- s_free(headline);
- s_free(originCity);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *header = makeWAISDocumentHeader(docID, versionNumber, score, bestMatch,
- docLength, lines, types, source, date, headline,
- originCity);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentShortHeader *makeWAISDocumentShortHeader(any *docID,
- long versionNumber,
- long score,
- long bestMatch,
- long docLen,
- long lines)
- /* construct a short document header, note that no fields are copied!
- if the application needs to save these fields, it should copy them,
- or set the field in this object to NULL before freeing it.
- */
- {
- WAISDocumentShortHeader *header = S_MALLOC(WAISDocumentShortHeader);
- header->DocumentID = docID;
- header->VersionNumber = versionNumber;
- header->Score = score;
- header->BestMatch = bestMatch;
- header->DocumentLength = docLen;
- header->Lines = lines;
- return (header);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentShortHeader(WAISDocumentShortHeader *header)
- {
- freeAny(header->DocumentID);
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentShortHeader(WAISDocumentShortHeader *header, char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentShortHeaderGroup,
- DefWAISShortHeaderSize);
- char *buf = buffer + header_len;
- unsigned long size;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(header->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(header->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeNum(header->Score, DT_Score, buf, len);
- buf = writeNum(header->BestMatch, DT_BestMatch, buf, len);
- buf = writeNum(header->DocumentLength, DT_DocumentLength, buf, len);
- buf = writeNum(header->Lines, DT_Lines, buf, len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentShortHeaderGroup,
- size,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentShortHeader(WAISDocumentShortHeader **header, char *buffer)
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- any *docID = NULL;
- long versionNumber, score, bestMatch, docLength, lines;
- versionNumber = score = bestMatch = docLength = lines = UNUSED;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_Score:
- buf = readNum(&score, buf);
- break;
- case DT_BestMatch:
- buf = readNum(&bestMatch, buf);
- break;
- case DT_DocumentLength:
- buf = readNum(&docLength, buf);
- break;
- case DT_Lines:
- buf = readNum(&lines, buf);
- break;
- default:
- freeAny(docID);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *header = makeWAISDocumentShortHeader(docID, versionNumber, score, bestMatch,
- docLength, lines);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentLongHeader *makeWAISDocumentLongHeader(any *docID,
- long versionNumber,
- long score,
- long bestMatch,
- long docLen,
- long lines,
- char **types,
- char *source,
- char *date,
- char *headline,
- char *originCity,
- char *stockCodes,
- char *companyCodes,
- char *industryCodes)
- /* construct a long document header, note that no fields are copied!
- if the application needs to save these fields, it should copy them,
- or set the field in this object to NULL before freeing it.
- */
- {
- WAISDocumentLongHeader *header = S_MALLOC(WAISDocumentLongHeader);
- header->DocumentID = docID;
- header->VersionNumber = versionNumber;
- header->Score = score;
- header->BestMatch = bestMatch;
- header->DocumentLength = docLen;
- header->Lines = lines;
- header->Types = types;
- header->Source = source;
- header->Date = date;
- header->Headline = headline;
- header->OriginCity = originCity;
- header->StockCodes = stockCodes;
- header->CompanyCodes = companyCodes;
- header->IndustryCodes = industryCodes;
- return (header);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentLongHeader(WAISDocumentLongHeader *header)
- {
- freeAny(header->DocumentID);
- doList((void **) header->Types, fs_free); /* can't use the macro here! */
- s_free(header->Source);
- s_free(header->Date);
- s_free(header->Headline);
- s_free(header->OriginCity);
- s_free(header->StockCodes);
- s_free(header->CompanyCodes);
- s_free(header->IndustryCodes);
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentLongHeader(WAISDocumentLongHeader *header, char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentLongHeaderGroup,
- DefWAISLongHeaderSize);
- char *buf = buffer + header_len;
- unsigned long size1;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(header->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(header->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeNum(header->Score, DT_Score, buf, len);
- buf = writeNum(header->BestMatch, DT_BestMatch, buf, len);
- buf = writeNum(header->DocumentLength, DT_DocumentLength, buf, len);
- buf = writeNum(header->Lines, DT_Lines, buf, len);
- if (header->Types != NULL) {
- long size;
- char *ptr = NULL;
- long i;
- buf = writeTag(DT_TYPE_BLOCK, buf, len);
- for (i = 0, size = 0, ptr = header->Types[i];
- ptr != NULL;
- ptr = header->Types[++i]) {
- long typeSize = strlen(ptr);
- size += writtenTagSize(DT_TYPE);
- size += writtenCompressedIntSize(typeSize);
- size += typeSize;
- }
- buf = writeCompressedInteger((unsigned long) size, buf, len);
- for (i = 0, ptr = header->Types[i]; ptr != NULL; ptr = header->Types[++i])
- buf = writeString(ptr, DT_TYPE, buf, len);
- }
- buf = writeString(header->Source, DT_Source, buf, len);
- buf = writeString(header->Date, DT_Date, buf, len);
- buf = writeString(header->Headline, DT_Headline, buf, len);
- buf = writeString(header->OriginCity, DT_OriginCity, buf, len);
- buf = writeString(header->StockCodes, DT_StockCodes, buf, len);
- buf = writeString(header->CompanyCodes, DT_CompanyCodes, buf, len);
- buf = writeString(header->IndustryCodes, DT_IndustryCodes, buf, len);
- /* now write the header and size */
- size1 = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentLongHeaderGroup,
- size1,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentLongHeader(WAISDocumentLongHeader **header, char *buffer)
- {
- char *buf = buffer;
- unsigned long size1;
- unsigned long headerSize;
- data_tag tag1;
- any *docID;
- long versionNumber, score, bestMatch, docLength, lines;
- char **types;
- char *source, *date, *headline, *originCity, *stockCodes, *companyCodes, *industryCodes;
- docID = NULL;
- versionNumber =
- score =
- bestMatch =
- docLength =
- lines = UNUSED;
- types = NULL;
- source =
- date =
- headline =
- originCity =
- stockCodes =
- companyCodes =
- industryCodes = NULL;
- buf = readUserInfoHeader(&tag1, &size1, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size1 + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_Score:
- buf = readNum(&score, buf);
- break;
- case DT_BestMatch:
- buf = readNum(&bestMatch, buf);
- break;
- case DT_DocumentLength:
- buf = readNum(&docLength, buf);
- break;
- case DT_Lines:
- buf = readNum(&lines, buf);
- break;
- case DT_TYPE_BLOCK:
- {
- unsigned long size = -1;
- long numTypes = 0;
- buf = readTag(&tag, buf);
- readCompressedInteger(&size, buf);
- while (size > 0) {
- char *type = NULL;
- char *originalBuf = buf;
- buf = readString(&type, buf);
- types = S_REALLOC2(char *, types, numTypes);
- types[numTypes++] = type;
- types[numTypes] = NULL;
- size -= (buf - originalBuf);
- }
- }
- /* FALLTHRU */
- case DT_Source:
- buf = readString(&source, buf);
- break;
- case DT_Date:
- buf = readString(&date, buf);
- break;
- case DT_Headline:
- buf = readString(&headline, buf);
- break;
- case DT_OriginCity:
- buf = readString(&originCity, buf);
- break;
- case DT_StockCodes:
- buf = readString(&stockCodes, buf);
- break;
- case DT_CompanyCodes:
- buf = readString(&companyCodes, buf);
- break;
- case DT_IndustryCodes:
- buf = readString(&industryCodes, buf);
- break;
- default:
- freeAny(docID);
- s_free(source);
- s_free(date);
- s_free(headline);
- s_free(originCity);
- s_free(stockCodes);
- s_free(companyCodes);
- s_free(industryCodes);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *header = makeWAISDocumentLongHeader(docID,
- versionNumber,
- score,
- bestMatch,
- docLength,
- lines,
- types,
- source,
- date,
- headline,
- originCity,
- stockCodes,
- companyCodes,
- industryCodes);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISSearchResponse *
- makeWAISSearchResponse(
- char *seedWordsUsed,
- WAISDocumentHeader **docHeaders,
- WAISDocumentShortHeader **shortHeaders,
- WAISDocumentLongHeader **longHeaders,
- WAISDocumentText **text,
- WAISDocumentHeadlines **headlines,
- WAISDocumentCodes **codes,
- diagnosticRecord ** diagnostics)
- {
- WAISSearchResponse *response = S_MALLOC(WAISSearchResponse);
- response->SeedWordsUsed = seedWordsUsed;
- response->DocHeaders = docHeaders;
- response->ShortHeaders = shortHeaders;
- response->LongHeaders = longHeaders;
- response->Text = text;
- response->Headlines = headlines;
- response->Codes = codes;
- response->Diagnostics = diagnostics;
- return (response);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISSearchResponse(WAISSearchResponse * response)
- {
- void *ptr = NULL;
- long i;
- s_free(response->SeedWordsUsed);
- if (response->DocHeaders != NULL)
- for (i = 0, ptr = (void *) response->DocHeaders[i];
- ptr != NULL;
- ptr = (void *) response->DocHeaders[++i])
- freeWAISDocumentHeader((WAISDocumentHeader *) ptr);
- s_free(response->DocHeaders);
- if (response->ShortHeaders != NULL)
- for (i = 0, ptr = (void *) response->ShortHeaders[i];
- ptr != NULL;
- ptr = (void *) response->ShortHeaders[++i])
- freeWAISDocumentShortHeader((WAISDocumentShortHeader *) ptr);
- s_free(response->ShortHeaders);
- if (response->LongHeaders != NULL)
- for (i = 0, ptr = (void *) response->LongHeaders[i];
- ptr != NULL;
- ptr = (void *) response->LongHeaders[++i])
- freeWAISDocumentLongHeader((WAISDocumentLongHeader *) ptr);
- s_free(response->LongHeaders);
- if (response->Text != NULL)
- for (i = 0, ptr = (void *) response->Text[i];
- ptr != NULL;
- ptr = (void *) response->Text[++i])
- freeWAISDocumentText((WAISDocumentText *) ptr);
- s_free(response->Text);
- if (response->Headlines != NULL)
- for (i = 0, ptr = (void *) response->Headlines[i];
- ptr != NULL;
- ptr = (void *) response->Headlines[++i])
- freeWAISDocumentHeadlines((WAISDocumentHeadlines *) ptr);
- s_free(response->Headlines);
- if (response->Codes != NULL)
- for (i = 0, ptr = (void *) response->Codes[i];
- ptr != NULL;
- ptr = (void *) response->Codes[++i])
- freeWAISDocumentCodes((WAISDocumentCodes *) ptr);
- s_free(response->Codes);
- if (response->Diagnostics != NULL)
- for (i = 0, ptr = (void *) response->Diagnostics[i];
- ptr != NULL;
- ptr = (void *) response->Diagnostics[++i])
- freeDiag((diagnosticRecord *) ptr);
- s_free(response->Diagnostics);
- s_free(response);
- }
- /*----------------------------------------------------------------------*/
- char *writeSearchResponseInfo(SearchResponseAPDU *query,
- char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_UserInformationLength,
- DefWAISSearchResponseSize);
- char *buf = buffer + header_len;
- WAISSearchResponse *info = (WAISSearchResponse *) query->DatabaseDiagnosticRecords;
- unsigned long size;
- void *header = NULL;
- long i;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeString(info->SeedWordsUsed, DT_SeedWordsUsed, buf, len);
- /* write out all the headers */
- if (info->DocHeaders != NULL) {
- for (i = 0, header = (void *) info->DocHeaders[i];
- header != NULL;
- header = (void *) info->DocHeaders[++i])
- buf = writeWAISDocumentHeader((WAISDocumentHeader *) header, buf, len);
- }
- if (info->ShortHeaders != NULL) {
- for (i = 0, header = (void *) info->ShortHeaders[i];
- header != NULL;
- header = (void *) info->ShortHeaders[++i])
- buf = writeWAISDocumentShortHeader((WAISDocumentShortHeader *) header,
- buf,
- len);
- }
- if (info->LongHeaders != NULL) {
- for (i = 0, header = (void *) info->LongHeaders[i];
- header != NULL;
- header = (void *) info->LongHeaders[++i])
- buf = writeWAISDocumentLongHeader((WAISDocumentLongHeader *) header,
- buf,
- len);
- }
- if (info->Text != NULL) {
- for (i = 0, header = (void *) info->Text[i];
- header != NULL;
- header = (void *) info->Text[++i])
- buf = writeWAISDocumentText((WAISDocumentText *) header, buf, len);
- }
- if (info->Headlines != NULL) {
- for (i = 0, header = (void *) info->Headlines[i];
- header != NULL;
- header = (void *) info->Headlines[++i])
- buf = writeWAISDocumentHeadlines((WAISDocumentHeadlines *) header,
- buf,
- len);
- }
- if (info->Codes != NULL) {
- for (i = 0, header = (void *) info->Codes[i];
- header != NULL;
- header = (void *) info->Codes[++i])
- buf = writeWAISDocumentCodes((WAISDocumentCodes *) header, buf, len);
- }
- if (info->Diagnostics != NULL) {
- for (i = 0, header = (void *) info->Diagnostics[i];
- header != NULL;
- header = (void *) info->Diagnostics[++i])
- buf = writeDiag((diagnosticRecord *) header, buf, len);
- }
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_UserInformationLength,
- size,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- static void cleanUpWaisSearchResponse(char *buf,
- char *seedWordsUsed,
- WAISDocumentHeader **docHeaders,
- WAISDocumentShortHeader **shortHeaders,
- WAISDocumentLongHeader **longHeaders,
- WAISDocumentText **text,
- WAISDocumentHeadlines **headlines,
- WAISDocumentCodes **codes,
- diagnosticRecord ** diags)
- /* if buf is NULL, we have just gotten a read error, and need to clean up
- any state we have built. If not, then everything is going fine, and
- we should just hang loose
- */
- {
- void *ptr = NULL;
- long i;
- if (buf == NULL) {
- s_free(seedWordsUsed);
- if (docHeaders != NULL)
- for (i = 0, ptr = (void *) docHeaders[i]; ptr != NULL;
- ptr = (void *) docHeaders[++i])
- freeWAISDocumentHeader((WAISDocumentHeader *) ptr);
- s_free(docHeaders);
- if (shortHeaders != NULL)
- for (i = 0, ptr = (void *) shortHeaders[i]; ptr != NULL;
- ptr = (void *) shortHeaders[++i])
- freeWAISDocumentShortHeader((WAISDocumentShortHeader *) ptr);
- s_free(shortHeaders);
- if (longHeaders != NULL)
- for (i = 0, ptr = (void *) longHeaders[i]; ptr != NULL;
- ptr = (void *) longHeaders[++i])
- freeWAISDocumentLongHeader((WAISDocumentLongHeader *) ptr);
- s_free(longHeaders);
- if (text != NULL)
- for (i = 0, ptr = (void *) text[i];
- ptr != NULL;
- ptr = (void *) text[++i])
- freeWAISDocumentText((WAISDocumentText *) ptr);
- s_free(text);
- if (headlines != NULL)
- for (i = 0, ptr = (void *) headlines[i]; ptr != NULL;
- ptr = (void *) headlines[++i])
- freeWAISDocumentHeadlines((WAISDocumentHeadlines *) ptr);
- s_free(headlines);
- if (codes != NULL)
- for (i = 0, ptr = (void *) codes[i]; ptr != NULL;
- ptr = (void *) codes[++i])
- freeWAISDocumentCodes((WAISDocumentCodes *) ptr);
- s_free(codes);
- if (diags != NULL)
- for (i = 0, ptr = (void *) diags[i]; ptr != NULL;
- ptr = (void *) diags[++i])
- freeDiag((diagnosticRecord *) ptr);
- s_free(diags);
- }
- }
- /*----------------------------------------------------------------------*/
- char *readSearchResponseInfo(void **info,
- char *buffer)
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- void *header = NULL;
- WAISDocumentHeader **docHeaders = NULL;
- WAISDocumentShortHeader **shortHeaders = NULL;
- WAISDocumentLongHeader **longHeaders = NULL;
- WAISDocumentText **text = NULL;
- WAISDocumentHeadlines **headlines = NULL;
- WAISDocumentCodes **codes = NULL;
- long numDocHeaders, numLongHeaders, numShortHeaders, numText, numHeadlines;
- long numCodes;
- char *seedWordsUsed = NULL;
- diagnosticRecord **diags = NULL;
- diagnosticRecord *diag = NULL;
- long numDiags = 0;
- numDocHeaders =
- numLongHeaders =
- numShortHeaders =
- numText =
- numHeadlines =
- numCodes = 0;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_SeedWordsUsed:
- buf = readString(&seedWordsUsed, buf);
- break;
- case DT_DatabaseDiagnosticRecords:
- if (diags == NULL) /* create a new diag list */
- {
- diags = S_MALLOC2(diagnosticRecord *);
- } else { /* grow the diag list */
- diags = S_REALLOC2(diagnosticRecord *, diags, numDiags);
- }
- buf = readDiag(&diag, buf);
- diags[numDiags++] = diag; /* put it in the list */
- diags[numDiags] = NULL;
- break;
- case DT_DocumentHeaderGroup:
- if (docHeaders == NULL) /* create a new header list */
- {
- docHeaders = S_MALLOC2(WAISDocumentHeader *);
- } else { /* grow the doc list */
- docHeaders = S_REALLOC2(WAISDocumentHeader *, docHeaders, numDocHeaders);
- }
- buf = readWAISDocumentHeader((WAISDocumentHeader **) &header, buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- docHeaders[numDocHeaders++] =
- (WAISDocumentHeader *) header; /* put it in the list */
- docHeaders[numDocHeaders] = NULL;
- break;
- case DT_DocumentShortHeaderGroup:
- if (shortHeaders == NULL) /* create a new header list */
- {
- shortHeaders = S_MALLOC2(WAISDocumentShortHeader *);
- } else { /* grow the doc list */
- shortHeaders = S_REALLOC2(WAISDocumentShortHeader *,
- shortHeaders,
- numShortHeaders);
- }
- buf = readWAISDocumentShortHeader((WAISDocumentShortHeader **) &header,
- buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- shortHeaders[numShortHeaders++] =
- (WAISDocumentShortHeader *) header; /* put it in the list */
- shortHeaders[numShortHeaders] = NULL;
- break;
- case DT_DocumentLongHeaderGroup:
- if (longHeaders == NULL) /* create a new header list */
- {
- longHeaders = S_MALLOC2(WAISDocumentLongHeader *);
- } else { /* grow the doc list */
- longHeaders = S_REALLOC2(WAISDocumentLongHeader *,
- longHeaders,
- numLongHeaders);
- }
- buf = readWAISDocumentLongHeader((WAISDocumentLongHeader **) &header,
- buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- longHeaders[numLongHeaders++] =
- (WAISDocumentLongHeader *) header; /* put it in the list */
- longHeaders[numLongHeaders] = NULL;
- break;
- case DT_DocumentTextGroup:
- if (text == NULL) /* create a new list */
- {
- text = S_MALLOC2(WAISDocumentText *);
- } else { /* grow the list */
- text = S_REALLOC2(WAISDocumentText *, text, numText);
- }
- buf = readWAISDocumentText((WAISDocumentText **) &header, buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- text[numText++] =
- (WAISDocumentText *) header; /* put it in the list */
- text[numText] = NULL;
- break;
- case DT_DocumentHeadlineGroup:
- if (headlines == NULL) /* create a new list */
- {
- headlines = S_MALLOC2(WAISDocumentHeadlines *);
- } else { /* grow the list */
- headlines = S_REALLOC2(WAISDocumentHeadlines *, headlines, numHeadlines);
- }
- buf = readWAISDocumentHeadlines((WAISDocumentHeadlines **) &header,
- buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- headlines[numHeadlines++] =
- (WAISDocumentHeadlines *) header; /* put it in the list */
- headlines[numHeadlines] = NULL;
- break;
- case DT_DocumentCodeGroup:
- if (codes == NULL) /* create a new list */
- {
- codes = S_MALLOC2(WAISDocumentCodes *);
- } else { /* grow the list */
- codes = S_REALLOC2(WAISDocumentCodes *, codes, numCodes);
- }
- buf = readWAISDocumentCodes((WAISDocumentCodes **) &header, buf);
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- RETURN_ON_NULL(buf);
- codes[numCodes++] =
- (WAISDocumentCodes *) header; /* put it in the list */
- codes[numCodes] = NULL;
- break;
- default:
- cleanUpWaisSearchResponse(buf,
- seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *info = (void *) makeWAISSearchResponse(seedWordsUsed,
- docHeaders,
- shortHeaders,
- longHeaders,
- text,
- headlines,
- codes,
- diags);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentText *makeWAISDocumentText(any *docID,
- long versionNumber,
- any *documentText)
- {
- WAISDocumentText *docText = S_MALLOC(WAISDocumentText);
- docText->DocumentID = docID;
- docText->VersionNumber = versionNumber;
- docText->DocumentText = documentText;
- return (docText);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentText(WAISDocumentText *docText)
- {
- freeAny(docText->DocumentID);
- freeAny(docText->DocumentText);
- s_free(docText);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentText(WAISDocumentText *docText, char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentTextGroup,
- DefWAISDocTextSize);
- char *buf = buffer + header_len;
- unsigned long size;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(docText->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(docText->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeAny(docText->DocumentText, DT_DocumentText, buf, len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentTextGroup, size, header_len, buffer, len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentText(WAISDocumentText **docText, char *buffer)
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- any *docID, *documentText;
- long versionNumber;
- docID = documentText = NULL;
- versionNumber = UNUSED;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_DocumentText:
- buf = readAny(&documentText, buf);
- break;
- default:
- freeAny(docID);
- freeAny(documentText);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *docText = makeWAISDocumentText(docID, versionNumber, documentText);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentHeadlines *makeWAISDocumentHeadlines(any *docID,
- long versionNumber,
- char *source,
- char *date,
- char *headline,
- char *originCity)
- {
- WAISDocumentHeadlines *docHeadline = S_MALLOC(WAISDocumentHeadlines);
- docHeadline->DocumentID = docID;
- docHeadline->VersionNumber = versionNumber;
- docHeadline->Source = source;
- docHeadline->Date = date;
- docHeadline->Headline = headline;
- docHeadline->OriginCity = originCity;
- return (docHeadline);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentHeadlines(WAISDocumentHeadlines *docHeadline)
- {
- freeAny(docHeadline->DocumentID);
- s_free(docHeadline->Source);
- s_free(docHeadline->Date);
- s_free(docHeadline->Headline);
- s_free(docHeadline->OriginCity);
- s_free(docHeadline);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentHeadlines(WAISDocumentHeadlines *docHeadline, char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentHeadlineGroup,
- DefWAISDocHeadlineSize);
- char *buf = buffer + header_len;
- unsigned long size;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(docHeadline->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(docHeadline->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeString(docHeadline->Source, DT_Source, buf, len);
- buf = writeString(docHeadline->Date, DT_Date, buf, len);
- buf = writeString(docHeadline->Headline, DT_Headline, buf, len);
- buf = writeString(docHeadline->OriginCity, DT_OriginCity, buf, len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentHeadlineGroup,
- size,
- header_len,
- buffer,
- len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentHeadlines(WAISDocumentHeadlines **docHeadline, char *buffer)
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- any *docID;
- long versionNumber;
- char *source, *date, *headline, *originCity;
- docID = NULL;
- versionNumber = UNUSED;
- source = date = headline = originCity = NULL;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_Source:
- buf = readString(&source, buf);
- break;
- case DT_Date:
- buf = readString(&date, buf);
- break;
- case DT_Headline:
- buf = readString(&headline, buf);
- break;
- case DT_OriginCity:
- buf = readString(&originCity, buf);
- break;
- default:
- freeAny(docID);
- s_free(source);
- s_free(date);
- s_free(headline);
- s_free(originCity);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *docHeadline = makeWAISDocumentHeadlines(docID, versionNumber, source, date,
- headline, originCity);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- WAISDocumentCodes *makeWAISDocumentCodes(any *docID,
- long versionNumber,
- char *stockCodes,
- char *companyCodes,
- char *industryCodes)
- {
- WAISDocumentCodes *docCodes = S_MALLOC(WAISDocumentCodes);
- docCodes->DocumentID = docID;
- docCodes->VersionNumber = versionNumber;
- docCodes->StockCodes = stockCodes;
- docCodes->CompanyCodes = companyCodes;
- docCodes->IndustryCodes = industryCodes;
- return (docCodes);
- }
- /*----------------------------------------------------------------------*/
- void freeWAISDocumentCodes(WAISDocumentCodes *docCodes)
- {
- freeAny(docCodes->DocumentID);
- s_free(docCodes->StockCodes);
- s_free(docCodes->CompanyCodes);
- s_free(docCodes->IndustryCodes);
- s_free(docCodes);
- }
- /*----------------------------------------------------------------------*/
- char *writeWAISDocumentCodes(WAISDocumentCodes *docCodes,
- char *buffer,
- long *len)
- {
- unsigned long header_len = userInfoTagSize(DT_DocumentCodeGroup,
- DefWAISDocCodeSize);
- char *buf = buffer + header_len;
- unsigned long size;
- RESERVE_SPACE_FOR_WAIS_HEADER(len);
- buf = writeAny(docCodes->DocumentID, DT_DocumentID, buf, len);
- buf = writeNum(docCodes->VersionNumber, DT_VersionNumber, buf, len);
- buf = writeString(docCodes->StockCodes, DT_StockCodes, buf, len);
- buf = writeString(docCodes->CompanyCodes, DT_CompanyCodes, buf, len);
- buf = writeString(docCodes->IndustryCodes, DT_IndustryCodes, buf, len);
- /* now write the header and size */
- size = buf - buffer;
- buf = writeUserInfoHeader(DT_DocumentCodeGroup, size, header_len, buffer, len);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *readWAISDocumentCodes(WAISDocumentCodes **docCodes,
- char *buffer)
- {
- char *buf = buffer;
- unsigned long size;
- unsigned long headerSize;
- data_tag tag1;
- any *docID;
- long versionNumber;
- char *stockCodes, *companyCodes, *industryCodes;
- docID = NULL;
- versionNumber = UNUSED;
- stockCodes = companyCodes = industryCodes = NULL;
- buf = readUserInfoHeader(&tag1, &size, buf);
- headerSize = buf - buffer;
- while (buf < (buffer + size + headerSize)) {
- data_tag tag = peekTag(buf);
- switch (tag) {
- case DT_DocumentID:
- buf = readAny(&docID, buf);
- break;
- case DT_VersionNumber:
- buf = readNum(&versionNumber, buf);
- break;
- case DT_StockCodes:
- buf = readString(&stockCodes, buf);
- break;
- case DT_CompanyCodes:
- buf = readString(&companyCodes, buf);
- break;
- case DT_IndustryCodes:
- buf = readString(&industryCodes, buf);
- break;
- default:
- freeAny(docID);
- s_free(stockCodes);
- s_free(companyCodes);
- s_free(industryCodes);
- REPORT_READ_ERROR(buf);
- break;
- }
- }
- *docCodes = makeWAISDocumentCodes(docID, versionNumber, stockCodes,
- companyCodes, industryCodes);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- char *writePresentInfo(PresentAPDU * present GCC_UNUSED, char *buffer,
- long *len GCC_UNUSED)
- {
- /* The WAIS protocol doesn't use present info */
- return (buffer);
- }
- /*----------------------------------------------------------------------*/
- char *readPresentInfo(void **info,
- char *buffer)
- {
- /* The WAIS protocol doesn't use present info */
- *info = NULL;
- return (buffer);
- }
- /*----------------------------------------------------------------------*/
- char *writePresentResponseInfo(PresentResponseAPDU * response GCC_UNUSED, char *buffer,
- long *len GCC_UNUSED)
- {
- /* The WAIS protocol doesn't use presentResponse info */
- return (buffer);
- }
- /*----------------------------------------------------------------------*/
- char *readPresentResponseInfo(void **info,
- char *buffer)
- {
- /* The WAIS protocol doesn't use presentResponse info */
- *info = NULL;
- return (buffer);
- }
- /*----------------------------------------------------------------------*/
- /* support for type 1 queries */
- /* new use values (for the chunk types) */
- #define BYTE "wb"
- #define LINE "wl"
- #define PARAGRAPH "wp"
- #define DATA_TYPE "wt"
- /* WAIS supports the following semantics for type 1 queries:
- 1. retrieve the header/codes from a document:
- System_Control_Number = docID
- Data Type = type (optional)
- And
- 2. retrieve a fragment of the text of a document:
- System_Control_Number = docID
- Data Type = type (optional)
- And
- Chunk >= start
- And
- Chunk < end
- And
- Information from multiple documents may be requested by using
- groups of the above joined by:
- OR
- ( XXX does an OR come after every group but the first, or do they
- all come at the end? )
- ( XXX return type could be in the element set)
- */
- static query_term **makeWAISQueryTerms(DocObj **docs)
- /* given a null terminated list of docObjs, construct the appropriate
- query of the form given above
- */
- {
- query_term **terms = NULL;
- long numTerms = 0;
- DocObj *doc = NULL;
- long i;
- if (docs == NULL)
- return ((query_term **) NULL);
- terms = (query_term **) s_malloc((size_t) (sizeof(query_term *) * 1));
- terms[numTerms] = NULL;
- /* loop through the docs making terms for them all */
- for (i = 0, doc = docs[i]; doc != NULL; doc = docs[++i]) {
- any *type = NULL;
- if (doc->Type != NULL)
- type = stringToAny(doc->Type);
- if (doc->ChunkCode == CT_document) /* a whole document */
- {
- terms = S_REALLOC2(query_term *, terms, numTerms + 2);
- terms[numTerms++] = makeAttributeTerm(SYSTEM_CONTROL_NUMBER,
- EQUAL, IGNORE, IGNORE,
- IGNORE, IGNORE, doc->DocumentID);
- if (type != NULL) {
- terms[numTerms++] = makeAttributeTerm(DATA_TYPE, EQUAL,
- IGNORE, IGNORE, IGNORE,
- IGNORE, type);
- terms[numTerms++] = makeOperatorTerm(AND);
- }
- terms[numTerms] = NULL;
- } else { /* a document fragment */
- char chunk_att[ATTRIBUTE_SIZE];
- any *startChunk = NULL;
- any *endChunk = NULL;
- terms = S_REALLOC2(query_term *, terms, numTerms + 6);
- switch (doc->ChunkCode) {
- case CT_byte:
- case CT_line:
- {
- char start[20], end[20];
- (doc->ChunkCode == CT_byte) ?
- strncpy(chunk_att, BYTE, ATTRIBUTE_SIZE) :
- strncpy(chunk_att, LINE, ATTRIBUTE_SIZE);
- sprintf(start, "%ld", doc->ChunkStart.Pos);
- startChunk = stringToAny(start);
- sprintf(end, "%ld", doc->ChunkEnd.Pos);
- endChunk = stringToAny(end);
- }
- break;
- case CT_paragraph:
- strncpy(chunk_att, PARAGRAPH, ATTRIBUTE_SIZE);
- startChunk = doc->ChunkStart.ID;
- endChunk = doc->ChunkEnd.ID;
- break;
- default:
- /* error */
- break;
- }
- terms[numTerms++] = makeAttributeTerm(SYSTEM_CONTROL_NUMBER,
- EQUAL, IGNORE, IGNORE,
- IGNORE,
- IGNORE, doc->DocumentID);
- if (type != NULL) {
- terms[numTerms++] = makeAttributeTerm(DATA_TYPE, EQUAL, IGNORE,
- IGNORE, IGNORE, IGNORE,
- type);
- terms[numTerms++] = makeOperatorTerm(AND);
- }
- terms[numTerms++] = makeAttributeTerm(chunk_att,
- GREATER_THAN_OR_EQUAL,
- IGNORE, IGNORE, IGNORE,
- IGNORE,
- startChunk);
- terms[numTerms++] = makeOperatorTerm(AND);
- terms[numTerms++] = makeAttributeTerm(chunk_att, LESS_THAN,
- IGNORE, IGNORE, IGNORE,
- IGNORE,
- endChunk);
- terms[numTerms++] = makeOperatorTerm(AND);
- terms[numTerms] = NULL;
- if (doc->ChunkCode == CT_byte || doc->ChunkCode == CT_line) {
- freeAny(startChunk);
- freeAny(endChunk);
- }
- }
- freeAny(type);
- if (i != 0) /* multiple independent queries, need a disjunction */
- {
- terms = S_REALLOC2(query_term *, terms, numTerms);
- terms[numTerms++] = makeOperatorTerm(OR);
- terms[numTerms] = NULL;
- }
- }
- return (terms);
- }
- /*----------------------------------------------------------------------*/
- static DocObj **makeWAISQueryDocs(query_term **terms)
- /* given a list of terms in the form given above, convert them to
- DocObjs.
- */
- {
- query_term *docTerm = NULL;
- query_term *fragmentTerm = NULL;
- DocObj **docs = NULL;
- DocObj *doc = NULL;
- long docNum, termNum;
- docNum = termNum = 0;
- docs = S_MALLOC(DocObj *);
- docs[docNum] = NULL;
- /* translate the terms into DocObjs */
- while (true) {
- query_term *typeTerm = NULL;
- char *type = NULL;
- long startTermOffset;
- docTerm = terms[termNum];
- if (docTerm == NULL)
- break; /* we're done converting */
- typeTerm = terms[termNum + 1]; /* get the lead Term if it exists */
- if (strcmp(typeTerm->Use, DATA_TYPE) == 0) /* we do have a type */
- {
- startTermOffset = 3;
- type = anyToString(typeTerm->Term);
- } else { /* no type */
- startTermOffset = 1;
- typeTerm = NULL;
- type = NULL;
- }
- /* grow the doc list */
- docs = S_REALLOC2(DocObj *, docs, docNum);
- /* figure out what kind of docObj to build - and build it */
- fragmentTerm = terms[termNum + startTermOffset];
- if (fragmentTerm != NULL && fragmentTerm->TermType == TT_Attribute) { /* build a document fragment */
- query_term *startTerm = fragmentTerm;
- query_term *endTerm = terms[termNum + startTermOffset + 2];
- if (strcmp(startTerm->Use, BYTE) == 0) { /* a byte chunk */
- doc = makeDocObjUsingBytes(duplicateAny(docTerm->Term),
- type,
- anyToLong(startTerm->Term),
- anyToLong(endTerm->Term));
- log_write("byte");
- } else if (strcmp(startTerm->Use, LINE) == 0) { /* a line chunk */
- doc = makeDocObjUsingLines(duplicateAny(docTerm->Term),
- type,
- anyToLong(startTerm->Term),
- anyToLong(endTerm->Term));
- log_write("line");
- } else {
- log_write("chunk"); /* a paragraph chunk */
- doc = makeDocObjUsingParagraphs(duplicateAny(docTerm->Term),
- type,
- duplicateAny(startTerm->Term),
- duplicateAny(endTerm->Term));
- }
- termNum += (startTermOffset + 4); /* point to next term */
- } else { /* build a full document */
- doc = makeDocObjUsingWholeDocument(duplicateAny(docTerm->Term),
- type);
- log_write("whole doc");
- termNum += startTermOffset; /* point to next term */
- }
- docs[docNum++] = doc; /* insert the new document */
- docs[docNum] = NULL; /* keep the doc list terminated */
- if (terms[termNum] != NULL)
- termNum++; /* skip the OR operator it necessary */
- else
- break; /* we are done */
- }
- return (docs);
- }
- /*----------------------------------------------------------------------*/
- any *makeWAISTextQuery(DocObj **docs)
- /* given a list of DocObjs, return an any whose contents is the corresponding
- type 1 query
- */
- {
- any *buf = NULL;
- query_term **terms = NULL;
- terms = makeWAISQueryTerms(docs);
- buf = writeQuery(terms);
- doList((void **) terms, freeTerm);
- s_free(terms);
- return (buf);
- }
- /*----------------------------------------------------------------------*/
- DocObj **readWAISTextQuery(any *buf)
- /* given an any whose contents are type 1 queries of the WAIS sort,
- construct a list of the corresponding DocObjs
- */
- {
- query_term **terms = NULL;
- DocObj **docs = NULL;
- terms = readQuery(buf);
- docs = makeWAISQueryDocs(terms);
- doList((void **) terms, freeTerm);
- s_free(terms);
- return (docs);
- }
- /*----------------------------------------------------------------------*/
- /* Customized free WAIS object routines: */
- /* */
- /* This set of procedures is for applications to free a WAIS object */
- /* which was made with makeWAISFOO. */
- /* Each procedure frees only the memory that was allocated in its */
- /* associated makeWAISFOO routine, thus it's not necessary for the */
- /* caller to assign nulls to the pointer fields of the WAIS object. */
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISInitResponse(WAISInitResponse *init)
- /* free an object made with makeWAISInitResponse */
- {
- s_free(init);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISSearch(WAISSearch *query)
- /* destroy an object made with makeWAISSearch() */
- {
- s_free(query);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeDocObj(DocObj *doc)
- /* free a docObj */
- {
- s_free(doc);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocumentHeader(WAISDocumentHeader *header)
- {
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocumentShortHeader(WAISDocumentShortHeader *header)
- {
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocumentLongHeader(WAISDocumentLongHeader *header)
- {
- s_free(header);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISSearchResponse(WAISSearchResponse * response)
- {
- s_free(response);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocumentText(WAISDocumentText *docText)
- {
- s_free(docText);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocHeadlines(WAISDocumentHeadlines *docHeadline)
- {
- s_free(docHeadline);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISDocumentCodes(WAISDocumentCodes *docCodes)
- {
- s_free(docCodes);
- }
- /*----------------------------------------------------------------------*/
- void CSTFreeWAISTextQuery(any *query)
- {
- freeAny(query);
- }
- /*----------------------------------------------------------------------*/
- /*
- * Routines originally from WMessage.c -- FM
- *
- *----------------------------------------------------------------------*/
- /* WIDE AREA INFORMATION SERVER SOFTWARE
- * No guarantees or restrictions. See the readme file for the full standard
- * disclaimer.
- * 3.26.90
- */
- /* This file is for reading and writing the wais packet header.
- * Morris@think.com
- */
- /* to do:
- * add check sum
- * what do you do when checksum is wrong?
- */
- /*---------------------------------------------------------------------*/
- void readWAISPacketHeader(char *msgBuffer,
- WAISMessage * header_struct)
- {
- /* msgBuffer is a string containing at least HEADER_LENGTH bytes. */
- memmove(header_struct->msg_len, msgBuffer, (size_t) 10);
- header_struct->msg_type = char_downcase((unsigned long) msgBuffer[10]);
- header_struct->hdr_vers = char_downcase((unsigned long) msgBuffer[11]);
- memmove(header_struct->server, (void *) (msgBuffer + 12), (size_t) 10);
- header_struct->compression = char_downcase((unsigned long) msgBuffer[22]);
- header_struct->encoding = char_downcase((unsigned long) msgBuffer[23]);
- header_struct->msg_checksum = char_downcase((unsigned long) msgBuffer[24]);
- }
- /*---------------------------------------------------------------------*/
- /* this modifies the header argument. See wais-message.h for the different
- * options for the arguments.
- */
- void writeWAISPacketHeader(char *header,
- long dataLen,
- long type,
- char *server,
- long compression,
- long encoding,
- long version)
- /* Puts together the new wais before-the-z39-packet header. */
- {
- char lengthBuf[11];
- char serverBuf[11];
- long serverLen = strlen(server);
- if (serverLen > 10)
- serverLen = 10;
- sprintf(lengthBuf, "%010ld", dataLen);
- strncpy(header, lengthBuf, 10);
- header[10] = type & 0xFF;
- header[11] = version & 0xFF;
- strncpy(serverBuf, server, serverLen);
- strncpy((char *) (header + 12), serverBuf, serverLen);
- header[22] = compression & 0xFF;
- header[23] = encoding & 0xFF;
- header[24] = '0'; /* checkSum(header + HEADER_LENGTH,dataLen); XXX the result must be ascii */
- }
- /*---------------------------------------------------------------------*/
|