Optim Data Privacy Providers  11.7.0
 All Data Structures Files Functions Variables Macros Groups Pages
Example
Collaboration diagram for Example:

The following is an example for Age Service Provider where the source date format is "%YYYY/%MM/%DD %HH24:%MI:%SS", for example, "2006/12/16 01:05:59".

Service Provider Initialization:

DP_SVC_DEF SvcDef; //Service Definition structure
DP_FIELD_DEF FldDef[MAX_COLUMNS]; //Array of DP_FIELD_DEF structures
DP_INIT_OP_DEF InitParameters[PARAMETER_MAX_SIZE]; //Array of DP_INIT_OP_DEF structures
DP_ROWSET_DEF rowSet; //RowSet which contains the rows to be masked
DP_ROW_DEF **pRow; //Pointer used to create the list of rows in rowSet
DP_FIELD_DATA_DEF *pData; //Pointer used to create the list of data fields
int iSvcToken; //Service Token
RETVAL retVal; //return code
short sMethod; //Method to use for masking
char Line[INPUT_LINE_MAX_SIZE]; //character buffer used to store the input value read from the CSV file
int *piRows = NULL; //Integer pointer to hold the row count in rowSet
int i = 0; //Counter
int j = 0; //Counter
int iLen = 0; //Length of the buffer
int iCnt = 0; //Count of rows in the rowSet
FILE *fin = NULL; //File handle for input CSV file
char PrvName[] = "AGE"; //Provider name in MBCS
#ifndef USE_ODPP_MBCS_CHAR_CALLS
ODPP_WCHAR SrcFormatW[] = L"%YYYY/%MM/%DD %HH24:%MI:%SS"; //Source date format
#else
char SrcFormat[] = "%YYYY/%MM/%DD %HH24:%MI:%SS"; //Source date format
#endif
DP_ROWSET_DEF *pRowSet = NULL; //RowSet pointer
DP_ROW_DEF *pCurRow = NULL; //Row pointer
DP_ROW_DEF *pPrevRow = NULL; //Row pointer
DP_FIELD_DATA_DEF *pPrev = NULL; //data field pointer
//Clear the Field Definition
memset(FldDef, 0, MAX_COLUMNS * sizeof(DP_FIELD_DEF));
//Clear the Parameter definition
memset(InitParameters, 0, PARAMETER_MAX_SIZE * sizeof(DP_INIT_OP_DEF));
//Clear the Service Definition
memset(&SvcDef, 0, sizeof(DP_SVC_DEF));
//Initialize the DP_FIELD_DEF structure
for(iTempCnt=0; iTempCnt < MAX_COLUMNS; iTempCnt++)
{
}
//Initialize the DP_INIT_OP_DEF structure
for(iTempCnt=0; iTempCnt < PARAMETER_MAX_SIZE; iTempCnt++)
{
INITIALIZE_ODPP_STRUCT(InitParameters[iTempCnt], DP_INIT_OP_DEF)
}
//Initialize the DP_SVC_DEF structure
//list of operands
//Set the parameter list to the Service Definition
SvcDef.pParams = &InitParameters[0];
//Set the field list to the field definition
SvcDef.pFldDef = &FldDef[0];
//Set this value to TRUE to return the aged value in the destination buffer which has to be allocated by the caller
SvcDef.bCopyToDest = TRUE;
#ifndef USE_ODPP_MBCS_CHAR_CALLS
// For wide character (Unicode) format
//Column 1
//To indicate that column name is in wide character format and USE_ODPP_MBCS_CHAR_CALLS is not defined
FldDef[0].cSubType = 'W';
//Allocate the pWC struct
FldDef[0].CN.pWC = (DPFD_WC_SS *) malloc(sizeof(DPFD_WC_SS));
if(NULL == FldDef[0].CN.pWC)
{
printf("\nFailed to allocate pWC struct of DP_FIELD_DEF\n");
goto CleanSvcDef;
}
memset(FldDef[0].CN.pWC, 0, sizeof(DPFD_WC_SS));
//Code page
FldDef[0].iDataCodePage = 0;
//DBMS type
FldDef[0].cDataDBMSType = 0;
//Store the maximum size for column name buffer
FldDef[0].iColNameBytes = (MAX_COLNAME_SIZE + 1) * sizeof(ODPP_WCHAR);
//Allocate buffer for column name in wide character (Unicode) format
FldDef[0].CN.pWC->pColName = (ODPP_WCHAR *) malloc(FldDef[0].iColNameBytes);
if(NULL == FldDef[0].CN.pWC->pColName)
{
printf("\nFailed to allocate memory for Column name\n");
goto CleanSvcDef;
}
memset(FldDef[0].CN.pWC->pColName, 0, FldDef[0].iColNameBytes);
//Set the source column name in FldDef
wcscpy(FldDef[0].CN.pWC->pColName, L"date");
//Set the data type for the source column
FldDef[0].sDatatype = ODPPDATATYPE_DATETIME_SZ;
//Set the column length to zero since it is not required for conversion for the above source data type
FldDef[0].iLength = 0;
#else
//For mixed character (SBCS/MBCS) format
//Column 1
//To indicate that column name is in mixed character (SBCS/MBCS) format and USE_ODPP_MBCS_CHAR_CALLS is defined
FldDef[0].cSubType = 'M';
//Allocate the pMC struct
FldDef[0].CN.pMC = (DPFD_MC_SS *) malloc(sizeof(DPFD_MC_SS));
if(NULL == FldDef[0].CN.pMC)
{
printf("\nFailed to allocate pMC struct of DP_FIELD_DEF\n");
return ODPPFAILURE;
}
//Clear the DPFD_MC_SS structure
memset(FldDef[0].CN.pMC, 0, sizeof(DPFD_MC_SS));
//For system default codepage
FldDef[0].iDataCodePage = -1;
//DBMS type code
FldDef[0].cDataDBMSType = RDB_NONE;
//Store the maximum size for column name buffer
FldDef[0].iColNameBytes = (MAX_COLNAME_SIZE + 1) * ODPP_MBCS_CHAR_BYTES;
//Allocate buffer for column name is in mixed character (SBCS/MBCS) format
FldDef[0].CN.pMC->pColName = (char *) malloc(FldDef[0].iColNameBytes);
if(NULL == FldDef[0].CN.pMC->pColName)
{
printf("\nFailed to allocate memory for Column name\n");
goto CleanSvcDef;
}
memset(FldDef[0].CN.pMC->pColName, 0, FldDef[0].iColNameBytes);
//Set the source column name in FldDef
strcpy(FldDef[0].CN.pMC->pColName, "Date");
//Set the data type for the source column
FldDef[0].sDatatype = ODPPDATATYPE_DATETIME_SZ;
//Set the column length to zero since it is not required for conversion for the above source data type
FldDef[0].iLength = 0;
#endif
//Set the Field count to 1 since one column is being supplied.
SvcDef.sFldCount = 1;
//Create the list of Operands
#ifndef USE_ODPP_MBCS_CHAR_CALLS
//For wide character (Unicode) format
//Parameter 1
//Parameter to specify source date format
InitParameters[0].usParameterID = ODPP_OPR_SOURCE_DATE_FORMAT;
//To indicate that current parameter will hold wide character (Unicode)string value
InitParameters[0].iValueBufBytes = PARAM_VAL_WC;
//Allocate the pWC struct DPPRM_VAL_WC_SS
InitParameters[0].PV.pWC = (DPPRM_VAL_WC_SS *) malloc(sizeof(DPPRM_VAL_WC_SS));
if(NULL == InitParameters[0].PV.pWC)
{
printf("Failed to allocate memory for pWC->DPPRM_VAL_WC_SS");
goto CleanSvcDef;
}
memset(InitParameters[0].PV.pWC, 0, sizeof(DPPRM_VAL_WC_SS));
//get the length of the format string
iLen = wcslen( SrcFormatW );
//Set the size of the parameter value buffer in bytes
InitParameters[0].iValueBufBytes = (iLen + 1) * sizeof(ODPP_WCHAR);
//Allocate memory for the format string in wide character (Unicode) format
InitParameters[0].PV.pWC->pParamVal = (ODPP_WCHAR *) malloc(InitParameters[0].iValueBufBytes);
if(NULL == InitParameters[0].PV.pWC->pParamVal)
{
printf("Failed to allocate memory for parameter value pParamVal");
goto CleanSvcDef;
}
memset(InitParameters[0].PV.pWC->pParamVal, 0, (iLen +1));
//Copy the format string
wcsncpy(InitParameters[0].PV.pWC->pParamVal, SrcFormatW, iLen);
//NULL terminate the pParmVal buffer
InitParameters[0].PV.pWC->pParamVal[iLen] = '\0';
#else
//For mixed character (MBCS/SBCS) format
//Parameter to specify source date format
InitParameters[0].usParameterID = ODPP_OPR_SOURCE_DATE_FORMAT;
//To indicate that current parameter will hold mixed character (MBCS/SBCS) string value
InitParameters[0].iValueSubType = PARAM_VAL_MC;
//Allocate the pMC struct DPPRM_VAL_MC_SS
InitParameters[0].PV.pMC = (DPPRM_VAL_MC_SS *) malloc(sizeof(DPPRM_VAL_MC_SS));
if(NULL == InitParameters[0].PV.pMC)
{
printf("Failed to allocate memory for pMC->DPPRM_VAL_MC_SS");
goto CleanSvcDef;
}
memset(InitParameters[0].PV.pMC, 0, sizeof(DPPRM_VAL_MC_SS));
//Get length of format string
iLen = (int)strlen(SrcFormat);
//Set the size of the parameter value buffer in bytes
InitParameters[0].iValueBufBytes = (iLen + 1) * ODPP_MBCS_CHAR_BYTES;
//Allocate memory for the format string in mixed character (MBCS/SBCS) format
InitParameters[0].PV.pMC->pParamVal = (char *) malloc(InitParameters[0].iValueBufBytes);
if(NULL == InitParameters[0].PV.pMC->pParamVal)
{
printf("Failed to allocate memory for parameter value pParamVal");
goto CleanSvcDef;
}
memset(InitParameters[0].PV.pMC->pParamVal, 0, (iLen+1));
//Copy format string
strncpy(InitParameters[0].PV.pMC->pParamVal, SrcFormat, iLen);
//NULL terminate the pParmVal buffer
InitParameters[0].PV.pMC->pParamVal[iLen] = '\0';
//For system default codepage
InitParameters[0].PV.pMC->iParamValCodePage = -1;
//DBMS Type code
InitParameters[0].PV.pMC->cParamValDBMSType = RDB_NONE;
#endif
//Parameter 2
//Source column index
InitParameters[1].usParameterID = ODPP_OPR_SOURCE_COLINDEX;
//To indicate that current parameter will hold numeric value.
InitParameters[1].iValueSubType = PARAM_VAL_NUM;
// index values always start with 0
InitParameters[1].PV.uiVal = 0;
//Parameter 3
//This parameter is used to specify the Method to choose during masking
InitParameters[2].usParameterID = ODPP_OPR_METHOD;
//To indicate that current parameter will hold numeric value.
InitParameters[2].iValueSubType = PARAM_VAL_NUM;
//Generates a consistently aged output
InitParameters[2].PV.uiVal = ODPP_METHOD_MASK;
//Parameter 4
//Mandatory Switch parameter
InitParameters[3].usParameterID = ODPP_OPR_SWITCH_NA;
//To indicate that current parameter will not hold any value
InitParameters[3].iValueSubType = PARAM_VAL_NONE;
//Parameter 5
//This parameter specifies the number of years for aging
InitParameters[4].usParameterID = ODPP_OPR_AGE_YEAR;
//To indicate that current parameter will hold numeric value.
InitParameters[4].iValueSubType = PARAM_VAL_NUM;
// Age date by 1 year
InitParameters[4].PV.uiVal = 1;
//Parameter 6
//This parameter specifies the number of months for aging
InitParameters[5].usParameterID = ODPP_OPR_AGE_MONTH;
//To indicate that current parameter will hold numeric value.
InitParameters[5].iValueSubType = PARAM_VAL_NUM;
// Age date by 3 months
InitParameters[5].PV.uiVal = 3;
//Parameter 7
//This parameter specifies the number of days for aging
InitParameters[6].usParameterID = ODPP_OPR_AGE_DAY;
//To indicate that current parameter will hold numeric value.
InitParameters[6].iValueSubType = PARAM_VAL_NUM;
// Age date by 45 days
InitParameters[6].PV.uiVal = 45;
SvcDef.sOprCount = 7; //Set the parameter count to 7 since seven parameters are being supplied
//Initialize the Service Provider
retVal = Provider_Init(&iSvcToken, &PrvName[0], strlen(PrvName), &SvcDef, FALSE);
if(ODPPSUCCESS != retVal)
{
printf("Provider Init Failed Err=%#x", retVal);
goto CleanSvcDef;
}


Service Provider Execution:

memset(&rowSet, 0, sizeof(DP_ROWSET_DEF)); //Clear the DP_ROWSET_DEF structure
pRow = &rowSet.pRowDefine; //Set pRow to point to the address of the first element in the list of Row Defines
piRows = &rowSet.iCount; //Set piRows to point to the address of the rowSet count
fin = fopen(&SourceFilePath[0],"r"); //Open the source CSV data file containing the date values
iCnt = 0; //Set row count to zero

Loop through each line of the source CSV file creating the field data for each row.

Loop BEGIN

Here the rowSet is created as a List of rows and not as an Array. An application can also allocate a fixed size array of DP_ROW_DEF structures, fill it with data and pass it to Provider_Service.

(*pRow) = (DP_ROW_DEF*)malloc(sizeof(DP_ROW_DEF)); //Allocate memory for the Row Define
if(NULL == (*pRow)) //Check if memory was allocated successfully
{
printf("Failed to allocate memory for the row");
goto CleanRowSet;
}
memset(*pRow, 0, sizeof(DP_ROW_DEF)); //Clear the allocated memory for the Row Define
pData = (DP_FIELD_DATA_DEF*)malloc(sizeof(DP_FIELD_DATA_DEF)); //Allocate memory for the data field
if(NULL == pData) //Check if memory was allocated successfully
{
printf("Failed to allocate memory for pData");
goto CleanRowSet;
}
memset(pData, 0, sizeof(DP_FIELD_DATA_DEF)); //Clear the allocated memory for the data field
pData->iSrcBufLen = iLen; //Copy iLen, the length of the source value read from CSV file, to pData
pData->pSrcBuf = (unsigned char*)malloc(pData->iSrcBufLen + 1); //Allocate memory for the source buffer
if(NULL == pData->pSrcBuf) //Check if memory was allocated successfully
{
printf("Failed to allocate memory for source buffer");
goto CleanRowSet;
}
memset(pData->pSrcBuf, 0, pData->iSrcBufLen + 1); //Clear the source buffer
strncpy((char*)pData->pSrcBuf, &Line[0], iLen); //Copy the source value from Line (the value read from CSV file), having length iLen, to the source buffer
pData->pDstBuf = (unsigned char*)malloc(DST_BUF_MAX_SIZE); //Allocate memory for the destination buffer since SvcDef.bCopyToDest was set to TRUE
if(NULL == pData->pDstBuf) //Check if memory was allocated successfully
{
printf("Failed to allocate memory for destination buffer");
goto CleanRowSet;
}
pData->iDstBufLen = DST_BUF_MAX_SIZE; //Set the size of the destination buffer
memset(pData->pDstBuf,0,DST_BUF_MAX_SIZE); //Clear the destination buffer
(*pRow)->pFldDataDefine = pData; //Copy the pData pointer to the Field Data Define
(*pRow)->sCount = 1; //Set the field count to one since the row consists of only one column
iCnt++; //Increment row count
pRow = &(*pRow)->pNext; //Move to the next row in the list and continue the loop to create the list of rows

