📄 htvms_waisui.c
字号:
break; case DT_ReferenceID: buf = readAny(&refID,buf); break; default: freeBitMap(versionBM); freeBitMap(optionsBM); s_free(auth); s_free(id); s_free(name); s_free(version); freeAny(refID); REPORT_READ_ERROR(buf); break; } } buf = readInitResponseInfo(&userInfo,buf); if (buf == NULL) { freeBitMap(versionBM); freeBitMap(optionsBM); s_free(auth); s_free(id); s_free(name); s_free(version); freeAny(refID); } RETURN_ON_NULL(buf); /* construct the basic init object */ *init = makeInitResponseAPDU(result, search,present,delete,accessControl,resourceControl, prefSize,maxMsgSize,auth,id,name,version,refID,userInfo); freeBitMap(versionBM); freeBitMap(optionsBM); s_free(auth); s_free(id); s_free(name); s_free(version); freeAny(refID); return(buf);}/*----------------------------------------------------------------------*/InitResponseAPDU*replyToInitAPDU(InitAPDU* init, boolean result, void* userInfo)/* respond to an init message in the default way - echoing back the init info */{ InitResponseAPDU* initResp; initResp = makeInitResponseAPDU(result, init->willSearch,init->willPresent,init->willDelete, init->supportAccessControl,init->supportResourceControl, init->PreferredMessageSize,init->MaximumRecordSize, init->IDAuthentication,defaultImplementationID(),defaultImplementationName(), defaultImplementationVersion(), init->ReferenceID,userInfo); return(initResp);}/*----------------------------------------------------------------------*/SearchAPDU*makeSearchAPDU(long small,long large,long medium,boolean replace,char* name,char** databases,char* type,char** elements,any* refID,void* queryInfo){ char* ptr = NULL; long i; SearchAPDU* query = (SearchAPDU*)s_malloc((size_t)sizeof(SearchAPDU)); query->PDUType = searchAPDU; query->SmallSetUpperBound = small; query->LargeSetLowerBound = large; query->MediumSetPresentNumber = medium; query->ReplaceIndicator = replace; query->ResultSetName = s_strdup(name); query->DatabaseNames = NULL; if (databases != NULL) { for (i = 0, ptr = databases[i]; ptr != NULL; ptr = databases[++i]) { if (query->DatabaseNames == NULL) query->DatabaseNames = (char**)s_malloc((size_t)(sizeof(char*) * 2)); else query->DatabaseNames = (char**)s_realloc((char*)query->DatabaseNames, (size_t)(sizeof(char*) * (i + 2))); query->DatabaseNames[i] = s_strdup(ptr); query->DatabaseNames[i+1] = NULL; } } query->QueryType = s_strdup(type); query->ElementSetNames = NULL; if (elements != NULL) { for (i = 0, ptr = elements[i]; ptr != NULL; ptr = elements[++i]) { if (query->ElementSetNames == NULL) query->ElementSetNames = (char**)s_malloc((size_t)(sizeof(char*) * 2)); else query->ElementSetNames = (char**)s_realloc((char*)query->ElementSetNames, (size_t)(sizeof(char*) * (i + 2))); query->ElementSetNames[i] = s_strdup(ptr); query->ElementSetNames[i+1] = NULL; } } query->ReferenceID = duplicateAny(refID); query->Query = queryInfo; /* not copied! */ return(query);}/*----------------------------------------------------------------------*/voidfreeSearchAPDU(SearchAPDU* query){ s_free(query->ResultSetName); s_free(query->QueryType); doList((void**)query->DatabaseNames,fs_free); /* can't use the macro here ! */ s_free(query->DatabaseNames); doList((void**)query->ElementSetNames,fs_free); /* can't use the macro here ! */ s_free(query->ElementSetNames); freeAny(query->ReferenceID); s_free(query);}/*----------------------------------------------------------------------*/#define DB_DELIMITER "\037" /* hex 1F occurs between each database name */#define ES_DELIMITER_1 "\037" /* separates database name from element name */#define ES_DELIMITER_2 "\036" /* hex 1E separates <db,es> groups from one another */char*writeSearchAPDU(SearchAPDU* query, char* buffer, long* len){ char* buf = buffer + HEADER_LEN; /* leave room for the header-length-indicator */ long size,i; char* ptr = NULL; char* scratch = NULL; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(query->PDUType,buf,len); buf = writeBinaryInteger(query->SmallSetUpperBound,(size_t)3,buf,len); buf = writeBinaryInteger(query->LargeSetLowerBound,(size_t)3,buf,len); buf = writeBinaryInteger(query->MediumSetPresentNumber,(size_t)3,buf,len); buf = writeBoolean(query->ReplaceIndicator,buf,len); buf = writeString(query->ResultSetName,DT_ResultSetName,buf,len); /* write database names */ if (query->DatabaseNames != NULL) { for (i = 0,scratch = NULL, ptr = query->DatabaseNames[i]; ptr != NULL; ptr = query->DatabaseNames[++i]) { if (scratch == NULL) scratch = s_strdup(ptr); else { size_t newScratchSize = (size_t)(strlen(scratch) + strlen(ptr) + 2); scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,DB_DELIMITER,2,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); } } buf = writeString(scratch,DT_DatabaseNames,buf,len); s_free(scratch); } buf = writeString(query->QueryType,DT_QueryType,buf,len); /* write element set names */ if (query->ElementSetNames != NULL) { for (i = 0,scratch = NULL, ptr = query->ElementSetNames[i]; ptr != NULL; ptr = query->ElementSetNames[++i]) { if (scratch == NULL) { if (query->ElementSetNames[i+1] == NULL) /* there is a single element set name */ { scratch = (char*)s_malloc((size_t)strlen(ptr) + 2); strncpy(scratch,ES_DELIMITER_1,2); s_strncat(scratch,ptr,strlen(ptr) + 1,strlen(ptr) + 2); } else /* this is the first of a series of element set names */ { size_t newScratchSize = (size_t)(strlen(ptr) + strlen(query->ElementSetNames[i + 1]) + 2); scratch = s_strdup(ptr); /* the database name */ ptr = query->ElementSetNames[++i]; /* the element set name */ scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,ES_DELIMITER_1,2,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); } } else { char* esPtr = query->ElementSetNames[++i]; /* the element set name */ size_t newScratchSize = (size_t)(strlen(scratch) + strlen(ptr) + strlen(esPtr) + 3); scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,ES_DELIMITER_2,2,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); s_strncat(scratch,ES_DELIMITER_1,2,newScratchSize); s_strncat(scratch,esPtr,strlen(esPtr) + 1,newScratchSize); } } buf = writeString(scratch,DT_ElementSetNames,buf,len); s_free(scratch); } buf = writeAny(query->ReferenceID,DT_ReferenceID,buf,len); /* go back and write the header-length-indicator */ RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); if (query->Query != NULL) buf = writeSearchInfo(query,buf,len); return(buf);}/*----------------------------------------------------------------------*/SearchResponseAPDU*makeSearchResponseAPDU(long result,long count,long recordsReturned,long nextPos,long resultStatus,long presentStatus,any* refID,void* records){ SearchResponseAPDU* query = (SearchResponseAPDU*)s_malloc((size_t)sizeof(SearchResponseAPDU)); query->PDUType = searchResponseAPDU; query->SearchStatus = result; query->ResultCount = count; query->NumberOfRecordsReturned = recordsReturned; query->NextResultSetPosition = nextPos; query->ResultSetStatus = resultStatus; query->PresentStatus = presentStatus; query->ReferenceID = duplicateAny(refID); query->DatabaseDiagnosticRecords = records; return(query);}/*----------------------------------------------------------------------*/voidfreeSearchResponseAPDU(SearchResponseAPDU* queryResponse){ freeAny(queryResponse->ReferenceID); s_free(queryResponse);}/*----------------------------------------------------------------------*/char*writeSearchResponseAPDU(SearchResponseAPDU* queryResponse, char* buffer, long* len){ char* buf = buffer + HEADER_LEN; /* leave room for the header-length-indicator */ long size; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(queryResponse->PDUType,buf,len); buf = writeBinaryInteger(queryResponse->SearchStatus,(size_t)1,buf,len); buf = writeBinaryInteger(queryResponse->ResultCount,(size_t)3,buf,len); buf = writeBinaryInteger(queryResponse->NumberOfRecordsReturned,(size_t)3,buf,len); buf = writeBinaryInteger(queryResponse->NextResultSetPosition,(size_t)3,buf,len); buf = writeNum(queryResponse->ResultSetStatus,DT_ResultSetStatus,buf,len); buf = writeNum(queryResponse->PresentStatus,DT_PresentStatus,buf,len); buf = writeAny(queryResponse->ReferenceID,DT_ReferenceID,buf,len); /* go back and write the header-length-indicator */ RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); if (queryResponse->DatabaseDiagnosticRecords != NULL) buf = writeSearchResponseInfo(queryResponse,buf,len); return(buf);}/*----------------------------------------------------------------------*/char*readSearchResponseAPDU(SearchResponseAPDU** queryResponse, char* buffer){ char* buf = buffer; long size; pdu_type pduType; long result,count,recordsReturned,nextPos; long resultStatus,presentStatus; any *refID = NULL; void* userInfo = NULL; /* read required part */ buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBinaryInteger(&result,(size_t)1,buf); buf = readBinaryInteger(&count,(size_t)3,buf); buf = readBinaryInteger(&recordsReturned,(size_t)3,buf); buf = readBinaryInteger(&nextPos,(size_t)3,buf); resultStatus = presentStatus = UNUSED; refID = NULL; /* read optional part */ while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_ResultSetStatus: buf = readNum(&resultStatus,buf); break; case DT_PresentStatus: buf = readNum(&presentStatus,buf); break; case DT_ReferenceID: buf = readAny(&refID,buf); break; default: freeAny(refID); REPORT_READ_ERROR(buf); break; } } buf = readSearchResponseInfo(&userInfo,buf); if (buf == NULL) freeAny(refID); RETURN_ON_NULL(buf); /* construct the search object */ *queryResponse = makeSearchResponseAPDU(result,count,recordsReturned,nextPos, (long)resultStatus,(long)presentStatus,refID,userInfo); freeAny(refID); return(buf);}/*** Routines originally from ZUtil.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 - Changed any->bits to any->bytes 4.11.90 HWM - fixed include file names, changed - writeCompressedIntegerWithPadding() to writeCompressedIntWithPadding() - generalized conditional includes (see c-dialect.h) 3.7.91 Jonny Goldman. Replaced "short" in makeBitMap with "int" line 632.*/char* readErrorPosition = NULL; /* pos where buf stoped making sense *//*----------------------------------------------------------------------*//* A note on error handling read - these are low level routines, they do not check the type tags which (sometimes) preceed the data (this is done by the higher level functions which call these functions). There is no attempt made to check that the reading does not exceed the read buffer. Such cases should be very rare and usually will be caught by the calling functions. (note - it is unlikely that a series of low level reads will go far off the edge without triggering a type error. However, it is possible for a single bad read in an array function (eg. readAny) to attempt to read a large ammount, possibly causing a segmentation violation or out of memory condition. *//*----------------------------------------------------------------------*/diagnosticRecord*makeDiag(boolean surrogate, char* code, char* addInfo){ diagnosticRecord* diag = (diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord)); diag->SURROGATE = surrogate; memcpy(diag->DIAG,code,DIAGNOSTIC_CODE_SIZE); diag->ADDINFO = s_strdup(addInfo); return(diag);}/*----------------------------------------------------------------------*/voidfreeDiag(diagnosticRecord* diag){ if (diag != NULL) { if (diag->ADDINFO != NULL) s_free(diag->ADDINFO); s_free(diag); }}/*----------------------------------------------------------------------*/#define END_OF_RECORD 0x1Dchar*writeDiag(diagnosticRecord* diag, char* buffer, long* len)/* diagnostics (as per Appendix D) have a very weird format - this changes in SR-1 */{ char* buf = buffer; long length; if (diag == NULL) /* handle unspecified optional args */ return(buf); buf = writeTag(DT_DatabaseDiagnosticRecords,buf,len); CHECK_FOR_SPACE_LEFT(0,len); length = 3; if (diag->ADDINFO != NULL) length += strlen(diag->ADDINFO); if (length >= 0xFFFF ) /* make sure the length is reasonable */ { length = 0xFFFF - 1; diag->ADDINFO[0xFFFF - 3 - 1] = '\0'; } buf = writeBinaryInteger(length,2,buf,len); CHECK_FOR_SPACE_LEFT(1,len); buf[0] = diag->DIAG[0]; buf++; CHECK_FOR_SPACE_LEFT(1,len); buf[0] = diag->DIAG[1]; buf++; if (length > 3) { CHECK_FOR_SPACE_LEFT(3,len); memcpy(buf,diag->ADDINFO,(size_t)length - 3); buf += length - 3; } CHECK_FOR_SPACE_LEFT(1,len); buf[0] = diag->SURROGATE; buf++; CHECK_FOR_SPACE_LEFT(1,len); buf[0] = END_OF_RECORD; buf++; return(buf);}/*----------------------------------------------------------------------*/char*readDiag(diagnosticRecord** diag, char* buffer){ char* buf = buffer; diagnosticRecord* d = (diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord)); data_tag tag; long len; buf = readTag(&tag,buf); buf = readBinaryInteger(&len,2,buf); d->DIAG[0] = buf[0]; d->DIAG[1] = buf[1]; d->DIAG[2] = '\0'; if (len > 3) { d->ADDINFO = (char*)s_malloc((size_t)(len - 3 + 1)); memcpy(d->ADDINFO,(char*)(buf + 2),(size_t)(len - 3)); d->ADDINFO[len - 3] = '\0'; } else d->ADDINFO = NULL; d->SURROGATE = buf[len - 1]; *diag = d; return(buf + len + 1);}/*----------------------------------------------------------------------*/#define continueBit 0x80#define dataMask 0x7F#define dataBits 7char*writeCompressedInteger(unsigned long num, char* buf, long* len)/* write a binary integer in the format described on p. 40. this might be sped up*/{ char byte; unsigned long i; unsigned long size; size = writtenCompressedIntSize(num); CHECK_FOR_SPACE_LEFT(size,len); for (i = size - 1; i != 0; i--) { byte = num & dataMask; if (i != (size-1)) /* turn on continue bit */ byte = (char)(byte | continueBit); buf[i] = byte; num = num >> dataBits; /* don't and here */ } return(buf + size);}/*----------------------------------------------------------------------*/char*readCompressedInteger(unsigned long *num, char* buf)/* read a binary integer in the format described on p. 40. this might be sped up*/{ long i = 0; unsigned char byte; *num = 0; do { byte = buf[i++]; *num = *num << dataBits; *num += (byte & dataMask); } while (byte & continueBit); return(buf + i);}/*----------------------------------------------------------------------*/#define pad 128 /* high bit is set */char*writeCompressedIntWithPadding(unsigned long num,unsigned long size,char* buffer,long* len)/* Like writeCompressedInteger, except writes padding (128) to make sure that size bytes are used. This can be read correctly by readCompressedInteger()*/{ char* buf = buffer; unsigned long needed,padding; long i; CHECK_FOR_SPACE_LEFT(size,len); needed = writtenCompressedIntSize(num);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -