xref: /aosp_15_r20/external/harfbuzz_ng/test/api/test-object.c (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2011  Google, Inc.
3*2d1272b8SAndroid Build Coastguard Worker  *
4*2d1272b8SAndroid Build Coastguard Worker  *  This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker  *
6*2d1272b8SAndroid Build Coastguard Worker  * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker  * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker  * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker  * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker  * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker  *
12*2d1272b8SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker  * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker  *
18*2d1272b8SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker  *
24*2d1272b8SAndroid Build Coastguard Worker  * Google Author(s): Behdad Esfahbod
25*2d1272b8SAndroid Build Coastguard Worker  */
26*2d1272b8SAndroid Build Coastguard Worker 
27*2d1272b8SAndroid Build Coastguard Worker #include "hb-test.h"
28*2d1272b8SAndroid Build Coastguard Worker 
29*2d1272b8SAndroid Build Coastguard Worker /* Unit tests for hb-object-private.h */
30*2d1272b8SAndroid Build Coastguard Worker 
31*2d1272b8SAndroid Build Coastguard Worker 
32*2d1272b8SAndroid Build Coastguard Worker static void *
create_blob(void)33*2d1272b8SAndroid Build Coastguard Worker create_blob (void)
34*2d1272b8SAndroid Build Coastguard Worker {
35*2d1272b8SAndroid Build Coastguard Worker   static char data[] = "test data";
36*2d1272b8SAndroid Build Coastguard Worker   return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
37*2d1272b8SAndroid Build Coastguard Worker }
38*2d1272b8SAndroid Build Coastguard Worker static void *
create_blob_from_inert(void)39*2d1272b8SAndroid Build Coastguard Worker create_blob_from_inert (void)
40*2d1272b8SAndroid Build Coastguard Worker {
41*2d1272b8SAndroid Build Coastguard Worker   return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL);
42*2d1272b8SAndroid Build Coastguard Worker }
43*2d1272b8SAndroid Build Coastguard Worker 
44*2d1272b8SAndroid Build Coastguard Worker static void *
create_buffer(void)45*2d1272b8SAndroid Build Coastguard Worker create_buffer (void)
46*2d1272b8SAndroid Build Coastguard Worker {
47*2d1272b8SAndroid Build Coastguard Worker   return hb_buffer_create ();
48*2d1272b8SAndroid Build Coastguard Worker }
49*2d1272b8SAndroid Build Coastguard Worker static void *
create_buffer_from_inert(void)50*2d1272b8SAndroid Build Coastguard Worker create_buffer_from_inert (void)
51*2d1272b8SAndroid Build Coastguard Worker {
52*2d1272b8SAndroid Build Coastguard Worker   return NULL;
53*2d1272b8SAndroid Build Coastguard Worker }
54*2d1272b8SAndroid Build Coastguard Worker 
55*2d1272b8SAndroid Build Coastguard Worker static void *
create_set(void)56*2d1272b8SAndroid Build Coastguard Worker create_set (void)
57*2d1272b8SAndroid Build Coastguard Worker {
58*2d1272b8SAndroid Build Coastguard Worker   return hb_set_create ();
59*2d1272b8SAndroid Build Coastguard Worker }
60*2d1272b8SAndroid Build Coastguard Worker static void *
create_set_from_inert(void)61*2d1272b8SAndroid Build Coastguard Worker create_set_from_inert (void)
62*2d1272b8SAndroid Build Coastguard Worker {
63*2d1272b8SAndroid Build Coastguard Worker   return NULL;
64*2d1272b8SAndroid Build Coastguard Worker }
65*2d1272b8SAndroid Build Coastguard Worker 
66*2d1272b8SAndroid Build Coastguard Worker static void *
create_face(void)67*2d1272b8SAndroid Build Coastguard Worker create_face (void)
68*2d1272b8SAndroid Build Coastguard Worker {
69*2d1272b8SAndroid Build Coastguard Worker   hb_blob_t *blob = (hb_blob_t *) create_blob ();
70*2d1272b8SAndroid Build Coastguard Worker   hb_face_t *face = hb_face_create (blob, 0);
71*2d1272b8SAndroid Build Coastguard Worker   hb_blob_destroy (blob);
72*2d1272b8SAndroid Build Coastguard Worker   return face;
73*2d1272b8SAndroid Build Coastguard Worker }
74*2d1272b8SAndroid Build Coastguard Worker static void *
create_face_from_inert(void)75*2d1272b8SAndroid Build Coastguard Worker create_face_from_inert (void)
76*2d1272b8SAndroid Build Coastguard Worker {
77*2d1272b8SAndroid Build Coastguard Worker   return hb_face_create (hb_blob_get_empty (), 0);
78*2d1272b8SAndroid Build Coastguard Worker }
79*2d1272b8SAndroid Build Coastguard Worker 
80*2d1272b8SAndroid Build Coastguard Worker static void *
create_font(void)81*2d1272b8SAndroid Build Coastguard Worker create_font (void)
82*2d1272b8SAndroid Build Coastguard Worker {
83*2d1272b8SAndroid Build Coastguard Worker   hb_face_t *face = (hb_face_t *) create_face ();
84*2d1272b8SAndroid Build Coastguard Worker   hb_font_t *font = hb_font_create (face);
85*2d1272b8SAndroid Build Coastguard Worker   hb_face_destroy (face);
86*2d1272b8SAndroid Build Coastguard Worker   return font;
87*2d1272b8SAndroid Build Coastguard Worker }
88*2d1272b8SAndroid Build Coastguard Worker static void *
create_font_from_inert(void)89*2d1272b8SAndroid Build Coastguard Worker create_font_from_inert (void)
90*2d1272b8SAndroid Build Coastguard Worker {
91*2d1272b8SAndroid Build Coastguard Worker   return hb_font_create (hb_face_get_empty ());
92*2d1272b8SAndroid Build Coastguard Worker }
93*2d1272b8SAndroid Build Coastguard Worker 
94*2d1272b8SAndroid Build Coastguard Worker static void *
create_font_funcs(void)95*2d1272b8SAndroid Build Coastguard Worker create_font_funcs (void)
96*2d1272b8SAndroid Build Coastguard Worker {
97*2d1272b8SAndroid Build Coastguard Worker   return hb_font_funcs_create ();
98*2d1272b8SAndroid Build Coastguard Worker }
99*2d1272b8SAndroid Build Coastguard Worker static void *
create_font_funcs_from_inert(void)100*2d1272b8SAndroid Build Coastguard Worker create_font_funcs_from_inert (void)
101*2d1272b8SAndroid Build Coastguard Worker {
102*2d1272b8SAndroid Build Coastguard Worker   return NULL;
103*2d1272b8SAndroid Build Coastguard Worker }
104*2d1272b8SAndroid Build Coastguard Worker 
105*2d1272b8SAndroid Build Coastguard Worker static void *
create_unicode_funcs(void)106*2d1272b8SAndroid Build Coastguard Worker create_unicode_funcs (void)
107*2d1272b8SAndroid Build Coastguard Worker {
108*2d1272b8SAndroid Build Coastguard Worker   return hb_unicode_funcs_create (NULL);
109*2d1272b8SAndroid Build Coastguard Worker }
110*2d1272b8SAndroid Build Coastguard Worker static void *
create_unicode_funcs_from_inert(void)111*2d1272b8SAndroid Build Coastguard Worker create_unicode_funcs_from_inert (void)
112*2d1272b8SAndroid Build Coastguard Worker {
113*2d1272b8SAndroid Build Coastguard Worker   return hb_unicode_funcs_create (hb_unicode_funcs_get_empty ());
114*2d1272b8SAndroid Build Coastguard Worker }
115*2d1272b8SAndroid Build Coastguard Worker 
116*2d1272b8SAndroid Build Coastguard Worker 
117*2d1272b8SAndroid Build Coastguard Worker 
118*2d1272b8SAndroid Build Coastguard Worker typedef void     *(*create_func_t)         (void);
119*2d1272b8SAndroid Build Coastguard Worker typedef void     *(*reference_func_t)      (void *obj);
120*2d1272b8SAndroid Build Coastguard Worker typedef void      (*destroy_func_t)        (void *obj);
121*2d1272b8SAndroid Build Coastguard Worker typedef hb_bool_t (*set_user_data_func_t)  (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace);
122*2d1272b8SAndroid Build Coastguard Worker typedef void *    (*get_user_data_func_t)  (void *obj, hb_user_data_key_t *key);
123*2d1272b8SAndroid Build Coastguard Worker typedef void      (*make_immutable_func_t) (void *obj);
124*2d1272b8SAndroid Build Coastguard Worker typedef hb_bool_t (*is_immutable_func_t)   (void *obj);
125*2d1272b8SAndroid Build Coastguard Worker 
126*2d1272b8SAndroid Build Coastguard Worker typedef struct {
127*2d1272b8SAndroid Build Coastguard Worker   create_func_t          create;
128*2d1272b8SAndroid Build Coastguard Worker   create_func_t          create_from_inert;
129*2d1272b8SAndroid Build Coastguard Worker   create_func_t          get_empty;
130*2d1272b8SAndroid Build Coastguard Worker   reference_func_t       reference;
131*2d1272b8SAndroid Build Coastguard Worker   destroy_func_t         destroy;
132*2d1272b8SAndroid Build Coastguard Worker   set_user_data_func_t   set_user_data;
133*2d1272b8SAndroid Build Coastguard Worker   get_user_data_func_t   get_user_data;
134*2d1272b8SAndroid Build Coastguard Worker   make_immutable_func_t  make_immutable;
135*2d1272b8SAndroid Build Coastguard Worker   is_immutable_func_t    is_immutable;
136*2d1272b8SAndroid Build Coastguard Worker   const char            *name;
137*2d1272b8SAndroid Build Coastguard Worker } object_t;
138*2d1272b8SAndroid Build Coastguard Worker 
139*2d1272b8SAndroid Build Coastguard Worker #define OBJECT_WITHOUT_IMMUTABILITY(name) \
140*2d1272b8SAndroid Build Coastguard Worker   { \
141*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         create_##name, \
142*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         create_##name##_from_inert, \
143*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         hb_##name##_get_empty, \
144*2d1272b8SAndroid Build Coastguard Worker     (reference_func_t)      hb_##name##_reference, \
145*2d1272b8SAndroid Build Coastguard Worker     (destroy_func_t)        hb_##name##_destroy, \
146*2d1272b8SAndroid Build Coastguard Worker     (set_user_data_func_t)  hb_##name##_set_user_data, \
147*2d1272b8SAndroid Build Coastguard Worker     (get_user_data_func_t)  hb_##name##_get_user_data, \
148*2d1272b8SAndroid Build Coastguard Worker     (make_immutable_func_t) NULL, \
149*2d1272b8SAndroid Build Coastguard Worker     (is_immutable_func_t)   NULL, \
150*2d1272b8SAndroid Build Coastguard Worker     #name, \
151*2d1272b8SAndroid Build Coastguard Worker   }
152*2d1272b8SAndroid Build Coastguard Worker #define OBJECT_WITH_IMMUTABILITY(name) \
153*2d1272b8SAndroid Build Coastguard Worker   { \
154*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         create_##name, \
155*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         create_##name##_from_inert, \
156*2d1272b8SAndroid Build Coastguard Worker     (create_func_t)         hb_##name##_get_empty, \
157*2d1272b8SAndroid Build Coastguard Worker     (reference_func_t)      hb_##name##_reference, \
158*2d1272b8SAndroid Build Coastguard Worker     (destroy_func_t)        hb_##name##_destroy, \
159*2d1272b8SAndroid Build Coastguard Worker     (set_user_data_func_t)  hb_##name##_set_user_data, \
160*2d1272b8SAndroid Build Coastguard Worker     (get_user_data_func_t)  hb_##name##_get_user_data, \
161*2d1272b8SAndroid Build Coastguard Worker     (make_immutable_func_t) hb_##name##_make_immutable, \
162*2d1272b8SAndroid Build Coastguard Worker     (is_immutable_func_t)   hb_##name##_is_immutable, \
163*2d1272b8SAndroid Build Coastguard Worker     #name, \
164*2d1272b8SAndroid Build Coastguard Worker   }
165*2d1272b8SAndroid Build Coastguard Worker static const object_t objects[] =
166*2d1272b8SAndroid Build Coastguard Worker {
167*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITHOUT_IMMUTABILITY (buffer),
168*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITHOUT_IMMUTABILITY (set),
169*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITH_IMMUTABILITY (blob),
170*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITH_IMMUTABILITY (face),
171*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITH_IMMUTABILITY (font),
172*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITH_IMMUTABILITY (font_funcs),
173*2d1272b8SAndroid Build Coastguard Worker   OBJECT_WITH_IMMUTABILITY (unicode_funcs)
174*2d1272b8SAndroid Build Coastguard Worker };
175*2d1272b8SAndroid Build Coastguard Worker #undef OBJECT
176*2d1272b8SAndroid Build Coastguard Worker 
177*2d1272b8SAndroid Build Coastguard Worker 
178*2d1272b8SAndroid Build Coastguard Worker #define MAGIC0 0x12345678
179*2d1272b8SAndroid Build Coastguard Worker #define MAGIC1 0x76543210
180*2d1272b8SAndroid Build Coastguard Worker 
181*2d1272b8SAndroid Build Coastguard Worker typedef struct {
182*2d1272b8SAndroid Build Coastguard Worker   int value;
183*2d1272b8SAndroid Build Coastguard Worker   gboolean freed;
184*2d1272b8SAndroid Build Coastguard Worker } data_t;
185*2d1272b8SAndroid Build Coastguard Worker 
186*2d1272b8SAndroid Build Coastguard Worker static int global_data;
187*2d1272b8SAndroid Build Coastguard Worker 
global_free_up(void * p G_GNUC_UNUSED)188*2d1272b8SAndroid Build Coastguard Worker static void global_free_up (void *p G_GNUC_UNUSED)
189*2d1272b8SAndroid Build Coastguard Worker {
190*2d1272b8SAndroid Build Coastguard Worker   global_data++;
191*2d1272b8SAndroid Build Coastguard Worker }
192*2d1272b8SAndroid Build Coastguard Worker 
free_up0(void * p)193*2d1272b8SAndroid Build Coastguard Worker static void free_up0 (void *p)
194*2d1272b8SAndroid Build Coastguard Worker {
195*2d1272b8SAndroid Build Coastguard Worker   data_t *data = (data_t *) p;
196*2d1272b8SAndroid Build Coastguard Worker 
197*2d1272b8SAndroid Build Coastguard Worker   g_assert_cmphex (data->value, ==, MAGIC0);
198*2d1272b8SAndroid Build Coastguard Worker   g_assert (!data->freed);
199*2d1272b8SAndroid Build Coastguard Worker   data->freed = TRUE;
200*2d1272b8SAndroid Build Coastguard Worker }
201*2d1272b8SAndroid Build Coastguard Worker 
free_up1(void * p)202*2d1272b8SAndroid Build Coastguard Worker static void free_up1 (void *p)
203*2d1272b8SAndroid Build Coastguard Worker {
204*2d1272b8SAndroid Build Coastguard Worker   data_t *data = (data_t *) p;
205*2d1272b8SAndroid Build Coastguard Worker 
206*2d1272b8SAndroid Build Coastguard Worker   g_assert_cmphex (data->value, ==, MAGIC1);
207*2d1272b8SAndroid Build Coastguard Worker   g_assert (!data->freed);
208*2d1272b8SAndroid Build Coastguard Worker   data->freed = TRUE;
209*2d1272b8SAndroid Build Coastguard Worker }
210*2d1272b8SAndroid Build Coastguard Worker 
211*2d1272b8SAndroid Build Coastguard Worker 
212*2d1272b8SAndroid Build Coastguard Worker typedef struct {
213*2d1272b8SAndroid Build Coastguard Worker   const object_t *klass;
214*2d1272b8SAndroid Build Coastguard Worker   void *object;
215*2d1272b8SAndroid Build Coastguard Worker   hb_user_data_key_t key;
216*2d1272b8SAndroid Build Coastguard Worker } deadlock_test_t;
217*2d1272b8SAndroid Build Coastguard Worker 
free_deadlock_test(void * p)218*2d1272b8SAndroid Build Coastguard Worker static void free_deadlock_test (void *p)
219*2d1272b8SAndroid Build Coastguard Worker {
220*2d1272b8SAndroid Build Coastguard Worker   deadlock_test_t *t = (deadlock_test_t *) p;
221*2d1272b8SAndroid Build Coastguard Worker 
222*2d1272b8SAndroid Build Coastguard Worker   g_assert (NULL == t->klass->get_user_data (t->object, &t->key));
223*2d1272b8SAndroid Build Coastguard Worker }
224*2d1272b8SAndroid Build Coastguard Worker 
225*2d1272b8SAndroid Build Coastguard Worker 
226*2d1272b8SAndroid Build Coastguard Worker static void
test_object(void)227*2d1272b8SAndroid Build Coastguard Worker test_object (void)
228*2d1272b8SAndroid Build Coastguard Worker {
229*2d1272b8SAndroid Build Coastguard Worker   unsigned int i;
230*2d1272b8SAndroid Build Coastguard Worker 
231*2d1272b8SAndroid Build Coastguard Worker   for (i = 0; i < G_N_ELEMENTS (objects); i++) {
232*2d1272b8SAndroid Build Coastguard Worker     const object_t *o = &objects[i];
233*2d1272b8SAndroid Build Coastguard Worker     void *obj;
234*2d1272b8SAndroid Build Coastguard Worker     hb_user_data_key_t key[1001];
235*2d1272b8SAndroid Build Coastguard Worker 
236*2d1272b8SAndroid Build Coastguard Worker     {
237*2d1272b8SAndroid Build Coastguard Worker       unsigned int j;
238*2d1272b8SAndroid Build Coastguard Worker       data_t data[1000] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
239*2d1272b8SAndroid Build Coastguard Worker       deadlock_test_t deadlock_test;
240*2d1272b8SAndroid Build Coastguard Worker 
241*2d1272b8SAndroid Build Coastguard Worker       g_test_message ("Testing object %s", o->name);
242*2d1272b8SAndroid Build Coastguard Worker 
243*2d1272b8SAndroid Build Coastguard Worker       g_test_message ("->create()");
244*2d1272b8SAndroid Build Coastguard Worker       obj = o->create ();
245*2d1272b8SAndroid Build Coastguard Worker       g_assert (obj);
246*2d1272b8SAndroid Build Coastguard Worker 
247*2d1272b8SAndroid Build Coastguard Worker       g_assert (obj == o->reference (obj));
248*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
249*2d1272b8SAndroid Build Coastguard Worker 
250*2d1272b8SAndroid Build Coastguard Worker       if (o->is_immutable)
251*2d1272b8SAndroid Build Coastguard Worker 	g_assert (!o->is_immutable (obj));
252*2d1272b8SAndroid Build Coastguard Worker 
253*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
254*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
255*2d1272b8SAndroid Build Coastguard Worker 
256*2d1272b8SAndroid Build Coastguard Worker       if (o->is_immutable) {
257*2d1272b8SAndroid Build Coastguard Worker 	o->make_immutable (obj);
258*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->is_immutable (obj));
259*2d1272b8SAndroid Build Coastguard Worker       }
260*2d1272b8SAndroid Build Coastguard Worker 
261*2d1272b8SAndroid Build Coastguard Worker       /* Should still work even if object is made immutable */
262*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE));
263*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->get_user_data (obj, &key[1]) == &data[1]);
264*2d1272b8SAndroid Build Coastguard Worker 
265*2d1272b8SAndroid Build Coastguard Worker       g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE));
266*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
267*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE));
268*2d1272b8SAndroid Build Coastguard Worker       g_assert (data[0].freed);
269*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
270*2d1272b8SAndroid Build Coastguard Worker       g_assert (!data[1].freed);
271*2d1272b8SAndroid Build Coastguard Worker 
272*2d1272b8SAndroid Build Coastguard Worker       data[0].freed = FALSE;
273*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
274*2d1272b8SAndroid Build Coastguard Worker       g_assert (!data[0].freed);
275*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
276*2d1272b8SAndroid Build Coastguard Worker       g_assert (data[0].freed);
277*2d1272b8SAndroid Build Coastguard Worker 
278*2d1272b8SAndroid Build Coastguard Worker       data[0].freed = FALSE;
279*2d1272b8SAndroid Build Coastguard Worker       global_data = 0;
280*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
281*2d1272b8SAndroid Build Coastguard Worker       g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE));
282*2d1272b8SAndroid Build Coastguard Worker       g_assert_cmpuint (global_data, ==, 0);
283*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE));
284*2d1272b8SAndroid Build Coastguard Worker       g_assert_cmpuint (global_data, ==, 0);
285*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
286*2d1272b8SAndroid Build Coastguard Worker       g_assert_cmpuint (global_data, ==, 1);
287*2d1272b8SAndroid Build Coastguard Worker 
288*2d1272b8SAndroid Build Coastguard Worker       global_data = 0;
289*2d1272b8SAndroid Build Coastguard Worker       for (j = 2; j < 1000; j++)
290*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE));
291*2d1272b8SAndroid Build Coastguard Worker       for (j = 2; j < 1000; j++)
292*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
293*2d1272b8SAndroid Build Coastguard Worker       for (j = 100; j < 1000; j++)
294*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->set_user_data (obj, &key[j], NULL, NULL, TRUE));
295*2d1272b8SAndroid Build Coastguard Worker       for (j = 2; j < 100; j++)
296*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
297*2d1272b8SAndroid Build Coastguard Worker       for (j = 100; j < 1000; j++)
298*2d1272b8SAndroid Build Coastguard Worker 	g_assert (!o->get_user_data (obj, &key[j]));
299*2d1272b8SAndroid Build Coastguard Worker       g_assert_cmpuint (global_data, ==, 900);
300*2d1272b8SAndroid Build Coastguard Worker 
301*2d1272b8SAndroid Build Coastguard Worker       /* Test set_user_data where the destroy() func calls user_data functions.
302*2d1272b8SAndroid Build Coastguard Worker        * Make sure it doesn't deadlock or corrupt memory. */
303*2d1272b8SAndroid Build Coastguard Worker       deadlock_test.klass = o;
304*2d1272b8SAndroid Build Coastguard Worker       deadlock_test.object = obj;
305*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE));
306*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE));
307*2d1272b8SAndroid Build Coastguard Worker 
308*2d1272b8SAndroid Build Coastguard Worker       g_assert (!data[1].freed);
309*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
310*2d1272b8SAndroid Build Coastguard Worker       g_assert (data[0].freed);
311*2d1272b8SAndroid Build Coastguard Worker       g_assert (data[1].freed);
312*2d1272b8SAndroid Build Coastguard Worker       g_assert_cmpuint (global_data, ==, 1000-2);
313*2d1272b8SAndroid Build Coastguard Worker     }
314*2d1272b8SAndroid Build Coastguard Worker 
315*2d1272b8SAndroid Build Coastguard Worker     {
316*2d1272b8SAndroid Build Coastguard Worker       data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
317*2d1272b8SAndroid Build Coastguard Worker 
318*2d1272b8SAndroid Build Coastguard Worker       g_test_message ("->get_empty()");
319*2d1272b8SAndroid Build Coastguard Worker       obj = o->get_empty ();
320*2d1272b8SAndroid Build Coastguard Worker       g_assert (obj);
321*2d1272b8SAndroid Build Coastguard Worker 
322*2d1272b8SAndroid Build Coastguard Worker       g_assert (obj == o->reference (obj));
323*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
324*2d1272b8SAndroid Build Coastguard Worker 
325*2d1272b8SAndroid Build Coastguard Worker       if (o->is_immutable)
326*2d1272b8SAndroid Build Coastguard Worker 	g_assert (o->is_immutable (obj));
327*2d1272b8SAndroid Build Coastguard Worker 
328*2d1272b8SAndroid Build Coastguard Worker       g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
329*2d1272b8SAndroid Build Coastguard Worker       g_assert (!o->get_user_data (obj, &key[0]));
330*2d1272b8SAndroid Build Coastguard Worker 
331*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
332*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
333*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
334*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
335*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
336*2d1272b8SAndroid Build Coastguard Worker 
337*2d1272b8SAndroid Build Coastguard Worker       g_assert (!data[0].freed);
338*2d1272b8SAndroid Build Coastguard Worker     }
339*2d1272b8SAndroid Build Coastguard Worker 
340*2d1272b8SAndroid Build Coastguard Worker     {
341*2d1272b8SAndroid Build Coastguard Worker       data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
342*2d1272b8SAndroid Build Coastguard Worker 
343*2d1272b8SAndroid Build Coastguard Worker       g_test_message ("->create_from_inert()");
344*2d1272b8SAndroid Build Coastguard Worker       obj = o->create_from_inert ();
345*2d1272b8SAndroid Build Coastguard Worker       if (!obj)
346*2d1272b8SAndroid Build Coastguard Worker 	continue;
347*2d1272b8SAndroid Build Coastguard Worker       if (obj == o->get_empty ())
348*2d1272b8SAndroid Build Coastguard Worker 	continue; /* Tested already */
349*2d1272b8SAndroid Build Coastguard Worker 
350*2d1272b8SAndroid Build Coastguard Worker       g_assert (obj == o->reference (obj));
351*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
352*2d1272b8SAndroid Build Coastguard Worker 
353*2d1272b8SAndroid Build Coastguard Worker       if (o->is_immutable)
354*2d1272b8SAndroid Build Coastguard Worker 	g_assert (!o->is_immutable (obj));
355*2d1272b8SAndroid Build Coastguard Worker 
356*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
357*2d1272b8SAndroid Build Coastguard Worker       g_assert (o->get_user_data (obj, &key[0]));
358*2d1272b8SAndroid Build Coastguard Worker 
359*2d1272b8SAndroid Build Coastguard Worker       o->destroy (obj);
360*2d1272b8SAndroid Build Coastguard Worker 
361*2d1272b8SAndroid Build Coastguard Worker       g_assert (data[0].freed);
362*2d1272b8SAndroid Build Coastguard Worker     }
363*2d1272b8SAndroid Build Coastguard Worker   }
364*2d1272b8SAndroid Build Coastguard Worker }
365*2d1272b8SAndroid Build Coastguard Worker 
366*2d1272b8SAndroid Build Coastguard Worker 
367*2d1272b8SAndroid Build Coastguard Worker int
main(int argc,char ** argv)368*2d1272b8SAndroid Build Coastguard Worker main (int argc, char **argv)
369*2d1272b8SAndroid Build Coastguard Worker {
370*2d1272b8SAndroid Build Coastguard Worker   hb_test_init (&argc, &argv);
371*2d1272b8SAndroid Build Coastguard Worker 
372*2d1272b8SAndroid Build Coastguard Worker   hb_test_add (test_object);
373*2d1272b8SAndroid Build Coastguard Worker 
374*2d1272b8SAndroid Build Coastguard Worker   return hb_test_run ();
375*2d1272b8SAndroid Build Coastguard Worker }
376