📄 staf.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include <stdlib.h>#include "STAFConnectionProvider.h"#include "STAFString.h"#include "STAFException.h"#include "STAFUtil.h"#include "STAFMutexSem.h"static const STAFString sBang(kUTF8_BANG);static const STAFString sAt(kUTF8_AT);static const STAFString sCaret(kUTF8_CARET);// Opening Privacy Delimiter, !!@static const STAFString sOpenPD(sBang + sBang + sAt);// Closing Privacy Delimiter, @!!static const STAFString sClosePD(sAt + sBang + sBang);// Escaped Opening Privacy Delimiter, ^!!@static const STAFString sEscOpenPD(sCaret + sOpenPD);// Escaped Closing Privacy Delimiter, ^@!!static const STAFString sEscClosePD(sCaret + sClosePD);// Our callers may be in a different runtime environment so, make sure we// register our exception handlers// #pragma handler(STAFRegister(char *, STAFHandle_t *))// #pragma handler(STAFRegisterUTF8(char *, STAFHandle_t *))// #pragma handler(STAFUnRegister(STAFHandle_t))// #pragma handler(STAFSubmit(STAFHandle_t, char *, char *, char *, unsigned int,\// char **, unsigned int *))// #pragma handler(STAFSubmitUTF8(STAFHandle_t, char *, char *, char *,\// unsigned int, char **, unsigned int *))// #pragma handler(STAFFree(STAFHandle_t, char *))// These are real hacks to get around a bug in the VAC++ compiler dealing// with exceptions being thrown from a function that has a #pragma handler//// So, we basically call these functions to perform the real work for the// intended APIsstatic STAFRC_t RealSTAFRegister(char *processName, STAFHandle_t *handle);static STAFRC_t RealSTAFRegisterUTF8(char *processName, STAFHandle_t *handle);static STAFRC_t RealSTAFUnRegister(STAFHandle_t handle);static STAFRC_t RealSTAFSubmit(STAFHandle_t handle, STAFSyncOption_t syncOption, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength);static STAFRC_t RealSTAFSubmitUTF8(STAFHandle_t handle, STAFSyncOption_t syncOption, const char *where, const char *service, const char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength);static STAFRC_t RealSTAFFree(STAFHandle_t handle, char *result);static void createCResult(STAFString result, char **resultPtr, unsigned int *resultLength);static unsigned int findNextUnescapedOpeningPD(const STAFString &data, unsigned int index);static unsigned int findNextUnescapedClosingPD(const STAFString &data, unsigned int index);STAFRC_t makeConnection(STAFConnectionPtr &connection, STAFString &errorBuffer){ try { static STAFMutexSem sConnProvSem; static STAFConnectionProvider *sConnProv = 0; static bool sConnProvIsInited = false; static STAFString endpoint = "local"; if (sConnProvIsInited == false) { STAFMutexSemLock lock(sConnProvSem); if (sConnProvIsInited == false) { STAFConnectionProviderConstructInfoLevel1 constructInfo = { kSTAFConnectionProviderOutbound, 0 }; constructInfo.mode = kSTAFConnectionProviderOutbound; sConnProv = STAFConnectionProvider::create("local", "STAFLIPC", &constructInfo, 1); sConnProvIsInited = true; } } connection = sConnProv->connect(endpoint); return kSTAFOk; } catch (STAFConnectionProviderException) { return kSTAFNotRunning; } catch (STAFException &se) { errorBuffer = se.getText(); return se.getErrorCode(); } catch (...) { errorBuffer = "Caught unknown exception in makeConnection()"; } return kSTAFUnknownError;}STAFRC_t STAFRegister(char *processName, STAFHandle_t *handle){ return RealSTAFRegister(processName, handle);}STAFRC_t RealSTAFRegister(char *processName, STAFHandle_t *handle){ STAFRC_t rc = kSTAFRegistrationError; try { STAFConnectionPtr connection; STAFString errorBuffer; rc = makeConnection(connection, errorBuffer); if (rc != kSTAFOk) return rc; connection->writeUInt(2); // API Number connection->writeUInt(0); // API Level STAFRC_t ack = static_cast<STAFRC_t>(connection->readUInt()); if (ack != kSTAFOk) return ack; connection->writeUInt(STAFUtilGetPID()); connection->writeString(processName); rc = (STAFRC_t)connection->readUInt(); connection->readUInt(*handle); } catch (STAFConnectionProviderConnectException) { rc = kSTAFNotRunning; } catch (STAFConnectionIOException) { rc = kSTAFCommunicationError; } catch (...) { rc = kSTAFUnknownError; } return rc;}STAFRC_t STAFRegisterUTF8(char *processName, STAFHandle_t *handle){ return RealSTAFRegisterUTF8(processName, handle);}STAFRC_t RealSTAFRegisterUTF8(char *processName, STAFHandle_t *handle){ STAFRC_t rc = kSTAFRegistrationError; try { STAFConnectionPtr connection; STAFString errorBuffer; rc = makeConnection(connection, errorBuffer); if (rc != kSTAFOk) return rc; connection->writeUInt(2); // API Number connection->writeUInt(0); // API Level STAFRC_t ack = static_cast<STAFRC_t>(connection->readUInt()); if (ack != kSTAFOk) return ack; connection->writeUInt(STAFUtilGetPID()); unsigned int processNameLength = strlen(processName); connection->writeUInt(processNameLength); connection->write(processName, processNameLength); rc = (STAFRC_t)connection->readUInt(); connection->readUInt(*handle); } catch (STAFConnectionProviderConnectException) { rc = kSTAFNotRunning; } catch (STAFConnectionIOException) { rc = kSTAFCommunicationError; } catch (STAFException &se) { rc = se.getErrorCode(); } catch (...) { rc = kSTAFUnknownError; } return rc;}STAFRC_t STAFUnRegister(STAFHandle_t handle){ return RealSTAFUnRegister(handle);}STAFRC_t RealSTAFUnRegister(STAFHandle_t handle){ STAFRC_t rc = kSTAFUnknownError; try { STAFConnectionPtr connection; STAFString errorBuffer; rc = makeConnection(connection, errorBuffer); if (rc != kSTAFOk) return rc; connection->writeUInt(3); // API Number connection->writeUInt(0); // API Level STAFRC_t ack = static_cast<STAFRC_t>(connection->readUInt()); if (ack != kSTAFOk) return ack; connection->writeUInt(STAFUtilGetPID()); connection->writeUInt(handle); rc = (STAFRC_t)connection->readUInt(); } catch (STAFConnectionProviderConnectException) { rc = kSTAFNotRunning; } catch (STAFConnectionIOException) { rc = kSTAFCommunicationError; } catch (STAFException &se) { rc = se.getErrorCode(); } catch (...) { rc = kSTAFUnknownError; } return rc;}STAFRC_t STAFSubmit(STAFHandle_t handle, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ return STAFSubmit2(handle, kSTAFReqSync, where, service, request, requestLength, resultPtr, resultLength);}STAFRC_t STAFSubmit2(STAFHandle_t handle, STAFSyncOption_t syncOption, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ return RealSTAFSubmit(handle, syncOption, where, service, request, requestLength, resultPtr, resultLength);}STAFRC_t RealSTAFSubmit(STAFHandle_t handle, STAFSyncOption_t syncOption, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ STAFRC_t rc = kSTAFUnknownError; *resultLength = 0; *resultPtr = 0; STAFString response; try { // Basically, we just piggy back on top of the UTF-8 version of // STAFSubmit STAFString whereUTF8(where); STAFString serviceUTF8(service); STAFString requestUTF8(request, requestLength); // Note: We don't need to add a null to requestUTF8 since we pass it's // length to RealSTAFSubmitUTF8 whereUTF8 += kUTF8_NULL; serviceUTF8 += kUTF8_NULL; char *theResultPtr = 0; unsigned int theResultLength = 0; rc = RealSTAFSubmitUTF8(handle, syncOption, whereUTF8.buffer(), serviceUTF8.buffer(), requestUTF8.buffer(), requestUTF8.length(), &theResultPtr, &theResultLength); response = STAFString(theResultPtr, theResultLength, STAFString::kUTF8); } catch (...) { rc = kSTAFUnknownError; } createCResult(response, resultPtr, resultLength); return rc;}STAFRC_t STAFSubmitUTF8(STAFHandle_t handle, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ return STAFSubmit2UTF8(handle, kSTAFReqSync, where, service, request, requestLength, resultPtr, resultLength);}STAFRC_t STAFSubmit2UTF8(STAFHandle_t handle, STAFSyncOption_t syncOption, char *where, char *service, char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ return RealSTAFSubmitUTF8(handle, syncOption, where, service, request, requestLength, resultPtr, resultLength);}STAFRC_t RealSTAFSubmitUTF8(STAFHandle_t handle, STAFSyncOption_t syncOption, const char *where, const char *service, const char *request, unsigned int requestLength, char **resultPtr, unsigned int *resultLength){ if ((syncOption != kSTAFReqSync) && (syncOption != kSTAFReqQueue) && (syncOption != kSTAFReqRetain) && (syncOption != kSTAFReqQueueRetain) && (syncOption != kSTAFReqFireAndForget)) { return kSTAFInvalidAsynchOption; } STAFRC_t rc = kSTAFUnknownError; *resultLength = 0; *resultPtr = 0; STAFString response; char *buffer2 = 0; // Note: I tried using a stack buffer of various sizes (64, 128, and 256 // bytes, to try to avoid doing most memory allocation, but that // actually made performance worse. try { STAFConnectionPtr connection; STAFString errorBuffer; rc = makeConnection(connection, errorBuffer); if (rc != kSTAFOk) { *resultLength = errorBuffer.length(); if (*resultLength != 0) { *resultPtr = new char[*resultLength + 1]; (*resultPtr)[*resultLength] = 0; memcpy(*resultPtr, errorBuffer.buffer(), *resultLength); } return rc; } unsigned int whereLength = strlen(where); unsigned int serviceLength = strlen(service); unsigned int buffer[2]; buffer[0] = 0; // API Number buffer[1] = STAFUtilConvertNativeUIntToLE(2); // API Level connection->write(buffer, sizeof(buffer)); STAFRC_t ack = static_cast<STAFRC_t>(connection->readUInt()); if (ack != kSTAFOk) return ack; unsigned int buffSize = (6 * sizeof(unsigned int)) + whereLength + serviceLength + requestLength; buffer2 = new char[buffSize]; int *buffer2int = reinterpret_cast<int *>(buffer2); buffer2int[0] = STAFUtilConvertNativeUIntToLE(syncOption); buffer2int[1] = STAFUtilConvertNativeUIntToLE(STAFUtilGetPID()); buffer2int[2] = STAFUtilConvertNativeUIntToLE(handle); buffer2int[3] = STAFUtilConvertNativeUIntToLE(whereLength); buffer2int[4] = STAFUtilConvertNativeUIntToLE(serviceLength); buffer2int[5] = STAFUtilConvertNativeUIntToLE(requestLength); char *buffer2offset = buffer2 + (6 * sizeof(unsigned int)); memcpy(buffer2offset, where, whereLength); buffer2offset += whereLength; memcpy(buffer2offset, service, serviceLength); buffer2offset += serviceLength; memcpy(buffer2offset, request, requestLength); connection->write(buffer2, buffSize); rc = static_cast<STAFRC_t>(connection->readUInt()); *resultLength = connection->readUInt(); if (*resultLength != 0) { *resultPtr = new char[*resultLength + 1]; (*resultPtr)[*resultLength] = 0; connection->read(*resultPtr, *resultLength); } } catch (STAFConnectionProviderConnectException &se) { rc = kSTAFNotRunning; response = STAFString(se.getText()); response += STAFString(": "); response += STAFString(se.getErrorCode()); } catch (STAFConnectionIOException &se) { rc = kSTAFCommunicationError; response = STAFString(se.getText()); response += STAFString(": "); response += STAFString(se.getErrorCode()); } catch (STAFException &se) { rc = se.getErrorCode(); response = STAFString(se.getText()); } catch (...) { rc = kSTAFUnknownError; } if (response.length() != 0) { // We must have thrown an exception try { // Free memory if we had already allocated it if (*resultPtr != 0) delete [] *resultPtr; *resultLength = response.length(); if (*resultLength != 0) { *resultPtr = new char[*resultLength + 1]; memcpy(*resultPtr, response.buffer(), *resultLength); (*resultPtr)[*resultLength] = 0; } } catch (...) { delete [] *resultPtr; *resultLength = 0; } } delete [] buffer2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -