Example - demographics_library - Latest

Demographics Library Reference for Windows and UNIX

Product type
Software
Portfolio
Locate
Product family
GeoStan Geocoding Suite
Product
GeoStan Geocoding Suite > Demographics Library
Version
Latest
ft:locale
en-US
Product name
Demographics Library
ft:title
Demographics Library Reference for Windows and UNIX
Copyright
2024
First publish date
1994
ft:lastEdition
2025-10-14
ft:lastPublication
2025-10-14T21:16:32.399000
L1_Product_Gateway
L2_Product_Segment
L3_Product_Brand
L4_Investment_Segment
L5_Product_Group
L6_Product_Name
///////////////////////////////////////////////////////////////
// Module:DemoTest.c
//
// Purpose:Simple test program to illustrate use of the demographic library interface.
//
// These coded instructions, statements, and computer programs contain unpublished trade secrets and proprietary 
// information of Precisely and are protected by Federal Copyright law and by Trade Secret law. 
// They may not be disclosed to third parties or used or copied or duplicated in any form, in whole or in part,
// without the prior written consent of Precisely.
///////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dl.h"

static long password;
static char initPaths[256], licenseFile[256];

#define FILE_HANDLES 3 // How many demographics files can be open at once
#define LINES_PER_PAGE 24 // How many lines to scroll at a time

/*
** Function: ShowError
**
** Purpose: Prints the message and detail of the last error that occured, or "No Error." if none have occured.
*/
void ShowError(DlId dl)
{
char msg[256], detail[256];
if ( DlErrorGet(dl, msg, detail) ) // DlErrorGet returns zero if there is NOT an error
 {
 printf("\nDlErrorGet:\n");
 printf("Msg: %s\n", msg);
 printf("Detail: %s\n\n", detail);
 }
else
 {
 printf("\nNo Error.\n\n");
 }
}

/*
** Function: PickHandle
**
** Purpose: DemoTest has several file handles, so that more than one .DLD file can be open at once. The exact
   number is specified by FILE_HANDLES. This function lets the user choose which of these to use.
*/

void PickHandle(int *pCurrentFile)
{
char buffer[10];
int iTemp;

printf("\nChoose a file number between 1 and %d.\n", FILE_HANDLES);

// Handles are zero based, so add one
printf("Current file handle is %d.\n", *pCurrentFile + 1);

gets(buffer);
if ( *buffer )// If user simply hits return, return to menu
 {
 iTemp = atoi(buffer) - 1;// Subtract 1 because handles are zero-based

// Make sure that the number is a valid choice
 if (iTemp >= 0 && iTemp < FILE_HANDLES)
  {
  *pCurrentFile = iTemp;
  }
 else
  {
  printf("Handle must be between 1 and %d.\n", FILE_HANDLES);
  }
 }
 printf("\n");
}

/*
** Function: Close
**
** Purpose: Close an open .DLD file.
*/

void Close(DlId dl, DlFileId *pId)
{
 if (!(*pId))// File Id's are kept equal to zero, if not open in this program.
  {
  printf("\nNo file open.\n");
  }
 else
  {
  if (!DlFileClose(*pId))// DlFileClose returns zero if it failed
   {
   printf("\nError closing file.\n");
   ShowError(dl);
   }
  else
   {
   *pId = 0;// If a file id is zero we know it is NOT open.
   printf("\nClosed.\n");
   }
  }
 printf("\n");
}

/*
** Function: Open
**
** Purpose: Open a .DLD file. If a file is currently open, it is closed.
*/

void Open(DlId dl, DlFileId *pId)
{
 char buffer[256];

 if (*pId)// First make sure no file is open
  {
  if (!DlFileClose(*pId))// If it is, then close it
   {
   printf("\nError closing file.\n");
   ShowError(dl);
   return;
   }
  }
  printf("\nEnter the path and filename of the demographics file.\n");
  gets(buffer);
  if (*buffer)// If the user simply hits return, return to menu.
   {
   *pId = DlFileOpen(dl, buffer);
   if (!(*pId))// DlFileOpen returns zero if it failed
    {
    printf("Unable to open specified file.\n");
    ShowError(dl);
    }
  }
 printf("\n");
}

