4 * Copyright (C) 1996-1998 Marcus Meissner
5 * Copyright (C) 2000 Alexandre Julliard
13 #include "wine/unicode.h"
16 #include "debugtools.h"
17 #include "ntdll_misc.h"
20 DEFAULT_DEBUG_CHANNEL(ntdll
);
22 /* STRING CREATION FUNCTIONS */
24 /**************************************************************************
25 * RtlInitAnsiString (NTDLL.@)
27 void WINAPI
RtlInitAnsiString( PSTRING target
, LPCSTR source
)
29 if ((target
->Buffer
= (LPSTR
)source
))
31 target
->Length
= strlen(source
);
32 target
->MaximumLength
= target
->Length
+ 1;
34 else target
->Length
= target
->MaximumLength
= 0;
38 /**************************************************************************
39 * RtlInitString (NTDLL.@)
41 void WINAPI
RtlInitString( PSTRING target
, LPCSTR source
)
43 return RtlInitAnsiString( target
, source
);
47 /**************************************************************************
48 * RtlFreeAnsiString (NTDLL.@)
50 void WINAPI
RtlFreeAnsiString( PSTRING str
)
52 if (str
->Buffer
) HeapFree( GetProcessHeap(), 0, str
->Buffer
);
56 /**************************************************************************
57 * RtlFreeOemString (NTDLL.@)
59 void WINAPI
RtlFreeOemString( PSTRING str
)
61 RtlFreeAnsiString( str
);
65 /**************************************************************************
66 * RtlCopyString (NTDLL.@)
68 void WINAPI
RtlCopyString( STRING
*dst
, const STRING
*src
)
72 unsigned int len
= min( src
->Length
, dst
->MaximumLength
);
73 memcpy( dst
->Buffer
, src
->Buffer
, len
);
80 /**************************************************************************
81 * RtlInitUnicodeString (NTDLL.@)
83 void WINAPI
RtlInitUnicodeString( PUNICODE_STRING target
, LPCWSTR source
)
85 if ((target
->Buffer
= (LPWSTR
)source
))
87 target
->Length
= strlenW(source
) * sizeof(WCHAR
);
88 target
->MaximumLength
= target
->Length
+ sizeof(WCHAR
);
90 else target
->Length
= target
->MaximumLength
= 0;
94 /**************************************************************************
95 * RtlCreateUnicodeString (NTDLL.@)
97 BOOLEAN WINAPI
RtlCreateUnicodeString( PUNICODE_STRING target
, LPCWSTR src
)
99 int len
= (strlenW(src
) + 1) * sizeof(WCHAR
);
100 if (!(target
->Buffer
= HeapAlloc( GetProcessHeap(), 0, len
))) return FALSE
;
101 memcpy( target
->Buffer
, src
, len
);
102 target
->MaximumLength
= len
;
103 target
->Length
= len
- 2;
108 /**************************************************************************
109 * RtlCreateUnicodeStringFromAsciiz (NTDLL.@)
111 BOOLEAN WINAPI
RtlCreateUnicodeStringFromAsciiz( PUNICODE_STRING target
, LPCSTR src
)
114 RtlInitAnsiString( &ansi
, src
);
115 return !RtlAnsiStringToUnicodeString( target
, &ansi
, TRUE
);
119 /**************************************************************************
120 * RtlFreeUnicodeString (NTDLL.@)
122 void WINAPI
RtlFreeUnicodeString( PUNICODE_STRING str
)
124 if (str
->Buffer
) HeapFree( GetProcessHeap(), 0, str
->Buffer
);
128 /**************************************************************************
129 * RtlCopyUnicodeString (NTDLL.@)
131 void WINAPI
RtlCopyUnicodeString( UNICODE_STRING
*dst
, const UNICODE_STRING
*src
)
135 unsigned int len
= min( src
->Length
, dst
->MaximumLength
);
136 memcpy( dst
->Buffer
, src
->Buffer
, len
);
138 /* append terminating NULL if enough space */
139 if (len
< dst
->MaximumLength
) dst
->Buffer
[len
/ sizeof(WCHAR
)] = 0;
141 else dst
->Length
= 0;
145 /**************************************************************************
146 * RtlEraseUnicodeString (NTDLL.@)
148 void WINAPI
RtlEraseUnicodeString( UNICODE_STRING
*str
)
152 memset( str
->Buffer
, 0, str
->MaximumLength
);
161 /******************************************************************************
162 * RtlCompareString (NTDLL.@)
164 LONG WINAPI
RtlCompareString( const STRING
*s1
, const STRING
*s2
, BOOLEAN CaseInsensitive
)
170 len
= min(s1
->Length
, s2
->Length
);
176 while (!ret
&& len
--) ret
= toupper(*p1
++) - toupper(*p2
++);
180 while (!ret
&& len
--) ret
= *p1
++ - *p2
++;
182 if (!ret
) ret
= s1
->Length
- s2
->Length
;
187 /******************************************************************************
188 * RtlCompareUnicodeString (NTDLL.@)
190 LONG WINAPI
RtlCompareUnicodeString( const UNICODE_STRING
*s1
, const UNICODE_STRING
*s2
,
191 BOOLEAN CaseInsensitive
)
197 len
= min(s1
->Length
, s2
->Length
) / sizeof(WCHAR
);
203 while (!ret
&& len
--) ret
= toupperW(*p1
++) - toupperW(*p2
++);
207 while (!ret
&& len
--) ret
= *p1
++ - *p2
++;
209 if (!ret
) ret
= s1
->Length
- s2
->Length
;
214 /**************************************************************************
215 * RtlEqualString (NTDLL.@)
217 BOOLEAN WINAPI
RtlEqualString( const STRING
*s1
, const STRING
*s2
, BOOLEAN CaseInsensitive
)
219 if (s1
->Length
!= s2
->Length
) return FALSE
;
220 return !RtlCompareString( s1
, s2
, CaseInsensitive
);
224 /**************************************************************************
225 * RtlEqualUnicodeString (NTDLL.@)
227 BOOLEAN WINAPI
RtlEqualUnicodeString( const UNICODE_STRING
*s1
, const UNICODE_STRING
*s2
,
228 BOOLEAN CaseInsensitive
)
230 if (s1
->Length
!= s2
->Length
) return FALSE
;
231 return !RtlCompareUnicodeString( s1
, s2
, CaseInsensitive
);
235 /**************************************************************************
236 * RtlPrefixString (NTDLL.@)
238 * Test if s1 is a prefix in s2
240 BOOLEAN WINAPI
RtlPrefixString( const STRING
*s1
, const STRING
*s2
, BOOLEAN ignore_case
)
244 if (s1
->Length
> s2
->Length
) return FALSE
;
247 for (i
= 0; i
< s1
->Length
; i
++)
248 if (toupper(s1
->Buffer
[i
]) != toupper(s2
->Buffer
[i
])) return FALSE
;
252 for (i
= 0; i
< s1
->Length
; i
++)
253 if (s1
->Buffer
[i
] != s2
->Buffer
[i
]) return FALSE
;
259 /**************************************************************************
260 * RtlPrefixUnicodeString (NTDLL.@)
262 * Test if s1 is a prefix in s2
264 BOOLEAN WINAPI
RtlPrefixUnicodeString( const UNICODE_STRING
*s1
,
265 const UNICODE_STRING
*s2
,
266 BOOLEAN ignore_case
)
270 if (s1
->Length
> s2
->Length
) return FALSE
;
273 for (i
= 0; i
< s1
->Length
/ sizeof(WCHAR
); i
++)
274 if (toupper(s1
->Buffer
[i
]) != toupper(s2
->Buffer
[i
])) return FALSE
;
278 for (i
= 0; i
< s1
->Length
/ sizeof(WCHAR
); i
++)
279 if (s1
->Buffer
[i
] != s2
->Buffer
[i
]) return FALSE
;
286 COPY BETWEEN ANSI_STRING or UNICODE_STRING
287 there is no parameter checking, it just crashes
291 /**************************************************************************
292 * RtlAnsiStringToUnicodeString (NTDLL.@)
295 * writes terminating 0
297 NTSTATUS WINAPI
RtlAnsiStringToUnicodeString( UNICODE_STRING
*uni
,
301 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, ansi
->Buffer
, ansi
->Length
, NULL
, 0 );
302 DWORD total
= (len
+ 1) * sizeof(WCHAR
);
304 if (total
> 0xffff) return STATUS_INVALID_PARAMETER_2
;
305 uni
->Length
= len
* sizeof(WCHAR
);
308 uni
->MaximumLength
= total
;
309 if (!(uni
->Buffer
= HeapAlloc( GetProcessHeap(), 0, total
))) return STATUS_NO_MEMORY
;
311 else if (total
> uni
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
313 MultiByteToWideChar( CP_ACP
, 0, ansi
->Buffer
, ansi
->Length
, uni
->Buffer
, len
);
314 uni
->Buffer
[len
] = 0;
315 return STATUS_SUCCESS
;
319 /**************************************************************************
320 * RtlOemStringToUnicodeString (NTDLL.@)
323 * writes terminating 0
324 * if resulting length > 0xffff it returns STATUS_INVALID_PARAMETER_2
326 NTSTATUS WINAPI
RtlOemStringToUnicodeString( UNICODE_STRING
*uni
,
330 DWORD len
= MultiByteToWideChar( CP_OEMCP
, 0, oem
->Buffer
, oem
->Length
, NULL
, 0 );
331 DWORD total
= (len
+ 1) * sizeof(WCHAR
);
333 if (total
> 0xffff) return STATUS_INVALID_PARAMETER_2
;
334 uni
->Length
= len
* sizeof(WCHAR
);
337 uni
->MaximumLength
= total
;
338 if (!(uni
->Buffer
= HeapAlloc( GetProcessHeap(), 0, total
))) return STATUS_NO_MEMORY
;
340 else if (total
> uni
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
342 MultiByteToWideChar( CP_OEMCP
, 0, oem
->Buffer
, oem
->Length
, uni
->Buffer
, len
);
343 uni
->Buffer
[len
] = 0;
344 return STATUS_SUCCESS
;
348 /**************************************************************************
349 * RtlUnicodeStringToAnsiString (NTDLL.@)
352 * writes terminating 0
353 * copies a part if the buffer is too small
355 NTSTATUS WINAPI
RtlUnicodeStringToAnsiString( STRING
*ansi
,
356 const UNICODE_STRING
*uni
,
359 NTSTATUS ret
= STATUS_SUCCESS
;
360 DWORD len
= RtlUnicodeStringToAnsiSize( uni
);
365 ansi
->MaximumLength
= len
+ 1;
366 if (!(ansi
->Buffer
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 ))) return STATUS_NO_MEMORY
;
368 else if (ansi
->MaximumLength
<= len
)
370 if (!ansi
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
371 ansi
->Length
= ansi
->MaximumLength
- 1;
372 ret
= STATUS_BUFFER_OVERFLOW
;
375 WideCharToMultiByte( CP_ACP
, 0, uni
->Buffer
, uni
->Length
/ sizeof(WCHAR
),
376 ansi
->Buffer
, ansi
->Length
, NULL
, NULL
);
377 ansi
->Buffer
[ansi
->Length
] = 0;
382 /**************************************************************************
383 * RtlUnicodeStringToOemString (NTDLL.@)
386 * allocates uni->Length+1
387 * writes terminating 0
389 NTSTATUS WINAPI
RtlUnicodeStringToOemString( STRING
*oem
,
390 const UNICODE_STRING
*uni
,
393 NTSTATUS ret
= STATUS_SUCCESS
;
394 DWORD len
= RtlUnicodeStringToOemSize( uni
);
399 oem
->MaximumLength
= len
+ 1;
400 if (!(oem
->Buffer
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 ))) return STATUS_NO_MEMORY
;
402 else if (oem
->MaximumLength
<= len
)
404 if (!oem
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
405 oem
->Length
= oem
->MaximumLength
- 1;
406 ret
= STATUS_BUFFER_OVERFLOW
;
409 WideCharToMultiByte( CP_OEMCP
, 0, uni
->Buffer
, uni
->Length
/ sizeof(WCHAR
),
410 oem
->Buffer
, oem
->Length
, NULL
, NULL
);
411 oem
->Buffer
[oem
->Length
] = 0;
416 /**************************************************************************
417 * RtlMultiByteToUnicodeN (NTDLL.@)
420 * if unistr is too small a part is copied
422 NTSTATUS WINAPI
RtlMultiByteToUnicodeN( LPWSTR dst
, DWORD dstlen
, LPDWORD reslen
,
423 LPCSTR src
, DWORD srclen
)
425 DWORD res
= MultiByteToWideChar( CP_ACP
, 0, src
, srclen
, dst
, dstlen
/sizeof(WCHAR
) );
427 *reslen
= res
? res
* sizeof(WCHAR
) : dstlen
; /* overflow -> we filled up to dstlen */
428 return STATUS_SUCCESS
;
432 /**************************************************************************
433 * RtlOemToUnicodeN (NTDLL.@)
435 NTSTATUS WINAPI
RtlOemToUnicodeN( LPWSTR dst
, DWORD dstlen
, LPDWORD reslen
,
436 LPCSTR src
, DWORD srclen
)
438 DWORD res
= MultiByteToWideChar( CP_OEMCP
, 0, src
, srclen
, dst
, dstlen
/sizeof(WCHAR
) );
440 *reslen
= res
? res
* sizeof(WCHAR
) : dstlen
; /* overflow -> we filled up to dstlen */
441 return STATUS_SUCCESS
;
445 /**************************************************************************
446 * RtlUnicodeToMultiByteN (NTDLL.@)
448 NTSTATUS WINAPI
RtlUnicodeToMultiByteN( LPSTR dst
, DWORD dstlen
, LPDWORD reslen
,
449 LPCWSTR src
, DWORD srclen
)
451 DWORD res
= WideCharToMultiByte( CP_ACP
, 0, src
, srclen
/sizeof(WCHAR
),
452 dst
, dstlen
, NULL
, NULL
);
454 *reslen
= res
? res
* sizeof(WCHAR
) : dstlen
; /* overflow -> we filled up to dstlen */
455 return STATUS_SUCCESS
;
459 /**************************************************************************
460 * RtlUnicodeToOemN (NTDLL.@)
462 NTSTATUS WINAPI
RtlUnicodeToOemN( LPSTR dst
, DWORD dstlen
, LPDWORD reslen
,
463 LPCWSTR src
, DWORD srclen
)
465 DWORD res
= WideCharToMultiByte( CP_OEMCP
, 0, src
, srclen
/sizeof(WCHAR
),
466 dst
, dstlen
, NULL
, NULL
);
468 *reslen
= res
? res
* sizeof(WCHAR
) : dstlen
; /* overflow -> we filled up to dstlen */
469 return STATUS_SUCCESS
;
477 /**************************************************************************
478 * RtlUpperString (NTDLL.@)
480 void WINAPI
RtlUpperString( STRING
*dst
, const STRING
*src
)
482 unsigned int i
, len
= min(src
->Length
, dst
->MaximumLength
);
484 for (i
= 0; i
< len
; i
++) dst
->Buffer
[i
] = toupper(src
->Buffer
[i
]);
489 /**************************************************************************
490 * RtlUpcaseUnicodeString (NTDLL.@)
493 * destination string is never 0-terminated because dest can be equal to src
494 * and src might be not 0-terminated
495 * dest.Length only set when success
497 NTSTATUS WINAPI
RtlUpcaseUnicodeString( UNICODE_STRING
*dest
,
498 const UNICODE_STRING
*src
,
501 DWORD i
, len
= src
->Length
;
505 dest
->MaximumLength
= len
;
506 if (!(dest
->Buffer
= HeapAlloc( GetProcessHeap(), 0, len
))) return STATUS_NO_MEMORY
;
508 else if (len
> dest
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
510 for (i
= 0; i
< len
/sizeof(WCHAR
); i
++) dest
->Buffer
[i
] = toupperW(src
->Buffer
[i
]);
512 return STATUS_SUCCESS
;
516 /**************************************************************************
517 * RtlUpcaseUnicodeStringToAnsiString (NTDLL.@)
520 * writes terminating 0
522 NTSTATUS WINAPI
RtlUpcaseUnicodeStringToAnsiString( STRING
*dst
,
523 const UNICODE_STRING
*src
,
527 UNICODE_STRING upcase
;
529 if (!(ret
= RtlUpcaseUnicodeString( &upcase
, src
, TRUE
)))
531 ret
= RtlUnicodeStringToAnsiString( dst
, &upcase
, doalloc
);
532 RtlFreeUnicodeString( &upcase
);
538 /**************************************************************************
539 * RtlUpcaseUnicodeStringToOemString (NTDLL.@)
542 * writes terminating 0
544 NTSTATUS WINAPI
RtlUpcaseUnicodeStringToOemString( STRING
*dst
,
545 const UNICODE_STRING
*src
,
549 UNICODE_STRING upcase
;
551 if (!(ret
= RtlUpcaseUnicodeString( &upcase
, src
, TRUE
)))
553 ret
= RtlUnicodeStringToOemString( dst
, &upcase
, doalloc
);
554 RtlFreeUnicodeString( &upcase
);
560 /**************************************************************************
561 * RtlUpcaseUnicodeToMultiByteN (NTDLL.@)
563 NTSTATUS WINAPI
RtlUpcaseUnicodeToMultiByteN( LPSTR dst
, DWORD dstlen
, LPDWORD reslen
,
564 LPCWSTR src
, DWORD srclen
)
570 if (!(upcase
= HeapAlloc( GetProcessHeap(), 0, srclen
))) return STATUS_NO_MEMORY
;
571 for (i
= 0; i
< srclen
/sizeof(WCHAR
); i
++) upcase
[i
] = toupperW(src
[i
]);
572 ret
= RtlUnicodeToMultiByteN( dst
, dstlen
, reslen
, upcase
, srclen
);
573 HeapFree( GetProcessHeap(), 0, upcase
);
578 /**************************************************************************
579 * RtlUpcaseUnicodeToOemN (NTDLL.@)
581 NTSTATUS WINAPI
RtlUpcaseUnicodeToOemN( LPSTR dst
, DWORD dstlen
, LPDWORD reslen
,
582 LPCWSTR src
, DWORD srclen
)
588 if (!(upcase
= HeapAlloc( GetProcessHeap(), 0, srclen
))) return STATUS_NO_MEMORY
;
589 for (i
= 0; i
< srclen
/sizeof(WCHAR
); i
++) upcase
[i
] = toupperW(src
[i
]);
590 ret
= RtlUnicodeToOemN( dst
, dstlen
, reslen
, upcase
, srclen
);
591 HeapFree( GetProcessHeap(), 0, upcase
);
600 /**************************************************************************
601 * RtlOemStringToUnicodeSize (NTDLL.@)
603 * Return the size in bytes necessary for the Unicode conversion of 'str',
604 * including the terminating NULL.
606 UINT WINAPI
RtlOemStringToUnicodeSize(PSTRING str
)
608 DWORD ret
= MultiByteToWideChar( CP_OEMCP
, 0, str
->Buffer
, str
->Length
, NULL
, 0 );
609 return (ret
+ 1) * sizeof(WCHAR
);
613 /**************************************************************************
614 * RtlAnsiStringToUnicodeSize (NTDLL.@)
616 * Return the size in bytes necessary for the Unicode conversion of 'str',
617 * including the terminating NULL.
619 DWORD WINAPI
RtlAnsiStringToUnicodeSize(PSTRING str
)
621 DWORD ret
= MultiByteToWideChar( CP_ACP
, 0, str
->Buffer
, str
->Length
, NULL
, 0 );
622 return (ret
+ 1) * sizeof(WCHAR
);
626 /**************************************************************************
627 * RtlMultiByteToUnicodeSize (NTDLL.@)
629 * Compute the size in bytes necessary for the Unicode conversion of 'str',
630 * without the terminating NULL.
632 NTSTATUS WINAPI
RtlMultiByteToUnicodeSize( DWORD
*size
, LPCSTR str
, UINT len
)
634 *size
= MultiByteToWideChar( CP_ACP
, 0, str
, len
, NULL
, 0 ) * sizeof(WCHAR
);
639 /**************************************************************************
640 * RtlUnicodeToMultiByteSize (NTDLL.@)
642 * Compute the size necessary for the multibyte conversion of 'str',
643 * without the terminating NULL.
645 NTSTATUS WINAPI
RtlUnicodeToMultiByteSize( DWORD
*size
, LPCWSTR str
, UINT len
)
647 *size
= WideCharToMultiByte( CP_ACP
, 0, str
, len
/ sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
652 /**************************************************************************
653 * RtlUnicodeStringToAnsiSize (NTDLL.@)
655 * Return the size in bytes necessary for the Ansi conversion of 'str',
656 * including the terminating NULL.
658 DWORD WINAPI
RtlUnicodeStringToAnsiSize( const UNICODE_STRING
*str
)
660 return WideCharToMultiByte( CP_ACP
, 0, str
->Buffer
, str
->Length
/ sizeof(WCHAR
),
661 NULL
, 0, NULL
, NULL
) + 1;
665 /**************************************************************************
666 * RtlUnicodeStringToOemSize (NTDLL.@)
668 * Return the size in bytes necessary for the OEM conversion of 'str',
669 * including the terminating NULL.
671 DWORD WINAPI
RtlUnicodeStringToOemSize( const UNICODE_STRING
*str
)
673 return WideCharToMultiByte( CP_OEMCP
, 0, str
->Buffer
, str
->Length
/ sizeof(WCHAR
),
674 NULL
, 0, NULL
, NULL
) + 1;
678 /**************************************************************************
679 * RtlAppendStringToString (NTDLL.@)
681 NTSTATUS WINAPI
RtlAppendStringToString( STRING
*dst
, const STRING
*src
)
683 unsigned int len
= src
->Length
+ dst
->Length
;
684 if (len
> dst
->MaximumLength
) return STATUS_BUFFER_TOO_SMALL
;
685 memcpy( dst
->Buffer
+ dst
->Length
, src
->Buffer
, src
->Length
);
687 return STATUS_SUCCESS
;
691 /**************************************************************************
692 * RtlAppendAsciizToString (NTDLL.@)
694 NTSTATUS WINAPI
RtlAppendAsciizToString( STRING
*dst
, LPCSTR src
)
698 unsigned int srclen
= strlen(src
);
699 unsigned int total
= srclen
+ dst
->Length
;
700 if (total
> dst
->MaximumLength
) return STATUS_BUFFER_TOO_SMALL
;
701 memcpy( dst
->Buffer
+ dst
->Length
, src
, srclen
);
704 return STATUS_SUCCESS
;
708 /**************************************************************************
709 * RtlAppendUnicodeToString (NTDLL.@)
711 NTSTATUS WINAPI
RtlAppendUnicodeToString( UNICODE_STRING
*dst
, LPCWSTR src
)
715 unsigned int srclen
= strlenW(src
) * sizeof(WCHAR
);
716 unsigned int total
= srclen
+ dst
->Length
;
717 if (total
> dst
->MaximumLength
) return STATUS_BUFFER_TOO_SMALL
;
718 memcpy( dst
->Buffer
+ dst
->Length
/sizeof(WCHAR
), src
, srclen
);
720 /* append terminating NULL if enough space */
721 if (total
< dst
->MaximumLength
) dst
->Buffer
[total
/ sizeof(WCHAR
)] = 0;
723 return STATUS_SUCCESS
;
727 /**************************************************************************
728 * RtlAppendUnicodeStringToString (NTDLL.@)
730 NTSTATUS WINAPI
RtlAppendUnicodeStringToString( UNICODE_STRING
*dst
, const UNICODE_STRING
*src
)
732 unsigned int len
= src
->Length
+ dst
->Length
;
733 if (len
> dst
->MaximumLength
) return STATUS_BUFFER_TOO_SMALL
;
734 memcpy( dst
->Buffer
+ dst
->Length
/sizeof(WCHAR
), src
->Buffer
, src
->Length
);
736 /* append terminating NULL if enough space */
737 if (len
< dst
->MaximumLength
) dst
->Buffer
[len
/ sizeof(WCHAR
)] = 0;
738 return STATUS_SUCCESS
;
746 /**************************************************************************
749 * Apply various feeble heuristics to guess whether
750 * the text buffer contains Unicode.
751 * FIXME: should implement more tests.
753 DWORD WINAPI
RtlIsTextUnicode(
759 DWORD flags
= -1, out_flags
= 0;
766 * Apply various tests to the text string. According to the
767 * docs, each test "passed" sets the corresponding flag in
768 * the output flags. But some of the tests are mutually
769 * exclusive, so I don't see how you could pass all tests ...
772 /* Check for an odd length ... pass if even. */
774 out_flags
|= IS_TEXT_UNICODE_ODD_LENGTH
;
776 /* Check for the special unicode marker byte. */
778 out_flags
|= IS_TEXT_UNICODE_SIGNATURE
;
781 * Check whether the string passed all of the tests.
783 flags
&= ITU_IMPLEMENTED_TESTS
;
784 if ((out_flags
& flags
) != flags
)