Blame test/api/test-buffer.c

Packit Service 5bcba8
/*
Packit Service 5bcba8
 * Copyright © 2011  Google, Inc.
Packit Service 5bcba8
 *
Packit Service 5bcba8
 *  This is part of HarfBuzz, a text shaping library.
Packit Service 5bcba8
 *
Packit Service 5bcba8
 * Permission is hereby granted, without written agreement and without
Packit Service 5bcba8
 * license or royalty fees, to use, copy, modify, and distribute this
Packit Service 5bcba8
 * software and its documentation for any purpose, provided that the
Packit Service 5bcba8
 * above copyright notice and the following two paragraphs appear in
Packit Service 5bcba8
 * all copies of this software.
Packit Service 5bcba8
 *
Packit Service 5bcba8
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
Packit Service 5bcba8
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
Packit Service 5bcba8
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
Packit Service 5bcba8
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
Packit Service 5bcba8
 * DAMAGE.
Packit Service 5bcba8
 *
Packit Service 5bcba8
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
Packit Service 5bcba8
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
Packit Service 5bcba8
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
Packit Service 5bcba8
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
Packit Service 5bcba8
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Packit Service 5bcba8
 *
Packit Service 5bcba8
 * Google Author(s): Behdad Esfahbod
Packit Service 5bcba8
 */
