Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
5.4 KiB

  1. //============================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: intl.c
  5. //
  6. // History:
  7. // Abolade Gbadegesin Nov-14-1995 Created.
  8. //
  9. // Internationalized string routines
  10. //============================================================================
  11. #include <windows.h>
  12. #include <nouiutil.h>
  13. //----------------------------------------------------------------------------
  14. // Function: padultoa
  15. //
  16. // This functions formats the specified unsigned integer
  17. // into the specified string buffer, padding the buffer
  18. // so that it is at least the specified width.
  19. //
  20. // It is assumed that the buffer is at least wide enough
  21. // to contain the output, so this function does not truncate
  22. // the conversion result to the length of the 'width' parameter.
  23. //----------------------------------------------------------------------------
  24. PTSTR padultoa(UINT val, PTSTR pszBuf, INT width) {
  25. TCHAR temp;
  26. PTSTR psz, zsp;
  27. psz = pszBuf;
  28. //
  29. // write the digits in reverse order
  30. //
  31. do {
  32. *psz++ = TEXT('0') + (val % 10);
  33. val /= 10;
  34. } while(val > 0);
  35. //
  36. // pad the string to the required width
  37. //
  38. zsp = pszBuf + width;
  39. while (psz < zsp) { *psz++ = TEXT('0'); }
  40. *psz-- = TEXT('\0');
  41. //
  42. // reverse the digits
  43. //
  44. for (zsp = pszBuf; zsp < psz; zsp++, psz--) {
  45. temp = *psz; *psz = *zsp; *zsp = temp;
  46. }
  47. //
  48. // return the result
  49. //
  50. return pszBuf;
  51. }
  52. // Function: GetNumberString
  53. //
  54. // This function takes an integer and formats a string with the value
  55. // represented by the number, grouping digits by powers of one-thousand
  56. DWORD
  57. GetNumberString(
  58. IN DWORD dwNumber,
  59. IN OUT PTSTR pszBuffer,
  60. IN OUT PDWORD pdwBufSize
  61. ) {
  62. static TCHAR szSep[4] = TEXT("");
  63. DWORD i, dwLength;
  64. TCHAR szDigits[12], *pszNumber;
  65. if (pdwBufSize == NULL) { return ERROR_INVALID_PARAMETER; }
  66. if (szSep[0] == TEXT('\0')) {
  67. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, 4);
  68. }
  69. //
  70. // convert the number to a string without thousands-separators
  71. //
  72. padultoa(dwNumber, szDigits, 0);
  73. dwLength = lstrlen(szDigits);
  74. //
  75. // if the length of the string without separators is n,
  76. // then the length of the string with separators is n + (n - 1) / 3
  77. //
  78. i = dwLength;
  79. dwLength += (dwLength - 1) / 3;
  80. if (pszBuffer != NULL && dwLength < *pdwBufSize) {
  81. PTSTR pszsrc, pszdst;
  82. pszsrc = szDigits + i - 1; pszdst = pszBuffer + dwLength;
  83. *pszdst-- = TEXT('\0');
  84. while (TRUE) {
  85. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  86. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  87. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  88. if (i) { *pszdst-- = *szSep; } else { break; }
  89. }
  90. }
  91. *pdwBufSize = dwLength;
  92. return NO_ERROR;
  93. }
  94. //----------------------------------------------------------------------------
  95. // Function: GetDurationString
  96. //
  97. // This function takes a millisecond count and formats a string
  98. // with the duration represented by the millisecond count.
  99. // The caller may specify the resolution required by setting the flags field
  100. //----------------------------------------------------------------------------
  101. DWORD
  102. GetDurationString(
  103. IN DWORD dwMilliseconds,
  104. IN DWORD dwFormatFlags,
  105. IN OUT PTSTR pszBuffer,
  106. IN OUT DWORD *pdwBufSize
  107. ) {
  108. static TCHAR szSep[4] = TEXT("");
  109. DWORD dwSize;
  110. TCHAR *psz, szOutput[64];
  111. if (pdwBufSize == NULL || (dwFormatFlags & GDSFLAG_All) == 0) {
  112. return ERROR_INVALID_PARAMETER;
  113. }
  114. if (szSep[0] == TEXT('\0')) {
  115. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, szSep, 4);
  116. }
  117. //
  118. // concatenate the strings together
  119. //
  120. psz = szOutput;
  121. dwFormatFlags &= GDSFLAG_All;
  122. if (dwFormatFlags & GDSFLAG_Days) {
  123. padultoa(dwMilliseconds / (24 * 60 * 60 * 1000), psz, 0);
  124. dwMilliseconds %= (24 * 60 * 60 * 1000);
  125. if (dwFormatFlags &= ~GDSFLAG_Days) { lstrcat(psz, szSep); }
  126. psz += lstrlen(psz);
  127. }
  128. if (dwFormatFlags & GDSFLAG_Hours) {
  129. padultoa(dwMilliseconds / (60 * 60 * 1000), psz, 2);
  130. dwMilliseconds %= (60 * 60 * 1000);
  131. if (dwFormatFlags &= ~GDSFLAG_Hours) { lstrcat(psz, szSep); }
  132. psz += lstrlen(psz);
  133. }
  134. if (dwFormatFlags & GDSFLAG_Minutes) {
  135. padultoa(dwMilliseconds / (60 * 1000), psz, 2);
  136. dwMilliseconds %= (60 * 1000);
  137. if (dwFormatFlags &= ~GDSFLAG_Minutes) { lstrcat(psz, szSep); }
  138. psz += lstrlen(psz);
  139. }
  140. if (dwFormatFlags & GDSFLAG_Seconds) {
  141. padultoa(dwMilliseconds / 1000, psz, 2);
  142. dwMilliseconds %= 1000;
  143. if (dwFormatFlags &= ~GDSFLAG_Seconds) { lstrcat(psz, szSep); }
  144. psz += lstrlen(psz);
  145. }
  146. if (dwFormatFlags & GDSFLAG_Mseconds) {
  147. padultoa(dwMilliseconds, psz, 0);
  148. psz += lstrlen(psz);
  149. }
  150. dwSize = (DWORD) (psz - szOutput + 1);
  151. if (*pdwBufSize >= dwSize && pszBuffer != NULL) {
  152. lstrcpy(pszBuffer, szOutput);
  153. }
  154. *pdwBufSize = dwSize;
  155. return NO_ERROR;
  156. }