Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cnvint.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cnvint.c 00008 00009 Abstract: 00010 00011 Text to integer and integer to text converion routines. 00012 00013 Author: 00014 00015 Steve Wood (stevewo) 23-Aug-1990 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include <ntrtlp.h> 00022 00023 #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME) 00024 #pragma alloc_text(PAGE,RtlIntegerToChar) 00025 #pragma alloc_text(PAGE,RtlCharToInteger) 00026 #pragma alloc_text(PAGE,RtlUnicodeStringToInteger) 00027 #pragma alloc_text(PAGE,RtlIntegerToUnicodeString) 00028 #pragma alloc_text(PAGE,RtlLargeIntegerToChar) 00029 #pragma alloc_text(PAGE,RtlInt64ToUnicodeString) 00030 #endif 00031 00032 CHAR RtlpIntegerChars[] = {'0', '1', '2', '3', '4', '5', '6', '7', 00033 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 00034 00035 WCHAR RtlpIntegerWChars[] = { L'0', L'1', L'2', L'3', L'4', L'5', 00036 L'6', L'7', L'8', L'9', L'A', L'B', 00037 L'C', L'D', L'E', L'F' }; 00038 00039 NTSTATUS 00040 RtlIntegerToChar ( 00041 IN ULONG Value, 00042 IN ULONG Base OPTIONAL, 00043 IN LONG OutputLength, 00044 OUT PSZ String 00045 ) 00046 00047 /*++ 00048 00049 Routine Description: 00050 00051 Arguments: 00052 00053 Return Value: 00054 00055 --*/ 00056 00057 { 00058 CHAR Result[ 33 ], *s; 00059 ULONG Shift, Mask, Digit, Length; 00060 00061 Shift = 0; 00062 switch( Base ) { 00063 case 16: Shift = 4; break; 00064 case 8: Shift = 3; break; 00065 case 2: Shift = 1; break; 00066 00067 case 0: Base = 10; 00068 case 10: Shift = 0; break; 00069 default: return( STATUS_INVALID_PARAMETER ); 00070 } 00071 00072 if (Shift != 0) { 00073 Mask = 0xF >> (4 - Shift); 00074 } 00075 00076 s = &Result[ 32 ]; 00077 *s = '\0'; 00078 do { 00079 if (Shift != 0) { 00080 Digit = Value & Mask; 00081 Value >>= Shift; 00082 } 00083 else { 00084 Digit = Value % Base; 00085 Value = Value / Base; 00086 } 00087 00088 *--s = RtlpIntegerChars[ Digit ]; 00089 } while (Value != 0); 00090 00091 Length = (ULONG) (&Result[ 32 ] - s); 00092 if (OutputLength < 0) { 00093 OutputLength = -OutputLength; 00094 while ((LONG)Length < OutputLength) { 00095 *--s = '0'; 00096 Length++; 00097 } 00098 } 00099 00100 if ((LONG)Length > OutputLength) { 00101 return( STATUS_BUFFER_OVERFLOW ); 00102 } 00103 else { 00104 try { 00105 RtlMoveMemory( String, s, Length ); 00106 00107 if ((LONG)Length < OutputLength) { 00108 String[ Length ] = '\0'; 00109 } 00110 } 00111 except( EXCEPTION_EXECUTE_HANDLER ) { 00112 return( GetExceptionCode() ); 00113 } 00114 00115 return( STATUS_SUCCESS ); 00116 } 00117 } 00118 00119 00120 NTSTATUS 00121 RtlCharToInteger ( 00122 IN PCSZ String, 00123 IN ULONG Base OPTIONAL, 00124 OUT PULONG Value 00125 ) 00126 { 00127 CHAR c, Sign; 00128 ULONG Result, Digit, Shift; 00129 00130 while ((Sign = *String++) <= ' ') { 00131 if (!*String) { 00132 String--; 00133 break; 00134 } 00135 } 00136 00137 c = Sign; 00138 if (c == '-' || c == '+') { 00139 c = *String++; 00140 } 00141 00142 if (!ARGUMENT_PRESENT( (ULONG_PTR)(Base) )) { 00143 Base = 10; 00144 Shift = 0; 00145 if (c == '0') { 00146 c = *String++; 00147 if (c == 'x') { 00148 Base = 16; 00149 Shift = 4; 00150 } 00151 else 00152 if (c == 'o') { 00153 Base = 8; 00154 Shift = 3; 00155 } 00156 else 00157 if (c == 'b') { 00158 Base = 2; 00159 Shift = 1; 00160 } 00161 else { 00162 String--; 00163 } 00164 00165 c = *String++; 00166 } 00167 } 00168 else { 00169 switch( Base ) { 00170 case 16: Shift = 4; break; 00171 case 8: Shift = 3; break; 00172 case 2: Shift = 1; break; 00173 case 10: Shift = 0; break; 00174 default: return( STATUS_INVALID_PARAMETER ); 00175 } 00176 } 00177 00178 Result = 0; 00179 while (c) { 00180 if (c >= '0' && c <= '9') { 00181 Digit = c - '0'; 00182 } 00183 else 00184 if (c >= 'A' && c <= 'F') { 00185 Digit = c - 'A' + 10; 00186 } 00187 else 00188 if (c >= 'a' && c <= 'f') { 00189 Digit = c - 'a' + 10; 00190 } 00191 else { 00192 break; 00193 } 00194 00195 if (Digit >= Base) { 00196 break; 00197 } 00198 00199 if (Shift == 0) { 00200 Result = (Base * Result) + Digit; 00201 } 00202 else { 00203 Result = (Result << Shift) | Digit; 00204 } 00205 00206 c = *String++; 00207 } 00208 00209 if (Sign == '-') { 00210 Result = (ULONG)(-(LONG)Result); 00211 } 00212 00213 try { 00214 *Value = Result; 00215 } 00216 except( EXCEPTION_EXECUTE_HANDLER ) { 00217 return( GetExceptionCode() ); 00218 } 00219 00220 return( STATUS_SUCCESS ); 00221 } 00222 00223 00224 NTSTATUS 00225 RtlUnicodeStringToInteger ( 00226 IN PUNICODE_STRING String, 00227 IN ULONG Base OPTIONAL, 00228 OUT PULONG Value 00229 ) 00230 { 00231 PCWSTR s; 00232 WCHAR c, Sign; 00233 ULONG nChars, Result, Digit, Shift; 00234 00235 s = String->Buffer; 00236 nChars = String->Length / sizeof( WCHAR ); 00237 while (nChars-- && (Sign = *s++) <= ' ') { 00238 if (!nChars) { 00239 Sign = UNICODE_NULL; 00240 break; 00241 } 00242 } 00243 00244 c = Sign; 00245 if (c == L'-' || c == L'+') { 00246 if (nChars) { 00247 nChars--; 00248 c = *s++; 00249 } 00250 else { 00251 c = UNICODE_NULL; 00252 } 00253 } 00254 00255 if (!ARGUMENT_PRESENT( (ULONG_PTR)Base )) { 00256 Base = 10; 00257 Shift = 0; 00258 if (c == L'0') { 00259 if (nChars) { 00260 nChars--; 00261 c = *s++; 00262 if (c == L'x') { 00263 Base = 16; 00264 Shift = 4; 00265 } 00266 else 00267 if (c == L'o') { 00268 Base = 8; 00269 Shift = 3; 00270 } 00271 else 00272 if (c == L'b') { 00273 Base = 2; 00274 Shift = 1; 00275 } 00276 else { 00277 nChars++; 00278 s--; 00279 } 00280 } 00281 00282 if (nChars) { 00283 nChars--; 00284 c = *s++; 00285 } 00286 else { 00287 c = UNICODE_NULL; 00288 } 00289 } 00290 } 00291 else { 00292 switch( Base ) { 00293 case 16: Shift = 4; break; 00294 case 8: Shift = 3; break; 00295 case 2: Shift = 1; break; 00296 case 10: Shift = 0; break; 00297 default: return( STATUS_INVALID_PARAMETER ); 00298 } 00299 } 00300 00301 Result = 0; 00302 while (c != UNICODE_NULL) { 00303 if (c >= L'0' && c <= L'9') { 00304 Digit = c - L'0'; 00305 } 00306 else 00307 if (c >= L'A' && c <= L'F') { 00308 Digit = c - L'A' + 10; 00309 } 00310 else 00311 if (c >= L'a' && c <= L'f') { 00312 Digit = c - L'a' + 10; 00313 } 00314 else { 00315 break; 00316 } 00317 00318 if (Digit >= Base) { 00319 break; 00320 } 00321 00322 if (Shift == 0) { 00323 Result = (Base * Result) + Digit; 00324 } 00325 else { 00326 Result = (Result << Shift) | Digit; 00327 } 00328 00329 if (!nChars) { 00330 break; 00331 } 00332 nChars--; 00333 c = *s++; 00334 } 00335 00336 if (Sign == L'-') { 00337 Result = (ULONG)(-(LONG)Result); 00338 } 00339 00340 try { 00341 *Value = Result; 00342 } 00343 except( EXCEPTION_EXECUTE_HANDLER ) { 00344 return( GetExceptionCode() ); 00345 } 00346 00347 return( STATUS_SUCCESS ); 00348 } 00349 00350 00351 NTSTATUS 00352 RtlIntegerToUnicode ( 00353 IN ULONG Value, 00354 IN ULONG Base OPTIONAL, 00355 IN LONG OutputLength, 00356 OUT PWSTR String 00357 ) 00358 00359 /*++ 00360 00361 Routine Description: 00362 00363 Arguments: 00364 00365 Return Value: 00366 00367 --*/ 00368 00369 { 00370 WCHAR Result[ 33 ], *s; 00371 ULONG Shift, Mask, Digit, Length; 00372 00373 Shift = 0; 00374 switch( Base ) { 00375 case 16: Shift = 4; break; 00376 case 8: Shift = 3; break; 00377 case 2: Shift = 1; break; 00378 00379 case 0: Base = 10; 00380 case 10: Shift = 0; break; 00381 default: return( STATUS_INVALID_PARAMETER ); 00382 } 00383 00384 if (Shift != 0) { 00385 Mask = 0xF >> (4 - Shift); 00386 } 00387 00388 s = &Result[ 32 ]; 00389 *s = L'\0'; 00390 do { 00391 if (Shift != 0) { 00392 Digit = Value & Mask; 00393 Value >>= Shift; 00394 } 00395 else { 00396 Digit = Value % Base; 00397 Value = Value / Base; 00398 } 00399 00400 *--s = RtlpIntegerWChars[ Digit ]; 00401 } while (Value != 0); 00402 00403 Length = (ULONG) (&Result[ 32 ] - s); 00404 if (OutputLength < 0) { 00405 OutputLength = -OutputLength; 00406 while ((LONG)Length < OutputLength) { 00407 *--s = L'0'; 00408 Length++; 00409 } 00410 } 00411 00412 if ((LONG)Length > OutputLength) { 00413 return( STATUS_BUFFER_OVERFLOW ); 00414 } 00415 else { 00416 try { 00417 RtlMoveMemory( String, s, Length * sizeof( WCHAR )); 00418 00419 if ((LONG)Length < OutputLength) { 00420 String[ Length ] = L'\0'; 00421 } 00422 } 00423 except( EXCEPTION_EXECUTE_HANDLER ) { 00424 return( GetExceptionCode() ); 00425 } 00426 00427 return( STATUS_SUCCESS ); 00428 } 00429 } 00430 00431 00432 NTSTATUS 00433 RtlIntegerToUnicodeString ( 00434 IN ULONG Value, 00435 IN ULONG Base OPTIONAL, 00436 IN OUT PUNICODE_STRING String 00437 ) 00438 { 00439 NTSTATUS Status; 00440 UCHAR ResultBuffer[ 16 ]; 00441 ANSI_STRING AnsiString; 00442 00443 Status = RtlIntegerToChar( Value, Base, sizeof( ResultBuffer ), ResultBuffer ); 00444 if (NT_SUCCESS( Status )) { 00445 AnsiString.Buffer = ResultBuffer; 00446 AnsiString.MaximumLength = sizeof( ResultBuffer ); 00447 AnsiString.Length = (USHORT)strlen( ResultBuffer ); 00448 Status = RtlAnsiStringToUnicodeString( String, &AnsiString, FALSE ); 00449 } 00450 00451 return( Status ); 00452 } 00453 00454 00455 NTSTATUS 00456 RtlLargeIntegerToChar ( 00457 IN PLARGE_INTEGER Value, 00458 IN ULONG Base OPTIONAL, 00459 IN LONG OutputLength, 00460 OUT PSZ String 00461 ) 00462 00463 /*++ 00464 00465 Routine Description: 00466 00467 Arguments: 00468 00469 Return Value: 00470 00471 --*/ 00472 00473 { 00474 CHAR Result[ 100 ], *s; 00475 ULONG Shift, Mask, Digit, Length; 00476 00477 Shift = 0; 00478 switch( Base ) { 00479 case 16: Shift = 4; break; 00480 case 8: Shift = 3; break; 00481 case 2: Shift = 1; break; 00482 00483 case 0: 00484 case 10: Shift = 0; break; 00485 default: return( STATUS_INVALID_PARAMETER ); 00486 } 00487 00488 if (Shift != 0) { 00489 Mask = 0xF >> (4 - Shift); 00490 } 00491 00492 s = &Result[ 99 ]; 00493 *s = '\0'; 00494 if (Shift != 0) { 00495 ULONG LowValue,HighValue,HighShift,HighMask; 00496 00497 LowValue = Value->LowPart; 00498 HighValue = Value->HighPart; 00499 HighShift = Shift - (sizeof(ULONG) % Shift); 00500 HighMask = 0xF >> (4 - HighShift); 00501 do { 00502 Digit = LowValue & Mask; 00503 LowValue = (LowValue >> Shift) | ((HighValue & HighMask) << (sizeof(ULONG) - HighShift)); 00504 HighValue = HighValue >> HighShift; 00505 *--s = RtlpIntegerChars[ Digit ]; 00506 } while ((LowValue | HighValue) != 0); 00507 } else { 00508 LARGE_INTEGER TempValue=*Value; 00509 do { 00510 TempValue = RtlExtendedLargeIntegerDivide(TempValue,Base,&Digit); 00511 *--s = RtlpIntegerChars[ Digit ]; 00512 } while (TempValue.HighPart != 0 || TempValue.LowPart != 0); 00513 } 00514 00515 Length = (ULONG)(&Result[ 99 ] - s); 00516 if (OutputLength < 0) { 00517 OutputLength = -OutputLength; 00518 while ((LONG)Length < OutputLength) { 00519 *--s = '0'; 00520 Length++; 00521 } 00522 } 00523 00524 if ((LONG)Length > OutputLength) { 00525 return( STATUS_BUFFER_OVERFLOW ); 00526 } 00527 else { 00528 try { 00529 RtlMoveMemory( String, s, Length ); 00530 00531 if ((LONG)Length < OutputLength) { 00532 String[ Length ] = '\0'; 00533 } 00534 } 00535 except( EXCEPTION_EXECUTE_HANDLER ) { 00536 return( GetExceptionCode() ); 00537 } 00538 00539 return( STATUS_SUCCESS ); 00540 } 00541 } 00542 00543 NTSTATUS 00544 RtlLargeIntegerToUnicode ( 00545 IN PLARGE_INTEGER Value, 00546 IN ULONG Base OPTIONAL, 00547 IN LONG OutputLength, 00548 OUT PWSTR String 00549 ) 00550 00551 /*++ 00552 00553 Routine Description: 00554 00555 Arguments: 00556 00557 Return Value: 00558 00559 --*/ 00560 00561 { 00562 WCHAR Result[ 100 ], *s; 00563 ULONG Shift, Mask, Digit, Length; 00564 00565 Shift = 0; 00566 switch( Base ) { 00567 case 16: Shift = 4; break; 00568 case 8: Shift = 3; break; 00569 case 2: Shift = 1; break; 00570 00571 case 0: 00572 case 10: Shift = 0; break; 00573 default: return( STATUS_INVALID_PARAMETER ); 00574 } 00575 00576 if (Shift != 0) { 00577 Mask = 0xF >> (4 - Shift); 00578 } 00579 00580 s = &Result[ 99 ]; 00581 *s = L'\0'; 00582 if (Shift != 0) { 00583 ULONG LowValue,HighValue,HighShift,HighMask; 00584 00585 LowValue = Value->LowPart; 00586 HighValue = Value->HighPart; 00587 HighShift = Shift - (sizeof(ULONG) % Shift); 00588 HighMask = 0xF >> (4 - HighShift); 00589 do { 00590 Digit = LowValue & Mask; 00591 LowValue = (LowValue >> Shift) | ((HighValue & HighMask) << (sizeof(ULONG) - HighShift)); 00592 HighValue = HighValue >> HighShift; 00593 *--s = RtlpIntegerWChars[ Digit ]; 00594 } while ((LowValue | HighValue) != 0); 00595 } else { 00596 LARGE_INTEGER TempValue=*Value; 00597 do { 00598 TempValue = RtlExtendedLargeIntegerDivide(TempValue,Base,&Digit); 00599 *--s = RtlpIntegerWChars[ Digit ]; 00600 } while (TempValue.HighPart != 0 || TempValue.LowPart != 0); 00601 } 00602 00603 Length = (ULONG)(&Result[ 99 ] - s); 00604 if (OutputLength < 0) { 00605 OutputLength = -OutputLength; 00606 while ((LONG)Length < OutputLength) { 00607 *--s = L'0'; 00608 Length++; 00609 } 00610 } 00611 00612 if ((LONG)Length > OutputLength) { 00613 return( STATUS_BUFFER_OVERFLOW ); 00614 } 00615 else { 00616 try { 00617 RtlMoveMemory( String, s, Length * sizeof( WCHAR )); 00618 00619 if ((LONG)Length < OutputLength) { 00620 String[ Length ] = L'\0'; 00621 } 00622 } 00623 except( EXCEPTION_EXECUTE_HANDLER ) { 00624 return( GetExceptionCode() ); 00625 } 00626 00627 return( STATUS_SUCCESS ); 00628 } 00629 } 00630 00631 NTSTATUS 00632 RtlInt64ToUnicodeString ( 00633 IN ULONGLONG Value, 00634 IN ULONG Base OPTIONAL, 00635 IN OUT PUNICODE_STRING String 00636 ) 00637 00638 { 00639 00640 NTSTATUS Status; 00641 UCHAR ResultBuffer[32]; 00642 ANSI_STRING AnsiString; 00643 LARGE_INTEGER Temp; 00644 00645 Temp.QuadPart = Value; 00646 Status = RtlLargeIntegerToChar(&Temp, 00647 Base, 00648 sizeof(ResultBuffer), 00649 ResultBuffer); 00650 00651 if (NT_SUCCESS(Status)) { 00652 AnsiString.Buffer = ResultBuffer; 00653 AnsiString.MaximumLength = sizeof(ResultBuffer); 00654 AnsiString.Length = (USHORT)strlen(ResultBuffer); 00655 Status = RtlAnsiStringToUnicodeString(String, &AnsiString, FALSE); 00656 } 00657 00658 return Status; 00659 }

Generated on Sat May 15 19:39:29 2004 for test by doxygen 1.3.7