📄 xptcomm.c
字号:
struct xptInternalTransportInfo *iti; /* Validate the provided xptTransportDescription structure */ // First make sure the necessary pointers are non-null if (!pTransport->shortName || !pTransport->description || !pTransport->selectProtocol || !pTransport->deselectProtocol || !pTransport->openCommunication || !pTransport->closeCommunication || !pTransport->beginExchange || !pTransport->endExchange || !pTransport->receiveData || !pTransport->sendData || !pTransport->sendComplete || !pTransport->setDocumentInfo || !pTransport->getDocumentInfo) return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_WRONG_PARAM); // Make sure no flags other that XPT_CLIENT and XPT_SERVER are specified if (pTransport->flags & ~(XPT_CLIENT | XPT_SERVER)) return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_WRONG_PARAM); // Make sure at least one of XPT_CLIENT and XPT_SERVER are specified if (!(pTransport->flags & (XPT_CLIENT | XPT_SERVER))) return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_WRONG_PARAM); iti = xppMalloc(sizeof(struct xptInternalTransportInfo)); if (!iti) return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_A_XPT_MEMORY); iti->desc.shortName = xppMalloc(xppStrlen(pTransport->shortName)+1); iti->desc.description = xppMalloc(xppStrlen(pTransport->description)+1); if (!iti->desc.shortName || !iti->desc.description) { if (iti->desc.shortName) xppFree((void *) iti->desc.shortName); if (iti->desc.description) xppFree((void *) iti->desc.description); xppFree(iti); return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_A_XPT_MEMORY); } // Copy the short name xppStrcpy((char *) iti->desc.shortName, pTransport->shortName); // Copy the description xppStrcpy((char *) iti->desc.description, pTransport->description); // Copy the flags and other fields iti->desc.flags = pTransport->flags; iti->desc.privateTransportInfo = pTransport->privateTransportInfo; // Copy the callback function pointers iti->desc.selectProtocol = pTransport->selectProtocol; iti->desc.deselectProtocol = pTransport->deselectProtocol; iti->desc.openCommunication = pTransport->openCommunication; iti->desc.closeCommunication = pTransport->closeCommunication; iti->desc.beginExchange = pTransport->beginExchange; iti->desc.endExchange = pTransport->endExchange; iti->desc.receiveData = pTransport->receiveData; iti->desc.sendData = pTransport->sendData; iti->desc.sendComplete = pTransport->sendComplete; iti->desc.setDocumentInfo = pTransport->setDocumentInfo; iti->desc.getDocumentInfo = pTransport->getDocumentInfo;#ifdef __EPOC_OS__ closeBindingTLS = pTransport->resetBindingTLS;#endif // Initialize count of open instance to zero iti->transportInstancesOpen = 0; // Now create the public version of the transport description structure availableTransports = xppRealloc(availableTransports, (availableTransportCount + 1) * sizeof(struct XptProtocolInfo)); if (!availableTransports) { availableTransportCount = 0; // We just lost all transport info return setLastErrorInfo(NULL, "xptRegisterTransport", SML_ERR_A_XPT_MEMORY); // This would be very bad } // Fill in the public version of the structure. It shares the shortName // and description string with the internal structure. availableTransports[availableTransportCount].internal = iti; availableTransports[availableTransportCount].shortName = iti->desc.shortName; availableTransports[availableTransportCount].description = iti->desc.description; availableTransports[availableTransportCount].flags = iti->desc.flags; availableTransports[availableTransportCount].id = ++transportIdCounter; // Make the new element an official part of the list ++availableTransportCount; XPTDEBUG(("Registered new transport \"%s\": %s\n", iti->desc.shortName, iti->desc.description)); return SML_ERR_OK;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptSetLastError(const struct xptTransportErrorInformation *info) { // On a multithreaded system, this information would be kept in a per-thread // control block. if (!info->errorMessage) return SML_ERR_WRONG_PARAM; lastError.protocolErrorCode = info->protocolErrorCode; if (lastError.errorMessage && *lastError.errorMessage && lastError.errorMessage != noError && lastError.errorMessage != noMemory) xppFree((void *) lastError.errorMessage); if (info->errorMessage) { lastError.errorMessage = xppMalloc(xppStrlen(info->errorMessage) + 1); if (!lastError.errorMessage) { lastError.errorMessage = noMemory; return SML_ERR_A_XPT_MEMORY; } // Copy the error message, so caller doesn't need to save it. xppStrcpy((char *) lastError.errorMessage, info->errorMessage); } return SML_ERR_OK;}XPTEXP1 const char * XPTAPI XPTEXP2 xptGetMetaInfoValue(const char *metaInformation, const char *tag, size_t *valueLen) {#define DELIMITERS " \t" const char *p, *vs, *ve; int found = 0; p = metaInformation; do { const char *ts, *te; // Skip over delimiters (the strspn() function would be handy here) for (ts=p; *ts && xppStrchr(DELIMITERS, *ts); ++ts) ; if (!*ts) break; // We've hit the end of the string // The variable p now points to the start of a tag name. Find the end. // The strpbrk() function would be handy here... for (te=ts; *te && !xppStrchr(DELIMITERS "=", *te); ++te) ; // The variable end now points just beyond the last char of the tag name. // Find the beginning and end of the value (if any). if (*te != '=') { // If the keyword ends with anything but '=', there's no value. p = vs = ve = te; } else { vs = te + 1; // Tolerate a quoted (single or double) string as well for the value if (*vs == '"' || *vs == '\'') { int q = *vs; ve = xppStrchr(++vs, q); if (ve) { p = ve + 1; } else { // Missing end quote is terminated by end of string ve = xppStrchr(vs, '\0'); p = ve; } } else { // No quotes. Find next delimiter (end of word) for (ve=vs; *ve && !xppStrchr(DELIMITERS, *ve); ++ve) ; p = ve; // For next time through the loop } } // See if this is the tag we care about found = te-ts == (int) xppStrlen(tag) && !xppMemicmp(tag, ts, te-ts); } while (!found && *p); if (!found) return NULL; *valueLen = ve-vs; return vs;}#undef DELIMITERSXPTEXP1 Ret_t XPTAPI XPTEXP2 xptGetProtocol(const char *protocolName, const struct XptProtocolInfo **pProtocolInfo) { const struct XptProtocolInfo *protocolList; int i, protocolCount; Ret_t rc; rc = xptGetProtocols(&protocolList, &protocolCount); if (rc != SML_ERR_OK) return rc; for (i = 0; i < protocolCount; ++i) { if (!xppStrcmp(protocolList[i].shortName, protocolName)) { *pProtocolInfo = protocolList + i; return SML_ERR_OK; } } *pProtocolInfo = NULL; return SML_ERR_A_XPT_INVALID_PROTOCOL;}#ifndef __EPOC_OS__ static int initialized XPT_DATA_SECTION = 0;#endif#ifdef __EPOC_OS__#define initialized TheXptGlobalsEpoc()->initialized#endifXPTEXP1 Ret_t XPTAPI XPTEXP2 xptGetProtocols(const struct XptProtocolInfo **pProtocolList, int *pProtocolCount) { if (!initialized) { Ret_t rc = initializeTransports(); // If initialization fails, xptGetProtocols() also fails if (rc != SML_ERR_OK) return setLastErrorInfo(NULL, "xptGetProtocols", rc); initialized = 1; // Initialization completed successfully } *pProtocolList = availableTransports; *pProtocolCount = availableTransportCount; return SML_ERR_OK;}// Clean up by unregistering transports (we'll have memory leaks otherwise!)// %%% luz 2003-06-26void xptCleanUp(void){ int idx; struct xptInternalTransportInfo *iti; // remove internal transport structures for (idx=0; idx<availableTransportCount; idx++) { iti = availableTransports[idx].internal; // Delete the strings xppFree((void *) iti->desc.shortName); xppFree((void *) iti->desc.description); // delete the internal struct itself xppFree(iti); } // remove transports table itself if (availableTransports) xppFree(availableTransports); // no transports available any more availableTransportCount=0; transportIdCounter=0; availableTransports=NULL; initialized=0; // not initialized any more}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptSelectProtocol (XptProtocolId_t protocolId, const char *metaInformation, unsigned int flags, XptServiceIDPtr_t pId) { struct XptProtocolInfo *pi; struct TransportInstance *ti; void *psi; Ret_t rc; // Find the transport with the specified protocol id for (pi = availableTransports; pi && pi->id != protocolId; ++pi) ; // It's an error if an unknown protocol id is specified if (!pi) return setLastErrorInfo(pi, "xptSelectProtocol", SML_ERR_WRONG_PARAM); XPTDEBUG(("Function xptSelectProtocol() entered, selecting transport \"%s\"\n", pi->shortName)); // Validate flags. if (flags != XPT_CLIENT && flags != XPT_SERVER) return setLastErrorInfo(pi, "xptSelectProtocol", SML_ERR_WRONG_PARAM); // Make sure protocol supports the requested mode if (!(pi->flags & flags)) return setLastErrorInfo(pi, "xptSelectProtocol", SML_ERR_A_XPT_INVALID_PROTOCOL); // Call through to the transport's implementation rc = pi->internal->desc.selectProtocol(pi->internal->desc.privateTransportInfo, metaInformation, flags, &psi); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's selectProtocol() returned error %d\n", (int) rc)); return setLastErrorInfo(pi, "xptSelectProtocol", rc); } // Allocate a transport instance control block ti = xppMalloc(sizeof(struct TransportInstance)); if (!ti) { // Tell the transport that we won't need the instance after all pi->internal->desc.deselectProtocol(psi); return setLastErrorInfo(pi, "xptSelectProtocol", SML_ERR_A_XPT_MEMORY); } // Initialize the transport instance control block ti->controlBlockId = TransportInstanceControlBlockId; ti->privateInstanceInfo = psi; ti->info = pi; ti->communicationHandlesOpen = 0; *pId = (void *) ti; ++pi->internal->transportInstancesOpen; XPTDEBUG(("Returning successfully from xptSelectProtocol() with new handle == %lx, Open instances == %d\n", (unsigned long) ti, pi->internal->transportInstancesOpen)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptDeselectProtocol(XptServiceID_t id) { Ret_t rc; struct XptProtocolInfo *pi; struct TransportInstance *ti = validateServiceId(id); if (!ti) return setLastErrorInfo(NULL, "xptDeselectProtocol", SML_ERR_A_XPT_INVALID_ID); // We'll need this later after we free the TransportInstance control block pi = ti->info; XPTDEBUG(("Function xptDeselectProtocol() entered, deselecting handle %lx for transport \"%s\"\n", (unsigned long) ti, pi->shortName)); // All open communication instances must be closed if (ti->communicationHandlesOpen) return setLastErrorInfo(pi, "xptDeselectProtocol", SML_ERR_A_XPT_IN_USE); // Call through to the transport's implementation rc = pi->internal->desc.deselectProtocol(ti->privateInstanceInfo); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's deselectProtocol() returned error %d\n", (int) rc)); return setLastErrorInfo(ti->info, "xptDeselectProtocol", rc); } // Ensure that a later reference to this block fails to validate ti->controlBlockId = 0; // Release the storage xppFree(ti); --pi->internal->transportInstancesOpen; XPTDEBUG(("Returning successfully from xptDeselectProtocol(). Open instances == %d\n", pi->internal->transportInstancesOpen)); return rc;}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptOpenCommunication(XptServiceID_t id, int role, XptCommunicationIDPtr_t pConn) { Ret_t rc; void *pci; struct CommunicationInstance *ci; struct TransportInstance *ti = validateServiceId(id); if (!ti) return setLastErrorInfo(NULL, "xptOpenCommunication", SML_ERR_A_XPT_INVALID_ID); // Validate role if (role != XPT_REQUEST_SENDER && role != XPT_REQUEST_RECEIVER) return setLastErrorInfo(ti->info, "xptOpenCommunication", SML_ERR_WRONG_PARAM); XPTDEBUG(("Function xptOpenCommunication() entered, as %s\n", role == XPT_REQUEST_SENDER ? "sender" : "receiver\n")); // Call through to the transport's implementation rc = ti->info->internal->desc.openCommunication(ti->privateInstanceInfo, role, &pci); // If the call failed, fill in the last-error information if (rc != SML_ERR_OK) { XPTDEBUG(("Transport's openCommunication() returned error %d\n", (int) rc));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -