STATUS uriEncodeString()

in src/source/Common/AwsV4Signer.c [847:910]


STATUS uriEncodeString(PCHAR pSrc, UINT32 srcLen, PCHAR pDst, PUINT32 pDstLen)
{
    STATUS retStatus = STATUS_SUCCESS;
    UINT32 encodedLen = 0, strLen, remaining, encLen = ARRAY_SIZE(URI_ENCODED_FORWARD_SLASH) - 1;
    PCHAR pCurPtr = pSrc, pEnc = pDst;
    CHAR ch;
    CHAR alpha[17] = "0123456789ABCDEF";

    // Set the source length to max if not specified
    strLen = (srcLen == 0) ? MAX_UINT32 : srcLen;

    // Set the remaining length
    remaining = (pDst == NULL) ? MAX_UINT32 : *pDstLen;

    CHK(pSrc != NULL && pDstLen != NULL, STATUS_NULL_ARG);

    while (((UINT32)(pCurPtr - pSrc) < strLen) && ((ch = *pCurPtr++) != '\0')) {
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') {
            encodedLen++;

            if (pEnc != NULL) {
                CHK(remaining > 0, STATUS_NOT_ENOUGH_MEMORY);
                remaining--;
                *pEnc++ = ch;
            }
        } else if (ch == '/') {
            encodedLen += encLen;

            if (pEnc != NULL) {
                CHK(remaining > encLen, STATUS_NOT_ENOUGH_MEMORY);
                STRCPY(pEnc, URI_ENCODED_FORWARD_SLASH);
                pEnc += encLen;
                remaining -= encLen;
            }
        } else {
            encodedLen += encLen;

            if (pEnc != NULL) {
                CHK(remaining > encLen, STATUS_NOT_ENOUGH_MEMORY);
                *pEnc++ = '%';
                *pEnc++ = alpha[ch >> 4];
                *pEnc++ = alpha[ch & 0x0f];
                remaining -= encLen;
            }
        }
    }

    // Account for the null terminator
    encodedLen++;

    if (pEnc != NULL) {
        CHK(remaining > 0, STATUS_NOT_ENOUGH_MEMORY);
        *pEnc++ = '\0';
        remaining--;
    }

CleanUp:

    if (pDstLen != NULL) {
        *pDstLen = encodedLen;
    }

    return retStatus;
}