Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / rtl / unicode.c
index ede4f1f..3198002 100644 (file)
@@ -76,32 +76,59 @@ const gunichar *cs_ucs4;
 
 
 /**
- * captive_validate_ucs2:
+ * captive_validate_ucs2_fixlen:
  * @string_ucs2: #const #captive_ucs2 * type string to validate.
  * Invalid string input is forbidden.
  * UTF-16 encoded strings are forbidden.
+ * @string_ucs2_fixlen: Number of characters from @string_ucs2 to check.
+ * captive_ucs2_strlen(@string_ucs2)>=@string_ucs2_fixlen is required.
+ * Negative value is forbidden.
  *
- * Checks the validity of all 16-bit unicharacters of 0-terminated string.
+ * Checks the validity of first @string_ucs2_fixlen 16-bit unicharacters of @string_ucs2.
  * It is required to have characters complying to g_unichar_validate().
+ * String length must be equal or larger than @string_ucs2_fixlen;
  *
  * Returns: %TRUE if the string is valid.
  */ 
-gboolean captive_validate_ucs2(const captive_ucs2 *string_ucs2)
+gboolean captive_validate_ucs2_fixlen(const captive_ucs2 *string_ucs2,glong string_ucs2_fixlen)
 {
 const captive_ucs2 *cs_ucs2;
 
        g_return_val_if_fail(captive_validate_unicode_types(),FALSE);
        g_return_val_if_fail(string_ucs2!=NULL,FALSE);
+       g_return_val_if_fail(string_ucs2_fixlen>=0,FALSE);
 
        /* g_unichar_validate() will reject surrogates (G_UNICODE_SURROGATE) */
-       for (cs_ucs2=string_ucs2;*cs_ucs2;cs_ucs2++)
+       for (cs_ucs2=string_ucs2;cs_ucs2<string_ucs2+string_ucs2_fixlen;cs_ucs2++) {
+               g_return_val_if_fail(*cs_ucs2!=0,FALSE);
                g_return_val_if_fail(g_unichar_validate(*cs_ucs2),FALSE);
+               }
 
        return TRUE;
 }
 
 
 /**
+ * captive_validate_ucs2:
+ * @string_ucs2: #const #captive_ucs2 * type string to validate.
+ * Invalid string input is forbidden.
+ * UTF-16 encoded strings are forbidden.
+ *
+ * Checks the validity of all 16-bit unicharacters of 0-terminated string.
+ * It is required to have characters complying to g_unichar_validate().
+ *
+ * Returns: %TRUE if the string is valid.
+ */ 
+gboolean captive_validate_ucs2(const captive_ucs2 *string_ucs2)
+{
+       g_return_val_if_fail(captive_validate_unicode_types(),FALSE);
+       g_return_val_if_fail(string_ucs2!=NULL,FALSE);
+
+       return captive_validate_ucs2_fixlen(string_ucs2,captive_ucs2_strlen(string_ucs2));
+}
+
+
+/**
  * captive_validate_utf8:
  * @string_utf8: #const #gchar * utf8 type string to validate.
  * Invalid string input is forbidden.
@@ -139,7 +166,9 @@ glong captive_ucs2_strlen(const captive_ucs2 *string_ucs2)
 {
 glong r;
 
-       g_return_val_if_fail(captive_validate_ucs2(string_ucs2),0);
+       /* Do not call captive_validate_ucs2(string_ucs2) as we would be looping! */
+       g_return_val_if_fail(captive_validate_unicode_types(),FALSE);
+       g_return_val_if_fail(string_ucs2!=NULL,FALSE);
 
        for (r=0;*string_ucs2;string_ucs2++)
                r++;
@@ -155,6 +184,7 @@ glong r;
  *
  * Checks the internal consistency of the given @string_UnicodeString.
  * It is required to have characters complying to g_unichar_validate().
+ * @string_UnicodeString MUST be zero-terminated.
  *
  * Returns: %TRUE if the string is valid.
  */
