Exemplo n.º 1
0
static void OutputUInt (char* szOutputBuffer, unsigned int uiBufferSize, unsigned int& uiWritePos, unsigned long long int value, int iWidth, int iPrecision, unsigned int Flags, int iBase, bool bUpperCase)
{
  #ifndef USE_STRICT_SPECIFICATION
    // In the non-strict implementation unsigned values will never be preceeded by signs (+ or space)
    Flags &= ~ (sprintfFlags::BlankSign | sprintfFlags::ForceSign);
  #endif

  // for a 32 Bit Integer one needs at most 10 digits
  // for a 64 Bit Integer one needs at most 20 digits
  // However, FormatUInt allows to add extra padding, so make the buffer a bit larger
  char s[128];
  int iNumDigits = 0;

  FormatUInt (s, iNumDigits, value, iBase, bUpperCase, iPrecision);

  // since the uint is casted to an int, we must make sure very large values are not mapped to negative ints
  // therefore do the ' > 0 ? 1 : 0 ' test to just pass on the proper sign, instead of casting it to an int
  int iNumberWidth = GetSignSize (value > 0 ? 1 : 0, Flags, iBase, iPrecision) + iNumDigits;

  if (Flags & sprintfFlags::LeftJustify)
  {
    OutputIntSign (szOutputBuffer, uiBufferSize, uiWritePos, value > 0 ? 1 : 0, Flags, iBase, bUpperCase, iPrecision);
    OutputReverseString (szOutputBuffer, uiBufferSize, uiWritePos, s, iNumDigits);
    OutputPadding (szOutputBuffer, uiBufferSize, uiWritePos, iWidth - iNumberWidth, ' ');
  }
  else
  {
    OutputIntSignAndPadding (szOutputBuffer, uiBufferSize, uiWritePos, value > 0 ? 1 : 0, Flags, iWidth - iNumberWidth, iBase, bUpperCase, iPrecision);
    OutputReverseString (szOutputBuffer, uiBufferSize, uiWritePos, s, iNumDigits);
  }    
}
Exemplo n.º 2
0
static void OutputInt (char* szOutputBuffer, unsigned int uiBufferSize, unsigned int& uiWritePos, long long int value, int iWidth, int iPrecision, unsigned int Flags, int iBase)
{
  // for a 32 Bit Integer one needs at most 10 digits
  // for a 64 Bit Integer one needs at most 20 digits
  // However, FormatUInt allows to add extra padding, so make the buffer a bit larger
  char s[128];
  int iNumDigits = 0;

  unsigned long long int absval = value < 0 ? -value : value;

  FormatUInt (s, iNumDigits, absval, iBase, false, iPrecision);

  int iNumberWidth = GetSignSize (value, Flags, iBase, iPrecision) + iNumDigits;

  if (Flags & sprintfFlags::LeftJustify)
  {
    OutputIntSign (szOutputBuffer, uiBufferSize, uiWritePos, value, Flags, iBase, false, iPrecision);
    OutputReverseString (szOutputBuffer, uiBufferSize, uiWritePos, s, iNumDigits);
    OutputPadding (szOutputBuffer, uiBufferSize, uiWritePos, iWidth - iNumberWidth, ' ');
  }
  else
  {
    OutputIntSignAndPadding (szOutputBuffer, uiBufferSize, uiWritePos, value, Flags, iWidth - iNumberWidth, iBase, false, iPrecision);
    OutputReverseString (szOutputBuffer, uiBufferSize, uiWritePos, s, iNumDigits);
  }    
}
Exemplo n.º 3
0
    StringExt *StringExt::AppendFormatV(char *sFormat, va_list sArgList)
    {
        StringExtFormatArg uArg;
        int nIndex, nWidth, nPrecision;
        bool bReverseAlign, bZeroFill;
        StringExtFormatType eFormatType;
        char sBuffer[65];
        int nLen;
        char *pCur, *pTemp, *sTemp;

        int nArgsLen = 0;
        int nArgsSize = 8;
        StringExtFormatArg *arrArgs = (StringExtFormatArg *)MemUtilsMallocArray( nArgsSize, sizeof(StringExtFormatArg));

        pCur = sFormat;
        while ( *pCur )
        {
            if ( *pCur == '{' )
            {
                ++pCur;
                if ( *pCur == '{' )
                {
                    ++pCur;
                    Append('{');
                }
                else
                {
                    // Разбираем форматированную строку
                    if ( !(*pCur >= '0' && *pCur <= '9') )
                        break;
                    nIndex = *pCur - '0';
                    for (++pCur; *pCur >= '0' && *pCur <= '9'; ++pCur )
                        nIndex = 10 * nIndex + (*pCur - '0');

                    if ( *pCur != ':' )
                        break;
                    ++pCur;
                    if ( *pCur == '-' )
                    {
                        bReverseAlign = true;
                        ++pCur;
                    }
                    else
                        bReverseAlign = false;
                    nWidth = 0;
                    bZeroFill = *pCur == '0';
                    for (; *pCur >= '0' && *pCur <= '9'; ++pCur )
                        nWidth = 10 * nWidth + (*pCur - '0');
                    if ( *pCur == '.' )
                    {
                        ++pCur;
                        nPrecision = 0;
                        for (; *pCur >= '0' && *pCur <= '9'; ++pCur )
                        {
                            nPrecision = 10 * nPrecision + (*pCur - '0');
                        }
                    }
                    else
                    {
                        nPrecision = 0;
                    }
                    for ( eFormatType = (StringExtFormatType)0;
                        c_arrsFormatStrings[ eFormatType ];
                    eFormatType = (StringExtFormatType)( eFormatType + 1 ) )
                    {
                        if (!strncmp( pCur, c_arrsFormatStrings[ eFormatType ], strlen(c_arrsFormatStrings[ eFormatType ])))
                        {
                            break;
                        }
                    }
                    if ( !c_arrsFormatStrings[ eFormatType ] )
                    {
                        break;
                    }
                    pCur += strlen( c_arrsFormatStrings[ eFormatType ] );
                    if (*pCur != '}')
                    {
                        break;
                    }
                    ++pCur;
                    // fetch the argument
                    if ( nIndex > nArgsLen )
                    {
                        break;
                    }
                    if ( nIndex == nArgsLen )
                    {
                        if ( nArgsLen == nArgsSize )
                        {
                            nArgsSize *= 2;
                            arrArgs = (StringExtFormatArg *)MemUtilsReallocArray( arrArgs, nArgsSize, sizeof(StringExtFormatArg));
                        }
                        switch ( eFormatType )
                        {
                        case fmtIntDecimal:
                        case fmtIntHex:
                        case fmtIntOctal:
                        case fmtIntBinary:
                        case fmtSpace:
                            arrArgs[nArgsLen].iValue = va_arg( sArgList, int );
                            break;
                        case fmtUIntDecimal:
                        case fmtUIntHex:
                        case fmtUIntOctal:
                        case fmtUIntBinary:
                            arrArgs[nArgsLen].uiValue = va_arg( sArgList, unsigned int );
                            break;
                        case fmtLongDecimal:
                        case fmtLongHex:
                        case fmtLongOctal:
                        case fmtLongBinary:
                            arrArgs[nArgsLen].lValue = va_arg( sArgList, long );
                            break;
                        case fmtULongDecimal:
                        case fmtULongHex:
                        case fmtULongOctal:
                        case fmtULongBinary:
                            arrArgs[nArgsLen].ulValue = va_arg( sArgList, unsigned long );
                            break;
                        case fmtDouble:
                        case fmtDoubleTrim:
                            arrArgs[nArgsLen].fValue = va_arg( sArgList, double );
                            break;
                        case fmtChar:
                            arrArgs[nArgsLen].cValue = (char)va_arg( sArgList, int );
                            break;
                        case fmtString:
                            arrArgs[nArgsLen].sValue = va_arg( sArgList, char * );
                            break;
                        case fmtStringExt:
                            arrArgs[nArgsLen].seValue = va_arg(sArgList, StringExt *);
                            break;
                        }
                        ++nArgsLen;
                    }

                    uArg = arrArgs[ nIndex ];
                    switch ( eFormatType )
                    {
                    case fmtIntDecimal:
                        FormatInt( uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen );
                        break;
                    case fmtIntHex:
                        FormatInt( uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen );
                        break;
                    case fmtIntOctal:
                        FormatInt( uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen );
                        break;
                    case fmtIntBinary:
                        FormatInt( uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen );
                        break;
                    case fmtUIntDecimal:
                        FormatUInt( uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen );
                        break;
                    case fmtUIntHex:
                        FormatUInt( uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen );
                        break;
                    case fmtUIntOctal:
                        FormatUInt( uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen );
                        break;
                    case fmtUIntBinary:
                        FormatUInt( uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen );
                        break;
                    case fmtLongDecimal:
                        FormatInt( uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen );
                        break;
                    case fmtLongHex:
                        FormatInt( uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen );
                        break;
                    case fmtLongOctal:
                        FormatInt( uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen );
                        break;
                    case fmtLongBinary:
                        FormatInt( uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen );
                        break;
                    case fmtULongDecimal:
                        FormatUInt( uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen );
                        break;
                    case fmtULongHex:
                        FormatUInt( uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen );
                        break;
                    case fmtULongOctal:
                        FormatUInt( uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen );
                        break;
                    case fmtULongBinary:
                        FormatUInt( uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen );
                        break;
                    case fmtDouble:
                        FormatDouble( uArg.fValue, sBuffer, sizeof(sBuffer), nPrecision, false, &sTemp, &nLen );
                        break;
                    case fmtDoubleTrim:
                        FormatDouble( uArg.fValue, sBuffer, sizeof(sBuffer), nPrecision, true, &sTemp, &nLen );
                        break;
                    case fmtChar:
                        sBuffer[0] = uArg.cValue;
                        sTemp = sBuffer;
                        nLen = 1;
                        bReverseAlign = !bReverseAlign;
                        break;
                    case fmtString:
                        sTemp = uArg.sValue;
                        nLen = strlen( sTemp );
                        bReverseAlign = !bReverseAlign;
                        break;
                    case fmtStringExt:
                        sTemp = uArg.seValue->GetBuffer();
                        nLen = uArg.seValue->GetLength();
                        bReverseAlign = !bReverseAlign;
                        break;
                    case fmtSpace:
                        sTemp = sBuffer;
                        nLen = 0;
                        nWidth = uArg.iValue;
                        break;
                    }
                    // Добавляем аргумент в нужном формате, с нужным прилеганием
                    if ( !bReverseAlign && nLen < nWidth )
                    {
                        for (int nCounter = nLen; nCounter < nWidth; ++nCounter )
                            Append(' ');
                    }
                    Append( sTemp, nLen);
                    if ( bReverseAlign && nLen < nWidth )
                    {
                        for (int nCounter = nLen; nCounter < nWidth; ++nCounter )
                            Append(' ');
                    }
                }
            }
            else if ( *pCur == '}' )
Exemplo n.º 4
0
static bool FormatUFloat (char* szOutputBuffer, unsigned int uiBufferSize, unsigned int& uiWritePos, double value, int iPrecision, unsigned int Flags, bool bRemoveZeroes)
{
  if (value < 0)
    value = - value;

  bool bRoundedUp = false;

  long long int uiIntPart = (long long int) value;

  char szFraction[128];
  int iFractionDigits = 0;

  double dRemainder = value - (double) uiIntPart;

  // make sure we don't write outside our buffer
  if (iPrecision > 64)
    iPrecision = 64;

  // When no precision is given a maximum of 6 fractional digits is written
  // However, all trailing zeros will be removed again, to shorten the number as much as possible
  const bool bRemoveTrailingZeros = bRemoveZeroes || (iPrecision < 0);
    
  if (iPrecision < 0)
    iPrecision = 6;

  for (int i = 0; i < iPrecision; ++i)
  {
    dRemainder *= 10.0f;
    long long int digit = (long long int) dRemainder;

    char cDigit = '0' + (char) (digit);
    szFraction[iFractionDigits++] = cDigit;

    dRemainder -= (double) digit;
  }

  // zero terminate the string
  szFraction[iFractionDigits] = '\0';

  // if the NEXT (not written digit) is 5 or larger, round the whole number up
  if (dRemainder >= 0.5)
  {
    if (RoundUpDigits (szFraction, iFractionDigits))
    {
      bRoundedUp = true;
      ++uiIntPart;
    }
  }

  if (bRemoveTrailingZeros)
    RemoveTrailingZeros (szFraction, iFractionDigits);


  {
    char szBuffer[128];
    int iNumDigits = 0;

    // for a 32 Bit Integer one needs at most 10 digits
    // for a 64 Bit Integer one needs at most 20 digits
    // However, FormatUInt allows to add extra padding, so make the buffer a bit larger
    FormatUInt (szBuffer, iNumDigits, uiIntPart, 10, false, 1);

    OutputReverseString (szOutputBuffer, uiBufferSize, uiWritePos, szBuffer, iNumDigits);
  }

  // if there is any fractional digit, or the user specifically requested it,
  // add the '.'
  if ((iFractionDigits > 0) || (Flags & sprintfFlags::Hash))
    OutputChar (szOutputBuffer, uiBufferSize, uiWritePos, '.');
    
  OutputString (szOutputBuffer, uiBufferSize, uiWritePos, szFraction, 0, 0, -1);

  return bRoundedUp;
}