From: Behdad Esfahbod Date: Fri, 26 Aug 2011 07:18:53 +0000 (+0200) Subject: [API] Make all _from_string() functions take a len parameter X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4c9fe88d30036340fe592bcbc375049b84602b8b;p=platform%2Fupstream%2FlibHarfBuzzSharp.git [API] Make all _from_string() functions take a len parameter Can be -1 for NUL-terminated string. This is useful for passing parts of a larger string to a function without having to copy or modify the string first. Affected functions: hb_tag_t hb_tag_from_string() hb_direction_from_string() hb_language_from_string() hb_script_from_string() --- diff --git a/src/hb-common.cc b/src/hb-common.cc index 48382ca..6093289 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -40,15 +40,17 @@ /* hb_tag_t */ hb_tag_t -hb_tag_from_string (const char *s) +hb_tag_from_string (const char *s, int len) { char tag[4]; unsigned int i; - if (!s || !*s) + if (!s || !len || !*s) return HB_TAG_NONE; - for (i = 0; i < 4 && s[i]; i++) + if (len < 0 || len > 4) + len = 4; + for (i = 0; i < (unsigned) len && s[i]; i++) tag[i] = s[i]; for (; i < 4; i++) tag[i] = ' '; @@ -67,9 +69,9 @@ const char direction_strings[][4] = { }; hb_direction_t -hb_direction_from_string (const char *str) +hb_direction_from_string (const char *str, int len) { - if (unlikely (!str || !*str)) + if (unlikely (!str || !len || !*str)) return HB_DIRECTION_INVALID; /* Lets match loosely: just match the first letter, such that @@ -167,11 +169,18 @@ static struct hb_static_lang_set_t : hb_lockable_set_t= 0) { + len = MIN (len, (int) sizeof (strbuf) - 1); + str = (char *) memcpy (strbuf, str, len); + strbuf[len] = '\0'; + } + hb_language_item_t *item = langs.find_or_insert (str, langs.lock); return likely (item) ? item->lang : HB_LANGUAGE_INVALID; @@ -197,7 +206,7 @@ hb_language_get_default (void) /* I hear that setlocale() doesn't honor env vars on Windows, * but for now we ignore that. */ - default_language = hb_language_from_string (setlocale (LC_CTYPE, NULL)); + default_language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1); } return default_language; @@ -241,9 +250,9 @@ hb_script_from_iso15924_tag (hb_tag_t tag) } hb_script_t -hb_script_from_string (const char *s) +hb_script_from_string (const char *s, int len) { - return hb_script_from_iso15924_tag (hb_tag_from_string (s)); + return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); } hb_tag_t diff --git a/src/hb-common.h b/src/hb-common.h index e4f1991..b7fef32 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -89,7 +89,8 @@ typedef uint32_t hb_tag_t; #define HB_TAG_NONE HB_TAG(0,0,0,0) -hb_tag_t hb_tag_from_string (const char *s); +/* len=-1 means s is NUL-terminated */ +hb_tag_t hb_tag_from_string (const char *s, int len); /* hb_direction_t */ @@ -102,8 +103,9 @@ typedef enum { HB_DIRECTION_BTT } hb_direction_t; +/* len=-1 means s is NUL-terminated */ hb_direction_t -hb_direction_from_string (const char *str); +hb_direction_from_string (const char *str, int len); const char * hb_direction_to_string (hb_direction_t direction); @@ -119,8 +121,9 @@ hb_direction_to_string (hb_direction_t direction); typedef struct _hb_language_t *hb_language_t; +/* len=-1 means s is NUL-terminated */ hb_language_t -hb_language_from_string (const char *str); +hb_language_from_string (const char *str, int len); const char * hb_language_to_string (hb_language_t language); @@ -293,8 +296,9 @@ hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag); /* suger for tag_from_string() then script_from_iso15924_tag */ +/* len=-1 means s is NUL-terminated */ hb_script_t -hb_script_from_string (const char *s); +hb_script_from_string (const char *s, int len); hb_tag_t hb_script_to_iso15924_tag (hb_script_t script); diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index dfeab9f..76b8a2f 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -238,7 +238,7 @@ hb_graphite_shape (hb_font_t *font, /* XXX(behdad): Do we need OT lang tag here? */ const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); - gr_feature_val *feats = gr_face_featureval_for_lang (data->grface, lang ? hb_tag_from_string (lang) : 0); + gr_feature_val *feats = gr_face_featureval_for_lang (data->grface, lang ? hb_tag_from_string (lang, -1) : 0); while (num_features--) { diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 82e4989..0f5ed1c 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -46,7 +46,7 @@ hb_icu_script_to_script (UScriptCode script) if (unlikely (script == USCRIPT_INVALID_CODE)) return HB_SCRIPT_INVALID; - return hb_script_from_string (uscript_getShortName (script)); + return hb_script_from_string (uscript_getShortName (script), -1); } UScriptCode diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index e910f95..dcae8f1 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -664,12 +664,12 @@ hb_ot_tag_to_language (hb_tag_t tag) for (i = 0; i < ARRAY_LENGTH (ot_languages); i++) if (ot_languages[i].tag == tag) - return hb_language_from_string (ot_languages[i].language); + return hb_language_from_string (ot_languages[i].language, -1); /* If tag starts with ZH, it's Chinese */ if ((tag & 0xFFFF0000) == 0x5A480000) { switch (tag) { - case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk"); /* Hong Kong */ + case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */ default: { /* Encode the tag... */ unsigned char buf[14] = "zh-x-hbot"; @@ -680,7 +680,7 @@ hb_ot_tag_to_language (hb_tag_t tag) if (buf[12] == 0x20) buf[12] = '\0'; buf[13] = '\0'; - return hb_language_from_string ((char *) buf); + return hb_language_from_string ((char *) buf, -1); } } } @@ -695,7 +695,7 @@ hb_ot_tag_to_language (hb_tag_t tag) if (buf[9] == 0x20) buf[9] = '\0'; buf[10] = '\0'; - return hb_language_from_string ((char *) buf); + return hb_language_from_string ((char *) buf, -1); } } diff --git a/test/test-buffer.c b/test/test-buffer.c index ec32e15..ab818d0 100644 --- a/test/test-buffer.c +++ b/test/test-buffer.c @@ -124,8 +124,8 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data) hb_buffer_set_script (b, HB_SCRIPT_ARABIC); g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC); - hb_buffer_set_language (b, hb_language_from_string ("fa")); - g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa")); + hb_buffer_set_language (b, hb_language_from_string ("fa", -1)); + g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1)); /* test reset clears properties */ diff --git a/test/test-common.c b/test/test-common.c index d5cbfc7..e00e601 100644 --- a/test/test-common.c +++ b/test/test-common.c @@ -79,14 +79,15 @@ test_types_direction (void) g_assert_cmpint (HB_DIRECTION_REVERSE (HB_DIRECTION_TTB), ==, HB_DIRECTION_BTT); g_assert_cmpint (HB_DIRECTION_REVERSE (HB_DIRECTION_BTT), ==, HB_DIRECTION_TTB); - g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string (NULL)); - g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string ("")); - g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string ("x")); - g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("r")); - g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("rtl")); - g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("RtL")); - g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("right-to-left")); - g_assert_cmpint (HB_DIRECTION_TTB, ==, hb_direction_from_string ("ttb")); + g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string (NULL, -1)); + g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string ("", -1)); + g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string ("t", 0)); + g_assert_cmpint (HB_DIRECTION_INVALID, ==, hb_direction_from_string ("x", -1)); + g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("r", -1)); + g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("rtl", -1)); + g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("RtL", -1)); + g_assert_cmpint (HB_DIRECTION_RTL, ==, hb_direction_from_string ("right-to-left", -1)); + g_assert_cmpint (HB_DIRECTION_TTB, ==, hb_direction_from_string ("ttb", -1)); g_assert (0 == strcmp ("ltr", hb_direction_to_string (HB_DIRECTION_LTR))); g_assert (0 == strcmp ("rtl", hb_direction_to_string (HB_DIRECTION_RTL))); @@ -102,14 +103,20 @@ test_types_tag (void) g_assert_cmphex (HB_TAG ('a','B','c','D'), ==, 0x61426344); - g_assert_cmphex (hb_tag_from_string ("aBcDe"), ==, 0x61426344); - g_assert_cmphex (hb_tag_from_string ("aBcD"), ==, 0x61426344); - g_assert_cmphex (hb_tag_from_string ("aBc"), ==, 0x61426320); - g_assert_cmphex (hb_tag_from_string ("aB"), ==, 0x61422020); - g_assert_cmphex (hb_tag_from_string ("a"), ==, 0x61202020); - - g_assert_cmphex (hb_tag_from_string (""), ==, HB_TAG_NONE); - g_assert_cmphex (hb_tag_from_string (NULL), ==, HB_TAG_NONE); + g_assert_cmphex (hb_tag_from_string ("aBcDe", -1), ==, 0x61426344); + g_assert_cmphex (hb_tag_from_string ("aBcD", -1), ==, 0x61426344); + g_assert_cmphex (hb_tag_from_string ("aBc", -1), ==, 0x61426320); + g_assert_cmphex (hb_tag_from_string ("aB", -1), ==, 0x61422020); + g_assert_cmphex (hb_tag_from_string ("a", -1), ==, 0x61202020); + g_assert_cmphex (hb_tag_from_string ("aBcDe", 1), ==, 0x61202020); + g_assert_cmphex (hb_tag_from_string ("aBcDe", 2), ==, 0x61422020); + g_assert_cmphex (hb_tag_from_string ("aBcDe", 3), ==, 0x61426320); + g_assert_cmphex (hb_tag_from_string ("aBcDe", 4), ==, 0x61426344); + g_assert_cmphex (hb_tag_from_string ("aBcDe", 4), ==, 0x61426344); + + g_assert_cmphex (hb_tag_from_string ("", -1), ==, HB_TAG_NONE); + g_assert_cmphex (hb_tag_from_string ("x", 0), ==, HB_TAG_NONE); + g_assert_cmphex (hb_tag_from_string (NULL, -1), ==, HB_TAG_NONE); } static void @@ -127,23 +134,26 @@ test_types_script (void) g_assert_cmpint (HB_SCRIPT_INVALID, ==, (hb_script_t) HB_TAG_NONE); g_assert_cmphex (HB_SCRIPT_ARABIC, !=, HB_SCRIPT_LATIN); - g_assert_cmphex (HB_SCRIPT_INVALID, ==, hb_script_from_string (NULL)); - g_assert_cmphex (HB_SCRIPT_INVALID, ==, hb_script_from_string ("")); - g_assert_cmphex (HB_SCRIPT_UNKNOWN, ==, hb_script_from_string ("x")); + g_assert_cmphex (HB_SCRIPT_INVALID, ==, hb_script_from_string (NULL, -1)); + g_assert_cmphex (HB_SCRIPT_INVALID, ==, hb_script_from_string ("", -1)); + g_assert_cmphex (HB_SCRIPT_INVALID, ==, hb_script_from_string ("x", 0)); + g_assert_cmphex (HB_SCRIPT_UNKNOWN, ==, hb_script_from_string ("x", -1)); - g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("arab")); - g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("Arab")); - g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("ARAB")); + g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("arab", -1)); + g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("Arab", -1)); + g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("ARAB", -1)); + g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_string ("Arabic", 6)); + g_assert_cmphex (HB_SCRIPT_ARABIC, !=, hb_script_from_string ("Arabic", 3)); g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_iso15924_tag (arab)); g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_iso15924_tag (Arab)); g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_iso15924_tag (ARAB)); /* Arbitrary tags that look like may be valid ISO 15924 should be preserved. */ - g_assert_cmphex (HB_SCRIPT_UNKNOWN, !=, hb_script_from_string ("wWyZ")); + g_assert_cmphex (HB_SCRIPT_UNKNOWN, !=, hb_script_from_string ("wWyZ", -1)); g_assert_cmphex (HB_SCRIPT_UNKNOWN, !=, hb_script_from_iso15924_tag (wWyZ)); /* Otherwise, UNKNOWN should be returned. */ - g_assert_cmphex (HB_SCRIPT_UNKNOWN, ==, hb_script_from_string ("x123")); + g_assert_cmphex (HB_SCRIPT_UNKNOWN, ==, hb_script_from_string ("x123", -1)); g_assert_cmphex (HB_SCRIPT_UNKNOWN, ==, hb_script_from_iso15924_tag (x123)); g_assert_cmphex (hb_script_to_iso15924_tag (HB_SCRIPT_ARABIC), ==, Arab); @@ -157,10 +167,10 @@ test_types_script (void) static void test_types_language (void) { - hb_language_t fa = hb_language_from_string ("fa"); - hb_language_t fa_IR = hb_language_from_string ("fa_IR"); - hb_language_t fa_ir = hb_language_from_string ("fa-ir"); - hb_language_t en = hb_language_from_string ("en"); + hb_language_t fa = hb_language_from_string ("fa", -1); + hb_language_t fa_IR = hb_language_from_string ("fa_IR", -1); + hb_language_t fa_ir = hb_language_from_string ("fa-ir", -1); + hb_language_t en = hb_language_from_string ("en", -1); g_assert (HB_LANGUAGE_INVALID == NULL); @@ -172,11 +182,14 @@ test_types_language (void) g_assert (en != fa); /* Test recall */ - g_assert (en == hb_language_from_string ("en")); - g_assert (en == hb_language_from_string ("eN")); - - g_assert (HB_LANGUAGE_INVALID == hb_language_from_string (NULL)); - g_assert (HB_LANGUAGE_INVALID == hb_language_from_string ("")); + g_assert (en == hb_language_from_string ("en", -1)); + g_assert (en == hb_language_from_string ("eN", -1)); + g_assert (en == hb_language_from_string ("Enx", 2)); + + g_assert (HB_LANGUAGE_INVALID == hb_language_from_string (NULL, -1)); + g_assert (HB_LANGUAGE_INVALID == hb_language_from_string ("", -1)); + g_assert (HB_LANGUAGE_INVALID == hb_language_from_string ("en", 0)); + g_assert (HB_LANGUAGE_INVALID != hb_language_from_string ("en", 1)); g_assert (NULL == hb_language_to_string (HB_LANGUAGE_INVALID)); /* Not sure how to test this better. Setting env vars diff --git a/test/test-ot-tag.c b/test/test-ot-tag.c index d440dbd..a00799d 100644 --- a/test/test-ot-tag.c +++ b/test/test-ot-tag.c @@ -40,7 +40,7 @@ test_simple_tags (const char *s, hb_script_t script) hb_script_t t1, t2; g_test_message ("Testing script %c%c%c%c: tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s); - tag = hb_tag_from_string (s); + tag = hb_tag_from_string (s, -1); hb_ot_tags_from_script (script, &t1, &t2); @@ -57,8 +57,8 @@ test_indic_tags (const char *s1, const char *s2, hb_script_t script) hb_script_t t1, t2; g_test_message ("Testing script %c%c%c%c: new tag %s, old tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s1, s2); - tag1 = hb_tag_from_string (s1); - tag2 = hb_tag_from_string (s2); + tag1 = hb_tag_from_string (s1, -1); + tag2 = hb_tag_from_string (s2, -1); hb_ot_tags_from_script (script, &t1, &t2); @@ -85,14 +85,14 @@ test_ot_tag_script_degenerate (void) test_simple_tags ("DFLT", HB_SCRIPT_INVALID); /* Spaces are replaced */ - g_assert_cmphex (hb_ot_tag_to_script (HB_TAG_CHAR4 ("be ")), ==, hb_script_from_string ("Beee")); + g_assert_cmphex (hb_ot_tag_to_script (HB_TAG_CHAR4 ("be ")), ==, hb_script_from_string ("Beee", -1)); } static void test_ot_tag_script_simple (void) { /* Arbitrary non-existent script */ - test_simple_tags ("wwyz", hb_script_from_string ("wWyZ")); + test_simple_tags ("wwyz", hb_script_from_string ("wWyZ", -1)); /* These we don't really care about */ test_simple_tags ("zyyy", HB_SCRIPT_COMMON); @@ -141,8 +141,8 @@ test_ot_tag_script_indic (void) static void test_language_two_way (const char *tag_s, const char *lang_s) { - hb_language_t lang = hb_language_from_string (lang_s); - hb_tag_t tag = hb_tag_from_string (tag_s); + hb_language_t lang = hb_language_from_string (lang_s, -1); + hb_tag_t tag = hb_tag_from_string (tag_s, -1); g_test_message ("Testing language %s <-> tag %s", lang_s, tag_s); @@ -153,8 +153,8 @@ test_language_two_way (const char *tag_s, const char *lang_s) static void test_tag_from_language (const char *tag_s, const char *lang_s) { - hb_language_t lang = hb_language_from_string (lang_s); - hb_tag_t tag = hb_tag_from_string (tag_s); + hb_language_t lang = hb_language_from_string (lang_s, -1); + hb_tag_t tag = hb_tag_from_string (tag_s, -1); g_test_message ("Testing language %s -> tag %s", lang_s, tag_s); @@ -164,8 +164,8 @@ test_tag_from_language (const char *tag_s, const char *lang_s) static void test_tag_to_language (const char *tag_s, const char *lang_s) { - hb_language_t lang = hb_language_from_string (lang_s); - hb_tag_t tag = hb_tag_from_string (tag_s); + hb_language_t lang = hb_language_from_string (lang_s, -1); + hb_tag_t tag = hb_tag_from_string (tag_s, -1); g_test_message ("Testing tag %s -> language %s", tag_s, lang_s); diff --git a/util/hb-view.cc b/util/hb-view.cc index cdb90b6..d89835c 100644 --- a/util/hb-view.cc +++ b/util/hb-view.cc @@ -62,11 +62,11 @@ _hb_cr_text_glyphs (cairo_t *cr, hb_buffer = hb_buffer_create (); if (shape_opts->direction) - hb_buffer_set_direction (hb_buffer, hb_direction_from_string (shape_opts->direction)); + hb_buffer_set_direction (hb_buffer, hb_direction_from_string (shape_opts->direction, -1)); if (shape_opts->script) - hb_buffer_set_script (hb_buffer, hb_script_from_string (shape_opts->script)); + hb_buffer_set_script (hb_buffer, hb_script_from_string (shape_opts->script, -1)); if (shape_opts->language) - hb_buffer_set_language (hb_buffer, hb_language_from_string (shape_opts->language)); + hb_buffer_set_language (hb_buffer, hb_language_from_string (shape_opts->language, -1)); if (len < 0) len = strlen (utf8); diff --git a/util/options.cc b/util/options.cc index d623243..3809b1a 100644 --- a/util/options.cc +++ b/util/options.cc @@ -133,10 +133,7 @@ parse_feature_tag (char **pp, hb_feature_t *feature) if (p == *pp) return FALSE; - **pp = '\0'; - feature->tag = hb_tag_from_string (p); - **pp = c; - + feature->tag = hb_tag_from_string (p, *pp - p); return TRUE; }