@@ -177,6 +207,42 @@ gboolean captive_validate_UnicodeString(const UNICODE_STRING *string_UnicodeStri
 
 
 /**
+ * captive_validate_UnicodeString_noterm:
+ * @string_UnicodeString_noterm: #PUNICODE_STRING type string to validate.
+ * Invalid string input is forbidden.
+ *
+ * Checks the internal consistency of the given @string_UnicodeString.
+ * It is required to have characters complying to g_unichar_validate().
+ * @string_UnicodeString_noterm does not neet to be zero-terminated.
+ *
+ * Returns: %TRUE if the string is valid.
+ */
+gboolean captive_validate_UnicodeString_noterm(const UNICODE_STRING *string_UnicodeString_noterm)
+{
+const WCHAR *cwp;
+
+       g_return_val_if_fail(captive_validate_unicode_types(),FALSE);
+       g_return_val_if_fail(sizeof(WCHAR)==sizeof(*string_UnicodeString_noterm->Buffer),FALSE);
+       g_return_val_if_fail(string_UnicodeString_noterm!=NULL,FALSE);
+       g_return_val_if_fail(string_UnicodeString_noterm->Length%sizeof(*string_UnicodeString_noterm->Buffer)==0,FALSE);
+       g_return_val_if_fail(string_UnicodeString_noterm->MaximumLength>=string_UnicodeString_noterm->Length,FALSE);
+
+       for (
+                       cwp=string_UnicodeString_noterm->Buffer;
+                       cwp<string_UnicodeString_noterm->Buffer
+                                       +(string_UnicodeString_noterm->Length/sizeof(*string_UnicodeString_noterm->Buffer));
+                       cwp++)
+               g_return_val_if_fail(*cwp!=0,FALSE);
+
+       g_return_val_if_fail(captive_validate_ucs2_fixlen(string_UnicodeString_noterm->Buffer,
+                                       string_UnicodeString_noterm->Length/sizeof(*string_UnicodeString_noterm->Buffer)),
+                       FALSE);
+
+       return TRUE;
+}
+
+
+/**
  * captive_validate_AnsiString:
  * @string_AnsiString: #PANSI_STRING type string to validate.
  * Invalid string input is forbidden.
@@ -197,6 +263,106 @@ gboolean captive_validate_AnsiString(const ANSI_STRING *string_AnsiString)
 }
 
 
+/**
+ * captive_ucs2_compare:
+ * @string_a_ucs2: First string of type #const #gunichar2 * in pure UCS-2.
+ * Invalid string input is forbidden. UTF-16 encoded pairs are forbidden.
+ * @string_b_ucs2: Second string of type #const #gunichar2 * in pure UCS-2.
+ * Invalid string input is forbidden. UTF-16 encoded pairs are forbidden.
+ *
+ * Compares case-sensitively @string_a_ucs2 and @string_b_ucs2.
+ *
+ * Returns: %TRUE if @string_a_ucs2 and @string_b_ucs2 are the same.
+ */
+gboolean captive_ucs2_compare(const captive_ucs2 *string_a_ucs2,const captive_ucs2 *string_b_ucs2)
+{
+guint ui;
+
+       g_return_val_if_fail(captive_validate_ucs2(string_a_ucs2),FALSE);
+       g_return_val_if_fail(captive_validate_ucs2(string_b_ucs2),FALSE);
+
+       ui=0;
+       do {
+               if (string_a_ucs2[ui]!=string_b_ucs2[ui])
+                       return FALSE;
+               } while (string_a_ucs2[ui++]);
+       return TRUE;
+}
+
+
+/**
+ * captive_UnicodeString_compare:
+ * @string_a_UnicodeString: First string of type #PUNICODE_STRING.
+ * Invalid string input is forbidden.
+ * @string_b_UnicodeString: Second string of type #PUNICODE_STRING.
+ * Invalid string input is forbidden.
+ *
+ * Compares case-sensitively @string_a_UnicodeString and @string_b_UnicodeString.
+ *
+ * Returns: %TRUE if @string_a_UnicodeString and @string_b_UnicodeString are the same.
+ */
+gboolean captive_UnicodeString_compare
+               (const UNICODE_STRING *string_a_UnicodeString,const UNICODE_STRING *string_b_UnicodeString)
+{
+       g_return_val_if_fail(captive_validate_UnicodeString(string_a_UnicodeString),FALSE);
+       g_return_val_if_fail(captive_validate_UnicodeString(string_b_UnicodeString),FALSE);
+
+       if (string_a_UnicodeString->Length!=string_b_UnicodeString->Length)
+               return FALSE;
+       return captive_ucs2_compare(string_a_UnicodeString->Buffer,string_b_UnicodeString->Buffer);
+}
+
+
+/**
+ * captive_ucs2_compare_insensitive:
+ * @string_a_ucs2: First string of type #const #gunichar2 * in pure UCS-2.
+ * Invalid string input is forbidden. UTF-16 encoded pairs are forbidden.
+ * @string_b_ucs2: Second string of type #const #gunichar2 * in pure UCS-2.
+ * Invalid string input is forbidden. UTF-16 encoded pairs are forbidden.
+ *
+ * Compares case-insensitively @string_a_ucs2 and @string_b_ucs2.
+ *
+ * Returns: %TRUE if @string_a_ucs2 and @string_b_ucs2 are the same.
+ */
+gboolean captive_ucs2_compare_insensitive(const captive_ucs2 *string_a_ucs2,const captive_ucs2 *string_b_ucs2)
+{
+guint ui;
+
+       g_return_val_if_fail(captive_validate_ucs2(string_a_ucs2),FALSE);
+       g_return_val_if_fail(captive_validate_ucs2(string_b_ucs2),FALSE);
+
+       ui=0;
+       do {
+               if (g_unichar_toupper(string_a_ucs2[ui])!=g_unichar_toupper(string_b_ucs2[ui]))
+                       return FALSE;
+               } while (string_a_ucs2[ui++]);
+       return TRUE;
+}
+
+
+/**
+ * captive_UnicodeString_compare_insensitive:
+ * @string_a_UnicodeString: First string of type #PUNICODE_STRING.
+ * Invalid string input is forbidden.
+ * @string_b_UnicodeString: Second string of type #PUNICODE_STRING.
+ * Invalid string input is forbidden.
+ *
+ * Compares case-insensitively @string_a_UnicodeString and @string_b_UnicodeString.
+ *
+ * Returns: %TRUE if @string_a_UnicodeString and @string_b_UnicodeString are the same.
+ */
+gboolean captive_UnicodeString_compare_insensitive
+               (const UNICODE_STRING *string_a_UnicodeString,const UNICODE_STRING *string_b_UnicodeString)
+{
+       g_return_val_if_fail(captive_validate_UnicodeString(string_a_UnicodeString),FALSE);
+       g_return_val_if_fail(captive_validate_UnicodeString(string_b_UnicodeString),FALSE);
+
+       if (string_a_UnicodeString->Length!=string_b_UnicodeString->Length)
+               return FALSE;
+       return captive_ucs2_compare_insensitive(string_a_UnicodeString->Buffer,string_b_UnicodeString->Buffer);
+}
+
+
 /* detect required memory size for g_alloca() */
 size_t _captive_UnicodeString_to_utf8_alloca_internal_sizeof(const UNICODE_STRING *string_UnicodeString)
 {