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); }
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); }