⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 per.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

    if (IS_OPEN_TYPE(tmpSynParent))
    {
        if (perDecodeLen(perLenTypeUNCONSTRAINED, &fieldLen, 0, 0, hPer, per->decodingPosition, &dec) <0)
        {
            RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
                "perDecNode: open type field length missing [%s].",
                pstGetFieldNamePtr(per->hSyn, fieldId)));
            return RV_ERROR_UNKNOWN;
        }

        RvLogDebug(&rvPerLogSource, (&rvPerLogSource,
            "Decoding open type."));
        per->decodingPosition += dec;
        saveLocation = per->decodingPosition;
    }

    if (tmpSynParent != RV_PST_ERROR_UNDEFINED_TYPE)
    {
        switch (type)
        {
        case pstNull:
            vtPath=valParent;
            if (fieldId!=RV_ERROR_UNKNOWN)
            ret =  vtPath =pvtAdd(per->hVal, valParent, fieldId, -123, NULL, NULL);
            break;
        case pstInteger:
            ret = perDecodeInt(&value, from, to, fromAbsent, toAbsent,
                                pstGetIsExtended(per->hSyn,tmpSynParent),
                                hPer, per->decodingPosition, &dec, (char*)"integer");
            vtPath=valParent;
            if ((fieldId!=RV_ERROR_UNKNOWN) && (ret >= 0))
                ret = vtPath=pvtAdd(per->hVal, valParent, fieldId, (RvInt32)value, NULL, NULL);
            per->decodingPosition += dec;
            break;
        case pstBoolean:
            ret = perDecodeBool(&boola, hPer, per->decodingPosition, &dec);
            vtPath=valParent;
            if ((fieldId!=RV_ERROR_UNKNOWN) && (ret >= 0))
                ret = vtPath=pvtAdd(per->hVal, valParent, fieldId, boola,  NULL, NULL);
            per->decodingPosition += dec;
            break;

        case pstUniversalString:
        case pstGeneralString:
        case pstBMPString:
        case pstIA5String:
        case pstNumericString:
        case pstPrintableString:
        case pstVisibleString:
            ret = perDecodeCharString(hPer, tmpSynParent, valParent, fieldId);
            break;

        case pstOctetString:
            ret = perDecodeOctetString(hPer, tmpSynParent, valParent, fieldId);
            break;

        case pstBitString:
            ret = perDecodeBitString(hPer, tmpSynParent, valParent, fieldId);
            break;
        case pstObjectIdentifier:
            ret = perDecodeOID(hPer, tmpSynParent, valParent, fieldId);
            break;
        case pstEnumeration:
        case pstChoice:
            startListLength = per->currentPositionInArrayOfSpecialNodes;
            ret = perDecodeChoice(hPer, tmpSynParent, valParent, fieldId);
            finishListLength = per->currentPositionInArrayOfSpecialNodes;
            for (i = 0; i < finishListLength - startListLength; i++)
                perPopElemFromArrayOfSpecialNodes(hPer);
            break;
        case pstSet:
        case pstSequence:
            startListLength = per->currentPositionInArrayOfSpecialNodes;
            ret = perDecodeSequece(hPer, tmpSynParent, valParent, fieldId);
            finishListLength = per->currentPositionInArrayOfSpecialNodes;
            for (i = 0; i < finishListLength - startListLength; i++)
                perPopElemFromArrayOfSpecialNodes(hPer);
            break;
        case pstSequenceOf:
        case pstSetOf:
            ret = perDecodeSequeceOF(hPer, tmpSynParent, valParent, fieldId);
            break;
        default:
            RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
                "perDecodeNode: %s TYPE unrecognized: %s.",
                pstGetFieldNamePtr(per->hSyn, fieldId),
                nprn(pstGetTokenName(type))));
            return RV_ERROR_UNKNOWN;
        } /* end of switch */
    }
    else /* tmpSynParent == RV_PST_ERROR_UNDEFINED_TYPE */
    {
        vtPath=valParent;
        /*if (fieldId!=RV_ERROR_UNKNOWN)
        ret = pvtAdd(per->hVal, valParent, fieldId, 555, NULL, NULL);*/
    }


    if (IS_OPEN_TYPE(tmpSynParent))
        per->decodingPosition = saveLocation + fieldLen*8; /* skip field */

    if (tmpSynParent != RV_PST_ERROR_UNDEFINED_TYPE && ret < 0)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNode: '%s' %s decoding Error!.",
            pstGetFieldNamePtr(per->hSyn, fieldId),
            nprn(pstGetTokenName(type))));

        switch (ret)
        {
            case RV_ERROR_UNKNOWN:
                per->encodingDecodingErrorBitMask |= encDecErrorsMessageIsInvalid;
                break;
            case RV_ERROR_OUTOFRESOURCES:
                per->encodingDecodingErrorBitMask |= encDecErrorsResourcesProblem;
                break;
        }

        return RV_ERROR_UNKNOWN;
    }

    if (speciality == pstDependingDependent || speciality == pstDepending)
        perPushElemToArrayOfSpecialNodes(hPer, ret);

    if (tmpSynParent == RV_PST_ERROR_UNDEFINED_TYPE)
        per->encodingDecodingErrorBitMask |= encDecErrorsObjectWasNotFound;

    return RV_TRUE;
}