Packit Service 5bcba8
Packit Service 5bcba8
#include "hb-test.h"
Packit Service 5bcba8
Packit Service 5bcba8
/* Unit tests for hb-buffer.h */
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
static const char utf8[10] = "ab\360\240\200\200defg";
Packit Service 5bcba8
static const uint16_t utf16[8] = {'a', 'b', 0xD840, 0xDC00, 'd', 'e', 'f', 'g'};
Packit Service 5bcba8
static const uint32_t utf32[7] = {'a', 'b', 0x20000, 'd', 'e', 'f', 'g'};
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
typedef enum {
Packit Service 5bcba8
  BUFFER_EMPTY,
Packit Service 5bcba8
  BUFFER_ONE_BY_ONE,
Packit Service 5bcba8
  BUFFER_UTF32,
Packit Service 5bcba8
  BUFFER_UTF16,
Packit Service 5bcba8
  BUFFER_UTF8,
Packit Service 5bcba8
  BUFFER_NUM_TYPES,
Packit Service 5bcba8
} buffer_type_t;
Packit Service 5bcba8
Packit Service 5bcba8
static const char *buffer_names[] = {
Packit Service 5bcba8
  "empty",
Packit Service 5bcba8
  "one-by-one",
Packit Service 5bcba8
  "utf32",
Packit Service 5bcba8
  "utf16",
Packit Service 5bcba8
  "utf8"
Packit Service 5bcba8
};
Packit Service 5bcba8
Packit Service 5bcba8
typedef struct
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *buffer;
Packit Service 5bcba8
} fixture_t;
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
fixture_init (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b;
Packit Service 5bcba8
  unsigned int i;
Packit Service 5bcba8
Packit Service 5bcba8
  b = fixture->buffer = hb_buffer_create ();
Packit Service 5bcba8
Packit Service 5bcba8
  switch (GPOINTER_TO_INT (user_data))
Packit Service 5bcba8
  {
Packit Service 5bcba8
    case BUFFER_EMPTY:
Packit Service 5bcba8
      break;
Packit Service 5bcba8
Packit Service 5bcba8
    case BUFFER_ONE_BY_ONE:
Packit Service 5bcba8
      for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
Packit Service 5bcba8
	hb_buffer_add (b, utf32[i], i);
Packit Service 5bcba8
      break;
Packit Service 5bcba8
Packit Service 5bcba8
    case BUFFER_UTF32:
Packit Service 5bcba8
      hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
Packit Service 5bcba8
      break;
Packit Service 5bcba8
Packit Service 5bcba8
    case BUFFER_UTF16:
Packit Service 5bcba8
      hb_buffer_add_utf16 (b, utf16, G_N_ELEMENTS (utf16), 1, G_N_ELEMENTS (utf16) - 2);
Packit Service 5bcba8
      break;
Packit Service 5bcba8
Packit Service 5bcba8
    case BUFFER_UTF8:
Packit Service 5bcba8
      hb_buffer_add_utf8  (b, utf8,  G_N_ELEMENTS (utf8),  1, G_N_ELEMENTS (utf8)  - 2);
Packit Service 5bcba8
      break;
Packit Service 5bcba8
Packit Service 5bcba8
    default:
Packit Service 5bcba8
      g_assert_not_reached ();
Packit Service 5bcba8
  }
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
fixture_finish (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_destroy (fixture->buffer);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_properties (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b = fixture->buffer;
Packit Service 5bcba8
  hb_unicode_funcs_t *ufuncs;
Packit Service 5bcba8
Packit Service 5bcba8
  /* test default properties */
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
Packit Service 5bcba8
  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_language (b) == NULL);
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  /* test property changes are retained */
Packit Service 5bcba8
  ufuncs = hb_unicode_funcs_create (NULL);
Packit Service 5bcba8
  hb_buffer_set_unicode_funcs (b, ufuncs);
Packit Service 5bcba8
  hb_unicode_funcs_destroy (ufuncs);
Packit Service 5bcba8
  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
Packit Service 5bcba8
  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
Packit Service 5bcba8
  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
Packit Service 5bcba8
  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
Packit Service 5bcba8
  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
Packit Service 5bcba8
  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  /* test clear_contents clears all these properties: */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_clear_contents (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
Packit Service 5bcba8
  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_language (b) == NULL);
Packit Service 5bcba8
Packit Service 5bcba8
  /* but not these: */
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_get_flags (b) != HB_BUFFER_FLAGS_DEFAULT);
Packit Service 5bcba8
  g_assert (hb_buffer_get_replacement_codepoint (b) != HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  /* test reset clears all properties */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
Packit Service 5bcba8
  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
Packit Service 5bcba8
  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
Packit Service 5bcba8
  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
Packit Service 5bcba8
  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
Packit Service 5bcba8
  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
Packit Service 5bcba8
  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
Packit Service 5bcba8
  g_assert (hb_buffer_get_language (b) == NULL);
Packit Service 5bcba8
  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
Packit Service 5bcba8
  g_assert (hb_buffer_get_replacement_codepoint (b) == HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b = fixture->buffer;
Packit Service 5bcba8
  unsigned int i, len, len2;
Packit Service 5bcba8
  buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
Packit Service 5bcba8
  hb_glyph_info_t *glyphs;
Packit Service 5bcba8
Packit Service 5bcba8
  if (buffer_type == BUFFER_EMPTY) {
Packit Service 5bcba8
    g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
    return;
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  len = hb_buffer_get_length (b);
Packit Service 5bcba8
  hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
Packit Service 5bcba8
  glyphs = hb_buffer_get_glyph_infos (b, &len2);
Packit Service 5bcba8
  g_assert_cmpint (len, ==, len2);
Packit Service 5bcba8
  g_assert_cmpint (len, ==, 5);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < len; i++) {
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].mask,      ==, 1);
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < len; i++) {
Packit Service 5bcba8
    unsigned int cluster;
Packit Service 5bcba8
    cluster = 1+i;
Packit Service 5bcba8
    if (i >= 2) {
Packit Service 5bcba8
      if (buffer_type == BUFFER_UTF16)
Packit Service 5bcba8
	cluster++;
Packit Service 5bcba8
      else if (buffer_type == BUFFER_UTF8)
Packit Service 5bcba8
        cluster += 3;
Packit Service 5bcba8
    }
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  /* reverse, test, and reverse back */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
Packit Service 5bcba8
  /* reverse_clusters works same as reverse for now since each codepoint is
Packit Service 5bcba8
   * in its own cluster */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse_clusters (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse_clusters (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
Packit Service 5bcba8
  /* now form a cluster and test again */
Packit Service 5bcba8
  glyphs[2].cluster = glyphs[1].cluster;
Packit Service 5bcba8
Packit Service 5bcba8
  /* reverse, test, and reverse back */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
Packit Service 5bcba8
  /* reverse_clusters twice still should return the original string,
Packit Service 5bcba8
   * but when applied once, the 1-2 cluster should be retained. */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse_clusters (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++) {
Packit Service 5bcba8
    unsigned int j = len-1-i;
Packit Service 5bcba8
    if (j == 1)
Packit Service 5bcba8
      j = 2;
Packit Service 5bcba8
    else if (j == 2)
Packit Service 5bcba8
      j = 1;
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse_clusters (b);
Packit Service 5bcba8
  for (i = 0; i < len; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  /* test setting length */
Packit Service 5bcba8
Packit Service 5bcba8
  /* enlarge */
Packit Service 5bcba8
  g_assert (hb_buffer_set_length (b, 10));
Packit Service 5bcba8
  glyphs = hb_buffer_get_glyph_infos (b, NULL);
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
Packit Service 5bcba8
  for (i = 0; i < 5; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
  for (i = 5; i < 10; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, 0);
Packit Service 5bcba8
  /* shrink */
Packit Service 5bcba8
  g_assert (hb_buffer_set_length (b, 3));
Packit Service 5bcba8
  glyphs = hb_buffer_get_glyph_infos (b, NULL);
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
Packit Service 5bcba8
  for (i = 0; i < 3; i++)
Packit Service 5bcba8
    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
  /* test reset clears content */
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_positions (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b = fixture->buffer;
Packit Service 5bcba8
  unsigned int i, len, len2;
Packit Service 5bcba8
  hb_glyph_position_t *positions;
Packit Service 5bcba8
Packit Service 5bcba8
  /* Without shaping, positions should all be zero */
Packit Service 5bcba8
  len = hb_buffer_get_length (b);
Packit Service 5bcba8
  hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
Packit Service 5bcba8
  positions = hb_buffer_get_glyph_positions (b, &len2);
Packit Service 5bcba8
  g_assert_cmpint (len, ==, len2);
Packit Service 5bcba8
  for (i = 0; i < len; i++) {
Packit Service 5bcba8
    g_assert_cmpint (0, ==, positions[i].x_advance);
Packit Service 5bcba8
    g_assert_cmpint (0, ==, positions[i].y_advance);
Packit Service 5bcba8
    g_assert_cmpint (0, ==, positions[i].x_offset);
Packit Service 5bcba8
    g_assert_cmpint (0, ==, positions[i].y_offset);
Packit Service 5bcba8
    g_assert_cmpint (0, ==, positions[i].var.i32);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  /* test reset clears content */
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_allocation (fixture_t *fixture, gconstpointer user_data)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b = fixture->buffer;
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_pre_allocate (b, 100));
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
  g_assert (hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  /* lets try a huge allocation, make sure it fails */
Packit Service 5bcba8
  g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  /* small one again */
Packit Service 5bcba8
  g_assert (hb_buffer_pre_allocate (b, 50));
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
  g_assert (hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  /* all allocation and size  */
Packit Service 5bcba8
  g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
  g_assert (hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  /* technically, this one can actually pass on 64bit machines, but
Packit Service 5bcba8
   * I'm doubtful that any malloc allows 4GB allocations at a time.
Packit Service 5bcba8
   * But let's only enable it on a 32-bit machine. */
Packit Service 5bcba8
  if (sizeof (long) == 4) {
Packit Service 5bcba8
    g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
Packit Service 5bcba8
    g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
  g_assert (hb_buffer_allocation_successful (b));
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
typedef struct {
Packit Service 5bcba8
  const char utf8[8];
Packit Service 5bcba8
  const uint32_t codepoints[8];
Packit Service 5bcba8
} utf8_conversion_test_t;
Packit Service 5bcba8
Packit Service 5bcba8
/* note: we skip the first and last byte when adding to buffer */
Packit Service 5bcba8
static const utf8_conversion_test_t utf8_conversion_tests[] = {
Packit Service 5bcba8
  {"a\303\207", {-1}},
Packit Service 5bcba8
  {"a\303\207b", {0xC7}},
Packit Service 5bcba8
  {"ab\303cd", {'b', -1, 'c'}},
Packit Service 5bcba8
  {"ab\303\302\301cd", {'b', -1, -1, -1, 'c'}}
Packit Service 5bcba8
};
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_utf8_conversion (void)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b;
Packit Service 5bcba8
  hb_glyph_info_t *glyphs;
Packit Service 5bcba8
  unsigned int bytes, chars, i, j, len;
Packit Service 5bcba8
Packit Service 5bcba8
  b = hb_buffer_create ();
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
Packit Service 5bcba8
  {
Packit Service 5bcba8
    const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
Packit Service 5bcba8
    char *escaped;
Packit Service 5bcba8
Packit Service 5bcba8
    escaped = g_strescape (test->utf8, NULL);
Packit Service 5bcba8
    g_test_message ("UTF-8 test #%d: %s", i, escaped);
Packit Service 5bcba8
    g_free (escaped);
Packit Service 5bcba8
Packit Service 5bcba8
    bytes = strlen (test->utf8);
Packit Service 5bcba8
    for (chars = 0; test->codepoints[chars]; chars++)
Packit Service 5bcba8
      ;
Packit Service 5bcba8
Packit Service 5bcba8
    hb_buffer_clear_contents (b);
Packit Service 5bcba8
    hb_buffer_add_utf8 (b, test->utf8, bytes,  1, bytes - 2);
Packit Service 5bcba8
Packit Service 5bcba8
    glyphs = hb_buffer_get_glyph_infos (b, &len;;
Packit Service 5bcba8
    g_assert_cmpint (len, ==, chars);
Packit Service 5bcba8
    for (j = 0; j < chars; j++)
Packit Service 5bcba8
      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_destroy (b);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
/* Following test table is adapted from glib/glib/tests/utf8-validate.c
Packit Service 5bcba8
 * with relicensing permission from Matthias Clasen. */
Packit Service 5bcba8
Packit Service 5bcba8
typedef struct {
Packit Service 5bcba8
  const char *utf8;
Packit Service 5bcba8
  int max_len;
Packit Service 5bcba8
  unsigned int offset;
Packit Service 5bcba8
  gboolean valid;
Packit Service 5bcba8
} utf8_validity_test_t;
Packit Service 5bcba8
Packit Service 5bcba8
static const utf8_validity_test_t utf8_validity_tests[] = {
Packit Service 5bcba8
  /* some tests to check max_len handling */
Packit Service 5bcba8
  /* length 1 */
Packit Service 5bcba8
  { "abcde", -1, 5, TRUE },
Packit Service 5bcba8
  { "abcde", 3, 3, TRUE },
Packit Service 5bcba8
  { "abcde", 5, 5, TRUE },
Packit Service 5bcba8
  /* length 2 */
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  1, 0, FALSE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  2, 2, TRUE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  3, 2, FALSE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  4, 4, TRUE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  5, 4, FALSE },
Packit Service 5bcba8
  { "\xc2\xa9\xc2\xa9\xc2\xa9",  6, 6, TRUE },
Packit Service 5bcba8
  /* length 3 */
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  1, 0, FALSE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  2, 0, FALSE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  3, 3, TRUE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  4, 3, FALSE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
Packit Service 5bcba8
  { "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
Packit Service 5bcba8
Packit Service 5bcba8
  /* examples from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
Packit Service 5bcba8
  /* greek 'kosme' */
Packit Service 5bcba8
  { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
Packit Service 5bcba8
  /* first sequence of each length */
Packit Service 5bcba8
  { "\x00", -1, 0, TRUE },
Packit Service 5bcba8
  { "\xc2\x80", -1, 2, TRUE },
Packit Service 5bcba8
  { "\xe0\xa0\x80", -1, 3, TRUE },
Packit Service 5bcba8
  { "\xf0\x90\x80\x80", -1, 4, TRUE },
Packit Service 5bcba8
  { "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
Packit Service 5bcba8
  /* last sequence of each length */
Packit Service 5bcba8
  { "\x7f", -1, 1, TRUE },
Packit Service 5bcba8
  { "\xdf\xbf", -1, 2, TRUE },
Packit Service 5bcba8
  { "\xef\xbf\xbf", -1, 0, TRUE },
Packit Service 5bcba8
  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
Packit Service 5bcba8
  { "\xf4\x90\xbf\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  /* other boundary conditions */
Packit Service 5bcba8
  { "\xed\x9f\xbf", -1, 3, TRUE },
Packit Service 5bcba8
  { "\xed\xa0\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xed\xbf\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xee\x80\x80", -1, 3, TRUE },
Packit Service 5bcba8
  { "\xef\xbf\xbd", -1, 3, TRUE },
Packit Service 5bcba8
  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
Packit Service 5bcba8
  /* malformed sequences */
Packit Service 5bcba8
  /* continuation bytes */
Packit Service 5bcba8
  { "\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf\x80\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
Packit Service 5bcba8
Packit Service 5bcba8
  /* all possible continuation byte */
Packit Service 5bcba8
  { "\x80", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x81", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x82", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x83", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x84", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x85", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x86", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x87", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x88", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x89", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8a", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8b", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8c", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8d", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8e", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x8f", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x90", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x91", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x92", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x93", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x94", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x95", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x96", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x97", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x98", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x99", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9a", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9b", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9c", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9d", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9e", -1, 0, FALSE },
Packit Service 5bcba8
  { "\x9f", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa0", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa1", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa2", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa3", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa4", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa5", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa6", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa7", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa8", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xa9", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xaa", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xab", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xac", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xad", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xae", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xaf", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb0", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb1", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb2", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb3", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb4", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb5", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb6", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb7", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb8", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xb9", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xba", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbb", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbc", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbd", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbe", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xbf", -1, 0, FALSE },
Packit Service 5bcba8
  /* lone start characters */
Packit Service 5bcba8
  { "\xc0\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc1\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc2\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc3\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc4\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc5\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc6\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc7\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc8\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xc9\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xca\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xcb\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xcc\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xcd\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xce\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xcf\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd0\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd1\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd2\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd3\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd4\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd5\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd6\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd7\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd8\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xd9\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xda\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xdb\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xdc\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xdd\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xde\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xdf\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe0\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe1\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe2\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe3\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe4\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe5\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe6\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe7\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe8\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xe9\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xea\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xeb\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xec\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xed\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xee\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xef\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf0\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf1\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf2\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf3\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf4\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf5\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf6\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf7\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf8\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xf9\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfa\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfb\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfc\x20", -1, 0, FALSE },
Packit Service 5bcba8
  { "\xfd\x20", -1, 0, FALSE },
Packit Service 5bcba8
  /* missing continuation bytes */
Packit Service 5bcba8
  { "\x20\xc0", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xe0\x80", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf0\x80\x80", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xdf", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xef\xbf", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf7\xbf\xbf", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
Packit Service 5bcba8
  /* impossible bytes */
Packit Service 5bcba8
  { "\x20\xfe\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xff\x20", -1, 1, FALSE },
Packit Service 5bcba8
  /* overlong sequences */
Packit Service 5bcba8
  { "\x20\xc0\xaf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xc1\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xc0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  /* illegal code positions */
Packit Service 5bcba8
  { "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xae\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
#if 0 /* We don't consider U+FFFE / U+FFFF and similar invalid. */
Packit Service 5bcba8
  { "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
Packit Service 5bcba8
  { "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
Packit Service 5bcba8
#endif
Packit Service 5bcba8
  { "", -1, 0, TRUE }
Packit Service 5bcba8
};
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_utf8_validity (void)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b;
Packit Service 5bcba8
  unsigned int i;
Packit Service 5bcba8
Packit Service 5bcba8
  b = hb_buffer_create ();
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
Packit Service 5bcba8
  {
Packit Service 5bcba8
    const utf8_validity_test_t *test = &utf8_validity_tests[i];
Packit Service 5bcba8
    unsigned int text_bytes, segment_bytes, j, len;
Packit Service 5bcba8
    hb_glyph_info_t *glyphs;
Packit Service 5bcba8
    char *escaped;
Packit Service 5bcba8
Packit Service 5bcba8
    escaped = g_strescape (test->utf8, NULL);
Packit Service 5bcba8
    g_test_message ("UTF-8 test #%d: %s", i, escaped);
Packit Service 5bcba8
    g_free (escaped);
Packit Service 5bcba8
Packit Service 5bcba8
    text_bytes = strlen (test->utf8);
Packit Service 5bcba8
    if (test->max_len == -1)
Packit Service 5bcba8
      segment_bytes = text_bytes;
Packit Service 5bcba8
    else
Packit Service 5bcba8
      segment_bytes = test->max_len;
Packit Service 5bcba8
Packit Service 5bcba8
    hb_buffer_clear_contents (b);
Packit Service 5bcba8
    hb_buffer_add_utf8 (b, test->utf8, text_bytes,  0, segment_bytes);
Packit Service 5bcba8
Packit Service 5bcba8
    glyphs = hb_buffer_get_glyph_infos (b, &len;;
Packit Service 5bcba8
    for (j = 0; j < len; j++)
Packit Service 5bcba8
      if (glyphs[j].codepoint == (hb_codepoint_t) -1)
Packit Service 5bcba8
	break;
Packit Service 5bcba8
Packit Service 5bcba8
    g_assert (test->valid ? j == len : j < len);
Packit Service 5bcba8
    if (!test->valid)
Packit Service 5bcba8
      g_assert (glyphs[j].cluster == test->offset);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_destroy (b);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
typedef struct {
Packit Service 5bcba8
  const uint16_t utf16[8];
Packit Service 5bcba8
  const uint32_t codepoints[8];
Packit Service 5bcba8
} utf16_conversion_test_t;
Packit Service 5bcba8
Packit Service 5bcba8
/* note: we skip the first and last item from utf16 when adding to buffer */
Packit Service 5bcba8
static const utf16_conversion_test_t utf16_conversion_tests[] = {
Packit Service 5bcba8
  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0xDF02}, {-1}},
Packit Service 5bcba8
  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -1}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0x61, 0xDF02}, {-1, 0x61}},
Packit Service 5bcba8
  {{0x41, 0xDF00, 0x61}, {-1}},
Packit Service 5bcba8
  {{0x41, 0x61}, {0}}
Packit Service 5bcba8
};
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_utf16_conversion (void)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b;
Packit Service 5bcba8
  unsigned int i;
Packit Service 5bcba8
Packit Service 5bcba8
  b = hb_buffer_create ();
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
Packit Service 5bcba8
  {
Packit Service 5bcba8
    const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
Packit Service 5bcba8
    unsigned int u_len, chars, j, len;
Packit Service 5bcba8
    hb_glyph_info_t *glyphs;
Packit Service 5bcba8
Packit Service 5bcba8
    g_test_message ("UTF-16 test #%d", i);
Packit Service 5bcba8
Packit Service 5bcba8
    for (u_len = 0; test->utf16[u_len]; u_len++)
Packit Service 5bcba8
      ;
Packit Service 5bcba8
    for (chars = 0; test->codepoints[chars]; chars++)
Packit Service 5bcba8
      ;
Packit Service 5bcba8
Packit Service 5bcba8
    hb_buffer_clear_contents (b);
Packit Service 5bcba8
    hb_buffer_add_utf16 (b, test->utf16, u_len,  1, u_len - 2);
Packit Service 5bcba8
Packit Service 5bcba8
    glyphs = hb_buffer_get_glyph_infos (b, &len;;
Packit Service 5bcba8
    g_assert_cmpint (len, ==, chars);
Packit Service 5bcba8
    for (j = 0; j < chars; j++)
Packit Service 5bcba8
      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_destroy (b);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
typedef struct {
Packit Service 5bcba8
  const uint32_t utf32[8];
Packit Service 5bcba8
  const uint32_t codepoints[8];
Packit Service 5bcba8
} utf32_conversion_test_t;
Packit Service 5bcba8
Packit Service 5bcba8
/* note: we skip the first and last item from utf32 when adding to buffer */
Packit Service 5bcba8
static const utf32_conversion_test_t utf32_conversion_tests[] = {
Packit Service 5bcba8
  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, -3, -3}},
Packit Service 5bcba8
  {{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0xDF02, 0x61}, {-3, -3}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0xDF02}, {-3}},
Packit Service 5bcba8
  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -3}},
Packit Service 5bcba8
  {{0x41, 0xD800, 0x61, 0xDF02}, {-3, 0x61}},
Packit Service 5bcba8
  {{0x41, 0xDF00, 0x61}, {-3}},
Packit Service 5bcba8
  {{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
Packit Service 5bcba8
  {{0x41, 0x110000, 0x61}, {-3}},
Packit Service 5bcba8
  {{0x41, 0x61}, {0}}
Packit Service 5bcba8
};
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_utf32_conversion (void)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b;
Packit Service 5bcba8
  unsigned int i;
Packit Service 5bcba8
Packit Service 5bcba8
  b = hb_buffer_create ();
Packit Service 5bcba8
  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
Packit Service 5bcba8
  {
Packit Service 5bcba8
    const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
Packit Service 5bcba8
    unsigned int u_len, chars, j, len;
Packit Service 5bcba8
    hb_glyph_info_t *glyphs;
Packit Service 5bcba8
Packit Service 5bcba8
    g_test_message ("UTF-32 test #%d", i);
Packit Service 5bcba8
Packit Service 5bcba8
    for (u_len = 0; test->utf32[u_len]; u_len++)
Packit Service 5bcba8
      ;
Packit Service 5bcba8
    for (chars = 0; test->codepoints[chars]; chars++)
Packit Service 5bcba8
      ;
Packit Service 5bcba8
Packit Service 5bcba8
    hb_buffer_clear_contents (b);
Packit Service 5bcba8
    hb_buffer_add_utf32 (b, test->utf32, u_len,  1, u_len - 2);
Packit Service 5bcba8
Packit Service 5bcba8
    glyphs = hb_buffer_get_glyph_infos (b, &len;;
Packit Service 5bcba8
    g_assert_cmpint (len, ==, chars);
Packit Service 5bcba8
    for (j = 0; j < chars; j++)
Packit Service 5bcba8
      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_destroy (b);
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_empty (hb_buffer_t *b)
Packit Service 5bcba8
{
Packit Service 5bcba8
  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
Packit Service 5bcba8
  g_assert (!hb_buffer_get_glyph_infos (b, NULL));
Packit Service 5bcba8
  g_assert (!hb_buffer_get_glyph_positions (b, NULL));
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
static void
Packit Service 5bcba8
test_buffer_empty (void)
Packit Service 5bcba8
{
Packit Service 5bcba8
  hb_buffer_t *b = hb_buffer_get_empty ();
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_get_empty ());
Packit Service 5bcba8
  g_assert (hb_buffer_get_empty () == b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  test_empty (b);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
Packit Service 5bcba8
Packit Service 5bcba8
  test_empty (b);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reverse (b);
Packit Service 5bcba8
  hb_buffer_reverse_clusters (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (!hb_buffer_set_length (b, 10));
Packit Service 5bcba8
Packit Service 5bcba8
  test_empty (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (hb_buffer_set_length (b, 0));
Packit Service 5bcba8
Packit Service 5bcba8
  test_empty (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
Packit Service 5bcba8
  hb_buffer_reset (b);
Packit Service 5bcba8
Packit Service 5bcba8
  test_empty (b);
Packit Service 5bcba8
Packit Service 5bcba8
  g_assert (!hb_buffer_allocation_successful (b));
Packit Service 5bcba8
}
Packit Service 5bcba8
Packit Service 5bcba8
int
Packit Service 5bcba8
main (int argc, char **argv)
Packit Service 5bcba8
{
Packit Service 5bcba8
  unsigned int i;
Packit Service 5bcba8
Packit Service 5bcba8
  hb_test_init (&argc, &argv);
Packit Service 5bcba8
Packit Service 5bcba8
  for (i = 0; i < BUFFER_NUM_TYPES; i++)
Packit Service 5bcba8
  {
Packit Service 5bcba8
    const void *buffer_type = GINT_TO_POINTER (i);
Packit Service 5bcba8
    const char *buffer_name = buffer_names[i];
Packit Service 5bcba8
Packit Service 5bcba8
    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
Packit Service 5bcba8
    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
Packit Service 5bcba8
    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
Packit Service 5bcba8
  }
Packit Service 5bcba8
Packit Service 5bcba8
  hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
Packit Service 5bcba8
Packit Service 5bcba8
  hb_test_add (test_buffer_utf8_conversion);
Packit Service 5bcba8
  hb_test_add (test_buffer_utf8_validity);
Packit Service 5bcba8
  hb_test_add (test_buffer_utf16_conversion);
Packit Service 5bcba8
  hb_test_add (test_buffer_utf32_conversion);
Packit Service 5bcba8
  hb_test_add (test_buffer_empty);
Packit Service 5bcba8
Packit Service 5bcba8
  return hb_test_run();
Packit Service 5bcba8
}