Loop END

After the rowSet has been created invoke the Service Provider to mask the source data

fclose(fin); //Close the source CSV file
*piRows = iCnt; //Set the count of rows in the rowSet
sMethod = ODPP_METHOD_DEFAULT; //Set sMethod to the default
retVal = Provider_Service(iSvcToken, sMethod, NULL, &rowSet); //Invoke the Service Provider
if(ODPPSUCCESS != retVal) //Check if the Service call was successful
{
printf("Provider service failed %d", retVal);
goto CleanRowSet;
}


Service Provider Termination:

retVal = Provider_Term(iSvcToken); //Terminate the provider after all rows have been masked in Provider_Service
if(ODPPSUCCESS != retVal) //Check for successful termination of the Service Provider
{
printf("Provider Terminate failed %d", retVal);
goto CleanRowSet;
}

Free the memory that has been allocated if an error occured

//Free the memory allocated in the rowSet
CleanRowSet:
pRowSet = &rowSet; //Pointer to the rowSet
pCurRow = pRowSet->pRowDefine; //Set pCurRow to point to the first Row Define
for(i = 0; ((i < pRowSet->iCount) && (NULL != pCurRow)); i++)
{
pPrevRow = pCurRow; //pPrevRow points to the current row
pData = pCurRow->pFldDataDefine; //Set pData to point to the first Field Data Define
for(j = 0; ((j < pCurRow->sCount) && (NULL != pData)); j++)
{
pPrev = pData; //pPrev points to the current Field Data Define
if(pData->pSrcBuf != NULL)
free(pData->pSrcBuf); //Free the source buffer
if(pData->pDstBuf != NULL)
free(pData->pDstBuf); //Free the destination buffer
pData = pData->pNext; //Move to the next data field
free(pPrev); //Free the previous Field Data Define
}
pCurRow = pCurRow->pNext; //Move to the next row
free(pPrevRow); //Free the previous row
}
//Free the memory allocated in the Service Definition
CleanSVCDef:
//Clear the field definition
for(i=0; i < MAX_COLUMNS; i++)
{
#ifndef USE_ODPP_MBCS_CHAR_CALLS
if(NULL != FldDef[i].CN.pWC)
{
if(NULL != FldDef[i].CN.pWC->pColName)
{
free(FldDef[i].CN.pWC->pColName);
FldDef[i].CN.pWC->pColName = NULL;
free(FldDef[i].CN.pWC);
FldDef[i].CN.pWC = NULL;
}
}
#else
if(NULL != FldDef[i].CN.pMC)
{
if(NULL != FldDef[i].CN.pMC->pColName)
{
free(FldDef[i].CN.pMC->pColName);
FldDef[i].CN.pMC->pColName = NULL;
free(FldDef[i].CN.pMC);
FldDef[i].CN.pMC = NULL;
}
}
#endif
}
//clear the Initialization parameter definition
for(i=0; i<PARAMETER_MAX_SIZE; i++)
{
#ifndef USE_ODPP_MBCS_CHAR_CALLS
if(PARAM_VAL_WC == InitParameters[i].iValueSubType)
{
if(NULL != InitParameters[i].PV.pWC)
{
if(NULL != InitParameters[i].PV.pWC->pParamVal)
{
free(InitParameters[i].PV.pWC->pParamVal);
InitParameters[i].PV.pWC->pParamVal = NULL;
free(InitParameters[i].PV.pWC);
InitParameters[i].PV.pWC = NULL;
}
}
}
#else
if(PARAM_VAL_MC == InitParameters[i].iValueSubType)
{
if(NULL != InitParameters[i].PV.pMC)
{
if(NULL != InitParameters[i].PV.pMC->pParamVal)
{
free(InitParameters[i].PV.pMC->pParamVal);
InitParameters[i].PV.pMC->pParamVal = NULL;
free(InitParameters[i].PV.pMC);
InitParameters[i].PV.pMC = NULL;
}
}
}
#endif
}
return retVal; //Return the error code