/*
** Function: ShowFileAttributes
**
** Purpose: Shows attributes about the currently open file.
** These are returned from DlFileGetAttribute, and are such things as the number of fields, the key type, 
** the key field name, etc.
*/
void ShowFileAttributes(DlFileId id)
{
 char buffer[256];
 intl lRetVal, lNumFields;

 if (!id)// First make sure a .DLD file is open          
  {
  printf("\nNo file open.\n");
  }
 else
  {
  printf("\nFILE ATTRIBUTES:\n");

// Retrieve the key field name - the key field is the one you search by
  DlFileGetAttribute(id, DlKeyFieldName, buffer, sizeof(buffer));
  printf("Name of key field: %s\n", buffer);

// Retrieve the type of value the key field is
  lRetVal = DlFileGetAttribute(id, DlKeyType, buffer, sizeof(buffer));
  printf("Numeric type of key: ");
// To check if a value (bit) is set in lRetVal, the binary & operator is used.
  if (lRetVal & DL_TYPE_ZIP)
   printf("ZIP Code\n");
  else if (lRetVal & DL_TYPE_ZIP4)
   printf("ZIP+4 Code\n");
  else if (lRetVal & DL_TYPE_CTY)
   printf("County\n");
  else if (lRetVal & DL_TYPE_CT)
   printf("Census tract\n");
  else if (lRetVal & DL_TYPE_BG)
   printf("Block group\n");
  else if (lRetVal & DL_TYPE_BLK)
   printf("Block\n");

// Retrieve the number of fields in the file.
  lRetVal = DlFileGetAttribute(id, DlNumFields, buffer, sizeof(buffer));
  lNumFields = DlFileNumFields(id);
  if (lRetVal == lNumFields) // Quick test to verify both functions return the same value
   printf("Number of fields: %d\n", lRetVal);
  else
   {
   printf("\nERROR\n");
   printf("DlFileGetAttribute returned %d fields in file.\n", lRetVal);
   printf("DlFileNumFields returned %d fields in file.\n\n", lNumFields);
   }

// Retrieve the maximum number of values per field
  lRetVal = DlFileGetAttribute(id, DlNumValues, buffer, sizeof(buffer));
  printf("Max Values per field: %d\n", lRetVal);

// Retrieve the key limit - if it is 1, then the key is limited to alphanumeric characters.
  DlFileGetAttribute(id, DlKeyLimit, buffer, sizeof(buffer));
  printf("Limited to alphanumeric?: %s\n", ( (lRetVal == 1)? "TRUE": "FALSE") );

// Retrieve a description of the file.
  DlFileGetAttribute(id, DlFileDescription, buffer, sizeof(buffer));
  printf("Description of file: %s\n", buffer);
  }
 printf("\n");
}

/*
** Function: Search
**
** Purpose: To search the current .DLD file for a key, specified by the user. Remember that the key field 
** type can be displayed from Attributes in the file menu (ShowFileAttributes).
*/
void Search(DlFileId id)
{
 char buffer[256];

 printf("\nEnter the key you wish to search for.\n");
 gets(buffer);

 if ( DlFileSearch(id, buffer) )// DlFileSearch returns a non- zero value for success.
  {
  printf("Found\n");
  }
 else
  {
  printf("Not Found\n");
  }
 printf("\n");
}
               ​
