📄 ospmsgutil.c
字号:
/**########################################################################*########################################################################*########################################################################* * COPYRIGHT (c) 1998, 1999 by TransNexus, LLC * * This software contains proprietary and confidential information * of TransNexus, LLC. Except as may be set forth in the license * agreement under which this software is supplied, use, disclosure, * or reproduction is prohibited without the prior, express, written* consent of TransNexus, LLC. * *******#########################################################################*#########################################################################*#########################################################################*//* * ospmsgutil.c - utility functions for OSP messages */#include "osp.h"#include "ospostime.h"#include "osperrno.h"#include "ospbfr.h"#include "ospxmlelem.h"#include "ospxmlattr.h"#include "ospmsgattr.h"#include "ospxmldoc.h"#include "ospmsg.h"#include "ospb64.h"#include "osptnlog.h"/**//*-----------------------------------------------------------------------* * OSPPMsgBinFromElement() - extract binary data from an element *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPMsgBinFromElement( OSPTXMLELEM *ospvElem, /* input is XML element */ unsigned *ospvDataLen, /* in: max size out: actual size */ unsigned char *ospvData /* where to put binary data */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; OSPTXMLATTR *attr; unsigned isBase64; if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvData == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvDataLen == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* assume default CDATA encoding (not base64) */ isBase64 = OSPC_FALSE; /* look for a type attribute that will identify the encoding */ for (attr = (OSPTXMLATTR *)OSPPXMLElemFirstAttr(ospvElem); (attr != (OSPTXMLATTR *)OSPC_OSNULL) && (ospvErrCode == OSPC_ERR_NO_ERROR); attr = (OSPTXMLATTR *)OSPPXMLElemNextAttr(ospvElem, attr)) { if (OSPPMsgGetAttrPart(OSPPXMLAttrGetName(attr)) == ospeAttrEncoding) { /* we found an encoding attribute - is it base64 */ if (OSPM_STRCMP(OSPPXMLAttrGetValue(attr), "base64") == 0) { /* yes, it's base64 instead of CDATA */ isBase64 = OSPC_TRUE; /* don't stop now, in case a later version supercedes */ } else if (OSPM_STRCMP(OSPPXMLAttrGetValue(attr), "cdata") == 0) { /* this says CDATA instead of base64 */ isBase64 = OSPC_FALSE; /* again, keep looking in case a later version is there */ } else { /* if it's not CDATA or base64, we can't interpret it */ ospvErrCode = OSPC_ERR_XML_BADCID_ENC; } } } /* as long as there's no error, we know the encoding to use */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (isBase64) { unsigned outlen = 0; unsigned char *encodeddata = OSPC_OSNULL; outlen = *ospvDataLen; encodeddata = (unsigned char *)OSPPXMLElemGetValue(ospvElem); /* decode the base64 */ ospvErrCode = OSPPBase64Decode((const char *)encodeddata, OSPM_STRLEN((char *)encodeddata), ospvData, &outlen); *ospvDataLen = outlen; } else { /* * The encoding must be CDATA. Note that the XML parsing * will have already stripped out the "<[CDATA[" and "]]>" * brackets but we still need to resolve any entity * references in the data. */ ospvErrCode = OSPPXMLDereference((const unsigned char *)OSPPXMLElemGetValue(ospvElem), ospvDataLen, ospvData); } } } return(ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPMsgBinToElement() - create an XML element from binary data *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPMsgBinToElement( unsigned ospvDataLen, /* size of binary data */ unsigned char *ospvData, /* pointer to binary data */ const unsigned char *ospvName, /* name of element */ OSPTXMLELEM **ospvElem, /* where to put XML element pointer */ OSPTBOOL ospvUseBase64 /* base64 (1) or CDATA (0) encoding */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; OSPTBFR *bfr = OSPC_OSNULL; if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvData == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvName == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvDataLen == 0) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; }#ifdef OSPC_USE_CDATA_ONLY ospvUseBase64 = OSPC_FALSE;#endif if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* start with no element */ *ospvElem = OSPC_OSNULL; if (ospvUseBase64 == OSPC_FALSE) { /* allocate the buffer we use for the CDATA */ bfr = OSPPBfrNew(ospvDataLen + OSPC_XMLDOC_CDATABEGLEN + OSPC_XMLDOC_CDATAENDLEN); if (bfr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } /* start with the CDATA header */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (OSPPBfrWriteBlock(&bfr, (void *)OSPC_XMLDOC_CDATABEG, OSPC_XMLDOC_CDATABEGLEN) != OSPC_XMLDOC_CDATABEGLEN) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } /* encode as CDATA */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLAddReference(ospvData, ospvDataLen, &bfr); } /* add the CDATA trailer */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (OSPPBfrWriteBlock(&bfr, (void *)OSPC_XMLDOC_CDATAEND, OSPC_XMLDOC_CDATAENDLEN) != OSPC_XMLDOC_CDATAENDLEN) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } } else { /* base64 encode it */ unsigned base64bufsz = ospvDataLen * 2 + 1; unsigned char *base64buf = OSPC_OSNULL; /* base64 buffer must be at least 4 bytes long */ if(base64bufsz < 4) { base64bufsz = 4; } OSPM_MALLOC(base64buf, unsigned char, base64bufsz); if (base64buf != OSPC_OSNULL) { ospvErrCode = OSPPBase64Encode(ospvData, ospvDataLen, base64buf, &base64bufsz);#ifdef OSPC_VERIFY_BUILDTOKEN if (ospvErrCode == OSPC_ERR_NO_ERROR) { unsigned char tmpbuf[5000]; unsigned tmpbufsize = sizeof(tmpbuf); ospvErrCode = OSPPBase64Decode((const char *)base64buf, base64bufsz, tmpbuf, &tmpbufsize); OSPTNLOGDUMP(ospvData, ospvDataLen, "DATA IN"); OSPTNLOGDUMP(tmpbuf, tmpbufsize, "DATA IN"); if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (OSPM_MEMCMP(tmpbuf, ospvData, tmpbufsize) || (tmpbufsize != ospvDataLen)) { ospvErrCode = 666; } } }#endif if (ospvErrCode == OSPC_ERR_NO_ERROR) { bfr = OSPPBfrNew(base64bufsz); if (bfr != OSPC_OSNULL) { if (OSPPBfrWriteBlock(&bfr, base64buf, base64bufsz) != base64bufsz) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } else { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } OSPM_FREE(base64buf); } else { ospvErrCode = OSPC_ERR_XML_MALLOC_FAILED; } } /* and finally the terminating 0 */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (OSPPBfrWriteByte(&bfr, '\0') != 1) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } /* create the element */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { *ospvElem = OSPPXMLElemNew((const char *)ospvName,(const char *)OSPPBfrLinearPtr(bfr)); if (*ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } else { if (ospvUseBase64 == OSPC_TRUE) { OSPTXMLATTR *attr = OSPC_OSNULL; attr = OSPPXMLAttrNew((const unsigned char *)"encoding", (const unsigned char *)"base64"); if (attr != OSPC_OSNULL) { OSPPXMLElemAddAttr(*ospvElem, attr); attr = OSPC_OSNULL; } else { ospvErrCode = OSPC_ERR_XML_NO_ATTR; } } } } /* destroy the buffer */ if (bfr != OSPC_OSNULL) { OSPPBfrDelete(&bfr); } } return(ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPMsgNumFromElement() - extract number value from an element *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPMsgNumFromElement( OSPTXMLELEM *ospvElem, /* input is XML element */ unsigned long *ospvNumber /* where to put number */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; char *cptr; if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvNumber == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* get the number - must be decimal */ *ospvNumber = OSPM_STRTOUL(OSPPXMLElemGetValue(ospvElem), &cptr, 10); /* check for errors */ if (cptr == ((char *)OSPPXMLElemGetValue(ospvElem))) { ospvErrCode = OSPC_ERR_DATA_BAD_NUMBER; } } return(ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPMsgNumToElement() - create an XML element from a number *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPMsgNumToElement( unsigned long ospvNumber, /* number to serve as data */ const unsigned char *ospvName, /* name of element */ OSPTXMLELEM **ospvElem /* where to put XML element pointer */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; char val[41]; /* 39 digits will accomodate 2^128 */ /*!!!PS added 1 */ char *cptr; if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvName == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_INVALID_ARGS; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* start with no element */ *ospvElem = OSPC_OSNULL; /* * So we don't have to worry about the size of unsigned longs on * the system, we work backwards. */ val[sizeof(val)-1]=0; /* !!!PS Make sure it looks like a string */ cptr = &val[sizeof(val)-2]; do { *cptr-- = (char)('0' + (ospvNumber%10)); ospvNumber = ospvNumber/10; } while ((ospvNumber != 0) && (cptr >= &val[0])); if (ospvNumber != 0) { /* error - we ran out of space before completing the number */ ospvErrCode = OSPC_ERR_DATA_BAD_NUMBER; } else { /* create the element */ *ospvElem = OSPPXMLElemNew((const char *)ospvName, &val[cptr-&val[0]+1]); if (*ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -