SAMV71 Xplained Ultra Software Package 1.5

strings.c

00001 /*++
00002 
00003 Copyright (c) Microsoft 1998, All Rights Reserved
00004 
00005 Module Name:
00006 
00007     strings.c
00008 
00009 Abstract:
00010 
00011     This module contains code for converting data buffers and integer values
00012     to and from string representation for display.
00013 
00014 Environment:
00015 
00016     User mode
00017 
00018 Revision History:
00019 
00020     May-98 : Created 
00021 
00022 --*/
00023 
00024 #include <windows.h>
00025 #include <stdlib.h>
00026 #include <limits.h>
00027 #include <math.h>
00028 #include "strings.h"
00029 
00030 #define ROUND_UP_ON_DIVIDE(d, n)    (0 == ((d) % (n)) ? ((d)/(n)) : ((d)/(n))+1)
00031 
00032 VOID
00033 Strings_CreateDataBufferString(
00034     IN  PCHAR    DataBuffer,
00035     IN  ULONG    DataBufferLength,
00036     IN  ULONG    NumBytesToDisplay,
00037     IN  ULONG    DisplayBlockSize,
00038     OUT PCHAR    *BufferString
00039 )
00040 /*++
00041 Routine Description:
00042     This routine takes a DataBuffer of size DataBufferLength and creates a string
00043     in BufferString that contains a string representation of the bytes stored in
00044     data buffer.  
00045 
00046     The parameter NumBytesToDisplay tells the routine the maximum number of bytes
00047     from the buffer to display.  For instance, a caller may only want to convert
00048     the first four bytes of an eight byte buffer to a string
00049 
00050     The parameter DisplayBlockSize indicates how many bytes should be grouped 
00051     together in the display.  Valid values are 1, 2, 4 and would indicate whether
00052     the displayed bytes should be displayed as bytes, words, or dwords.
00053 
00054     The routine allocates a buffer big enough to store the data.  Callers of this
00055     routine are responsible for freeing this string buffer.  
00056 --*/
00057 {
00058     ULONG   BufferStringLength;
00059     ULONG   MaxDisplayedBytes;
00060     PUCHAR  NextByte;
00061     PUCHAR  String;
00062     PUCHAR  CurrentBufferOffset;
00063     INT     nFullIterations;
00064     INT     LeftOverBytes;
00065     INT     IterationIndex;
00066     INT     ByteOffset;
00067 
00068     /*
00069     // Determine the maximum number of bytes that will be displayed in 
00070     //    the string
00071     */
00072     
00073     MaxDisplayedBytes = (NumBytesToDisplay > DataBufferLength) ? DataBufferLength
00074                                                                : NumBytesToDisplay;
00075 
00076     /*
00077     // Determine the size of the string we'll need: This is based on the 
00078     //   maximum number of displayed bytes (MaxDisplayedBytes) and the 
00079     //   DisplayBlockSize
00080     */
00081 
00082     BufferStringLength = 2*MaxDisplayedBytes + ROUND_UP_ON_DIVIDE(MaxDisplayedBytes,
00083                                                                   DisplayBlockSize
00084                                                                  );
00085 
00086     /*
00087     // Now we need to allocate string space
00088     */
00089 
00090     String = (PCHAR) malloc(BufferStringLength * sizeof(CHAR));
00091 
00092     if (NULL != String) {
00093 
00094         /*
00095         // Determine how many iterations through the conversion routine must be made.
00096         */
00097         
00098         nFullIterations = MaxDisplayedBytes / DisplayBlockSize;
00099 
00100         /*
00101         // Initialize our variables which point to data in the buffer to convert
00102         //   and the byte in the string in which to put the converted data value. 
00103         //   Next byte is set to String-1 because it is incremented on entry into the
00104         //   loop.
00105         */
00106         
00107         CurrentBufferOffset = DataBuffer;
00108         NextByte = String-1;
00109 
00110         /*
00111         // Each iteration of the loop creates a block of DisplayBlockSize.  Any
00112         //   partial iterations are performed afterwards if the number of bytes
00113         //   to display is not a multiple of the display block size
00114         */
00115         
00116         for (IterationIndex = 0; IterationIndex < nFullIterations; IterationIndex++) 
00117         {
00118             NextByte++;
00119 
00120             /*
00121             // Output a block of data size.  Notice the bytes are accessed in
00122             //    reverse order to display the the MSB of a block as the first
00123             //    value in the string
00124             */
00125             
00126             for (ByteOffset = DisplayBlockSize-1; ByteOffset >= 0; ByteOffset--) 
00127             {
00128                 wsprintf(NextByte, "%02X", *(CurrentBufferOffset+ByteOffset));
00129 
00130                 NextByte += 2;
00131             }
00132 
00133             /*
00134             // Insert the space to separate blocks
00135             */
00136             
00137             *(NextByte) = ' ';
00138 
00139             CurrentBufferOffset += DisplayBlockSize;
00140         }
00141 
00142         /*
00143         // Resolve any other bytes that are left over
00144         */
00145         
00146         LeftOverBytes = (MaxDisplayedBytes % DisplayBlockSize);
00147 
00148         if (0 == LeftOverBytes) 
00149         {
00150             *(NextByte) = '\0';
00151         }
00152 
00153         for (ByteOffset = LeftOverBytes-1, NextByte++; ByteOffset >= 0; ByteOffset--) 
00154         {
00155             wsprintf(NextByte, "%02X", *(CurrentBufferOffset+ByteOffset));
00156             NextByte += 2;
00157         }
00158     }
00159     
00160     *BufferString = String;
00161 
00162     return;
00163 }
00164 
00165 BOOL
00166 Strings_StringToUnsignedList(
00167     IN OUT  PCHAR   InString,
00168     IN      ULONG   UnsignedSize,
00169     IN      ULONG   Base,
00170     OUT     PCHAR   *UnsignedList,
00171     OUT     PULONG  nUnsigneds
00172 )
00173 /*++
00174 Routine Description:
00175     This routine takes an input string, InString, and creates a list of unsigned
00176     values of all the values that are in the list.  The caller can specify a
00177     base, Base, for all the numbers in the list or specify 0 to let the function
00178     determine the base depending on the format of the number in the string.
00179 
00180     The parameter UnsignedSize specifies the size of unsigneds to store in the list.
00181     
00182     The routine allocates a CHAR buffer to store the list of unsigned values.  
00183 
00184     On exit, nUnsigneds will report the number of unsigned values stored in 
00185     UnsignedList.
00186     
00187     The function will return TRUE if it could convert all of the numbers in the
00188     string into the unsigned list.  It will return FALSE if there was a problem
00189     with the string or if there was a problem allocating memory to store the 
00190     unsigned list.  
00191 --*/
00192 {
00193     CHAR    tokDelims[] = "\t,; ";
00194     PCHAR   strToken;
00195     PCHAR   endp;
00196     BOOL    fStatus;
00197     ULONG   ulValue;
00198     PCHAR   pList;
00199     PCHAR   pNewList;
00200     ULONG   nAllocUnsigneds;
00201     ULONG   nActualUnsigneds;
00202     ULONG   ulMaxValue;
00203 
00204     /*
00205     // Begin by initializing our unsigned list
00206     //      1) Start with initial allocation for 2 unsigneds, this will
00207     //          be expanded if necessary
00208     //      2) If initial allocation fails, return FALSE;
00209     */
00210 
00211     nAllocUnsigneds = 2;
00212     nActualUnsigneds = 0;
00213 
00214     pList = (PCHAR) malloc(nAllocUnsigneds * sizeof(ULONG));
00215 
00216     if (NULL == pList) 
00217     {
00218         return (FALSE);
00219     }
00220 
00221     /*
00222     // Calculate the maximum value that can be represented with the value for
00223     //   iBufferSize;
00224     */
00225 
00226     ulMaxValue = (sizeof(ULONG) == UnsignedSize) ? ULONG_MAX 
00227                                                  : (1 << (UnsignedSize*8)) - 1;
00228 
00229     /*
00230     // Begin our processing of the token string.
00231     //  1) Set fStatus to TRUE to get through loop the first time
00232     //  2) Try to get the first token -- if we can't get the first token
00233     //        then we pass through loop
00234     */
00235 
00236     fStatus = TRUE;
00237 
00238     strToken = strtok(InString, tokDelims);
00239 
00240     /*
00241     // Loop until there are no more tokens or we detect an error (fStatus == FALSE)
00242     */
00243 
00244     while (NULL != strToken && fStatus) 
00245     {
00246         /*
00247         // Set fStatus initially to false.  Only if nothing goes wrong in 
00248         //    the loop will this get set to TRUE
00249         */
00250 
00251         fStatus = FALSE;
00252 
00253         /*
00254         // Attempt to convert the token
00255         */
00256 
00257         ulValue = strtoul(strToken, &endp, Base);
00258 
00259         /*
00260         // To be a valid value, *endp must point to the NULL character
00261         */
00262 
00263         if ('\0' == *endp) 
00264         {
00265             /*
00266             // Check to see that the ulValue found is less than or equal to 
00267             //     the maximum allowed by UnsignedSize.
00268             */
00269 
00270             if (ulValue <= ulMaxValue) 
00271             {    
00272                 /*
00273                 // If we're set to overrun our buffer, attempt to allocate
00274                 //    more space.  If we can't then release the old space
00275                 //    and fail the loop.  
00276                 */
00277 
00278                 if (nAllocUnsigneds == nActualUnsigneds) 
00279                 {
00280                     nAllocUnsigneds *= 2;
00281 
00282                     pNewList = (PCHAR) realloc(pList, UnsignedSize*nAllocUnsigneds);
00283 
00284                     if (NULL == pNewList)
00285                     {
00286                         break;
00287                     }
00288                     pList = pNewList;
00289                 }
00290 
00291                 /*
00292                 // Add the token to the end of the list of unsigneds
00293                 */
00294 
00295                 memcpy(pList + (UnsignedSize * nActualUnsigneds),
00296                        &ulValue,
00297                        UnsignedSize);
00298 
00299                 nActualUnsigneds++;
00300 
00301                 /*
00302                 // Prepare to reenter the loop.  Set fStatus = TRUE 
00303                 //    Try to get another token
00304                 */
00305 
00306                 fStatus = TRUE;
00307 
00308                 strToken = strtok(NULL, tokDelims);
00309             }
00310         }
00311     }
00312 
00313     /*
00314     // If the loop failed for some reason or we found no unsigneds
00315     //     release the list
00316     */
00317 
00318     if (!fStatus || 0 == nActualUnsigneds) 
00319     {
00320         free(pList);
00321         pList = NULL;
00322         nActualUnsigneds = 0;
00323     }
00324 
00325     *UnsignedList = pList;
00326     *nUnsigneds = nActualUnsigneds;
00327     
00328     return (fStatus);
00329 }
00330 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines