windows-nt/Source/XPSP1/NT/enduser/netmeeting/t120/mst120/userdata.cpp
2020-09-26 16:20:57 +08:00

965 lines
27 KiB
C++

#include "precomp.h"
#include "fsdiag.h"
DEBUG_FILEZONE(ZONE_T120_GCCNC);
/*
* userdata.cpp
*
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the class CUserDataListContainer. CUserDataListContainer
* objects are used to maintain user data elements. A user data element
* consists of an Object Key and an optional octet string. The Object
* Key data is maintained internally by this class by using an
* CObjectKeyContainer container. The optional octet string data is maintained
* internally through the use of a Rogue Wave string container.
*
* Protected Instance Variables:
* m_UserDataItemList
* List of structures used to hold the user data internally.
* m_pSetOfUserDataPDU
* Storage for the "PDU" form of the user data.
* m_cbDataSize
* Variable holding the size of the memory which will be required to
* hold any data referenced by the "API" GCCUserData structure.
*
* Caveats:
* None.
*
* Author:
* jbo
*/
#include "userdata.h"
#include "clists.h"
USER_DATA::~USER_DATA(void)
{
if (NULL != key)
{
key->Release();
}
delete poszOctetString;
}
/*
* CUserDataListContainer()
*
* Public Function Description
* This CUserDataListContainer constructor is used to create a CUserDataListContainer object
* from "API" data. The constructor immediately copies the user data
* passed in as a list of "GCCUserData" structures into it's internal form
* where a Rogue Wave container holds the data in the form of
* USER_DATA structures.
*/
CUserDataListContainer::
CUserDataListContainer(UINT cMembers, PGCCUserData *user_data_list, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('U','r','D','L')),
m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
m_cbDataSize(0),
m_pSetOfUserDataPDU(NULL)
{
/*
* Copy the user data into the internal structures.
*/
*pRetCode = CopyUserDataList(cMembers, user_data_list);
}
/*
* CUserDataListContainer()
*
* Public Function Description
* This CUserDataListContainer constructor is used to create a CUserDataListContainer object
* from data passed in as a "PDU" SetOfUserData structure. The user
* data is copied into it's internal form where a Rogue Wave container
* holds the data in the form of USER_DATA structures.
*/
CUserDataListContainer::
CUserDataListContainer(PSetOfUserData set_of_user_data, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('U','r','D','L')),
m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
m_cbDataSize(0),
m_pSetOfUserDataPDU(NULL)
{
/*
* Copy the user data into the internal structures.
*/
*pRetCode = UnPackUserDataFromPDU(set_of_user_data);
}
/*
* CUserDataListContainer()
*
* Public Function Description
* This CUserDataListContainer copy constructor is used to create a CUserDataListContainer
* object from another CUserDataListContainer object. The constructor immediately
* copies the user data passed in into it's internal form where a Rogue
* Wave list holds the data in the form of USER_DATA structures.
*/
CUserDataListContainer::
CUserDataListContainer(CUserDataListContainer *user_data_list, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('U','r','D','L')),
m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
m_cbDataSize(0),
m_pSetOfUserDataPDU(NULL)
{
GCCError rc;
USER_DATA *user_data_info_ptr;
USER_DATA *lpUsrDataInfo;
/*
* Set up an iterator for the internal list of "info" structures in the
* CUserDataListContainer object to be copied.
*/
user_data_list->m_UserDataItemList.Reset();
/*
* Copy each USER_DATA structure contained in the CUserDataListContainer object to
* be copied.
*/
while (NULL != (lpUsrDataInfo = user_data_list->m_UserDataItemList.Iterate()))
{
/*
* Create a new USER_DATA structure to hold each element of the new
* CUserDataListContainer object. Report an error if creation of this structure
* fails.
*/
DBG_SAVE_FILE_LINE
user_data_info_ptr = new USER_DATA;
if (user_data_info_ptr != NULL)
{
user_data_info_ptr->poszOctetString = NULL;
/*
* Go ahead and insert the pointer to the USER_DATA structure
* into the internal Rogue Wave list.
*/
m_UserDataItemList.Append(user_data_info_ptr);
/*
* Create a new CObjectKeyContainer object to hold the "key" using the
* copy constructor for the CObjectKeyContainer class. Check to be sure
* construction of the object is successful. Note that validation
* of the object key data is not done here since this would be done
* when the original CUserDataListContainer object was created.
*/
DBG_SAVE_FILE_LINE
user_data_info_ptr->key = new CObjectKeyContainer(lpUsrDataInfo->key, &rc);
if ((NULL != user_data_info_ptr->key) && (GCC_NO_ERROR == rc))
{
/*
* If an octet string exists, create a new Rogue Wave string to hold
* the octet string portion of the "key" and copy the octet string
* from the old CUserDataListContainer object into the new USER_DATA
* structure.
*/
if (lpUsrDataInfo->poszOctetString != NULL)
{
if (NULL == (user_data_info_ptr->poszOctetString =
::My_strdupO(lpUsrDataInfo->poszOctetString)))
{
ERROR_OUT(("UserData::UserData: can't create octet string"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
}
else
{
ASSERT(NULL == user_data_info_ptr->poszOctetString);
}
}
else
{
ERROR_OUT(("UserData::UserData: Error creating new ObjectKeyData"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
}
else
{
ERROR_OUT(("UserData::UserData: can't create USER_DATA"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
}
rc = GCC_NO_ERROR;
MyExit:
*pRetCode = rc;
}
/*
* ~CUserDataListContainer()
*
* Public Function Description
* This is the destructor for the CUserDataListContainer class. It is used to
* clean up any memory allocated during the life of this object.
*/
CUserDataListContainer::
~CUserDataListContainer(void)
{
/*
* Free any PDU data which may have not been freed.
*/
if (m_pSetOfUserDataPDU)
{
FreeUserDataListPDU();
}
/*
* Set up an iterator to use for iterating through the internal Rogue
* Wave list of USER_DATA structures.
*/
USER_DATA *pUserDataItem;
m_UserDataItemList.Reset();
while (NULL != (pUserDataItem = m_UserDataItemList.Iterate()))
{
/*
* Delete any memory being referenced in the USER_DATA structure.
*/
delete pUserDataItem;
}
}
/*
* LockUserDataList ()
*
* Public Function Description:
* This routine locks the user data list and determines the amount of
* memory referenced by the "API" user data list structures.
*/
UINT CUserDataListContainer::
LockUserDataList(void)
{
/*
* If this is the first time this routine is called, determine the size of
* the memory required to hold the data. Otherwise, just increment the
* lock count.
*/
if (Lock() == 1)
{
USER_DATA *lpUsrDataInfo;
/*
* Set aside memory to hold the pointers to the GCCUserData structures
* as well as the structures themselves. The "sizeof" the structure
* must be rounded to an even four-byte boundary.
*/
m_cbDataSize = m_UserDataItemList.GetCount() *
(sizeof(PGCCUserData) + ROUNDTOBOUNDARY(sizeof(GCCUserData)) );
m_UserDataItemList.Reset();
while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
{
/*
* Lock the data for the object keys, adding the amount of memory
* necessary to hold the object key data to the total memory size.
*/
m_cbDataSize += lpUsrDataInfo->key->LockObjectKeyData();
/*
* Check to see if this user data element contains the optional
* user data octet string. Add the space to hold it if it exists.
*/
if (lpUsrDataInfo->poszOctetString != NULL)
{
/*
* Since the user data structure contains a pointer to a
* OSTR structure, we must add the amount of memory
* needed to hold the structure as well as the string data.
*/
m_cbDataSize += ROUNDTOBOUNDARY(sizeof(OSTR));
/*
* The data referenced by the octet string is just the byte
* length of the octet string.
*/
m_cbDataSize += ROUNDTOBOUNDARY(lpUsrDataInfo->poszOctetString->length);
}
}
}
return m_cbDataSize;
}
/*
* GetUserDataList ()
*
* Public Function Description:
* This routine retrieves user data elements contained in the user data
* object and returns them in the "API" form of a list of pointers to
* "GCCUserData" structures. The number of user data elements contained
* in this object is also returned.
*/
UINT CUserDataListContainer::
GetUserDataList(USHORT *number_of_members, PGCCUserData **user_data_list, LPBYTE memory)
{
UINT cbDataSizeToRet = 0;
UINT data_length = 0;
Int user_data_counter = 0;
PGCCUserData user_data_ptr;
/*
* If the user data has been locked, fill in the output parameters and
* the data referenced by the pointers. Otherwise, report that the object
* has yet to be locked into the "API" form.
*/
if (GetLockCount() > 0)
{
USER_DATA *lpUsrDataInfo;
/*
* Fill in the output length parameter which indicates how much data
* referenced outside the structure will be written.
*/
cbDataSizeToRet = m_cbDataSize;
/*
* Fill in the number of user data entities and save a pointer to the
* memory location passed in. This is where the pointers to the
* GCCUserData structures will be written. The actual structures will
* be written into memory immediately following the list of pointers.
*/
*number_of_members = (USHORT) m_UserDataItemList.GetCount();
*user_data_list = (PGCCUserData *)memory;
/*
* Save the amount of memory needed to hold the list of pointers
* as well as the actual user data structures.
*/
data_length = m_UserDataItemList.GetCount() * sizeof(PGCCUserData);
/*
* Move the memory pointer past the list of user data pointers. This
* is where the first user data structure will be written.
*/
memory += data_length;
/*
* Iterate through the internal list of USER_DATA structures,
* building "API" GCCUserData structures in memory.
*/
m_UserDataItemList.Reset();
while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
{
/*
* Save the pointer to the user data structure in the list
* of pointers.
*/
user_data_ptr = (PGCCUserData)memory;
(*user_data_list)[user_data_counter++] = user_data_ptr;
/*
* Move the memory pointer past the user data structure. This is
* where the object key data and octet string data will be written.
*/
memory += ROUNDTOBOUNDARY(sizeof(GCCUserData));
/*
* Fill in the user data structure starting with the object key.
*/
data_length = lpUsrDataInfo->key->GetGCCObjectKeyData(&user_data_ptr->key, memory);
/*
* Move the memory pointer past the object key data. This is
* where the octet string structure will be written, if it exists.
* If the octet string does exist, save the memory pointer in the
* user data structure's octet string pointer and fill in the
* elements of the octet string structure. Otherwise, set the
* octet string pointer to NULL.
*/
memory += data_length;
if (lpUsrDataInfo->poszOctetString == NULL)
{
user_data_ptr->octet_string = NULL;
}
else
{
user_data_ptr->octet_string = (LPOSTR) memory;
/*
* Move the memory pointer past the octet string structure.
* This is where the actual string data for the octet string
* will be written.
*/
memory += ROUNDTOBOUNDARY(sizeof(OSTR));
/*
* Write the octet string data into memory and set the octet
* string structure pointer and length.
*/
user_data_ptr->octet_string->length =
lpUsrDataInfo->poszOctetString->length;
user_data_ptr->octet_string->value = (LPBYTE)memory;
/*
* Now copy the octet string data from the internal Rogue Wave
* string into the object key structure held in memory.
*/
::CopyMemory(memory, lpUsrDataInfo->poszOctetString->value,
lpUsrDataInfo->poszOctetString->length);
/*
* Move the memory pointer past the octet string data.
*/
memory += ROUNDTOBOUNDARY(user_data_ptr->octet_string->length);
}
}
}
else
{
*user_data_list = NULL;
*number_of_members = 0;
ERROR_OUT(("CUserDataListContainer::GetUserDataList: Error Data Not Locked"));
}
return cbDataSizeToRet;
}
/*
* UnLockUserDataList ()
*
* Public Function Description:
* This routine is used to "unlock" the "API" data for this object. This
* results in the lock count for this object being decremented. When the
* lock count transitions from 1 to 0, a check is made to determine
* whether the object has been freed through a call to
* FreeUserDataList. If so, the object will automatically delete
* itself.
*/
void CUserDataListContainer::
UnLockUserDataList(void)
{
USER_DATA *user_data_info_ptr;
if (Unlock(FALSE) == 0)
{
/*
* Unlock any memory locked for the CObjectKeyContainer objects in the
* internal USER_DATA structures.
*/
m_UserDataItemList.Reset();
while (NULL != (user_data_info_ptr = m_UserDataItemList.Iterate()))
{
/*
* Unlock any CObjectKeyContainer memory being referenced in the
* USER_DATA structure.
*/
if (user_data_info_ptr->key != NULL)
{
user_data_info_ptr->key->UnLockObjectKeyData ();
}
}
}
// we have to call Release() because we used Unlock(FALSE)
Release();
}
/*
* GetUserDataPDU ()
*
* Public Function Description:
* This routine converts the user data from it's internal form of a list
* of USER_DATA structures into the "PDU" form which can be passed in
* to the ASN.1 encoder. A pointer to a "PDU" "SetOfUserData" structure is
* returned.
*/
GCCError CUserDataListContainer::
GetUserDataPDU(PSetOfUserData *set_of_user_data)
{
GCCError rc = GCC_NO_ERROR;
PSetOfUserData new_pdu_user_data_ptr;
PSetOfUserData old_pdu_user_data_ptr = NULL;
/*
* If this is the first time that PDU data has been requested then we must
* fill in the internal PDU structure and copy it into the structure pointed
* to by the output parameter. On subsequent calls to "GetPDU" we can just
* copy the internal PDU structure into the structure pointed to by the
* output parameter.
*/
if (NULL == m_pSetOfUserDataPDU)
{
USER_DATA *lpUsrDataInfo;
/*
* Iterate through the list of USER_DATA structures, converting
* each into "PDU" form and saving the pointers in the linked list of
* "SetsOfUserData".
*/
m_UserDataItemList.Reset();
while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
{
DBG_SAVE_FILE_LINE
new_pdu_user_data_ptr = new SetOfUserData;
/*
* If an allocation failure occurs, call the routine which will
* iterate through the list freeing any data which had been
* allocated.
*/
if (new_pdu_user_data_ptr == NULL)
{
ERROR_OUT(("CUserDataListContainer::GetUserDataPDU: Allocation error, cleaning up"));
rc = GCC_ALLOCATION_FAILURE;
break;
}
//
// Ensure everything is clean.
//
::ZeroMemory(new_pdu_user_data_ptr, sizeof(SetOfUserData));
/*
* The first time through, set the PDU structure pointer equal
* to the first SetOfUserData created. On subsequent loops, set
* the structure's "next" pointer equal to the new structure.
*/
if (m_pSetOfUserDataPDU == NULL)
{
m_pSetOfUserDataPDU = new_pdu_user_data_ptr;
}
else
{
old_pdu_user_data_ptr->next = new_pdu_user_data_ptr;
}
old_pdu_user_data_ptr = new_pdu_user_data_ptr;
/*
* Initialize the new "next" pointer to NULL and convert the
* user data element.
*/
new_pdu_user_data_ptr->next = NULL;
if (ConvertUserDataInfoToPDUUserData(lpUsrDataInfo, new_pdu_user_data_ptr) != GCC_NO_ERROR)
{
ERROR_OUT(("UserData::GetUserDataPDU: can't convert USER_DATA to PDU"));
rc = GCC_ALLOCATION_FAILURE;
break;
}
}
if (GCC_NO_ERROR != rc)
{
FreeUserDataListPDU();
ASSERT(NULL == m_pSetOfUserDataPDU);
}
}
/*
* Copy the internal PDU structure into the structure pointed to by the
* output parameter.
*/
*set_of_user_data = m_pSetOfUserDataPDU;
return rc;
}
/*
* FreeUserDataListPDU ()
*
* Public Function Description:
* This routine frees any data which was allocated as a result of a call
* to "GetUserDataPDU" which was called in order to build up a "PDU"
* structure holding the user data.
*/
void CUserDataListContainer::
FreeUserDataListPDU(void)
{
PSetOfUserData pdu_user_data_set;
PSetOfUserData next_pdu_user_data_set;
USER_DATA *lpUsrDataInfo;
/*
* Check to make sure "PDU" data has been allocated for this object.
*/
if (NULL != m_pSetOfUserDataPDU)
{
pdu_user_data_set = m_pSetOfUserDataPDU;
m_pSetOfUserDataPDU = NULL; // so no one can use it now.
/*
* Loop through the list, freeing the user data associated with
* each structure contained in the list.
*/
while (pdu_user_data_set != NULL)
{
next_pdu_user_data_set = pdu_user_data_set->next;
delete pdu_user_data_set;
pdu_user_data_set = next_pdu_user_data_set;
}
}
else
{
TRACE_OUT(("CUserDataListContainer::FreeUserDataListPDU: Error PDU data not allocated"));
}
/*
* Iterate through the internal list, telling each CObjectKeyContainer object
* to free any PDU data which it has allocated.
*/
m_UserDataItemList.Reset();
while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
{
if (lpUsrDataInfo->key != NULL)
{
lpUsrDataInfo->key->FreeObjectKeyDataPDU();
}
}
}
/*
* GCCError CopyUserDataList ( UINT number_of_members,
* PGCCUserData * user_data_list)
*
* Private member function of CUserDataListContainer.
*
* Function Description:
* This routine copies the user data passed in as "API" data into it's
* internal form where the Rogue Wave m_UserDataItemList holds the data
* in the form of USER_DATA structures.
*
* Formal Parameters:
* number_of_members (i) The number of elements in the user data list.
* user_datalist (i) The list holding the user data to store.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_BAD_USER_DATA - The user data passed in contained
* an invalid object key.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CUserDataListContainer::
CopyUserDataList(UINT number_of_members, PGCCUserData *user_data_list)
{
GCCError rc = GCC_NO_ERROR;
USER_DATA *user_data_info_ptr;
UINT i;
LPOSTR octet_string_ptr;
/*
* Return an error if no user data is passed in.
*/
if (number_of_members == 0)
return (GCC_BAD_USER_DATA);
for (i = 0; i < number_of_members; i++)
{
/*
* Create a new "info" structure to hold the user data internally.
*/
DBG_SAVE_FILE_LINE
user_data_info_ptr = new USER_DATA;
if (user_data_info_ptr != NULL)
{
user_data_info_ptr->poszOctetString = NULL;
/*
* Create a new CObjectKeyContainer object which will be used to store
* the "key" portion of the object data internally.
*/
DBG_SAVE_FILE_LINE
user_data_info_ptr->key = new CObjectKeyContainer(&user_data_list[i]->key, &rc);
if (user_data_info_ptr->key == NULL)
{
ERROR_OUT(("UserData::CopyUserDataList: Error creating new CObjectKeyContainer"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
else if (rc != GCC_NO_ERROR)
{
ERROR_OUT(("UserData::CopyUserDataList: Error creating new CObjectKeyContainer - bad data"));
goto MyExit;
}
/*
* Store the optional user data octet string in the list.
*/
octet_string_ptr = user_data_list[i]->octet_string;
if ((octet_string_ptr != NULL) && (rc == GCC_NO_ERROR))
{
/*
* Create a new Rogue Wave string container to hold the
* octet string.
*/
if (NULL == (user_data_info_ptr->poszOctetString = ::My_strdupO2(
octet_string_ptr->value,
octet_string_ptr->length)))
{
ERROR_OUT(("UserData::CopyUserDataList: can't create octet string"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
}
else
{
ASSERT(NULL == user_data_info_ptr->poszOctetString);
}
}
else
{
ERROR_OUT(("UserData::CopyUserDataList: can't create USER_DATA"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
/*
* Insert the pointer to the USER_DATA structure into the Rogue Wave list.
*/
m_UserDataItemList.Append(user_data_info_ptr);
}
MyExit:
if (GCC_NO_ERROR != rc)
{
delete user_data_info_ptr;
}
return rc;
}
/*
* GCCError UnPackUserDataFromPDU (PSetOfUserData set_of_user_data)
*
* Private member function of CUserDataListContainer.
*
* Function Description:
* This routine unpacks the user data from the "PDU" form into the
* internal form which is maintained as a Rogue Wave list of USER_DATA
* structures.
*
* Formal Parameters:
* set_of_user_data (i) The "PDU" user data list to copy.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CUserDataListContainer::
UnPackUserDataFromPDU(PSetOfUserData set_of_user_data)
{
PSetOfUserData pUserData;
GCCError rc = GCC_NO_ERROR;
for (pUserData = set_of_user_data; NULL != pUserData; pUserData = pUserData->next)
{
/*
* Convert the user data elements into the internal format which
* is a USER_DATA structure and insert the pointers to the
* USER_DATA structures into the m_UserDataItemList.
*/
if (ConvertPDUDataToInternal(pUserData) != GCC_NO_ERROR)
{
ERROR_OUT(("CUserDataListContainer::UnPackUserDataFromPDU: Error converting PDU data to internal"));
rc = GCC_ALLOCATION_FAILURE;
break;
}
}
return rc;
}
/*
* GCCError ConvertPDUDataToInternal ( PSetOfUserData user_data_ptr)
*
* Private member function of CUserDataListContainer.
*
* Function Description:
* This routine converts an individual user data element from the "PDU"
* structure form into the internal form which is a USER_DATA
* structure.
*
* Formal Parameters:
* user_data_ptr (i) The "PDU" user data list to copy.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CUserDataListContainer::
ConvertPDUDataToInternal(PSetOfUserData user_data_ptr)
{
USER_DATA *user_data_info_ptr;
GCCError rc = GCC_NO_ERROR;
DBG_SAVE_FILE_LINE
user_data_info_ptr = new USER_DATA;
if (user_data_info_ptr != NULL)
{
user_data_info_ptr->poszOctetString = NULL;
/*
* Create a new CObjectKeyContainer object which will be used to store the
* "key" portion of the user data internally. If an error occurs
* constructing the key report it. Otherwise, check for any user data
* which may need to be stored. Note that any error in creating the
* CObjectKeyContainer object is reported as an allocation failure. An error
* could occur if a bad object key was received as PDU data but this
* would have originated from some other provider since we validate all
* object keys created locally. We therefore report it as an allocation
* failure.
*/
DBG_SAVE_FILE_LINE
user_data_info_ptr->key = new CObjectKeyContainer(&user_data_ptr->user_data_element.key, &rc);
if ((user_data_info_ptr->key == NULL) || (rc != GCC_NO_ERROR))
{
ERROR_OUT(("UserData::ConvertPDUDataToInternal: Error creating new CObjectKeyContainer"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
else
{
/*
* The object key was successfully saved so store any actual user
* data in the list if it is present.
*/
if (user_data_ptr->user_data_element.bit_mask & USER_DATA_FIELD_PRESENT)
{
if (NULL == (user_data_info_ptr->poszOctetString = ::My_strdupO2(
user_data_ptr->user_data_element.user_data_field.value,
user_data_ptr->user_data_element.user_data_field.length)))
{
ERROR_OUT(("UserData::ConvertPDUDataToInternal: can't create octet string"));
rc = GCC_ALLOCATION_FAILURE;
goto MyExit;
}
}
else
{
ASSERT(NULL == user_data_info_ptr->poszOctetString);
}
}
/*
* Initialize the structure pointers to NULL and insert the pointer
* to the USER_DATA structure into the Rogue Wave list.
*/
m_UserDataItemList.Append(user_data_info_ptr);
}
else
{
ERROR_OUT(("UserData::ConvertPDUDataToInternal: can't create USER_DATA"));
rc = GCC_ALLOCATION_FAILURE;
// goto MyExit;
}
MyExit:
if (GCC_NO_ERROR != rc)
{
delete user_data_info_ptr;
}
return rc;
}
/*
* GCCError ConvertUserDataInfoToPDUUserData (
* USER_DATA *user_data_info_ptr,
* PSetOfUserData pdu_user_data_ptr)
*
* Private member function of CUserDataListContainer.
*
* Function Description:
* This routine converts the user data from the internal form which is a
* USER_DATA structure into the "PDU" structure form "SetOfUserData".
*
* Formal Parameters:
* user_data_info_ptr (i) The internal user data structure to convert.
* pdu_user_data_ptr (o) The structure to hold the PDU data after
* conversion.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PARAMETER - The internal key pointer was
* corrupted.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CUserDataListContainer::
ConvertUserDataInfoToPDUUserData(USER_DATA *user_data_info_ptr, PSetOfUserData pdu_user_data_ptr)
{
GCCError rc = GCC_NO_ERROR;
/*
* Initialize the user data bit mask to zero.
*/
pdu_user_data_ptr->user_data_element.bit_mask = 0;
/*
* Fill in the octet string pointer and length if the octet string
* exists. Set the bit mask indicating that the string exists.
*/
if (user_data_info_ptr->poszOctetString != NULL)
{
pdu_user_data_ptr->user_data_element.user_data_field.value =
user_data_info_ptr->poszOctetString->value;
pdu_user_data_ptr->user_data_element.user_data_field.length =
user_data_info_ptr->poszOctetString->length;
pdu_user_data_ptr->user_data_element.bit_mask |= USER_DATA_FIELD_PRESENT;
}
/*
* Fill in the object key data.
*/
if (user_data_info_ptr->key != NULL)
{
/*
* Retrieve the "PDU" object key data from the internal CObjectKeyContainer
* object.
*/
if (user_data_info_ptr->key->GetObjectKeyDataPDU (
&pdu_user_data_ptr->user_data_element.key) != GCC_NO_ERROR)
{
rc = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("UserData::ConvertUserDataInfoToPDUUserData: no valid UserDataInfo key"));
rc = GCC_INVALID_PARAMETER;
}
return rc;
}