parseSCUSCPRole(PRV_SCUSCPROLE * role, unsigned char *buf,
                unsigned long *length, unsigned long availData)
{
    unsigned short
        UIDLength;

    // We need at least 8 bytes of data, else we read past the end of buf
    if (availData < 8)
        return makeLengthError("SCU-SCP role list", availData, 8);

    role->type = *buf++;
    role->rsv1 = *buf++;
    EXTRACT_SHORT_BIG(buf, role->length);
    buf += 2;

    EXTRACT_SHORT_BIG(buf, UIDLength);
    buf += 2;

    // Check if all the length fields are valid (we have the minimum needed
    // number of bytes, no field is larger than its surrounding field).
    if (availData - 4 < role->length)
        return makeLengthError("SCU-SCP role list", availData, 0, role->length);
    if (role->length < 4)
        return makeLengthError("SCU-SCP role list UID", role->length, 4);
    if (role->length - 4 < UIDLength)
        return makeLengthError("SCU-SCP role list UID", role->length, 0, UIDLength);

    if (UIDLength > DICOM_UI_LENGTH)
    {
      DCMNET_WARN("Provided role SOP Class UID length " << UIDLength
            << " is larger than maximum allowed UID length " << DICOM_UI_LENGTH << " (will use 64 bytes max)");
      UIDLength = DICOM_UI_LENGTH;
    }

    // The UID in the source buffer is not necessarily null terminated. Copy with memcpy
    // and add a zero byte. We have already checked that there is enough data available
    // in the source source buffer and enough space in the target buffer.
    (void) memcpy(role->SOPClassUID, buf, UIDLength);
    role->SOPClassUID[UIDLength] = '\0';

    buf += UIDLength;
    role->SCURole = *buf++;
    role->SCPRole = *buf++;

    *length = 2 + 2 + role->length;

    DCMNET_TRACE("Subitem parse: Type "
            << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(2) << (unsigned int)role->type
            << STD_NAMESPACE dec << ", Length " << STD_NAMESPACE setw(4) << (int)role->length
            << ", Content: SOP Class: " << role->SOPClassUID << " SCU: " << (int)role->SCURole << " SCP: " << (int)role->SCPRole);
    return EC_Normal;
}
parseSCUSCPRole(PRV_SCUSCPROLE * role, unsigned char *buf,
                unsigned long *length, unsigned long availData)
{
    unsigned short
        UIDLength;

     
    if (availData < 8)
        return makeLengthError("SCU-SCP role list", availData, 8);

    role->type = *buf++;
    role->rsv1 = *buf++;
    EXTRACT_SHORT_BIG(buf, role->length);
    buf += 2;

    EXTRACT_SHORT_BIG(buf, UIDLength);
    buf += 2;

     
     
    if (availData - 4 < role->length)
        return makeLengthError("SCU-SCP role list", availData, 0, role->length);
    if (role->length < 4)
        return makeLengthError("SCU-SCP role list UID", role->length, 4);
    if (role->length - 4 < UIDLength)
        return makeLengthError("SCU-SCP role list UID", role->length, 0, UIDLength);

    if (UIDLength > DICOM_UI_LENGTH)
    {
      DCMNET_WARN("Provided role SOP Class UID length " << UIDLength
            << " is larger than maximum allowed UID length " << DICOM_UI_LENGTH << " (will use 64 bytes max)");
      UIDLength = DICOM_UI_LENGTH;
    }

     
     
     
    (void) memcpy(role->SOPClassUID, buf, UIDLength);
    role->SOPClassUID[UIDLength] = '\0';

    buf += UIDLength;
    role->SCURole = *buf++;
    role->SCPRole = *buf++;

    *length = 2 + 2 + role->length;

    DCMNET_TRACE("Subitem parse: Type "
            << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(2) << (unsigned int)role->type
            << STD_NAMESPACE dec << ", Length " << STD_NAMESPACE setw(4) << (int)role->length
            << ", Content: SOP Class: " << role->SOPClassUID << " SCU: " << (int)role->SCURole << " SCP: " << (int)role->SCPRole);
    return EC_Normal;
}