/************************************************************************
 * perConstruct
 * purpose: Construct PER information needed by the encode/decode manager.
 * input  : maxBufSize  - Maximum size of buffer supported (messages larger
 *                        than this size in bytes cannot be decoded/encoded).
 * output : none
 * return : none
 ************************************************************************/
void perConstruct(IN int maxBufSize)
{
    emTypeOfEncoding eSys;

    eSys.Encode = perEncode;
    eSys.Decode = perDecode;

    if (timesPerConstructed == 0)
    {
        /* First time we call perConstruct() - make sure we register our log sources */
        RvLogSourceConstruct(RvLogGet(), &rvPerLogSource, RV_LOG_LIBCODE_ASN1, "PER", "PER Encoder/Decoder");
        RvLogSourceConstruct(RvLogGet(), &rvPerErrLogSource, RV_LOG_LIBCODE_ASN1, "PERERR", "PER Error Messages");
    }
    timesPerConstructed++;

    emSetEncoding(emPER, &eSys);

    /* Make sure we create a buffer with sufficient size for this thread */
    if (perMaxBufSize < maxBufSize)
        perMaxBufSize = maxBufSize;
    perBufferInit();
}


/*
Desc: Free per allocations.
Free func list and structure.
*/
void perDestruct(void)
{
    timesPerConstructed--;
    if(timesPerConstructed == 0)
    {
        RvLogSourceDestruct(RvLogGet(), &rvPerLogSource);
        RvLogSourceDestruct(RvLogGet(), &rvPerErrLogSource);
    }
    perBufferEnd();
}
/*
Desc: Encode a message from root.
*/
int
perEncode(
          IN  HPVT  valH,            /* encoding from value tree */
          IN  int    valNodeId,       /* root of encoding */
          OUT RvUint8*buffer,         /* encoding to this buffer */
          IN  int    bufferLength,    /* in bytes */
          OUT int*   encoded)         /* bytes encoded to buffer */
{
    perStruct per;
    RvUint8 octets[32];
    HBB bbH;
    int synNodeId;
    int ret;

#ifdef RV_CODER_DEBUG
    if (bbGetAllocationSize(0) >(int)sizeof(octets))
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perEncode: Allocation space for length not enough [%d].",
            bbGetAllocationSize(0)));
        return RV_ERROR_UNKNOWN;
    }
