blob: 87cd7a4202b5306053f099dfef88524a31198e9a [file] [log] [blame]
Behdad Esfahbodf0954d12009-07-30 15:33:57 -04001/*
2 * Copyright (C) 2009 Red Hat, Inc.
3 *
4 * This is part of HarfBuzz, an OpenType Layout engine library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 *
24 * Red Hat Author(s): Behdad Esfahbod
25 */
26
27#include "hb-private.h"
28
29#include "hb-blob.h"
30#include "hb-refcount-private.h"
31
32struct _hb_blob_t {
Behdad Esfahbode97a95f2009-08-01 19:05:44 -040033 hb_reference_count_t ref_count;
34
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040035 const char *data;
36 unsigned int len;
37 hb_memory_mode_t mode;
38
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040039 hb_destroy_func_t destroy;
40 void *user_data;
41};
42static hb_blob_t _hb_blob_nil = {
Behdad Esfahbod35a73832009-08-01 19:30:31 -040043 HB_REFERENCE_COUNT_INVALID, /* ref_count */
Behdad Esfahbode97a95f2009-08-01 19:05:44 -040044
Behdad Esfahbod35a73832009-08-01 19:30:31 -040045 NULL, /* data */
46 0, /* len */
47 HB_MEMORY_MODE_READONLY, /* mode */
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040048
Behdad Esfahbod35a73832009-08-01 19:30:31 -040049 NULL, /* destroy */
50 NULL /* user_data */
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040051};
52
53static void
54_hb_blob_destroy_user_data (hb_blob_t *blob)
55{
56 if (blob->destroy) {
57 blob->destroy (blob->user_data);
58 blob->destroy = NULL;
59 blob->user_data = NULL;
60 }
61}
62
63hb_blob_t *
64hb_blob_create (const char *data,
65 unsigned int len,
66 hb_memory_mode_t mode,
67 hb_destroy_func_t destroy,
68 void *user_data)
69{
70 hb_blob_t *blob;
71
Behdad Esfahbode97a95f2009-08-01 19:05:44 -040072 blob = calloc (1, sizeof (hb_blob_t));
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040073 if (!blob) {
74 if (destroy)
75 destroy (user_data);
76 return &_hb_blob_nil;
77 }
78
Behdad Esfahbod35a73832009-08-01 19:30:31 -040079 HB_REFERENCE_COUNT_DO_CREATE (blob);
80
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040081 blob->data = data;
82 blob->len = len;
83 blob->mode = mode;
84
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040085 blob->destroy = destroy;
86 blob->user_data = user_data;
87
88 if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
89 blob->mode = HB_MEMORY_MODE_READONLY;
90 hb_blob_make_writeable (blob);
91 }
92
93 return blob;
94}
95
96hb_blob_t *
97hb_blob_reference (hb_blob_t *blob)
98{
Behdad Esfahbod35a73832009-08-01 19:30:31 -040099 HB_REFERENCE_COUNT_DO_REFERENCE (blob);
Behdad Esfahbodf0954d12009-07-30 15:33:57 -0400100}
101
102void
103hb_blob_destroy (hb_blob_t *blob)
104{
Behdad Esfahbod35a73832009-08-01 19:30:31 -0400105 HB_REFERENCE_COUNT_DO_DESTROY (blob);
Behdad Esfahbodf0954d12009-07-30 15:33:57 -0400106
107 _hb_blob_destroy_user_data (blob);
108
109 free (blob);
110}
111
112const char *
113hb_blob_get_data (hb_blob_t *blob,
114 unsigned int *len)
115{
116 if (len)
117 *len = blob->len;
118
119 return blob->data;
120}
121
122hb_bool_t
123hb_blob_is_writeable (hb_blob_t *blob)
124{
125 return blob->mode == HB_MEMORY_MODE_WRITEABLE;
126}
127
128hb_bool_t
129hb_blob_try_writeable_inplace (hb_blob_t *blob)
130{
131 if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITEABLE) {
132 /* XXX
133 * mprotect
134 blob->mode == HB_MEMORY_MODE_WRITEABLE;
135 */
136 }
137
138 return blob->mode == HB_MEMORY_MODE_WRITEABLE;
139}
140
141/* DANGER: May rebase or nullify */
142void
143hb_blob_make_writeable (hb_blob_t *blob)
144{
145 if (blob->mode == HB_MEMORY_MODE_READONLY_NEVER_DUPLICATE)
146 {
147 _hb_blob_destroy_user_data (blob);
148 blob->data = NULL;
149 blob->len = 0;
150 }
151 else if (blob->mode == HB_MEMORY_MODE_READONLY)
152 {
153 char *new_data;
154
155 new_data = malloc (blob->len);
156 if (new_data)
157 memcpy (new_data, blob->data, blob->len);
158
159 _hb_blob_destroy_user_data (blob);
160
161 if (!new_data) {
162 blob->data = NULL;
163 blob->len = 0;
164 } else
165 blob->data = new_data;
166
167 blob->mode = HB_MEMORY_MODE_WRITEABLE;
168 }
169 else
170 hb_blob_try_writeable_inplace (blob);
171}