/*
** Function: ListFields
**
** Purpose: This function determines how many fields there are, and then loops through all of them, outputting 
** their names.
*/
void ListFields(DlId dl, DlFileId idFile)
{
 intl lNumFields, lCount;
// Number of fields in the file, and a counter for the loop ID that will be used to retrieve DlFieldId idField;
// each field name
 char buffer[256];
//Here we get the number of fields
 lNumFields = DlFileNumFields(idFile);
 if (lNumFields < 1)
  {
//Error if the return was invalid
  printf("\nDlFileNumFields returned less than 1.\n");
  ShowError(dl);
  }
 else
  {
  printf("\n");
      ​
// Now loop through all the fields (zero based)
 for (lCount = 0; lCount < lNumFields; lCount++)
  {
// Set idField to the current field number
  idField = DlFieldGetN(idFile, lCount);
             ​
// Make sure it was set, print an error if not
  if (!idField)
   {
   printf("DlFieldGetN failed to retrieve field number %d.\n", lCount);
   ShowError(dl);
   break;
   }
// Get the field name and print it
   DlFieldGetAttribute(idField, DlName, buffer,
   sizeof(buffer));
   printf("%d: %s\n", lCount, buffer);
               ​
// If LINES_PER_PAGE lines have been printed
   if (!((lCount + 1) % LINES_PER_PAGE))
    { // Pause until return is pressed so the user can read what was output.
    printf("<more>");
    gets(buffer);
    }
   }
  }
 printf("\n");
}
               ​
/*
** Function: ChooseField
**
** Purpose: To retrieve data, a successful file search on a key value must have been done, and a field 
** must be specified. This function specifies the field by name or number.
*/
void ChooseField(DlFileId idFile, DlFieldId *idField)
{
 intl lFieldNum; // Used when a user chooses by number
 intl lNumFields; // Used to show a user the valid range when choosing by number
 char choice[10]; // Choice - to choose by name or number
 char buffer[256]; // Used when a user chooses by name

 printf("\nChoose by number? (Y or N for name): ");
 gets(choice);
               ​
 if (*choice)// If the user simply hit return, return to menu.
  {
  if (*choice == 'Y' || *choice== 'y')// Check for upper & lower case...
   {
   lNumFields = DlFileNumFields(idFile);

   printf("Enter the field number (between 0 and %d): ", lNumFields - 1);
   gets(buffer);
   lFieldNum = atol(buffer);//Convert to a number
               ​
// DlFieldGetN retrieves a field by number
   *idField = DlFieldGetN(idFile, lFieldNum);
   }
  else if (*choice == 'N' || *choice== 'n')// Check for upper & lower case.
   {
   printf("Enter the field name: ");
   gets(buffer);
   *idField = DlFieldGet(idFile, buffer);// DlFieldGet retrieves a field name.
   }
  else
   printf("Invalid entry.\n");
               ​
  if (!*idField)// Check to see if the field was found
   {
   printf("Field not found.\n");
   }
  }
 printf("\n");
}
               ​
/*
** Function: ShowFieldAttributes
**
** Purpose: Shows attribute information on the currently selected field. Some of these include 
** field name, width, type (character or numeric),etc.
*/
void ShowFieldAttributes(DlFieldId idField)
{
 char buffer[256];
 intl lRetVal;
               ​
// Make sure there is a field selected
 if (!idField)
  {
  printf("\nNo field specified.\n");
  }
 else
  {
  printf("\nFIELD ATTRIBUTES:\n");
// Retrieve the name
  DlFieldGetAttribute(idField, DlName, buffer, sizeof(buffer));
  printf("Field Name: %s\n", buffer);
               ​
// Retrieve the name as seen in the .DLD file
  DlFieldGetAttribute(idField, DlFieldname, buffer, sizeof(buffer));
  printf("Name in .DLD file: %s\n", buffer);
               ​
// Retrieve the field width. Notice that numeric values are retrieved by return value, rather than through buffer
  lRetVal = DlFieldGetAttribute(idField, DlWidth, buffer, sizeof(buffer));
  printf("Field Width: %d\n", lRetVal);
               ​
// Retrieve the field type.
  lRetVal = DlFieldGetAttribute(idField, DlType, buffer, sizeof(buffer));
  if (lRetVal == 'C')
   {
   printf("Field Type: Character\n");
   }
  else if (lRetVal == 'N')
   {
   printf("Field Type: Numeric\n");
               ​
// If the field is numeric, then retrieve the number of decimal places. All numbers come back without 
// decimals, and this value can be used to display them correctly
   lRetVal = DlFieldGetAttribute(idField, DlDecimals, buffer, sizeof(buffer));
   printf("Decimal Places: %d\n", lRetVal);
   }
               ​
// Retrieve the number of possible unique values for this field
// This value is used with DlFieldGetValueAttribute
  lRetVal = DlFieldGetAttribute(idField, DlNumvalues,
  buffer, sizeof(buffer));
  printf("Number of possible values: %d\n", lRetVal);
               ​
// Retrieve a short description of the field
  DlFieldGetAttribute(idField, DlDescription, buffer, sizeof(buffer));
  printf("Short Description of file: %s\n", buffer);
               ​
// Retrieve a long description of the field
  DlFieldGetAttribute(idField, DlHelp, buffer, sizeof(buffer));
  printf("Long Description of file: %s\n", buffer);
  }
 printf("\n");
}
               ​
