STATUS PrintSummary (char *pSummary)
{
    char       *pSummaryPos;        /* current position in pSummary */
    ITEM_TABLE  ItemTable;          /* header at start of pSummary */
    USHORT      ItemCount;          /* number of items in pSummary */
    USHORT      NameLength;         /* length of item name w/out terminator*/
    USHORT      ValueLength;        /* length of item value, incl. type */
    WORD        DataType;           /* item data type word */
    char       *szDataType;         /* printable data type name */
    USHORT      TextLen;            /* length of printable item text */
    NUMBER      NumericItem;        /* an item of type TYPE_NUMBER */
    NUMBER_PAIR NumberPair;         /* part of item of TYPE_NUMBER_RANGE */
    RANGE       Range;              /* part of item of TYPE_NUMBER_RANGE */
    TIMEDATE    TimeItem;           /* a time/date item */
    TIMEDATE_PAIR   TimePairItem;   /* part of time/date list or range */
    WORD        TimeStringLen;      /* length of ASCII time/date */
    STATUS      error;              /* return code from API calls */
    USHORT      i;                  /* counter for loop over items */
    USHORT      j;                  /* " " " " multi-valued items */
    char        Text[] = "TYPE_TEXT";
    char        Text_List[] = "TYPE_TEXT_LIST";
    char        Number[] = "TYPE_NUMBER";
    char        Number_Range[] = "TYPE_NUMBER_RANGE";
    char        Time[] = "TYPE_TIME";
    char        Time_Range[] = "TYPE_TIME_RANGE";
    char        Unrecognized[] = "Unrecognized";

   /* Initialize pSummaryPos to the position of the beginning of
      the summary buffer. Keep pSummary unmodified. Modify pSummaryPos.
    */

    pSummaryPos = pSummary;

   /* Copy the ITEM_TABLE header at the beginning of the summary buffer
      to a local variable. Advance pSummaryPos to point to the next
      byte in the summary buffer after the ITEM_TABLE.
    */
    memcpy ((char*)(&ItemTable), pSummaryPos, sizeof(ITEM_TABLE));
    pSummaryPos += sizeof(ItemTable);

   /* pSummaryPos now points to the first ITEM in an array of ITEM
      structures. Copy this array of ITEM structures into the global
      Items[] array.
    */

    ItemCount = ItemTable.Items;

    for (i=0; i < ItemCount; i++)
    {
        memcpy((char*)(&Items[i]), pSummaryPos, sizeof(ITEM));
        pSummaryPos += sizeof(ITEM);
    }

   /* pSummaryPos now points to the first item name. Loop over each
      item, copying the item name into the ItemName variable and
      converting the item value to printable text in ItemText.
    */

    for (i=0; i < ItemCount; i++)
    {
       /* zero out two global arrays that we re-use for each item */
        memset (ItemText, 0, MAX_ITEM_LEN);
        memset (ItemName, 0, MAX_ITEM_NAME_LEN);

        NameLength = Items[i].NameLength;
        memcpy (ItemName, pSummaryPos, NameLength);
        ItemName[NameLength] = '\0';
        pSummaryPos += NameLength;

        /*  Handle the case of a zero length item  */

        if (Items[i].ValueLength == 0)
        {
            strcpy(ItemName, "  *  ");
            ItemText[0] = '\0';
            goto PrintItem;
        }

        /* pSummaryPos now points to the item value. First get the
           data type. Then step over the data type word to the data
           value and convert the value to printable text. Store the
           text in ItemText.
        */

        memcpy ((char*)(&DataType), pSummaryPos, sizeof(WORD));
        pSummaryPos += sizeof(WORD);

        ValueLength = Items[i].ValueLength - sizeof(WORD);

        /* The way to extract an item depends on the data type. */

        switch (DataType)
        {
            case TYPE_TEXT:
                szDataType = Text;
                memcpy (ItemText, pSummaryPos, ValueLength);
                ItemText[ValueLength] = '\0';
                pSummaryPos += ValueLength;
                break;

            case TYPE_TEXT_LIST:
                szDataType = Text_List;
                if (error = ExtractTextList (pSummaryPos, ItemText))
                {
                    printf ("Error: unable to extract text list.\n");
                    ItemText[0] = '\0';
                }
                pSummaryPos += ValueLength;
                break;

            case TYPE_NUMBER:
                szDataType = Number;
                memcpy ((char *)(&NumericItem), pSummaryPos, sizeof(NUMBER));
                  sprintf (ItemText, "%f", NumericItem);
                pSummaryPos += sizeof(NUMBER);
                break;

            case TYPE_NUMBER_RANGE:
                szDataType = Number_Range;
                TextLen = 0;
                memcpy ((char*)(&Range), pSummaryPos, sizeof(RANGE));
                pSummaryPos += sizeof(RANGE);
                for (j=0; j < Range.ListEntries; j++)
                {
                    memcpy ((char*)(&NumericItem), pSummaryPos,
                            sizeof(NUMBER));
                    sprintf (ItemText+TextLen, "%f ", NumericItem);
                    pSummaryPos += sizeof(NUMBER);
                    TextLen = strlen(ItemText);
                }
                if ((Range.ListEntries != 0) && (Range.RangeEntries != 0))
                {
                    memcpy (ItemText+TextLen, "; ", 2);
                    TextLen += 2;
                }
                for (j=0; j < Range.RangeEntries; j++)
                {
                    memcpy ((char*)(&NumberPair), pSummaryPos,
                            sizeof(NUMBER_PAIR));
                    sprintf (ItemText+TextLen, "%f - %f ", NumberPair.Lower,
                             NumberPair.Upper);
                    pSummaryPos += sizeof(NUMBER_PAIR);
                    TextLen = strlen(ItemText);
                }
                break;

#ifndef APITESTMODE

            case TYPE_TIME:
                szDataType = Time;
                memcpy ((char*)(&TimeItem), pSummaryPos, sizeof(TIMEDATE));
                pSummaryPos += sizeof(TIMEDATE);
                if (error = ConvertTIMEDATEToText (
                            NULL, NULL, &TimeItem,
                            ItemText, MAXALPHATIMEDATE,
                            &TimeStringLen))
                {
                    printf ("Error: unable to convert TIMEDATE to text.\n");
                    TimeStringLen = 0;
                }
                ItemText[TimeStringLen] = '\0';
                break;

            case TYPE_TIME_RANGE:
                szDataType = Time_Range;
                TextLen = 0;
                memcpy ((char*)(&Range), pSummaryPos, sizeof(RANGE));
                pSummaryPos += sizeof(RANGE);
                for (j=0; j < Range.ListEntries; j++)
                {
                    if (j != 0)
                    {
                        memcpy (ItemText+TextLen, ",", 1);
                        TextLen++;
                    }
                    memcpy ((char*)(&TimeItem), pSummaryPos,
                            sizeof(TIMEDATE));
                    pSummaryPos += sizeof(TIMEDATE);
                    if (error = ConvertTIMEDATEToText (
                                NULL, NULL,
                                &TimeItem,
                                ItemText+TextLen,
                                MAXALPHATIMEDATE, &TimeStringLen))
                    {
                        printf("Error: unable to convert TIMEDATE to text.\n");
                        TimeStringLen = 0;
                    }
                    TextLen += TimeStringLen;
                }

                if (Range.RangeEntries == 0)
                {
                    ItemText[TextLen] = '\0';
                    break;
                }

               /* Append a space, semicolon, space to separate time/dates
                  from time/date ranges.
                */

                memcpy (ItemText+TextLen, " ; ", 3);
                TextLen += 3;

                for (j=0; j < Range.RangeEntries; j++)

                {
                    if (j != 0)
                    {
                        memcpy (ItemText+TextLen, ",", 1);
                        TextLen++;
                    }
                    memcpy ((char*)&TimePairItem, pSummaryPos,
                            sizeof(TIMEDATE_PAIR));
                    pSummaryPos += sizeof(TIMEDATE_PAIR);
                    if (error = ConvertTIMEDATEToText (
                                NULL, NULL,
                                &TimePairItem.Lower, ItemText+TextLen,
                                MAXALPHATIMEDATE, &TimeStringLen))
                    {
                        printf("Error: unable to convert TIMEDATE to text.\n");
                        TimeStringLen = 0;
                    }
                    TextLen += TimeStringLen;
                    memcpy (ItemText+TextLen, "-", 1);
                    TextLen++;
                    if (error = ConvertTIMEDATEToText (
                                NULL, NULL,
                                &TimePairItem.Upper, ItemText+TextLen,
                                MAXALPHATIMEDATE, &TimeStringLen))
                    {
                        printf("Error: unable to convert TIMEDATE to text.\n");
                        TimeStringLen = 0;
                    }
                    TextLen += TimeStringLen;
                }
                ItemText[TextLen] = '\0'; /* zero terminate the text */
                break;

#endif
            /* Item is not one of the data types this program handles. */

            default:
                szDataType = Unrecognized;
                ItemText[0] = '\0';
                pSummaryPos += ValueLength;
                break;
        } /* end of switch on data type */

PrintItem:
        /* Print the item name, data type, and value. */
        printf ("\tItem Name = %s\n", ItemName);
        printf ("\tData Type = %s\n", szDataType);

#ifndef APITESTMODE
        printf ("\tItem Value = \"%s\"\n\n", ItemText);
#else
        if (strcmp(ItemName,"$UpdatedBy")==0)
          printf ("\tItem Value =\n\n", ItemText);
        else
          printf ("\tItem Value = \"%s\"\n\n", ItemText);
#endif

    }/* End of loop over items in the summary. */

    /* Print final line feed to end display for this note. */

    printf ("\n");

    return (NOERROR);
}
Example #2
0
STATUS LNPUBLIC print_file_summary_list (ITEM_TABLE *summary, void* szReturn)
{
	#define     MAX_ITEMS           30
	#define     MAX_TEXT_LEN        1000
	#define     DATATYPE_SIZE       sizeof(USHORT)
	#define     NAME_LENGTH_SIZE    sizeof(USHORT)
	#define     ITEM_LENGTH_SIZE    sizeof(USHORT)	
	#define     NUMERIC_SIZE        sizeof(FLOAT)
	#define     TIME_SIZE           ODSLength(_TIMEDATE)

	/* Local variables */
    BYTE       *summary_position;       /* current position in summary */
    ITEM_TABLE item_table;              /* header at start of summary */
    USHORT     item_count;              /* number of items in summary */
    USHORT     name_length[MAX_ITEMS];  /* length of each item name */
    USHORT     item_length[MAX_ITEMS];  /* length of each item */
    char       item_name[MAX_TEXT_LEN]; /* name of a summary item */
    USHORT     datatype;                /* type of item */
    char       item_text[MAX_TEXT_LEN]; /* text of a summary item */
    FLOAT      numeric_item;            /* a numeric item */
    TIMEDATE   time_item;               /* a time/date item */
    WORD       time_string_len;         /* length of ASCII time/date */
    STATUS     error;                   /* return code from API calls */
    USHORT     i;                       /* a counter */

    CStringList* lstText;
    lstText = (CStringList*)szReturn;

	/* Print a blank line to start this display. */
    printf ("\n");

	/* Get the header at the beginning of the summary buffer. */
    item_table = *summary;

	/* Keep track of where we are in the buffer. */
    summary_position = (BYTE *) summary;

	/* Get the number of items in the summary. */
    item_count = item_table.Items;

	/* Check boundary of the array */
	if (item_count > MAX_ITEMS)
	{
		printf("ERROR: Number of items has exceeded boundary of defined array.\n");
		return (0);
	}

	/* Advance the buffer pointer over the header. */
    summary_position += ODSLength(_ITEM_TABLE);

	/* Get the length of each item in the summary. */
    for (i=0; i < item_count; i++)
    {
        memcpy (&name_length[i], summary_position, NAME_LENGTH_SIZE);
        summary_position += NAME_LENGTH_SIZE;
        memcpy (&item_length[i], summary_position, ITEM_LENGTH_SIZE);
        summary_position += ITEM_LENGTH_SIZE;
    }

	/* Start a loop that extracts each item in the summary. */
    bool bNeedAdd = false;
    for (i=0; i < item_count; i++)
    {
		/* Print the name of the item. */
        memcpy (item_name, summary_position, name_length[i]);
        item_name[name_length[i]] = '\0';
        summary_position += name_length[i];

        printf ("%s:  ", item_name);
        if (0 == strcmp(item_name, "$TITLE"))
        {
            bNeedAdd = true;
        }

		/* Get the data type of this item. */
        memcpy (&datatype, summary_position, DATATYPE_SIZE);
        summary_position += DATATYPE_SIZE;

		/* Extract the item from the summary and put it in readable
		form. The way in which we extract the item depends on its type.
		This program handles TEXT, NUMBER, and TIME. */
        switch (datatype)
        {
			/* Extract a text item from the summary. */
			case TYPE_TEXT:
				memcpy (item_text, summary_position, item_length[i] - DATATYPE_SIZE);
				item_text[item_length[i] - DATATYPE_SIZE] = '\0';
				if (bNeedAdd)
				{
					lstText->AddTail(item_text);
					bNeedAdd = false;
				}
            break;

			/* Extract a number item from the summary. */
			case TYPE_NUMBER:
				memcpy (&numeric_item, summary_position, NUMERIC_SIZE);
				sprintf (item_text, "%g", numeric_item);
            break;

			/* Extract a time/date item from the summary. */
	        case TYPE_TIME:
	            memcpy (&time_item, summary_position, TIME_SIZE);
	            if (error = ConvertTIMEDATEToText (NULL,
                                               NULL,
                                               &time_item,
                                               item_text,
                                               MAXALPHATIMEDATE,
                                               &time_string_len))
				return (ERR(error));
	            item_text[time_string_len] = '\0';
            break;

			case TYPE_TEXT_LIST:
			{
				LIST      *pList;
				WORD      list_entry;
				char      *Buffer;
				WORD      text_size;

				memset (item_text,'\0', item_length[i] - DATATYPE_SIZE + 1);
				pList = (LIST *)summary_position;
				for (list_entry = 0; list_entry < pList->ListEntries; list_entry++)
				{
					ListGetText(pList, FALSE, list_entry, &Buffer, &text_size);
					strncat (item_text, Buffer, text_size);
				}
			}
			break;

			/* If the summary item is not one of the data types this program handles. */
			default:
            strcpy (item_text, "(Data type not handled)");
            break;
        }

		/* Print the item. */
        printf ("%s\n", item_text);

		/* Advance to next item in the summary. */
        summary_position += (item_length[i] - DATATYPE_SIZE);

		/* End of loop that is extracting each item in the summary. */
	}

	/* End of function */
    return (NOERROR);
}