/* WIDE AREA INFORMATION SERVER SOFTWARE: Developed by Thinking Machines Corporation and put into the public domain with no guarantees or restrictions. */ /*----------------------------------------------------------------------*/ #define _C_Z39_50_ #include "zprot.h" #include "zutil.h" #include "cutil.h" #include #define RESERVE_SPACE_FOR_HEADER(spaceLeft) \ *spaceLeft -= HEADER_LEN; #define RELEASE_HEADER_SPACE(spaceLeft) \ if (*spaceLeft > 0) \ *spaceLeft += HEADER_LEN; /*----------------------------------------------------------------------*/ InitAPDU* makeInitAPDU(search, present, deleteIt, accessControl, resourceControl, prefSize, maxMsgSize, auth, id, name, version, refID, userInfo) boolean search; boolean present; boolean deleteIt; boolean accessControl; boolean resourceControl; long prefSize; long maxMsgSize; char* auth; char* id; char* name; char* version; any* refID; void* userInfo; { InitAPDU* init = (InitAPDU*)s_malloc((size_t)sizeof(InitAPDU)); init->PDUType = initAPDU; init->willSearch = search; init->willPresent = present; init->willDelete = deleteIt; init->supportAccessControl = accessControl; init->supportResourceControl = resourceControl; init->PreferredMessageSize = prefSize; init->MaximumRecordSize = maxMsgSize; init->IDAuthentication = s_strdup(auth); init->ImplementationID = s_strdup(id); init->ImplementationName = s_strdup(name); init->ImplementationVersion = s_strdup(version); init->ReferenceID = duplicateAny(refID); init->UserInformationField = userInfo; return(init); } /*----------------------------------------------------------------------*/ void freeInitAPDU(init) InitAPDU* init; { s_free(init->IDAuthentication); s_free(init->ImplementationID); s_free(init->ImplementationName); s_free(init->ImplementationVersion); freeAny(init->ReferenceID); s_free(init); } /*----------------------------------------------------------------------*/ char* writeInitAPDU(init,buffer,len) InitAPDU* init; char* buffer; /* Pointer into large malloc-ed buffer!!*/ long* len; { char* buf = buffer + HEADER_LEN; long size; bit_map* optionsBM = NULL; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(init->PDUType,buf,len); buf = writeProtocolVersion(buf,len); optionsBM = makeBitMap((unsigned long)5,init->willSearch,init->willPresent, init->willDelete,init->supportAccessControl, init->supportResourceControl); buf = writeBitMap(optionsBM,DT_Options,buf,len); freeBitMap(optionsBM); buf = writeNum(init->PreferredMessageSize,DT_PreferredMessageSize,buf,len); buf = writeNum(init->MaximumRecordSize,DT_MaximumRecordSize,buf,len); buf = writeString(init->IDAuthentication,DT_IDAuthentication,buf,len); buf = writeString(init->ImplementationID,DT_ImplementationID,buf,len); buf = writeString(init->ImplementationName,DT_ImplementationName,buf,len); buf = writeString(init->ImplementationVersion,DT_ImplementationVersion,buf,len); buf = writeAny(init->ReferenceID,DT_ReferenceID,buf,len); RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); /* Note the UserInformatioNField wont be included in the size !!H*/ if (init->UserInformationField != NULL) buf = writeInitInfo(init,buf,len); /* Note this is dummied out!!*/ return(buf); } /*----------------------------------------------------------------------*/ char* readInitAPDU(init,buffer) InitAPDU** init; char* buffer; { char* buf = buffer; boolean search,present,delete,accessControl,resourceControl; long prefSize,maxMsgSize; char *auth,*id,*name,*version; long size; pdu_type pduType; bit_map* versionBM = NULL; bit_map* optionsBM = NULL; any *refID = NULL; void* userInfo = NULL; auth = id = name = version = NULL; buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBitMap(&versionBM,buf); buf = readBitMap(&optionsBM,buf); buf = readNum(&prefSize,buf); buf = readNum(&maxMsgSize,buf); search = bitAtPos(0L,optionsBM); present = bitAtPos(1L,optionsBM); delete = bitAtPos(2L,optionsBM); accessControl = bitAtPos(3L,optionsBM); resourceControl = bitAtPos(4L,optionsBM); while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_IDAuthentication: buf = readString(&auth,buf); break; case DT_ImplementationID: buf = readString(&id,buf); break; case DT_ImplementationName: buf = readString(&name,buf); break; case DT_ImplementationVersion: buf = readString(&version,buf); 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 = readInitInfo(&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); *init = makeInitAPDU(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* makeInitResponseAPDU(result, search, present, deleteIt, accessControl, resourceControl, prefSize, maxMsgSize, auth, id, name, version, refID, userInfo) boolean result; boolean search; boolean present; boolean deleteIt; boolean accessControl; boolean resourceControl; long prefSize; long maxMsgSize; char* auth; char* id; char* name; char* version; any* refID; void* userInfo; { InitResponseAPDU* init = (InitResponseAPDU*)s_malloc((size_t)sizeof(InitResponseAPDU)); init->PDUType = initResponseAPDU; init->Result = result; init->willSearch = search; init->willPresent = present; init->willDelete = deleteIt; init->supportAccessControl = accessControl; init->supportResourceControl = resourceControl; init->PreferredMessageSize = prefSize; init->MaximumRecordSize = maxMsgSize; init->IDAuthentication = s_strdup(auth); init->ImplementationID = s_strdup(id); init->ImplementationName = s_strdup(name); init->ImplementationVersion = s_strdup(version); init->ReferenceID = duplicateAny(refID); init->UserInformationField = userInfo; return(init); } /*----------------------------------------------------------------------*/ void freeInitResponseAPDU(init) InitResponseAPDU* init; { s_free(init->IDAuthentication); s_free(init->ImplementationID); s_free(init->ImplementationName); s_free(init->ImplementationVersion); freeAny(init->ReferenceID); s_free(init); } /*----------------------------------------------------------------------*/ char* writeInitResponseAPDU(init,buffer,len) InitResponseAPDU* init; char* buffer; long* len; { char* buf = buffer + HEADER_LEN; long size; bit_map* optionsBM = NULL; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(init->PDUType,buf,len); buf = writeBoolean(init->Result,buf,len); buf = writeProtocolVersion(buf,len); optionsBM = makeBitMap((unsigned long)5,init->willSearch,init->willPresent, init->willDelete,init->supportAccessControl, init->supportResourceControl); buf = writeBitMap(optionsBM,DT_Options,buf,len); freeBitMap(optionsBM); buf = writeNum(init->PreferredMessageSize,DT_PreferredMessageSize,buf,len); buf = writeNum(init->MaximumRecordSize,DT_MaximumRecordSize,buf,len); buf = writeString(init->IDAuthentication,DT_IDAuthentication,buf,len); buf = writeString(init->ImplementationID,DT_ImplementationID,buf,len); buf = writeString(init->ImplementationName,DT_ImplementationName,buf,len); buf = writeString(init->ImplementationVersion,DT_ImplementationVersion,buf,len); buf = writeAny(init->ReferenceID,DT_ReferenceID,buf,len); RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); if (init->UserInformationField != NULL) buf = writeInitResponseInfo(init,buf,len); return(buf); } /*----------------------------------------------------------------------*/ char* readInitResponseAPDU(init,buffer) InitResponseAPDU** init; char* buffer; { char* buf = buffer; boolean search,present,delete,accessControl,resourceControl; long prefSize,maxMsgSize; char *auth,*id,*name,*version; long size; pdu_type pduType; bit_map* versionBM = NULL; bit_map* optionsBM = NULL; boolean result; any *refID = NULL; void* userInfo = NULL; auth = id = name = version = NULL; refID = NULL; buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBoolean(&result,buf); buf = readBitMap(&versionBM,buf); buf = readBitMap(&optionsBM,buf); buf = readNum(&prefSize,buf); buf = readNum(&maxMsgSize,buf); search = bitAtPos(0L,optionsBM); present = bitAtPos(1L,optionsBM); delete = bitAtPos(2L,optionsBM); accessControl = bitAtPos(3L,optionsBM); resourceControl = bitAtPos(4L,optionsBM); while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_IDAuthentication: buf = readString(&auth,buf); break; case DT_ImplementationID: buf = readString(&id,buf); break; case DT_ImplementationName: buf = readString(&name,buf); break; case DT_ImplementationVersion: buf = readString(&version,buf); 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); *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(init,result,userInfo) InitAPDU* init; boolean result; void* userInfo; { 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(small, large, medium, replace, name, databases, type, elements, refID, queryInfo) 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; return(query); } /*----------------------------------------------------------------------*/ void freeSearchAPDU(query) SearchAPDU* query; { s_free(query->ResultSetName); s_free(query->QueryType); doList((void**)query->DatabaseNames,fs_free); s_free(query->DatabaseNames); doList((void**)query->ElementSetNames,fs_free); s_free(query->ElementSetNames); freeAny(query->ReferenceID); s_free(query); } /*----------------------------------------------------------------------*/ #define DB_DELIMITER "\037" #define ES_DELIMITER_1 "\037" #define ES_DELIMITER_2 "\036" char* writeSearchAPDU(query,buffer,len) SearchAPDU* query; char* buffer; long* len; { char* buf = buffer + HEADER_LEN; 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); 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) + 3); scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,DB_DELIMITER,2L,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); 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) { scratch = (char*)s_malloc((size_t)strlen(ptr) + 3); strncpy(scratch,ES_DELIMITER_1,2); s_strncat(scratch,ptr,strlen(ptr) + 1,strlen(ptr) + 2); } else { size_t newScratchSize = (size_t)(strlen(ptr) + strlen(query->ElementSetNames[i + 1]) + 3); scratch = s_strdup(ptr); ptr = query->ElementSetNames[++i]; scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,ES_DELIMITER_1,2L,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); } } else { char* esPtr = query->ElementSetNames[++i]; size_t newScratchSize = (size_t)(strlen(scratch) + strlen(ptr) + strlen(esPtr) + 3); scratch = (char*)s_realloc(scratch,newScratchSize); s_strncat(scratch,ES_DELIMITER_2,2L,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); s_strncat(scratch,ES_DELIMITER_1,2L,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); 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); } /*----------------------------------------------------------------------*/ #if !defined(IN_RMG) && !defined(PFS_THREADS) /* Note - uses strtok */ char* readSearchAPDU(query,buffer) SearchAPDU** query; char* buffer; { char* buf = buffer; long size; pdu_type pduType; long small,large,medium,numItems; boolean replace; char *name,*databaseNames,*type,*elements; char **dbList,**elemList; any *refID; void* userInfo = NULL; name = databaseNames = type = elements = NULL; dbList = elemList = NULL; refID = NULL; buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBinaryInteger(&small,(size_t)3,buf); buf = readBinaryInteger(&large,(size_t)3,buf); buf = readBinaryInteger(&medium,(size_t)3,buf); buf = readBoolean(&replace,buf); while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_ResultSetName: buf = readString(&name,buf); break; case DT_DatabaseNames: { char *tok; buf = readString(&databaseNames,buf); assert(P_IS_THIS_THREAD_MASTER()); tok = strtok(databaseNames,DB_DELIMITER); numItems = 0; while (tok != NULL) { if (dbList == NULL) dbList = (char**)s_malloc((size_t)(sizeof(char*) * 2)); else dbList = (char**)s_realloc((char*)dbList,(size_t)(sizeof(char*) * (numItems+2))); dbList[numItems++] = s_strdup(tok); dbList[numItems] = NULL; tok = strtok(NULL,DB_DELIMITER); } } break; case DT_QueryType: buf = readString(&type,buf); break; case DT_ElementSetNames: { char *tok; buf = readString(&elements,buf); if (elements[0] == ES_DELIMITER_1[0]) { elemList = (char**)s_malloc((size_t)(sizeof(char*) * 2)); elemList[0] = s_strdup(elements); elemList[1] = NULL; } else { char* esTok = NULL; assert(P_IS_THIS_THREAD_MASTER()); /* strtok thread unsafe */ tok = strtok(elements,ES_DELIMITER_1); esTok = strtok(NULL,ES_DELIMITER_2); numItems = 0; while (tok != NULL) { if (elemList == NULL) elemList = (char**)s_malloc((size_t)(sizeof(char*) * 3)); else elemList = (char**)s_realloc((char*)elemList,(size_t)(sizeof(char*) * (numItems * 2 + 1))); elemList[numItems++] = s_strdup(tok); elemList[numItems++] = s_strdup(esTok); elemList[numItems] = NULL; tok = strtok(NULL,ES_DELIMITER_1); esTok = strtok(NULL,ES_DELIMITER_2); } } } break; case DT_ReferenceID: buf = readAny(&refID,buf); break; default: s_free(name); s_free(type); s_free(databaseNames); doList((void**)dbList,fs_free); s_free(dbList); s_free(elements); doList((void**)elemList,fs_free); s_free(elemList); freeAny(refID); REPORT_READ_ERROR(buf); break; } } buf = readSearchInfo(&userInfo,buf); if (buf == NULL) { s_free(name); s_free(type); s_free(databaseNames); doList((void**)dbList,fs_free); s_free(dbList); s_free(elements); doList((void**)elemList,fs_free); s_free(elemList); freeAny(refID); } RETURN_ON_NULL(buf); *query = makeSearchAPDU(small,large,medium,replace,name,dbList,type,elemList,refID,userInfo); s_free(name); s_free(type); s_free(databaseNames); doList((void**)dbList,fs_free); s_free(dbList); s_free(elements); doList((void**)elemList,fs_free); s_free(elemList); freeAny(refID); return(buf); } #endif /*!IN_RMG && !PFS_THREADS*/ /*----------------------------------------------------------------------*/ SearchResponseAPDU* makeSearchResponseAPDU(result,count,recordsReturned,nextPos,resultStatus, presentStatus,refID,records) 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); } /*----------------------------------------------------------------------*/ void freeSearchResponseAPDU(queryResponse) SearchResponseAPDU* queryResponse; { freeAny(queryResponse->ReferenceID); s_free(queryResponse); } /*----------------------------------------------------------------------*/ #if !defined(IN_RMG) && !defined(PFS_THREADS) char* writeSearchResponseAPDU(queryResponse,buffer,len) SearchResponseAPDU* queryResponse; char* buffer; long* len; { char* buf = buffer + HEADER_LEN; 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); 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); } /*----------------------------------------------------------------------*/ #endif /*!IN_RMG && !PFS_THREADS*/ char* readSearchResponseAPDU(queryResponse,buffer) 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; 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; 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); *queryResponse = makeSearchResponseAPDU(result,count,recordsReturned,nextPos, (long)resultStatus,(long)presentStatus,refID,userInfo); freeAny(refID); return(buf); } #if !defined(IN_RMG) && !defined(PFS_THREADS) #ifdef NOTUSED /*----------------------------------------------------------------------*/ PresentAPDU* makePresentAPDU(recsReq,startPos,resultID,refID,info) long recsReq; long startPos; char* resultID; any* refID; void* info; { PresentAPDU* present = (PresentAPDU*)s_malloc((size_t)sizeof(PresentAPDU)); present->PDUType = presentAPDU; present->NumberOfRecordsRequested = recsReq; present->ResultSetStartPosition = startPos; present->ResultSetID = s_strdup(resultID); present->ElementSetNames = NULL; present->ReferenceID = duplicateAny(refID); present->PresentInfo = info; return(present); } /*----------------------------------------------------------------------*/ void freePresentAPDU(present) PresentAPDU* present; { s_free(present->ResultSetID); freeAny(present->ReferenceID); s_free(present); } /*----------------------------------------------------------------------*/ char* writePresentAPDU(present,buffer,len) PresentAPDU* present; char* buffer; long* len; { char* buf = buffer + HEADER_LEN; long size; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(present->PDUType,buf,len); buf = writeBinaryInteger(present->NumberOfRecordsRequested,(size_t)3,buf,len); buf = writeBinaryInteger(present->ResultSetStartPosition,(size_t)3,buf,len); buf = writeString(present->ResultSetID,DT_ResultSetID,buf,len); buf = writeAny(present->ReferenceID,DT_ReferenceID,buf,len); RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); if (present->PresentInfo != NULL) buf = writePresentInfo(present,buf,len); return(buf); } /*----------------------------------------------------------------------*/ char* readPresentAPDU(present,buffer) PresentAPDU** present; char* buffer; { char* buf = buffer; long size; pdu_type pduType; long recsReq,startPos; char* resultID = NULL; any *refID = NULL; void* userInfo = NULL; buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBinaryInteger(&recsReq,(size_t)3,buf); buf = readBinaryInteger(&startPos,(size_t)3,buf); buf = readString(&resultID,buf); while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_ReferenceID: buf = readAny(&refID,buf); break; default: s_free(resultID); freeAny(refID); REPORT_READ_ERROR(buf); break; } } buf = readPresentInfo(&userInfo,buf); if (buf == NULL) { s_free(resultID); freeAny(refID); } RETURN_ON_NULL(buf); *present = makePresentAPDU(recsReq,startPos,resultID,refID,userInfo); s_free(resultID); freeAny(refID); return(buf); } /*----------------------------------------------------------------------*/ PresentResponseAPDU* makePresentResponseAPDU(status,recsRet,nextPos,refID,records) boolean status; long recsRet; long nextPos; any* refID; void* records; { PresentResponseAPDU* present = (PresentResponseAPDU*)s_malloc((size_t)sizeof(PresentResponseAPDU)); present->PDUType = presentResponseAPDU; present->PresentStatus = status; present->NumberOfRecordsReturned = recsRet; present->NextResultSetPosition = nextPos; present->ReferenceID = duplicateAny(refID); present->DatabaseDiagnosticRecords = records; return(present); } /*----------------------------------------------------------------------*/ void freePresentResponseAPDU(present) PresentResponseAPDU* present; { freeAny(present->ReferenceID); s_free(present); } /*----------------------------------------------------------------------*/ char* writePresentResponseAPDU(present,buffer,len) PresentResponseAPDU* present; char* buffer; long* len; { char* buf = buffer + HEADER_LEN; long size; RESERVE_SPACE_FOR_HEADER(len); buf = writePDUType(present->PDUType,buf,len); buf = writeBoolean(present->PresentStatus,buf,len); buf = writeBinaryInteger(present->NumberOfRecordsReturned,(size_t)3,buf,len); buf = writeBinaryInteger(present->NextResultSetPosition,(size_t)3,buf,len); buf = writeAny(present->ReferenceID,DT_ReferenceID,buf,len); RELEASE_HEADER_SPACE(len); size = buf - buffer - HEADER_LEN; writeBinaryInteger(size,HEADER_LEN,buffer,len); if (present->DatabaseDiagnosticRecords != NULL) buf = writePresentResponseInfo(present,buf,len); return(buf); } /*----------------------------------------------------------------------*/ char* readPresentResponseAPDU(present,buffer) PresentResponseAPDU** present; char* buffer; { char* buf = buffer; long size; pdu_type pduType; boolean status; long recsRet,nextPos; any *refID = NULL; void* userInfo = NULL; buf = readBinaryInteger(&size,HEADER_LEN,buf); buf = readPDUType(&pduType,buf); buf = readBoolean(&status,buf); buf = readBinaryInteger(&recsRet,(size_t)3,buf); buf = readBinaryInteger(&nextPos,(size_t)3,buf); while (buf < (buffer + size + HEADER_LEN)) { data_tag tag = peekTag(buf); switch (tag) { case DT_ReferenceID: buf = readAny(&refID,buf); break; default: freeAny(refID); REPORT_READ_ERROR(buf); break; } } buf = readPresentResponseInfo(&userInfo,buf); if (buf == NULL) freeAny(refID); RETURN_ON_NULL(buf); *present = makePresentResponseAPDU(status,recsRet,nextPos,refID,userInfo); freeAny(refID); return(buf); } /*----------------------------------------------------------------------*/ #endif /*NOTUSED*/ #endif /*!IN_RMG && !PFS_THREADS*/