int ezStringUtils::vsnprintf(char* szOutputBuffer, unsigned int uiBufferSize, const char* szFormat, va_list args0) { va_list args; va_copy(args, args0); EZ_ASSERT(ezUnicodeUtils::IsValidUtf8(szFormat), "The sprintf format string must be valid Utf8."); // make sure the last character is a \0 if ((szOutputBuffer) && (uiBufferSize > 0)) szOutputBuffer[uiBufferSize - 1] = '\0'; unsigned int uiReadPos = 0; unsigned int uiWritePos = 0; bool bError = false; while (szFormat[uiReadPos] != '\0') { const char c = szFormat[uiReadPos]; ++uiReadPos; // if c is not %, just print it out and be done with it if (c != '%') { OutputChar (szOutputBuffer, uiBufferSize, uiWritePos, c); continue; } // otherwise parse the formatting string to find out what has to be done char cNext = szFormat[uiReadPos]; // *** parse the format string *** // first read the flags (as many as there are) unsigned int Flags = ReadFlags (szFormat, uiReadPos, cNext); // read the width of the field int iWidth = ReadWidth (szFormat, uiReadPos, cNext); // read the precision specifier int iPrecision = ReadPrecision (szFormat, uiReadPos, cNext); // read the input data 'length' (short / int / long it, float / double) const sprintfLength::Enum Length = ReadLength (szFormat, uiReadPos, cNext); // read the 'specifier' type const char cSpecifier = ReadSpecifier (szFormat, uiReadPos, cNext, bError); if (bError) { snprintf (szOutputBuffer, uiBufferSize, "Error in formatting string at position %u ('%c').", uiReadPos, cSpecifier); va_end(args); return -1; } // if 'width' was specified as '*', read it from an extra parameter if (iWidth < 0) iWidth = va_arg (args, int); // if 'precision' was specified as '*', read it from an extra parameter if (iPrecision == -2) iPrecision = va_arg (args, int); // % Sign if (cSpecifier == '%') { OutputChar (szOutputBuffer, uiBufferSize, uiWritePos, '%'); continue; } // Nothing: Writes the current write position back to an int pointer if (cSpecifier == 'n') { int* p = va_arg (args, int*); if (p) *p = (int) uiWritePos; continue; } // String if (cSpecifier == 's') { const char* s = va_arg (args, const char*); OutputString (szOutputBuffer, uiBufferSize, uiWritePos, s, Flags, iWidth, iPrecision); continue; } // Character if (cSpecifier == 'c') { char c2 = va_arg (args, int); char s[2] = {c2, 0}; OutputString (szOutputBuffer, uiBufferSize, uiWritePos, s, Flags, iWidth, iPrecision); continue; }
void ReadLeaders() { ReadFlags(); ReadWidth(); if (*format_ == '.') ReadPrecision(); ReadModifiers(); }