/*
** Function: ShowFieldValueAttributes
**
** Purpose: Show attributes for unique values in current field. The number of unique values is retrieved by 
** DlFieldGetAttribue, and the attributes for these values are retrieved by DlFieldGetValueAttribute.
*/
void ShowFieldValueAttributes(DlFieldId idField)
{
 intl lNumValues, lCount;
// Number of unique values in field, and a counter for the loop.
 char buffer[256];
               ​
 if (!idField)// Make sure a field is selected
  {
  printf("\nNo field specified.\n");
  }
  else
  {
  printf("\n");
               ​
// First get the number of unique values
  lNumValues = DlFieldGetAttribute(idField, DlNumvalues,
  buffer, sizeof(buffer));
               ​
// If it returns zero, there are no unique values, and thus no descriptions
  if(!lNumValues)
   {
   printf("No value descriptions for this field.\n");
   }
               ​
// DlFieldGetValueAttribute accepts a number which serves as an index to retrieve a description. 
// Remember that this index is zero based.
  for (lCount = 0; lCount < lNumValues; lCount++)
   {             ​
// Retrieve the unique value, notify user if unsuccessful
    if ( DlFieldGetValueAttribute(idField, lCount, DlKey, buffer, sizeof(buffer)) )
     printf("DlKey: %s\n", buffer);
    else
     printf("DlKey: <valnum %d unsuccessful>\n", lCount);
               ​
// Retrieve the short description for this unique value
    if ( DlFieldGetValueAttribute(idField, lCount, DlValDescription, buffer, sizeof(buffer)) )
     printf(" DlValDescription: %s\n", buffer);
    else
     printf(" DlValDescription: <unsuccessful>\n");
               ​
// Retrieve the long description for this unique value
    if ( DlFieldGetValueAttribute(idField, lCount, DlValHelp, buffer, sizeof(buffer)) )
     printf(" DlValHelp: %s\n", buffer);
    else
     printf(" DlValHelp: <unsuccessful>\n");
               ​
// We'll assume that each value is 4 lines, just to make sure nothing scrolls off the top of the screen 
// before the user can read it. Waits for return to be pressed to continue.
   if (!( ((lCount + 1) * 4 ) % LINES_PER_PAGE))
    {
    printf("<more>");
    gets(buffer);
    }
   }
  }
 printf("\n");
}
               ​
/*
** Function: PrintData
**
** Purpose: To output the data specified after a successful search has been completed, and a file 
** has been successfully specified. This checks if a field is specified, but whether a search has been 
** completed is tracked internally by DemoLib.
*/
               ​
void PrintData(DlId dl, DlFieldId idField)
{
 char buffer[256];
 intl lRetVal;
// Make sure a field is selected
 if (!idField)
  {
  printf("\nNo field specified.\n");
  }
  else
  {
  printf("\n");
               ​
// First determine what type of value will be retrieved, by using DlFieldGetAttribute
  lRetVal = DlFieldGetAttribute(idField, DlType, buffer, sizeof(buffer));
               ​
// If it's a character, then the value will be retrieved from DlFieldGetString
  if (lRetVal == 'C')
   {
   printf("Value is character; results will be shown from DlFieldGetString.\n");
               ​
// DlFieldGetString returns zero if it failed.
   if (!(DlFieldGetString(idField, "DlFieldGetString printf string: %s\n", buffer, sizeof(buffer))) )
    {
    printf("No data returned from DlFieldGetString.\n");
    ShowError(dl);
    }
  printf(buffer);
  }
               ​
// If it's numeric, the value will be retrieved from DlFieldGetString and DlFieldGetNum.
  else if (lRetVal == 'N')
   {
   printf("Value is numeric; results will be shown from DlFieldGetString and DlFieldGetNum.\n");
   printf("Decimal places are not shown.\n");
               ​
   lRetVal = DlFieldGetNum(idField);
   printf("DlFieldGetNum value: %d\n", lRetVal);
               ​
// DlFieldGetString returns zero if it failed
   if (!(DlFieldGetString(idField, "DlFieldGetString
   printf string: %d\n", buffer, sizeof(buffer))) )
    {
    printf("No data returned from DlFieldGetString.\n");
    ShowError(dl);
    }
    printf(buffer);
   }
               ​
// The short description (SDESC) and long description (LDESC) are always retrieved
   if (!(DlFieldGetString(idField, "SDESC", buffer, sizeof(buffer))) )
    {
    printf("No short description returned from DlFieldGetString.\n");
    }
   else
    {
    printf("DlFieldGetString SDESC: %s\n", buffer);
    }
               ​
   if (!(DlFieldGetString(idField, "LDESC", buffer, sizeof(buffer))) )
    {
    printf("No long description returned from DlFieldGetString.\n");
    }
   else
    {
    printf("DlFieldGetString LDESC: %s\n", buffer);
    }
  }
 printf("\n");
}
               ​
/*
** Function: ReadIniFile
**
** Purpose: Reads in a file name "demotest.ini" in the working directory,which contains the license file name, 
** password, and the path for DlInit, so the user doesn't have to enter it every time they run the program.
*/
void ReadIniFile()
{
 char pass[10];
 char * p;
 FILE * setup = fopen( "demotest.ini", "rt" );
 if ( setup )
  {
  fgets( licenseFile, sizeof(licenseFile), setup );
  p = strchr( licenseFile, '\n' );
  if ( p ) *p = 0;
               ​
  fgets( pass, sizeof(pass), setup );
  p = strchr( pass, '\n' );
  if ( p ) *p = 0;
  password = atol(pass);
               ​
// If this entry is not in the file, initPaths will simply be empty ("") which is what we want
  fgets( initPaths, sizeof(initPaths), setup );
  p = strchr( initPaths, '\n' );
  if ( p ) *p = 0;
               ​
  fclose( setup );
  }
 else
  {
// If there is no ini file, and no command line parameters, just make everything empty, strings or zero.
  *licenseFile = 0;
  password = 0;
  *initPaths = 0;
  }
}
               ​
/*
** Function: FieldMenu
**
** Purpose: This is the second menu that is presented after a file has successfully been opened.
*/
void FieldMenu(DlId dl, DlFileId idFile)
 {
 int iDone;
 DlFieldId idField;
               ​
 if (idFile)
  {
  idField = 0;
  for (iDone = 0 ; !iDone ; )
   {
   char choice[10];
   printf( "Search File, List Fields, Choose Field, Attributes, Value Attributes,\n" "Print Data, 
   Error, File Menu (S/L/C/A/V/P/E/F):" );
   gets( choice );
   switch (*choice)
    {
    case 'S':
    case 's':
     Search(idFile);
     break;
    case 'L':
    case 'l':
     ListFields(dl, idFile);
     break;
    case 'C':
    case 'c':
// This accepts a pointer to a DlFieldId, so it can change its value
     ChooseField(idFile, &idField);
     break;
    case 'A':
    case 'a':
     ShowFieldAttributes(idField);
     break;
    case 'V':
    case 'v':
     ShowFieldValueAttributes(idField);
     break;
    case 'P':
    case 'p':
     PrintData(dl, idField);
     break;
    case 'E':
    case 'e':
     ShowError(dl);
     break;
    case 'F':
    case 'f':
     iDone = 1;
     break;
    default:
// If the user enters an invalid choice, request a valid one
               ​
   printf( "Please enter S, L, C, A, V, P, E, or F.\n" );
   }
  }
 }
 else
  {
   printf("\nNo file open.\n\n");
  }
}
               ​
/*
** Function: main
**
** Purpose: This gets all initilization data, either from the user or from the ini file, and 
** initialized the demographics library.
*/
void main( int argc, char ** argv )
 {
 DlId dl;// Handle to demographics library
 DlFileId dlFiles[FILE_HANDLES];// Array of demographics file handles
 int iCurrentFile;// Current index into handle array
 int iCount, iDone;// Counter for loop, and value to check if loop is done
 char pass[16]; // Password from user
               ​
 printf( "Starting...\n" );
               ​
// If user didn't enter at least a license file and password, read the ini file
 if ( argc < 3 )
  {
  ReadIniFile();
  if ( password == 0 )// There was no ini file, so get info from user
   {
   printf("Enter license file path and name: ");
   gets( licenseFile );
   if ( *licenseFile )
    {
    printf("Enter the 8 digit password: ");
    password = atol(pass);
    printf("Enter the search path for DlInit: ");
    gets(initPaths);
    }
   }
  }
               ​
// Otherwise the user did enter license file and password
 else
  {
  strcpy( licenseFile, argv[1] );
  password= atol(argv[2]);
               ​
// If there are more arguments, then take it as the search path for DlInit
  if (argc > 3)
   strcpy( initPaths, argv[3]);
  else
   *initPaths = 0;
  }
               ​
// Initialize demographics library
 dl = DlInit(initPaths);
               ​
// And check to make sure it was successful
 if ( !dl )
  {
  printf( "Unable to initialize demographics library.\n" );
  }
 else
  {
  #if defined( _WINDOWS )
  _wsetexit( _WINEXITNOPERSIST );
  #endif
               ​
// Set the license file and password. This is not needed to use Census90.dld
  if ( !(DlSetLicense(dl, licenseFile, password)) )
   printf("License file could not be opened.\nOnly\CENSUS90.DLD will be accessible.\n");
               ​
// Set all file handles to zero to indicate no file is open
  for (iCount = 0; iCount < FILE_HANDLES; iCount++)
   {
   dlFiles[iCount] = 0;
   }
// The current file handle (in the array) is the first one (zero)
   iCurrentFile = 0;
               ​
// Loop until user chooses to quit, at which point iDone will be set to zero
   for (iDone = 0 ; !iDone ; )
    {
    char choice[10];
    printf( "Pick Handle, Open, Close, Attributes, Field Menu, Error, Quit(P/O/C/A/F/E/Q): " );
    gets( choice );
    switch (*choice)
     {
     case 'P':
     case 'p':
               ​
// Accepts a pointer so it can alter the value
      PickHandle(&iCurrentFile);
      break;
     case 'O':
     case 'o':
               ​
// Sending a pointer to the file handle specified by iCurrentFile
      Open(dl, &(dlFiles[iCurrentFile]));
      break;
     case 'C':
     case 'c':
               ​
// Sending a pointer to the file handle specified by iCurrentFile
      Close(dl, &(dlFiles[iCurrentFile]));
      break;
     case 'A':
     case 'a':
      ShowFileAttributes(dlFiles[iCurrentFile]);
      break;
     case 'F':
     case 'f':
      FieldMenu(dl, dlFiles[iCurrentFile]);
      break;
     case 'E':
     case 'e':
      ShowError(dl);
      break;
     case 'Q':
     case 'q':
      iDone = 1;
      break;
     default:

// If the user enters an invalid choice, request a valid one.
      printf( "Please enter P, O, C, A, F, E, or Q.\n" );
     }
    }
   }

// Close all file handles
   printf("\nClosing files...\n");
   for (iCount = 0; iCount < FILE_HANDLES; iCount++)
    {
    printf("Handle %d:", iCount + 1);
    Close(dl, &(dlFiles[iCount]));
    }

// Free all memory and resources allocated by DlInit
 DlTerm( dl );
}