static int EventProbeComputeSizes()

in src/LttngHelpers.c [976:1166]


static int EventProbeComputeSizes(
    struct lttngh_EventProbeContext* pContext,
    struct lttngh_DataDesc* pDataDesc,
    unsigned cDataDesc)
    lttng_ust_notrace;
static int EventProbeComputeSizes(
    struct lttngh_EventProbeContext* pContext,
    struct lttngh_DataDesc* pDataDesc,
    unsigned cDataDesc)
{
    unsigned cbTranscodeWanted = 0;

    pContext->maxAlign = 1;
    assert(pContext->cbData == 0);

    unsigned i;
    for (i = 0; i != cDataDesc; i += 1)
    {
        switch (pDataDesc[i].Type)
        {
        case lttngh_DataType_StringUtf16Transcoded:
        case lttngh_DataType_StringUtf32Transcoded:
        {
            unsigned cbUtf8;

            if (pDataDesc[i].Type == lttngh_DataType_StringUtf16Transcoded)
            {
                unsigned cch16 = (unsigned)(pDataDesc[i].Size / sizeof(char16_t));
                assert(cch16 != 0); // Error in caller - Size should have included NUL.
                cch16 -= 1;         // Do not count NUL.

                if (caa_unlikely(cch16 > 65535))
                {
                    if (cch16 == ~0u)
                    {
                        cch16 = 0; // Error in caller - Size was 0.
                    }
                    else
                    {
                        cch16 = 65535;
                    }
                }

                cbUtf8 = Utf16ToUtf8Size((char16_t const*)pDataDesc[i].Data, cch16);
            }
            else
            {
                unsigned cch32 = (unsigned)(pDataDesc[i].Size / sizeof(char32_t));
                assert(cch32 != 0); // Error in caller - Size should have included NUL.
                cch32 -= 1;         // Do not count NUL.

                if (caa_unlikely(cch32 > 65535))
                {
                    if (cch32 == ~0u)
                    {
                        cch32 = 0; // Error in caller - Size was 0.
                    }
                    else
                    {
                        cch32 = 65535;
                    }
                }

                cbUtf8 = Utf32ToUtf8Size((char32_t const*)pDataDesc[i].Data, cch32);
            }

            if (caa_unlikely(cbUtf8 > 65535))
            {
                cbUtf8 = 65535;
            }

            // Use DataDesc.Length as scratch space to store utf-8 content size.
            pDataDesc[i].Length = (uint16_t)cbUtf8; // Does not count NUL.

            cbUtf8 += 1; // Include room for 8-bit NUL.
            if (caa_unlikely(cbTranscodeWanted < cbUtf8))
            {
                cbTranscodeWanted = cbUtf8;
            }

            pContext->cbData += cbUtf8;
            if (caa_unlikely(pContext->cbData < cbUtf8))
            {
                return EOVERFLOW;
            }
            break;
        }
        case lttngh_DataType_SequenceUtf16Transcoded:
        case lttngh_DataType_SequenceUtf32Transcoded:
        {
#if lttngh_UST_RING_BUFFER_NATURAL_ALIGN
            if (__alignof__(uint16_t) > pContext->maxAlign)
            {
                pContext->maxAlign = __alignof__(uint16_t);
            }

            unsigned const alignAdjust =
                lib_ring_buffer_align(pContext->cbData, __alignof__(uint16_t));
            pContext->cbData += alignAdjust;
            if (caa_unlikely(pContext->cbData < alignAdjust))
            {
                return EOVERFLOW;
            }
#endif // lttngh_UST_RING_BUFFER_NATURAL_ALIGN

            unsigned cbUtf8;

            if (pDataDesc[i].Type == lttngh_DataType_SequenceUtf16Transcoded)
            {
                unsigned cch16 = (unsigned)(pDataDesc[i].Size / sizeof(char16_t));
                if (caa_unlikely(cch16 > 65535))
                {
                    cch16 = 65535;
                }

                cbUtf8 = Utf16ToUtf8Size((char16_t const*)pDataDesc[i].Data, cch16);
            }
            else
            {
                unsigned cch32 = (unsigned)(pDataDesc[i].Size / sizeof(char32_t));
                if (caa_unlikely(cch32 > 65535))
                {
                    cch32 = 65535;
                }

                cbUtf8 = Utf32ToUtf8Size((char32_t const*)pDataDesc[i].Data, cch32);
            }

            if (caa_unlikely(cbUtf8 > 65535))
            {
                cbUtf8 = 65535;
            }

            // Use DataDesc.Length as scratch space to store utf-8 content size.
            pDataDesc[i].Length = (uint16_t)cbUtf8;

            cbUtf8 += 2; // Include room for 16-bit length.
            if (caa_unlikely(cbTranscodeWanted < cbUtf8))
            {
                cbTranscodeWanted = cbUtf8;
            }

            pContext->cbData += cbUtf8;
            if (caa_unlikely(pContext->cbData < cbUtf8))
            {
                return EOVERFLOW;
            }
            break;
        }
        default:
        {
#if lttngh_UST_RING_BUFFER_NATURAL_ALIGN
            if (pDataDesc[i].Alignment > pContext->maxAlign)
            {
                pContext->maxAlign = pDataDesc[i].Alignment;
            }

            unsigned const alignAdjust =
                lib_ring_buffer_align(pContext->cbData, pDataDesc[i].Alignment);
            pContext->cbData += alignAdjust;
            if (caa_unlikely(pContext->cbData < alignAdjust))
            {
                return EOVERFLOW;
            }
#endif // lttngh_UST_RING_BUFFER_NATURAL_ALIGN

            pContext->cbData += pDataDesc[i].Size;
            if (pContext->cbData < pDataDesc[i].Size)
            {
                return EOVERFLOW;
            }
            break;
        }
        }
    }

    // If our scratch buffer is too small, try to heap allocate.
    if (caa_unlikely(pContext->cbTranscodeScratch < cbTranscodeWanted))
    {
        unsigned char* pbTranscodeWanted = (unsigned char*)malloc(cbTranscodeWanted);
        if (caa_unlikely(pbTranscodeWanted == NULL))
        {
            return ENOMEM;
        }

        pContext->cbTranscodeScratch = cbTranscodeWanted;
        pContext->pbTranscodeScratch = pbTranscodeWanted;
    }

    return 0;
}