archie/prospero/lib/psrv/wais_gw/wprot.c
2024-05-27 16:13:40 +02:00

2369 lines
60 KiB
C

/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#define _C_WAIS_protocol_
#include "wprot.h"
#include "cutil.h"
#include "panic.h"
#include <string.h>
#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;
static char* writeUserInfoHeader _AP((data_tag tag,long infoSize,
long estHeaderSize,char* buffer,
long* len));
static unsigned long userInfoTagSize _AP((data_tag tag,
unsigned long length));
/*----------------------------------------------------------------------*/
char*
writeInitInfo(init,buffer,len)
InitAPDU* init;
char* buffer;
long* len;
{
char *userInfo, *buf;
/*!! Clever - set it to Null, and then test it */
userInfo = NULL;
if(userInfo != NULL) {
buf = writeString(userInfo, DT_UserInformationField, buffer, len);
return(buf);
}
else return buffer;
}
/*----------------------------------------------------------------------*/
static char* readUserInfoHeader _AP((data_tag* tag,unsigned long* num,
char* buffer));
char*
readInitInfo(info,buffer)
void** info;
char* buffer;
{
readString((char **)info, buffer);
return buffer;
}
/*----------------------------------------------------------------------*/
static unsigned long
userInfoTagSize(tag,length)
data_tag tag;
unsigned long length;
{
unsigned long size;
size = writtenCompressedIntSize(tag);
size += writtenCompressedIntSize(length);
return(size);
}
/*----------------------------------------------------------------------*/
static char*
writeUserInfoHeader(tag,infoSize,estHeaderSize,buffer,len)
data_tag tag;
long infoSize;
long estHeaderSize;
char* buffer;
long* len;
{
long dummyLen = 100;
char* buf = buffer;
long realSize = infoSize - estHeaderSize;
long realHeaderSize = userInfoTagSize(tag,realSize);
if (buffer == NULL || *len == 0)
return(NULL);
buf = writeTag(tag,buf,&dummyLen);
if (estHeaderSize != realHeaderSize)
{
CHECK_FOR_SPACE_LEFT(realHeaderSize - estHeaderSize,len);
memmove(buffer + realHeaderSize,buffer + estHeaderSize,(size_t)(realSize));
}
writeCompressedInteger(realSize,buf,&dummyLen);
return(buffer + realHeaderSize + realSize);
}
/*----------------------------------------------------------------------*/
static char*
readUserInfoHeader(tag,num,buffer)
data_tag* tag;
unsigned long* num;
char* buffer;
{
char* buf = buffer;
buf = readTag(tag,buf);
buf = readCompressedInteger(num,buf);
return(buf);
}
/*----------------------------------------------------------------------*/
WAISInitResponse*
makeWAISInitResponse(chunkCode,
chunkIDLen,
chunkMarker,
highlightMarker,
deHighlightMarker,
newLineChars)
long chunkCode;
long chunkIDLen;
char* chunkMarker;
char* highlightMarker;
char* deHighlightMarker;
char* newLineChars;
{
WAISInitResponse* init = (WAISInitResponse*)s_malloc((size_t)sizeof(WAISInitResponse));
init->ChunkCode = chunkCode;
init->ChunkIDLength = chunkIDLen;
init->ChunkMarker = chunkMarker;
init->HighlightMarker = highlightMarker;
init->DeHighlightMarker = deHighlightMarker;
init->NewlineCharacters = newLineChars;
return(init);
}
/*----------------------------------------------------------------------*/
void
freeWAISInitResponse(init)
WAISInitResponse* init;
{
if(!init)
return;
s_free(init->ChunkMarker);
s_free(init->HighlightMarker);
s_free(init->DeHighlightMarker);
s_free(init->NewlineCharacters);
s_free(init);
}
/*----------------------------------------------------------------------*/
char*
writeInitResponseInfo(init,buffer,len)
InitResponseAPDU* init;
char* buffer;
long* len;
{
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_UserInformationLength,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readInitResponseInfo(info,buffer)
void** info;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
long chunkCode,chunkIDLen;
char* chunkMarker = NULL;
char* highlightMarker = NULL;
char* deHighlightMarker = NULL;
char* newLineChars = NULL;
chunkCode = chunkIDLen = UNUSED;
buf = readUserInfoHeader(&tag,&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); /*does a return */
break;
}
}
*info = (void *)makeWAISInitResponse(chunkCode,chunkIDLen,chunkMarker,
highlightMarker,deHighlightMarker,
newLineChars);
return(buf);
}
/*----------------------------------------------------------------------*/
WAISSearch*
makeWAISSearch(seedWords,
docs,
textList,
dateFactor,
beginDateRange,
endDateRange,
maxDocsRetrieved)
char* seedWords;
DocObj** docs;
char** textList;
long dateFactor;
char* beginDateRange;
char* endDateRange;
long maxDocsRetrieved;
{
WAISSearch* query = (WAISSearch*)s_malloc((size_t)sizeof(WAISSearch));
query->SeedWords = seedWords;
query->Docs = docs;
query->TextList = textList;
query->DateFactor = dateFactor;
query->BeginDateRange = beginDateRange;
query->EndDateRange = endDateRange;
query->MaxDocumentsRetrieved = maxDocsRetrieved;
return(query);
}
/*----------------------------------------------------------------------*/
void
freeWAISSearch(query)
WAISSearch* query;
{
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)
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(docID,type) /*!!ALLOC*/
any* docID;
char* type;
{
DocObj* doc = (DocObj*)s_malloc((size_t)sizeof(DocObj));
doc->DocumentID = docID;
doc->Type = type;
doc->ChunkCode = CT_document;
return(doc);
}
/*----------------------------------------------------------------------*/
DocObj*
makeDocObjUsingLines(docID,type,start,end) /*!!ALLOC*/
any* docID;
char* type;
long start;
long end;
{
DocObj* doc = (DocObj*)s_malloc((size_t)sizeof(DocObj));
doc->ChunkCode = CT_line;
doc->DocumentID = docID;
doc->Type = type;
doc->ChunkStart.Pos = start;
doc->ChunkEnd.Pos = end;
return(doc);
}
/*----------------------------------------------------------------------*/
DocObj*
makeDocObjUsingBytes(docID,type,start,end)
any* docID;
char* type;
long start;
long end;
{
DocObj* doc = (DocObj*)s_malloc((size_t)sizeof(DocObj));
doc->ChunkCode = CT_byte;
doc->DocumentID = docID;
doc->Type = type;
doc->ChunkStart.Pos = start;
doc->ChunkEnd.Pos = end;
return(doc);
}
/*----------------------------------------------------------------------*/
DocObj*
makeDocObjUsingParagraphs(docID,type,start,end)
any* docID;
char* type;
any* start;
any* end;
{
DocObj* doc = (DocObj*)s_malloc((size_t)sizeof(DocObj));
doc->ChunkCode = CT_paragraph;
doc->DocumentID = docID;
doc->Type = type;
doc->ChunkStart.ID = start;
doc->ChunkEnd.ID = end;
return(doc);
}
/*----------------------------------------------------------------------*/
void
freeDocObj(doc)
DocObj* doc;
{
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 _AP((DocObj* doc,char* buffer,long* len));
static char*
writeDocObj(doc,buffer,len)
DocObj* doc;
char* buffer;
long* len;
{
char* buf = buffer;
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:
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 _AP((DocObj** doc,char* buffer));
static char*
readDocObj(doc,buffer) /*!!ALLOCS (in doc) */
DocObj** doc;
char* buffer;
{
char* buf = buffer;
data_tag tag;
char *retval = NULL;
*doc = (DocObj*)s_malloc((size_t)sizeof(DocObj));
tag = peekTag(buf);
buf = readAny(&((*doc)->DocumentID),buf);
if (tag == DT_DocumentID)
{ (*doc)->ChunkCode = CT_document;
tag = peekTag(buf);
if (tag == DT_TYPE)
buf = readString(&((*doc)->Type),buf);
}
else if (tag == DT_DocumentIDChunk)
{ boolean readParagraphs = false;
tag = peekTag(buf);
if (tag == DT_TYPE)
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);
doc = NULL; /* Prevent caller using bad pointer*/
CLEAN_REPORT_READ_ERROR(buf); /*Returns*/
break;
}
}
else
{ freeAny((*doc)->DocumentID);
s_free(*doc);
doc = NULL; /* Prevent caller using bad pointer*/
CLEAN_REPORT_READ_ERROR(buf);
}
RETURN(buf);
cleanup:
return(retval);
}
/*----------------------------------------------------------------------*/
char*
writeSearchInfo(query,buffer,len)
SearchAPDU* query;
char* buffer;
long* len;
{
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);
}
}
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_UserInformationLength,size,header_len,buffer,len);
return(buf);
}
}
/*----------------------------------------------------------------------*/
char*
readSearchInfo(info,buffer)
void** info;
char* buffer;
{
data_tag type = peekTag(buffer);
if (type == DT_Query)
{ char* buf = buffer;
any* query = NULL;
buf = readAny(&query,buf);
*info = (void *)query;
return(buf);
}
else
{ char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
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;
char *retval;
dateFactor = maxDocsRetrieved = UNUSED;
buf = readUserInfoHeader(&tag,&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)
{ docIDs = (DocObj**)s_malloc((size_t)sizeof(DocObj*) * 2);
}
else
{ docIDs = (DocObj**)s_realloc((char*)docIDs,(size_t)(sizeof(DocObj*) * (docs + 2)));
}
buf = readDocObj(&doc,buf);
CLEAN_RETURN_ON_NULL(buf);
docIDs[docs++] = doc;
docIDs[docs] = NULL;
break;
case DT_TextList:
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:
CLEAN_REPORT_READ_ERROR(buf);
break;
}
}
*info = (void *)makeWAISSearch(seedWords,docIDs,textList,
dateFactor,beginDateRange,endDateRange,
maxDocsRetrieved);
return(buf);
cleanup:
/* Note only cleanup on error success returns pointers to these*/
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);
}
return(retval);
}
/* Note cleanup is only for else part - if part cleans itself up */
}
/*----------------------------------------------------------------------*/
WAISDocumentHeader*
makeWAISDocumentHeader(docID,
versionNumber,
score,
bestMatch,
docLen,
lines,
types,
source,
theDate,
headline,
originCity)
any* docID;
long versionNumber;
long score;
long bestMatch;
long docLen;
long lines;
char** types;
char* source;
char* theDate;
char* headline;
char* originCity;
{
WAISDocumentHeader* header =
(WAISDocumentHeader*)s_malloc((size_t)sizeof(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 = theDate;
header->Headline = headline;
header->OriginCity = originCity;
return(header);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentHeader(header)
WAISDocumentHeader* header;
{
freeAny(header->DocumentID);
doList((void**)header->Types,fs_free);
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(header,buffer,len)
WAISDocumentHeader* header;
char* buffer;
long* len;
{
unsigned long header_len = userInfoTagSize(DT_DocumentHeaderGroup ,
DefWAISDocHeaderSize);
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);
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentHeaderGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentHeader(header,buffer)
WAISDocumentHeader** header;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any* docID = NULL;
long versionNumber,score,bestMatch,docLength,lines;
char** types = NULL;
char *source = NULL;
char *theDate = NULL;
char *headline = NULL;
char *originCity = NULL;
char *retval = NULL;
versionNumber = score = bestMatch = docLength = lines = UNUSED;
buf = readUserInfoHeader(&tag,&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;
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 = (char**)s_realloc(types,(size_t)(sizeof(char*) * (numTypes + 2)));
types[numTypes++] = type;
types[numTypes] = NULL;
size -= (buf - originalBuf);
}
}
case DT_Source:
buf = readString(&source,buf);
break;
case DT_Date:
buf = readString(&theDate,buf);
break;
case DT_Headline:
buf = readString(&headline,buf);
break;
case DT_OriginCity:
buf = readString(&originCity,buf);
break;
default:
CLEAN_REPORT_READ_ERROR(buf);
break;
}
}
*header = makeWAISDocumentHeader(docID,versionNumber,score,bestMatch,
docLength,lines,types,source,theDate,headline,
originCity);
return(buf);
cleanup:
/* Only comes this way on error */
freeAny(docID);
s_free(source);
s_free(theDate);
s_free(headline);
s_free(originCity);
return(retval);
}
/*----------------------------------------------------------------------*/
WAISDocumentShortHeader*
makeWAISDocumentShortHeader(docID,
versionNumber,
score,
bestMatch,
docLen,
lines)
any* docID;
long versionNumber;
long score;
long bestMatch;
long docLen;
long lines;
{
WAISDocumentShortHeader* header =
(WAISDocumentShortHeader*)s_malloc((size_t)sizeof(WAISDocumentShortHeader));
header->DocumentID = docID;
header->VersionNumber = versionNumber;
header->Score = score;
header->BestMatch = bestMatch;
header->DocumentLength = docLen;
header->Lines = lines;
return(header);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentShortHeader(header)
WAISDocumentShortHeader* header;
{
freeAny(header->DocumentID);
s_free(header);
}
/*----------------------------------------------------------------------*/
char*
writeWAISDocumentShortHeader(header,buffer,len)
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentShortHeaderGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentShortHeader(header,buffer)
WAISDocumentShortHeader** header;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any* docID = NULL;
long versionNumber,score,bestMatch,docLength,lines;
versionNumber = score = bestMatch = docLength = lines = UNUSED;
buf = readUserInfoHeader(&tag,&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(docID,
versionNumber,
score,
bestMatch,
docLen,
lines,
types,
source,
theDate,
headline,
originCity,
stockCodes,
companyCodes,
industryCodes)
any* docID;
long versionNumber;
long score;
long bestMatch;
long docLen;
long lines;
char** types;
char* source;
char* theDate;
char* headline;
char* originCity;
char* stockCodes;
char* companyCodes;
char* industryCodes;
{
WAISDocumentLongHeader* header =
(WAISDocumentLongHeader*)s_malloc((size_t)sizeof(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 = theDate;
header->Headline = headline;
header->OriginCity = originCity;
header->StockCodes = stockCodes;
header->CompanyCodes = companyCodes;
header->IndustryCodes = industryCodes;
return(header);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentLongHeader(header)
WAISDocumentLongHeader* header;
{
freeAny(header->DocumentID);
doList((void**)header->Types,fs_free);
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(header,buffer,len)
WAISDocumentLongHeader* header;
char* buffer;
long* len;
{
unsigned long header_len = userInfoTagSize(DT_DocumentLongHeaderGroup ,
DefWAISLongHeaderSize);
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);
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentLongHeaderGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentLongHeader(header,buffer)
WAISDocumentLongHeader** header;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any* docID;
long versionNumber,score,bestMatch,docLength,lines;
char **types;
char *source,*theDate,*headline,*originCity,*stockCodes,*companyCodes,*industryCodes;
docID = NULL;
versionNumber = score = bestMatch = docLength = lines = UNUSED;
types = NULL;
source = theDate = headline = originCity = stockCodes = companyCodes = industryCodes = NULL;
buf = readUserInfoHeader(&tag,&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;
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 = (char**)s_realloc(types,(size_t)(sizeof(char*) * (numTypes + 2)));
types[numTypes++] = type;
types[numTypes] = NULL;
size -= (buf - originalBuf);
}
}
case DT_Source:
buf = readString(&source,buf);
break;
case DT_Date:
buf = readString(&theDate,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(theDate);
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,theDate,headline,
originCity,stockCodes,companyCodes,
industryCodes);
return(buf);
}
/*----------------------------------------------------------------------*/
WAISSearchResponse*
makeWAISSearchResponse(seedWordsUsed,
docHeaders,
shortHeaders,
longHeaders,
text,
headlines,
codes,
diagnostics)
char* seedWordsUsed;
WAISDocumentHeader** docHeaders;
WAISDocumentShortHeader** shortHeaders;
WAISDocumentLongHeader** longHeaders;
WAISDocumentText** text;
WAISDocumentHeadlines** headlines;
WAISDocumentCodes** codes;
diagnosticRecord** diagnostics;
{
WAISSearchResponse* response = (WAISSearchResponse*)s_malloc((size_t)sizeof(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(response)
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(query,buffer,len)
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);
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);
}
size = buf - buffer;
buf = writeUserInfoHeader(DT_UserInformationLength,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
static void
cleanUpWaisSearchResponse _AP((char* buf,char* seedWordsUsed,
WAISDocumentHeader** docHeaders,
WAISDocumentShortHeader** shortHeaders,
WAISDocumentLongHeader** longHeaders,
WAISDocumentText** text,
WAISDocumentHeadlines** headlines,
WAISDocumentCodes** codes,
diagnosticRecord**diags));
static void
cleanUpWaisSearchResponse (buf,seedWordsUsed,docHeaders,shortHeaders,
longHeaders,text,headlines,codes,diags)
char* buf;
char* seedWordsUsed;
WAISDocumentHeader** docHeaders;
WAISDocumentShortHeader** shortHeaders;
WAISDocumentLongHeader** longHeaders;
WAISDocumentText** text;
WAISDocumentHeadlines** headlines;
WAISDocumentCodes** codes;
diagnosticRecord** diags;
{
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(info,buffer)
void** info;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
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(&tag,&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)
{ diags = (diagnosticRecord**)s_malloc((size_t)sizeof(diagnosticRecord*) * 2);
}
else
{ diags = (diagnosticRecord**)s_realloc((char*)diags,(size_t)(sizeof(diagnosticRecord*) * (numDiags + 2)));
}
buf = readDiag(&diag,buf);
diags[numDiags++] = diag;
diags[numDiags] = NULL;
break;
case DT_DocumentHeaderGroup:
if (docHeaders == NULL)
{ docHeaders = (WAISDocumentHeader**)s_malloc((size_t)sizeof(WAISDocumentHeader*) * 2);
}
else
{ docHeaders = (WAISDocumentHeader**)s_realloc((char*)docHeaders,(size_t)(sizeof(WAISDocumentHeader*) * (numDocHeaders + 2)));
}
buf = readWAISDocumentHeader((WAISDocumentHeader**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
docHeaders[numDocHeaders++] =
(WAISDocumentHeader*)header;
docHeaders[numDocHeaders] = NULL;
break;
case DT_DocumentShortHeaderGroup:
if (shortHeaders == NULL)
{ shortHeaders = (WAISDocumentShortHeader**)s_malloc((size_t)sizeof(WAISDocumentShortHeader*) * 2);
}
else
{ shortHeaders = (WAISDocumentShortHeader**)s_realloc((char*)shortHeaders,(size_t)(sizeof(WAISDocumentShortHeader*) * (numShortHeaders + 2)));
}
buf = readWAISDocumentShortHeader((WAISDocumentShortHeader**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
shortHeaders[numShortHeaders++] =
(WAISDocumentShortHeader*)header;
shortHeaders[numShortHeaders] = NULL;
break;
case DT_DocumentLongHeaderGroup:
if (longHeaders == NULL)
{ longHeaders = (WAISDocumentLongHeader**)s_malloc((size_t)sizeof(WAISDocumentLongHeader*) * 2);
}
else
{ longHeaders = (WAISDocumentLongHeader**)s_realloc((char*)longHeaders,(size_t)(sizeof(WAISDocumentLongHeader*) * (numLongHeaders + 2)));
}
buf = readWAISDocumentLongHeader((WAISDocumentLongHeader**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
longHeaders[numLongHeaders++] =
(WAISDocumentLongHeader*)header;
longHeaders[numLongHeaders] = NULL;
break;
case DT_DocumentTextGroup:
if (text == NULL)
{ text = (WAISDocumentText**)s_malloc((size_t)sizeof(WAISDocumentText*) * 2);
}
else
{ text = (WAISDocumentText**)s_realloc((char*)text,(size_t)(sizeof(WAISDocumentText*) * (numText + 2)));
}
buf = readWAISDocumentText((WAISDocumentText**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
text[numText++] =
(WAISDocumentText*)header;
text[numText] = NULL;
break;
case DT_DocumentHeadlineGroup:
if (headlines == NULL)
{ headlines = (WAISDocumentHeadlines**)s_malloc((size_t)sizeof(WAISDocumentHeadlines*) * 2);
}
else
{ headlines = (WAISDocumentHeadlines**)s_realloc((char*)headlines,(size_t)(sizeof(WAISDocumentHeadlines*) * (numHeadlines + 2)));
}
buf = readWAISDocumentHeadlines((WAISDocumentHeadlines**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
headlines[numHeadlines++] =
(WAISDocumentHeadlines*)header;
headlines[numHeadlines] = NULL;
break;
case DT_DocumentCodeGroup:
if (codes == NULL)
{ codes = (WAISDocumentCodes**)s_malloc((size_t)sizeof(WAISDocumentCodes*) * 2);
}
else
{ codes = (WAISDocumentCodes**)s_realloc((char*)codes,(size_t)(sizeof(WAISDocumentCodes*) * (numCodes + 2)));
}
buf = readWAISDocumentCodes((WAISDocumentCodes**)&header,buf);
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
RETURN_ON_NULL(buf);
codes[numCodes++] =
(WAISDocumentCodes*)header;
codes[numCodes] = NULL;
break;
default:
cleanUpWaisSearchResponse(buf,seedWordsUsed,docHeaders,shortHeaders,longHeaders,text,headlines,codes,diags);
REPORT_READ_ERROR(buf);
break;
} /*switch*/
}/*while*/
*info = (void *)makeWAISSearchResponse(seedWordsUsed,docHeaders,shortHeaders,
longHeaders,text,headlines,codes,diags);
return(buf);
}
/*----------------------------------------------------------------------*/
WAISDocumentText*
makeWAISDocumentText(docID,versionNumber,documentText)
any* docID;
long versionNumber;
any* documentText;
{
WAISDocumentText* docText = (WAISDocumentText*)s_malloc((size_t)sizeof(WAISDocumentText));
docText->DocumentID = docID;
docText->VersionNumber = versionNumber;
docText->DocumentText = documentText;
return(docText);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentText(docText)
WAISDocumentText* docText;
{
freeAny(docText->DocumentID);
freeAny(docText->DocumentText);
s_free(docText);
}
/*----------------------------------------------------------------------*/
char*
writeWAISDocumentText(docText,buffer,len)
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentTextGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentText(docText,buffer)
WAISDocumentText** docText;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any *docID,*documentText;
long versionNumber;
docID = documentText = NULL;
versionNumber = UNUSED;
buf = readUserInfoHeader(&tag,&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(docID,
versionNumber,
source,
theDate,
headline,
originCity)
any* docID;
long versionNumber;
char* source;
char* theDate;
char* headline;
char* originCity;
{
WAISDocumentHeadlines* docHeadline =
(WAISDocumentHeadlines*)s_malloc((size_t)sizeof(WAISDocumentHeadlines));
docHeadline->DocumentID = docID;
docHeadline->VersionNumber = versionNumber;
docHeadline->Source = source;
docHeadline->Date = theDate;
docHeadline->Headline = headline;
docHeadline->OriginCity = originCity;
return(docHeadline);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentHeadlines(docHeadline)
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(docHeadline,buffer,len)
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentHeadlineGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentHeadlines(docHeadline,buffer)
WAISDocumentHeadlines** docHeadline;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any* docID;
long versionNumber;
char *source,*theDate,*headline,*originCity;
docID = NULL;
versionNumber = UNUSED;
source = theDate = headline = originCity = NULL;
buf = readUserInfoHeader(&tag,&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(&theDate,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(theDate);
s_free(headline);
s_free(originCity);
REPORT_READ_ERROR(buf);
break;
}
}
*docHeadline = makeWAISDocumentHeadlines(docID,versionNumber,source,theDate,
headline,originCity);
return(buf);
}
/*----------------------------------------------------------------------*/
WAISDocumentCodes*
makeWAISDocumentCodes(docID,
versionNumber,
stockCodes,
companyCodes,
industryCodes)
any* docID;
long versionNumber;
char* stockCodes;
char* companyCodes;
char* industryCodes;
{
WAISDocumentCodes* docCodes = (WAISDocumentCodes*)s_malloc((size_t)sizeof(WAISDocumentCodes));
docCodes->DocumentID = docID;
docCodes->VersionNumber = versionNumber;
docCodes->StockCodes = stockCodes;
docCodes->CompanyCodes = companyCodes;
docCodes->IndustryCodes = industryCodes;
return(docCodes);
}
/*----------------------------------------------------------------------*/
void
freeWAISDocumentCodes(docCodes)
WAISDocumentCodes* docCodes;
{
freeAny(docCodes->DocumentID);
s_free(docCodes->StockCodes);
s_free(docCodes->CompanyCodes);
s_free(docCodes->IndustryCodes);
s_free(docCodes);
}
/*----------------------------------------------------------------------*/
char*
writeWAISDocumentCodes(docCodes,buffer,len)
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);
size = buf - buffer;
buf = writeUserInfoHeader(DT_DocumentCodeGroup,size,header_len,buffer,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readWAISDocumentCodes(docCodes,buffer)
WAISDocumentCodes** docCodes;
char* buffer;
{
char* buf = buffer;
unsigned long size;
unsigned long headerSize;
data_tag tag;
any* docID;
long versionNumber;
char *stockCodes,*companyCodes,*industryCodes;
docID = NULL;
versionNumber = UNUSED;
stockCodes = companyCodes = industryCodes = NULL;
buf = readUserInfoHeader(&tag,&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(present,buffer,len)
PresentAPDU* present;
char* buffer;
long* len;
{
return(buffer);
}
/*----------------------------------------------------------------------*/
char*
readPresentInfo(info,buffer)
void** info;
char* buffer;
{
*info = NULL;
return(buffer);
}
/*----------------------------------------------------------------------*/
char*
writePresentResponseInfo(response,buffer,len)
PresentResponseAPDU* response;
char* buffer;
long* len;
{
return(buffer);
}
/*----------------------------------------------------------------------*/
char*
readPresentResponseInfo(info,buffer)
void** info;
char* buffer;
{
*info = NULL;
return(buffer);
}
/*----------------------------------------------------------------------*/
#define BYTE "wb"
#define LINE "wl"
#define PARAGRAPH "wp"
#define DATA_TYPE "wt"
static query_term** makeWAISQueryTerms _AP((DocObj** docs));
static query_term**
makeWAISQueryTerms(docs)
DocObj** docs;
{
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;
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)
{ terms = (query_term**)s_realloc((char*)terms,
(size_t)(sizeof(query_term*) *
(numTerms + 3 + 1)));
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
{ char chunk_att[ATTRIBUTE_SIZE];
any* startChunk = NULL;
any* endChunk = NULL;
terms = (query_term**)s_realloc((char*)terms,
(size_t)(sizeof(query_term*) *
(numTerms + 7 + 1)));
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:
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)
{ terms = (query_term**)s_realloc((char*)terms,
(size_t)(sizeof(query_term*) *
(numTerms + 1 + 1)));
terms[numTerms++] = makeOperatorTerm(OR);
terms[numTerms] = NULL;
}
}
return(terms);
}
/*----------------------------------------------------------------------*/
static DocObj** makeWAISQueryDocs _AP((query_term** terms));
static DocObj**
makeWAISQueryDocs(terms)
query_term** terms;
{
query_term* docTerm = NULL;
query_term* fragmentTerm = NULL;
DocObj** docs = NULL;
DocObj* doc = NULL;
long docNum,termNum;
docNum = termNum = 0;
docs = (DocObj**)s_malloc((size_t)(sizeof(DocObj*) * 1));
docs[docNum] = NULL;
while (true)
{
query_term* typeTerm = NULL;
char* type = NULL;
long startTermOffset;
docTerm = terms[termNum];
if (docTerm == NULL)
break; ;
typeTerm = terms[termNum + 1];
if (strcmp(typeTerm->Use,DATA_TYPE) == 0)
{ startTermOffset = 3;
type = anyToString(typeTerm->Term);
}
else
{ startTermOffset = 1;
typeTerm = NULL;
type = NULL;
}
docs = (DocObj**)s_realloc((char*)docs,(size_t)(sizeof(DocObj*) *
(docNum + 1 + 1)));
fragmentTerm = terms[termNum + startTermOffset];
if (fragmentTerm != NULL && fragmentTerm->TermType == TT_Attribute)
{
query_term* startTerm = fragmentTerm;
query_term* endTerm = terms[termNum + startTermOffset + 2];
if (strcmp(startTerm->Use,BYTE) == 0)
doc = makeDocObjUsingBytes(duplicateAny(docTerm->Term),
type,
anyToLong(startTerm->Term),
anyToLong(endTerm->Term));
else if (strcmp(startTerm->Use,LINE) == 0)
doc = makeDocObjUsingLines(duplicateAny(docTerm->Term),
type,
anyToLong(startTerm->Term),
anyToLong(endTerm->Term));
else if (strcmp(startTerm->Use,PARAGRAPH) == 0)
doc = makeDocObjUsingParagraphs(duplicateAny(docTerm->Term),
type,
duplicateAny(startTerm->Term),
duplicateAny(endTerm->Term));
termNum += (startTermOffset + 4);
}
else
{
doc = makeDocObjUsingWholeDocument(duplicateAny(docTerm->Term),
type);
termNum += startTermOffset;
}
docs[docNum++] = doc;
docs[docNum] = NULL;
if (terms[termNum] != NULL)
termNum++;
else
break;
}
return(docs);
}
/*----------------------------------------------------------------------*/
any*
makeWAISTextQuery(docs)
DocObj** docs;
{
any *buf = NULL;
query_term** terms = NULL;
terms = makeWAISQueryTerms(docs);
buf = writeQuery(terms);
doList((void**)terms,freeTerm);
s_free(terms);
return(buf);
}
/*----------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
DocObj**
readWAISTextQuery(buf)
any* buf;
{
query_term** terms = NULL;
DocObj** docs = NULL;
terms = readQuery(buf);
docs = makeWAISQueryDocs(terms);
doList((void**)terms,freeTerm);
s_free(terms);
return(docs);
}
#endif
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
void
CSTFreeWAISInitResponse(init)
WAISInitResponse* init;
{
s_free(init);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISSearch(query)
WAISSearch* query;
{
s_free(query);
}
/*----------------------------------------------------------------------*/
void
CSTFreeDocObj(doc)
DocObj* doc;
{
s_free(doc);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentHeader(header)
WAISDocumentHeader* header;
{
s_free(header);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentShortHeader(header)
WAISDocumentShortHeader* header;
{
s_free(header);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentLongHeader(header)
WAISDocumentLongHeader* header;
{
s_free(header);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISSearchResponse(response)
WAISSearchResponse* response;
{
s_free(response);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentText(docText)
WAISDocumentText* docText;
{
s_free(docText);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentHeadlines(docHeadline)
WAISDocumentHeadlines* docHeadline;
{
s_free(docHeadline);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISDocumentCodes(docCodes)
WAISDocumentCodes* docCodes;
{
s_free(docCodes);
}
/*----------------------------------------------------------------------*/
void
CSTFreeWAISTextQuery(query)
any* query;
{
freeAny(query);
}
/*----------------------------------------------------------------------*/