📄 xptcomm.c
字号:
return setLastErrorInfo(ti->info, "xptOpenCommunication", rc); } // Allocate a communication instance control block ci = xppMalloc(sizeof(struct CommunicationInstance)); if (!ci) { // Tell the communication that we won't need the instance after all ti->info->internal->desc.closeCommunication(pci); return setLastErrorInfo(ti->info, "xptOpenCommunication", SML_ERR_A_XPT_MEMORY); } // Initialize the communication instance control block ci->controlBlockId = CommunicationInstanceControlBlockId; ci->privateCommunicationInfo = pci; ci->transport = ti; ci->state = CI_STATE_READY_FOR_EXCHANGE; ci->role = role; *pConn = (void *) ci; ++ti->communicationHandlesOpen; XPTDEBUG(("Returning successfully from xptOpenCommunication() with new handle == %lx. Open instances == %d\n", (unsigned long) ci, ti->communicationHandlesOpen)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptCloseCommunication(XptCommunicationID_t conn) { Ret_t rc; struct TransportInstance *ti; struct CommunicationInstance *ci = validateCommunicationId(conn); if (!ci) return setLastErrorInfo(NULL, "xptCloseCommunication", SML_ERR_A_XPT_INVALID_ID); // We'll need this later after we free the CommunicationInstance control block ti = ci->transport; XPTDEBUG(("Function xptCloseCommunication() entered, closing handle %lx\n", (unsigned long) ci)); // Call through to the transport's implementation rc = ti->info->internal->desc.closeCommunication(ci->privateCommunicationInfo); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's closeCommunication() returned error %d\n", (int) rc)); return setLastErrorInfo(ti->info, "xptCloseCommunication", rc); } // Ensure that a later reference to this block fails to validate ci->controlBlockId = 0; // Release the storage xppFree(ci); --ti->communicationHandlesOpen; XPTDEBUG(("Returning successfully from xptCloseCommunication(). Open instances == %d\n", ti->communicationHandlesOpen)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptBeginExchange(XptCommunicationID_t conn) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(conn); if (!ci) return setLastErrorInfo(NULL, "xptBeginExchange", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptBeginExchange() entered for handle %lx\n", (unsigned long) ci)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_READY_FOR_EXCHANGE) return setLastErrorInfo(ci->transport->info, "xptBeginExchange", SML_ERR_A_XPT_INVALID_STATE); // Call through to the transport's implementation rc = ci->transport->info->internal->desc.beginExchange(ci->privateCommunicationInfo); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's beginExchange() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptBeginExchange", rc); } // Establish the new state ci->state = ci->role == XPT_REQUEST_SENDER ? CI_STATE_EXPECTING_SET_DOC : CI_STATE_EXPECTING_GET_DOC; XPTDEBUG(("Returning successfully from xptBeginExchange()\n")); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptEndExchange(XptCommunicationID_t conn) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(conn); if (!ci) return setLastErrorInfo(NULL, "xptEndExchange", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptEndExchange() entered for handle %lx\n", (unsigned long) ci)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_EXPECTING_END_EXCHANGE) return setLastErrorInfo(ci->transport->info, "xptEndExchange", SML_ERR_A_XPT_INVALID_STATE); // Call through to the transport's implementation rc = ci->transport->info->internal->desc.endExchange(ci->privateCommunicationInfo); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's endExchange() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptEndExchange", rc); } // Establish the new state ci->state = CI_STATE_READY_FOR_EXCHANGE; XPTDEBUG(("Returning successfully from xptEndExchange()\n")); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptReceiveData(XptCommunicationID_t connection, void *buffer, size_t bufferLen, size_t *dataLen) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(connection); if (!ci) return setLastErrorInfo(NULL, "xptReceiveData", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptReceiveData() entered for handle %lx, reading %ld bytes\n", (unsigned long) ci, (long) bufferLen)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_RECEIVING) return setLastErrorInfo(ci->transport->info, "xptReceiveData", SML_ERR_A_XPT_INVALID_STATE); if (!bufferLen) return setLastErrorInfo(ci->transport->info, "xptReceiveData", SML_ERR_WRONG_PARAM); // Make sure the application isn't trying to read beyond the end of the // document. if (bufferLen > ci->bytesRemaining) { // false if bytesRemaining == (size_t) -1 bufferLen = ci->bytesRemaining; if (!bufferLen) { // Application has read all the data *dataLen = 0; // Generate an end-of-file condition // Establish the new state ci->state = ci->role == XPT_REQUEST_SENDER ? CI_STATE_EXPECTING_END_EXCHANGE : CI_STATE_EXPECTING_SET_DOC; return SML_ERR_OK; } } // Call through to the transport's implementation rc = ci->transport->info->internal->desc.receiveData(ci->privateCommunicationInfo, buffer, bufferLen, dataLen); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's receiveData() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptReceiveData", rc); } // Account for the bytes provided by the transport if (ci->bytesRemaining != (size_t) -1) { ci->bytesRemaining -= *dataLen; if (ci->bytesRemaining && !*dataLen) { XPTDEBUG(("Transport returned incomplete document. %lu more bytes expected.\n", (unsigned long) ci->bytesRemaining)); // Let the application deal with it } } // Establish the new state if (ci->bytesRemaining == 0) ci->state = ci->role == XPT_REQUEST_SENDER ? CI_STATE_EXPECTING_END_EXCHANGE : CI_STATE_EXPECTING_SET_DOC; XPTDEBUG(("Returning successfully from xptReceiveData(), having read %ld bytes.\n", (long) *dataLen)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptSendData(XptCommunicationID_t connection, const void *buffer, size_t bufferLen, size_t *bytesSent) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(connection); if (!ci) return setLastErrorInfo(NULL, "xptSendData", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptSendData() entered for handle %lx, sending %ld bytes.\n", (unsigned long) ci, (long) bufferLen)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_SENDING) return setLastErrorInfo(ci->transport->info, "xptSendData", SML_ERR_A_XPT_INVALID_STATE); // Make sure the application isn't trying to write more data than is in the // document. if (bufferLen > ci->bytesRemaining) // false if bytesRemaining == (size_t) -1 return setLastErrorInfo(ci->transport->info, "xptSendData", SML_ERR_WRONG_PARAM); // Call through to the transport's implementation rc = ci->transport->info->internal->desc.sendData(ci->privateCommunicationInfo, buffer, bufferLen, bytesSent); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's sendData() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptSendData", rc); } // Account for the bytes absorbed by the transport if (ci->bytesRemaining != (size_t) -1) ci->bytesRemaining -= *bytesSent; XPTDEBUG(("Returning successfully from xptSendData(), " "having written %ld bytes.\n", (long) *bytesSent)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptSendComplete(XptCommunicationID_t connection) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(connection); if (!ci) return setLastErrorInfo(NULL, "xptSendComplete", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptSendComplete() entered for handle %lx.\n", (unsigned long) ci)); // Ensure the communication instance is in the proper state for this call. // Make sure the application wrote the exact number of expected bytes, if // it specified the number of bytes up front. if (ci->state != CI_STATE_SENDING || (ci->bytesRemaining != (size_t) -1 && ci->bytesRemaining)) return setLastErrorInfo(ci->transport->info, "xptSendComplete", SML_ERR_A_XPT_INVALID_STATE); // Establish the new state ci->state = ci->role == XPT_REQUEST_SENDER ? CI_STATE_EXPECTING_GET_DOC : CI_STATE_EXPECTING_END_EXCHANGE; // Call through to the transport's implementation rc = ci->transport->info->internal->desc.sendComplete(ci->privateCommunicationInfo); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's sendComplete() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptSendComplete", rc); } XPTDEBUG(("Returning successfully from xptSendComplete()\n")); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptSetDocumentInfo(XptCommunicationID_t conn, const XptCommunicationInfo_t *pDoc) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(conn); if (!ci) return setLastErrorInfo(NULL, "xptSetDocumentInfo", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptSetDocumentInfo() entered for handle %lx\n", (unsigned long) ci)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_EXPECTING_SET_DOC) return setLastErrorInfo(ci->transport->info, "xptSetDocumentInfo", SML_ERR_A_XPT_INVALID_STATE); // Call through to the transport's implementation rc = ci->transport->info->internal->desc.setDocumentInfo(ci->privateCommunicationInfo, pDoc); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's setDocumentInfo() returned error %d\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptSetDocumentInfo", rc); } // Establish the new state ci->state = CI_STATE_SENDING; ci->bytesRemaining = pDoc->cbLength; XPTDEBUG(("Returning successfully from xptSetDocumentInfo()\n")); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptGetDocumentInfo(XptCommunicationID_t conn, XptCommunicationInfo_t *pDoc) { Ret_t rc; struct CommunicationInstance *ci = validateCommunicationId(conn); if (!ci) return setLastErrorInfo(NULL, "xptGetDocumentInfo", SML_ERR_A_XPT_INVALID_ID); XPTDEBUG(("Function xptGetDocumentInfo() entered for handle %lx\n", (unsigned long) ci)); // Ensure the communication instance is in the proper state for this call if (ci->state != CI_STATE_EXPECTING_GET_DOC) return setLastErrorInfo(ci->transport->info, "xptGetDocumentInfo", SML_ERR_A_XPT_INVALID_STATE); // Call through to the transport's implementation rc = ci->transport->info->internal->desc.getDocumentInfo(ci->privateCommunicationInfo, pDoc); // %%% luz:2002-05-28: added handling server access denied if (rc == SML_ERR_A_XPT_ACCESS_DENIED) { XPTDEBUG(("Transport's getDocumentInfo() returned access denied error %x\n", (int) rc)); setLastErrorInfo(ci->transport->info, "xptGetDocumentInfo", rc); // but we will return with data } // %%% end luz // If the call failed, fill in the last-error information else if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's getDocumentInfo() returned error %x\n", (int) rc)); return setLastErrorInfo(ci->transport->info, "xptGetDocumentInfo", rc); } // Establish the new state ci->state = CI_STATE_RECEIVING; ci->bytesRemaining = pDoc->cbLength; XPTDEBUG(("Returning successfully from xptGetDocumentInfo(), rc=%x\n",rc)); return rc;}XPTEXP1 const XptErrorInformation_t * XPTAPI XPTEXP2 xptGetLastError(void) { // On a multithreaded system, this information would be kept in a per-thread // control block. return &lastError;}XPTEXP1 void XPTAPI XPTEXP2 xptDebug(const char *format, ...) { va_list args; va_start(args, format);#ifdef TRACE_TO_STDOUT // Send to the platform local convenient output location. On most // platforms, this is stdout. localOutput(format, args);#else // We should direct the output to the normal toolkit trace output location. smlLibPrint("TRACE-XPT: "); // Print a unique intro for this msg smlLibVprintf(format, args);#endif va_end(args);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -