Changeset 3730 for trunk/src/kernel32/heapstring.cpp
- Timestamp:
- Jun 18, 2000, 2:55:17 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/heapstring.cpp
r3690 r3730 1 /* $Id: heapstring.cpp,v 1.2 7 2000-06-12 12:20:05phaller Exp $ */1 /* $Id: heapstring.cpp,v 1.28 2000-06-18 12:55:17 phaller Exp $ */ 2 2 3 3 /* … … 20 20 #include <stdlib.h> 21 21 #include <string.h> 22 #include <stdio.h> 22 23 #include <winnls.h> 23 24 #include <unicode.h> … … 1052 1053 1053 1054 1055 1056 /************************************************************************** 1057 * This function is used just locally ! 1058 * Description: Inverts a string. 1059 */ 1060 static void OLE_InvertString(char* string) 1061 { 1062 char sTmpArray[128]; 1063 INT counter, i = 0; 1064 1065 for (counter = strlen(string); counter > 0; counter--) 1066 { 1067 memcpy(sTmpArray + i, string + counter-1, 1); 1068 i++; 1069 } 1070 memcpy(sTmpArray + i, "\0", 1); 1071 strcpy(string, sTmpArray); 1072 } 1073 1074 /*************************************************************************************** 1075 * This function is used just locally ! 1076 * Description: Test if the given string (psNumber) is valid or not. 1077 * The valid characters are the following: 1078 * - Characters '0' through '9'. 1079 * - One decimal point (dot) if the number is a floating-point value. 1080 * - A minus sign in the first character position if the number is 1081 * a negative value. 1082 * If the function succeeds, psBefore/psAfter will point to the string 1083 * on the right/left of the decimal symbol. pbNegative indicates if the 1084 * number is negative. 1085 */ 1086 static INT OLE_GetNumberComponents(char* pInput, char* psBefore, char* psAfter, BOOL* pbNegative) 1087 { 1088 char sNumberSet[] = "0123456789"; 1089 BOOL bInDecimal = FALSE; 1090 1091 /* Test if we do have a minus sign */ 1092 if ( *pInput == '-' ) 1093 { 1094 *pbNegative = TRUE; 1095 pInput++; /* Jump to the next character. */ 1096 } 1097 1098 while(*pInput != '\0') 1099 { 1100 /* Do we have a valid numeric character */ 1101 if ( strchr(sNumberSet, *pInput) != NULL ) 1102 { 1103 if (bInDecimal == TRUE) 1104 *psAfter++ = *pInput; 1105 else 1106 *psBefore++ = *pInput; 1107 } 1108 else 1109 { 1110 /* Is this a decimal point (dot) */ 1111 if ( *pInput == '.' ) 1112 { 1113 /* Is it the first time we find it */ 1114 if ((bInDecimal == FALSE)) 1115 bInDecimal = TRUE; 1116 else 1117 return -1; /* ERROR: Invalid parameter */ 1118 } 1119 else 1120 { 1121 /* It's neither a numeric character, nor a decimal point. 1122 * Thus, return an error. 1123 */ 1124 return -1; 1125 } 1126 } 1127 pInput++; 1128 } 1129 1130 /* Add an End of Line character to the output buffers */ 1131 *psBefore = '\0'; 1132 *psAfter = '\0'; 1133 1134 return 0; 1135 } 1136 1137 /************************************************************************** 1138 * This function is used just locally ! 1139 * Description: A number could be formatted using different numbers 1140 * of "digits in group" (example: 4;3;2;0). 1141 * The first parameter of this function is an array 1142 * containing the rule to be used. It's format is the following: 1143 * |NDG|DG1|DG2|...|0| 1144 * where NDG is the number of used "digits in group" and DG1, DG2, 1145 * are the corresponding "digits in group". 1146 * Thus, this function returns the grouping value in the array 1147 * pointed by the second parameter. 1148 */ 1149 static INT OLE_GetGrouping(char* sRule, INT index) 1150 { 1151 char sData[2], sRuleSize[2]; 1152 INT nData, nRuleSize; 1153 1154 memcpy(sRuleSize, sRule, 1); 1155 memcpy(sRuleSize+1, "\0", 1); 1156 nRuleSize = atoi(sRuleSize); 1157 1158 if (index > 0 && index < nRuleSize) 1159 { 1160 memcpy(sData, sRule+index, 1); 1161 memcpy(sData+1, "\0", 1); 1162 nData = atoi(sData); 1163 } 1164 1165 else 1166 { 1167 memcpy(sData, sRule+nRuleSize-1, 1); 1168 memcpy(sData+1, "\0", 1); 1169 nData = atoi(sData); 1170 } 1171 1172 return nData; 1173 } 1174 1175 1054 1176 /***************************************************************************** 1055 1177 * Name : GetNumberFormat … … 1058 1180 * Variables : 1059 1181 * Result : 1060 * Remark : 1182 * Remark : KERNEL32.355 1061 1183 * Status : 1062 1184 * … … 1065 1187 1066 1188 1067 ODINFUNCTION6( int, GetNumberFormatA,1068 LCID, Locale,1069 DWORD, dw Flags,1070 LPCSTR, lp Value,1189 ODINFUNCTION6(INT, GetNumberFormatA, 1190 LCID, locale, 1191 DWORD, dwflags, 1192 LPCSTR, lpvalue, 1071 1193 CONST NUMBERFMTA *,lpFormat, 1072 1194 LPSTR, lpNumberStr, 1073 1195 int, cchNumber) 1074 1196 { 1075 dprintf(("GetNumberFormatA(%08x,%08x,%s,%08x,%s,%08x) not properly implemented.\n", 1076 Locale, 1077 dwFlags, 1078 lpValue, 1079 lpFormat, 1080 lpNumberStr, 1081 cchNumber)); 1197 dprintf(("not properly implemented.\n")); 1082 1198 1083 // @@@PH cheap ass emulation 1084 lstrcpynA(lpNumberStr, 1085 lpValue, 1086 cchNumber); 1087 1088 return lstrlenA(lpNumberStr); 1089 } 1199 char sNumberDigits[3], sDecimalSymbol[5], sDigitsInGroup[11], sDigitGroupSymbol[5], sILZero[2]; 1200 INT nNumberDigits, nNumberDecimal, i, j, nCounter, nStep, nRuleIndex, nGrouping, nDigits, retVal, nLZ; 1201 char sNumber[128], sDestination[128], sDigitsAfterDecimal[10], sDigitsBeforeDecimal[128]; 1202 char sRule[10], sSemiColumn[]=";", sBuffer[5], sNegNumber[2]; 1203 char *pStr = NULL, *pTmpStr = NULL; 1204 LCID systemDefaultLCID; 1205 BOOL bNegative = FALSE; 1206 enum Operations 1207 { 1208 USE_PARAMETER, 1209 USE_LOCALEINFO, 1210 USE_SYSTEMDEFAULT, 1211 RETURN_ERROR 1212 } used_operation; 1213 1214 strncpy(sNumber, lpvalue, 128); 1215 sNumber[127] = '\0'; 1216 1217 /* Make sure we have a valid input string, get the number 1218 * of digits before and after the decimal symbol, and check 1219 * if this is a negative number. 1220 */ 1221 if ( OLE_GetNumberComponents(sNumber, sDigitsBeforeDecimal, sDigitsAfterDecimal, &bNegative) != -1) 1222 { 1223 nNumberDecimal = strlen(sDigitsBeforeDecimal); 1224 nDigits = strlen(sDigitsAfterDecimal); 1225 } 1226 else 1227 { 1228 SetLastError(ERROR_INVALID_PARAMETER); 1229 return 0; 1230 } 1231 1232 /* Which source will we use to format the string */ 1233 used_operation = RETURN_ERROR; 1234 if (lpFormat != NULL) 1235 { 1236 if (dwflags == 0) 1237 used_operation = USE_PARAMETER; 1238 } 1239 else 1240 { 1241 if (dwflags & LOCALE_NOUSEROVERRIDE) 1242 used_operation = USE_LOCALEINFO; 1243 else 1244 used_operation = USE_SYSTEMDEFAULT; 1245 } 1246 1247 /* Load the fields we need */ 1248 switch(used_operation) 1249 { 1250 case USE_LOCALEINFO: 1251 GetLocaleInfoA(locale, LOCALE_IDIGITS, sNumberDigits, sizeof(sNumberDigits)); 1252 GetLocaleInfoA(locale, LOCALE_SDECIMAL, sDecimalSymbol, sizeof(sDecimalSymbol)); 1253 GetLocaleInfoA(locale, LOCALE_SGROUPING, sDigitsInGroup, sizeof(sDigitsInGroup)); 1254 GetLocaleInfoA(locale, LOCALE_STHOUSAND, sDigitGroupSymbol, sizeof(sDigitGroupSymbol)); 1255 GetLocaleInfoA(locale, LOCALE_ILZERO, sILZero, sizeof(sILZero)); 1256 GetLocaleInfoA(locale, LOCALE_INEGNUMBER, sNegNumber, sizeof(sNegNumber)); 1257 break; 1258 case USE_PARAMETER: 1259 sprintf(sNumberDigits, "%d",lpFormat->NumDigits); 1260 strcpy(sDecimalSymbol, lpFormat->lpDecimalSep); 1261 sprintf(sDigitsInGroup, "%d;0",lpFormat->Grouping); 1262 strcpy(sDigitGroupSymbol, lpFormat->lpThousandSep); 1263 sprintf(sILZero, "%d",lpFormat->LeadingZero); 1264 sprintf(sNegNumber, "%d",lpFormat->NegativeOrder); 1265 break; 1266 case USE_SYSTEMDEFAULT: 1267 systemDefaultLCID = GetSystemDefaultLCID(); 1268 GetLocaleInfoA(systemDefaultLCID, LOCALE_IDIGITS, sNumberDigits, sizeof(sNumberDigits)); 1269 GetLocaleInfoA(systemDefaultLCID, LOCALE_SDECIMAL, sDecimalSymbol, sizeof(sDecimalSymbol)); 1270 GetLocaleInfoA(systemDefaultLCID, LOCALE_SGROUPING, sDigitsInGroup, sizeof(sDigitsInGroup)); 1271 GetLocaleInfoA(systemDefaultLCID, LOCALE_STHOUSAND, sDigitGroupSymbol, sizeof(sDigitGroupSymbol)); 1272 GetLocaleInfoA(systemDefaultLCID, LOCALE_ILZERO, sILZero, sizeof(sILZero)); 1273 GetLocaleInfoA(systemDefaultLCID, LOCALE_INEGNUMBER, sNegNumber, sizeof(sNegNumber)); 1274 break; 1275 default: 1276 SetLastError(ERROR_INVALID_PARAMETER); 1277 return 0; 1278 } 1279 1280 nNumberDigits = atoi(sNumberDigits); 1281 1282 /* Remove the ";" */ 1283 i=0; 1284 j = 1; 1285 for (nCounter=0; nCounter<strlen(sDigitsInGroup); nCounter++) 1286 { 1287 if ( memcmp(sDigitsInGroup + nCounter, sSemiColumn, 1) != 0 ) 1288 { 1289 memcpy(sRule + j, sDigitsInGroup + nCounter, 1); 1290 i++; 1291 j++; 1292 } 1293 } 1294 sprintf(sBuffer, "%d", i); 1295 memcpy(sRule, sBuffer, 1); /* Number of digits in the groups ( used by OLE_GetGrouping() ) */ 1296 memcpy(sRule + j, "\0", 1); 1297 1298 /* First, format the digits before the decimal. */ 1299 if ((nNumberDecimal>0) && (atoi(sDigitsBeforeDecimal) != 0)) 1300 { 1301 /* Working on an inverted string is easier ! */ 1302 OLE_InvertString(sDigitsBeforeDecimal); 1303 1304 nStep = nCounter = i = j = 0; 1305 nRuleIndex = 1; 1306 nGrouping = OLE_GetGrouping(sRule, nRuleIndex); 1307 1308 /* Here, we will loop until we reach the end of the string. 1309 * An internal counter (j) is used in order to know when to 1310 * insert the "digit group symbol". 1311 */ 1312 while (nNumberDecimal > 0) 1313 { 1314 i = nCounter + nStep; 1315 memcpy(sDestination + i, sDigitsBeforeDecimal + nCounter, 1); 1316 nCounter++; 1317 j++; 1318 if (j >= nGrouping) 1319 { 1320 j = 0; 1321 if (nRuleIndex < sRule[0]) 1322 nRuleIndex++; 1323 nGrouping = OLE_GetGrouping(sRule, nRuleIndex); 1324 memcpy(sDestination + i+1, sDigitGroupSymbol, strlen(sDigitGroupSymbol)); 1325 nStep+= strlen(sDigitGroupSymbol); 1326 } 1327 1328 nNumberDecimal--; 1329 } 1330 1331 memcpy(sDestination + i+1, "\0", 1); 1332 /* Get the string in the right order ! */ 1333 OLE_InvertString(sDestination); 1334 } 1335 else 1336 { 1337 nLZ = atoi(sILZero); 1338 if (nLZ != 0) 1339 { 1340 /* Use 0.xxx instead of .xxx */ 1341 memcpy(sDestination, "0", 1); 1342 memcpy(sDestination+1, "\0", 1); 1343 } 1344 else 1345 memcpy(sDestination, "\0", 1); 1346 1347 } 1348 1349 /* Second, format the digits after the decimal. */ 1350 j = 0; 1351 nCounter = nNumberDigits; 1352 if ( (nDigits>0) && (pStr = strstr (sNumber, ".")) ) 1353 { 1354 i = strlen(sNumber) - strlen(pStr) + 1; 1355 strncpy ( sDigitsAfterDecimal, sNumber + i, nNumberDigits); 1356 j = strlen(sDigitsAfterDecimal); 1357 if (j < nNumberDigits) 1358 nCounter = nNumberDigits-j; 1359 } 1360 for (i=0;i<nCounter;i++) 1361 memcpy(sDigitsAfterDecimal+i+j, "0", 1); 1362 memcpy(sDigitsAfterDecimal + nNumberDigits, "\0", 1); 1363 1364 i = strlen(sDestination); 1365 j = strlen(sDigitsAfterDecimal); 1366 /* Finally, construct the resulting formatted string. */ 1367 1368 for (nCounter=0; nCounter<i; nCounter++) 1369 memcpy(sNumber + nCounter, sDestination + nCounter, 1); 1370 1371 memcpy(sNumber + nCounter, sDecimalSymbol, strlen(sDecimalSymbol)); 1372 1373 for (i=0; i<j; i++) 1374 memcpy(sNumber + nCounter+i+strlen(sDecimalSymbol), sDigitsAfterDecimal + i, 1); 1375 memcpy(sNumber + nCounter+i+strlen(sDecimalSymbol), "\0", 1); 1376 1377 /* Is it a negative number */ 1378 if (bNegative == TRUE) 1379 { 1380 i = atoi(sNegNumber); 1381 pStr = sDestination; 1382 pTmpStr = sNumber; 1383 switch (i) 1384 { 1385 case 0: 1386 *pStr++ = '('; 1387 while (*sNumber != '\0') 1388 *pStr++ = *pTmpStr++; 1389 *pStr++ = ')'; 1390 break; 1391 case 1: 1392 *pStr++ = '-'; 1393 while (*pTmpStr != '\0') 1394 *pStr++ = *pTmpStr++; 1395 break; 1396 case 2: 1397 *pStr++ = '-'; 1398 *pStr++ = ' '; 1399 while (*pTmpStr != '\0') 1400 *pStr++ = *pTmpStr++; 1401 break; 1402 case 3: 1403 while (*pTmpStr != '\0') 1404 *pStr++ = *pTmpStr++; 1405 *pStr++ = '-'; 1406 break; 1407 case 4: 1408 while (*pTmpStr != '\0') 1409 *pStr++ = *pTmpStr++; 1410 *pStr++ = ' '; 1411 *pStr++ = '-'; 1412 break; 1413 default: 1414 while (*pTmpStr != '\0') 1415 *pStr++ = *pTmpStr++; 1416 break; 1417 } 1418 } 1419 else 1420 strcpy(sDestination, sNumber); 1421 1422 /* If cchNumber is zero, then returns the number of bytes or characters 1423 * required to hold the formatted number string 1424 */ 1425 if (cchNumber==0) 1426 retVal = strlen(sDestination) + 1; 1427 else 1428 { 1429 strncpy (lpNumberStr, sDestination, cchNumber-1); 1430 *(lpNumberStr+cchNumber-1) = '\0'; /* ensure we got a NULL at the end */ 1431 retVal = strlen(lpNumberStr); 1432 } 1433 1434 return retVal; 1435 } 1436 1437 1090 1438 1091 1439 … … 1103 1451 1104 1452 int WIN32API GetNumberFormatW(LCID Locale, 1105 1106 1107 1108 1109 1453 DWORD dwFlags, 1454 LPCWSTR lpValue, 1455 CONST NUMBERFMTW *lpFormat, 1456 LPWSTR lpNumberStr, 1457 int cchNumber) 1110 1458 { 1111 1459 dprintf(("GetNumberFormatW(%08x,%08x,%s,%08x,%s,%08x) not properly implemented.\n",
Note:
See TracChangeset
for help on using the changeset viewer.