#endif  /* RV_CODER_DEBUG */
    bbH = bbConstructFrom(0, (char *)octets, sizeof(octets));
    bbSetOctets(bbH, bufferLength, 0, buffer);

    if (!buffer || !bbH)
        return RV_ERROR_UNKNOWN;

    memset((void *)&per, 0, sizeof(per));
    per.hSyn = pvtGetSynTree(valH, valNodeId);
    per.hVal = valH;
    per.isOuterMostValueEmpty = RV_FALSE;
    per.hBB = bbH;
    per.encodingDecodingErrorBitMask = 0x0;
    per.buf = perGetBuffer();

    if (pvtGet(valH, valNodeId, NULL, &synNodeId, NULL, NULL) <0)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perEncode: value tree root id is illagal [%d].", valNodeId));
        return RV_ERROR_UNKNOWN;
    }

    ret = perEncNode((HPER)&per, synNodeId, valNodeId, -1, RV_FALSE);
    if ((ret == RV_ERROR_UNKNOWN) && (((bbStruct*)(per.hBB))->isOverflowOfBuffer == RV_TRUE))
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "Encoding error: Overflow of buffer."));
    }

    if (encoded)
        *encoded = bbBytesInUse(per.hBB);
    perEncodeComplete((HPER)&per, (int)bbBitsInUse(per.hBB));
    return ret;
}



/*
Desc: Decode a message from root.
*/
int
perDecode(
          OUT HPVT valH,         /* decoding to value tree */
          IN  int   valNodeId,    /* root of encoding */
          IN  RvInt32 fieldId,      /* root field Id */
          IN  RvUint8 *buffer,      /* decoding from this buffer */
          IN  int   bufferLength, /* in bytes */
          OUT int*  decoded)     /* number of BYTES successfully decoded from buffer */
{
    perStruct per;
    RvUint8 octets[64];
    HBB bbH;
    int synRootId;
    pstChildExt child;
    pstFieldSpeciality speciality;
    int index;

    if (buffer == NULL)
        return RV_ERROR_NULLPTR;

    bbH = bbConstructFrom(10, (char *)octets, sizeof(octets));
    bbSetOctets(bbH, bufferLength, bufferLength*8, buffer);

    if (bbH == NULL)
        return RV_ERROR_OUTOFRANGE;

    memset((void *)&per, 0, sizeof(per));
    per.hSyn = pvtGetSynTree(valH, valNodeId);
    per.hVal = valH;
    per.isOuterMostValueEmpty = RV_FALSE;
    per.hBB = bbH;
    per.currentPositionInArrayOfSpecialNodes = 0;
    per.encodingDecodingErrorBitMask = 0x0;
    per.buf = perGetBuffer();

    pvtGet(valH, valNodeId, NULL, &synRootId, NULL, NULL);
    if ((index=pstGetFieldIndex(per.hSyn, synRootId, fieldId)) >=0)
    {
        pstGetChildExt(per.hSyn, synRootId,index,&child);
        speciality = child.speciality;
        synRootId = child.nodeId;
    }
    else
        speciality = pstNotSpecial;

    if (perDecNode((HPER)&per, synRootId, speciality, valNodeId, fieldId) < 0  &&
        ((bbStruct*)(per.hBB))->isOverflowOfBuffer == RV_TRUE)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "Decoding error: Overflow of buffer."));
    }

    if (decoded)
        *decoded = bbSetByte(per.decodingPosition);

    if (per.encodingDecodingErrorBitMask)
    {
        if (per.encodingDecodingErrorBitMask &  encDecErrorsResourcesProblem)
            return RV_ERROR_OUTOFRESOURCES;

        if (per.encodingDecodingErrorBitMask &  encDecErrorsMessageIsInvalid)
            return RV_ERROR_UNKNOWN;

        /* We might have an H.450 message with parts we can't understand. In such a case,
           we should still think of the message as decodable without any real errors
        if (per.encodingDecodingErrorBitMask &  encDecErrorsObjectWasNotFound)
            return RV_ERROR_BADPARAM;*/
    }

    return RV_TRUE;
}



#ifdef __cplusplus
}
#endif



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -