1f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2009  Red Hat, Inc.
3f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod *
4c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
5f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod *
6f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * Permission is hereby granted, without written agreement and without
7f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
8f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * software and its documentation for any purpose, provided that the
9f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
10f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * all copies of this software.
11f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod *
12f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * DAMAGE.
17f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod *
18f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod *
24f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
25f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod */
26f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
27f88d3bd7e407d332bb04688344c54756d24128c9Behdad Esfahbod/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
2873f7f8919ea1f09b8c5b29f231ac84105cde2145Behdad Esfahbod#ifndef _POSIX_C_SOURCE
2952c8d1226f3509276b11a1fadbd29e5363c0ecd7Behdad Esfahbod#define _POSIX_C_SOURCE 199309L
3073f7f8919ea1f09b8c5b29f231ac84105cde2145Behdad Esfahbod#endif
31f88d3bd7e407d332bb04688344c54756d24128c9Behdad Esfahbod
32c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#include "hb-private.hh"
33f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
3456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod#include "hb-object-private.hh"
35f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
36ec90ee23b29aab187c3fa209970aa97434c84b1bBehdad Esfahbod#ifdef HAVE_SYS_MMAN_H
37c486ea9c3582710474c1085c21c1dc5e2700adc3Behdad Esfahbod#ifdef HAVE_UNISTD_H
38a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod#include <unistd.h>
39c486ea9c3582710474c1085c21c1dc5e2700adc3Behdad Esfahbod#endif /* HAVE_UNISTD_H */
40a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod#include <sys/mman.h>
41ec90ee23b29aab187c3fa209970aa97434c84b1bBehdad Esfahbod#endif /* HAVE_SYS_MMAN_H */
42a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
43acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod#include <stdio.h>
44acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod#include <errno.h>
45acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
46acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
47acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
4895e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#ifndef HB_DEBUG_BLOB
4911e3ec444a85fc72541823c2e98cc92c4ceb19afBehdad Esfahbod#define HB_DEBUG_BLOB (HB_DEBUG+0)
5095e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod#endif
5195e202403ffa543c817f45cca21fbc116eb8e807Behdad Esfahbod
5256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
531bc1cb3603167f5da309336f7018c8b0608ac104Behdad Esfahbodstruct hb_blob_t {
5456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod  hb_object_header_t header;
556220e5fc0dad728e67a92e838d3ac275d032f2c7Behdad Esfahbod  ASSERT_POD ();
5656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
571c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  bool immutable;
5856eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
5956eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod  const char *data;
601c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  unsigned int length;
611c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  hb_memory_mode_t mode;
6256eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
6356eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod  void *user_data;
6456eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod  hb_destroy_func_t destroy;
6556eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod};
6656eb5ad6f94c32189ad219438db9a18683ca6846Behdad Esfahbod
671c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
681c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodstatic bool _try_writable (hb_blob_t *blob);
691c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
70f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodstatic void
71f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod_hb_blob_destroy_user_data (hb_blob_t *blob)
72f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
73f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  if (blob->destroy) {
74f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod    blob->destroy (blob->user_data);
75f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod    blob->user_data = NULL;
76e5847f75fb7bd25c5db6061d8e20d61fa469f9feBehdad Esfahbod    blob->destroy = NULL;
77f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  }
78f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
79f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
805f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
812cd5323531dcd800549b2cb1cb51d708e72ab2d8Behdad Esfahbod * hb_blob_create: (skip)
822cd5323531dcd800549b2cb1cb51d708e72ab2d8Behdad Esfahbod * @data: Pointer to blob data.
835f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @length: Length of @data in bytes.
845f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @mode: Memory mode for @data.
852cd5323531dcd800549b2cb1cb51d708e72ab2d8Behdad Esfahbod * @user_data: Data parameter to pass to @destroy.
862cd5323531dcd800549b2cb1cb51d708e72ab2d8Behdad Esfahbod * @destroy: Callback to call when @data is not needed anymore.
875f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
885f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Creates a new "blob" object wrapping @data.  The @mode parameter is used
895f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * to negotiate ownership and lifecycle of @data.
905f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
91288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: New blob, or the empty blob if something failed or if @length is
925f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * zero.  Destroy with hb_blob_destroy().
935f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
945f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
955f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
96f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodhb_blob_t *
97f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodhb_blob_create (const char        *data,
98a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod		unsigned int       length,
99f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod		hb_memory_mode_t   mode,
100e5847f75fb7bd25c5db6061d8e20d61fa469f9feBehdad Esfahbod		void              *user_data,
101e5847f75fb7bd25c5db6061d8e20d61fa469f9feBehdad Esfahbod		hb_destroy_func_t  destroy)
102f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
103f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  hb_blob_t *blob;
104f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
1057d5e7613ced3dd39d05df83ca7e8952cbecd68f6Behdad Esfahbod  if (!length ||
1067d5e7613ced3dd39d05df83ca7e8952cbecd68f6Behdad Esfahbod      length >= 1u << 31 ||
1077d5e7613ced3dd39d05df83ca7e8952cbecd68f6Behdad Esfahbod      data + length < data /* overflows */ ||
1087d5e7613ced3dd39d05df83ca7e8952cbecd68f6Behdad Esfahbod      !(blob = hb_object_create<hb_blob_t> ())) {
109f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod    if (destroy)
110f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod      destroy (user_data);
111f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    return hb_blob_get_empty ();
112f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  }
113f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
114f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  blob->data = data;
115a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod  blob->length = length;
116f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  blob->mode = mode;
117f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
118f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  blob->user_data = user_data;
119e5847f75fb7bd25c5db6061d8e20d61fa469f9feBehdad Esfahbod  blob->destroy = destroy;
120f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
121f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
122f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod    blob->mode = HB_MEMORY_MODE_READONLY;
1231c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod    if (!_try_writable (blob)) {
124fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbod      hb_blob_destroy (blob);
125f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod      return hb_blob_get_empty ();
126fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbod    }
127f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  }
128f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
129f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  return blob;
130f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
131f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
1325f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
1335f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_create_sub_blob:
1345f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @parent: Parent blob.
1355f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @offset: Start offset of sub-blob within @parent, in bytes.
1365f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @length: Length of sub-blob.
1375f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1385f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Returns a blob that represents a range of bytes in @parent.  The new
1395f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
1405f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * will never modify data in the parent blob.  The parent data is not
1415f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * expected to be modified, and will result in undefined behavior if it
1425f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * is.
1435f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1445f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Makes @parent immutable.
1455f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
146288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: New blob, or the empty blob if something failed or if
147288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * @length is zero or @offset is beyond the end of @parent's data.  Destroy
148288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * with hb_blob_destroy().
1495f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1505f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
1515f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
152f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodhb_blob_t *
153a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbodhb_blob_create_sub_blob (hb_blob_t    *parent,
154a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod			 unsigned int  offset,
155a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod			 unsigned int  length)
156a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod{
157a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod  hb_blob_t *blob;
158a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
1594101ca7dbbdf1438fa116fb8cad935501ac7cca8Behdad Esfahbod  if (!length || offset >= parent->length)
160f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    return hb_blob_get_empty ();
161a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
1621c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  hb_blob_make_immutable (parent);
163a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
1641c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob = hb_blob_create (parent->data + offset,
165d4141a44b97377a65e6d2a3e03b3709307af38c1Behdad Esfahbod			 MIN (length, parent->length - offset),
166c3ba49b6fa1865e8318926eaa6c0f2063d1053bbBehdad Esfahbod			 HB_MEMORY_MODE_READONLY,
167d4141a44b97377a65e6d2a3e03b3709307af38c1Behdad Esfahbod			 hb_blob_reference (parent),
1681c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod			 (hb_destroy_func_t) hb_blob_destroy);
169a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
170a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod  return blob;
171a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod}
172a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
1735f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
1745f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_get_empty:
1755f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1765f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Returns the singleton empty blob.
1775f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1785f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * See TODO:link object types for more information.
1795f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
180288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: (transfer full): the empty blob.
1815f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
1825f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
1835f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
184a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbodhb_blob_t *
1854911062d5be0d937ee8f1a70cc93e05d162f45b3Behdad Esfahbodhb_blob_get_empty (void)
186a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod{
187f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  static const hb_blob_t _hb_blob_nil = {
188f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    HB_OBJECT_HEADER_STATIC,
189f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
1900594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    true, /* immutable */
191f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
192f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    NULL, /* data */
193f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    0, /* length */
194f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    HB_MEMORY_MODE_READONLY, /* mode */
195f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
196f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    NULL, /* user_data */
197f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    NULL  /* destroy */
198f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  };
199f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
200f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  return const_cast<hb_blob_t *> (&_hb_blob_nil);
201a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod}
202a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbod
2035f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
204288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * hb_blob_reference: (skip)
2055f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
2065f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2075f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Increases the reference count on @blob.
2085f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2095f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * See TODO:link object types for more information.
2105f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
211288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: @blob.
2125f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2135f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
2145f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
215a26442437ae9f11674e0d68cd5cbf395ade7695dBehdad Esfahbodhb_blob_t *
216f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodhb_blob_reference (hb_blob_t *blob)
217f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
21847e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  return hb_object_reference (blob);
219f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
220f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
2215f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
222288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * hb_blob_destroy: (skip)
2235f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
2245f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2255f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Descreases the reference count on @blob, and if it reaches zero, destroys
2265f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob, freeing all memory, possibly calling the destroy-callback the blob
2275f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * was created for if it has not been called already.
2285f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2295f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * See TODO:link object types for more information.
2305f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2315f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
2325f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
233f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodvoid
234f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbodhb_blob_destroy (hb_blob_t *blob)
235f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
23647e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!hb_object_destroy (blob)) return;
237f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
238f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  _hb_blob_destroy_user_data (blob);
239f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
240f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod  free (blob);
241f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
242f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
2435f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
244288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * hb_blob_set_user_data: (skip)
2455f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
2465f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @key: key for data to set.
2475f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @data: data to set.
2485f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @destroy: callback to call when @data is not needed anymore.
2495f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @replace: whether to replace an existing data with the same key.
2505f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
251288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value:
2525f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2535f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
2545f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
2555fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t
2565fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_blob_set_user_data (hb_blob_t          *blob,
2575fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod		       hb_user_data_key_t *key,
2585fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod		       void *              data,
25933ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod		       hb_destroy_func_t   destroy,
26033ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod		       hb_bool_t           replace)
2615fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
26233ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod  return hb_object_set_user_data (blob, key, data, destroy, replace);
2635fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
2645fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
2655f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
266288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * hb_blob_get_user_data: (skip)
2675f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
2685f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @key: key for data to get.
2695f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
270288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod *
2715f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
272288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: (transfer none):
2735f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2745f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
2755f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
2765fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid *
2775fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_blob_get_user_data (hb_blob_t          *blob,
2785fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod		       hb_user_data_key_t *key)
2795fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
2805fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod  return hb_object_get_user_data (blob, key);
2815fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
2825fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
2835fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
2845f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
2855f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_make_immutable:
2865f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
2875f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
288288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod *
2895f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
2905f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
2915f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
292fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbodvoid
2931c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_blob_make_immutable (hb_blob_t *blob)
294fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbod{
29547e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (hb_object_is_inert (blob))
2967f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod    return;
2977f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
2980594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  blob->immutable = true;
2991c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod}
3007acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod
3015f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
3025f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_is_immutable:
3035f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
3045f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
305288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod *
3065f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
307288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: TODO
3085f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3095f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
3105f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
3111c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_bool_t
3121c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_blob_is_immutable (hb_blob_t *blob)
3131c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod{
3141c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  return blob->immutable;
3151c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod}
3167f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3175a11c875d8c95d480e6f32b57e969ee34ca1940dBehdad Esfahbod
3185f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
3195f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_get_length:
3205f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
3215f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
322288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod *
3235f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
324288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Return value: the length of blob data in bytes.
3255f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3265f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
3275f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
3281c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodunsigned int
3291c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_blob_get_length (hb_blob_t *blob)
3301c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod{
3311c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  return blob->length;
332f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
333f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
3345f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
3355f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_get_data:
3365f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
337288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * @length: (out):
3385f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
339288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod *
3405f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
341288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Returns: (transfer none) (array length=length):
3425f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3435f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
3445f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
3451c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodconst char *
3461c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_blob_get_data (hb_blob_t *blob, unsigned int *length)
347f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
3481c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (length)
3491c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod    *length = blob->length;
3507f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3511c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  return blob->data;
3521c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod}
3537f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3545f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod/**
3555f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * hb_blob_get_data_writable:
3565f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @blob: a blob.
3575f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * @length: (out): output length of the writable data.
3585f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3595f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Tries to make blob data writable (possibly copying it) and
3605f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * return pointer to data.
3615f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3625f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Fails if blob has been made immutable, or if memory allocation
3635f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * fails.
3645f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
365288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * Returns: (transfer none) (array length=length): Writable blob data,
366288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod * or %NULL if failed.
3675f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod *
3685f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod * Since: 1.0
3695f512017ba615ba6ac8e5da2ea0c57a72db2c26bBehdad Esfahbod **/
3701c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodchar *
3711c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodhb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
3721c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod{
3731c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (!_try_writable (blob)) {
3741c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod    if (length)
3751c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod      *length = 0;
3767f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3771c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod    return NULL;
3781c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  }
3797f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3801c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (length)
3811c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod    *length = blob->length;
3827f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
3831c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  return const_cast<char *> (blob->data);
384f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
385f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
3864ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
3874ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbodstatic hb_bool_t
3881c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod_try_make_writable_inplace_unix (hb_blob_t *blob)
3894ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod{
3904ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
391917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  uintptr_t pagesize = -1, mask, length;
3924ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod  const char *addr;
3934ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
3944ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
395917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
3964ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
397917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
3984ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#elif defined(HAVE_GETPAGESIZE)
399917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  pagesize = (uintptr_t) getpagesize ();
4004ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#endif
4014ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
402917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  if ((uintptr_t) -1L == pagesize) {
403cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod    DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
4040594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
4054ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod  }
406cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
4074ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
4084ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod  mask = ~(pagesize-1);
409917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  addr = (const char *) (((uintptr_t) blob->data) & mask);
410917c227500305aee543981ad24a39f868c5ca0b7Behdad Esfahbod  length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
411cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob,
412cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod		  "calling mprotect on [%p..%p] (%lu bytes)",
413cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod		  addr, addr+length, (unsigned long) length);
4144ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod  if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
415cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod    DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
4160594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
4174ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod  }
4184ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
4191c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->mode = HB_MEMORY_MODE_WRITABLE;
4201c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
421cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob,
422cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod		  "successfully made [%p..%p] (%lu bytes) writable\n",
423cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod		  addr, addr+length, (unsigned long) length);
4240594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return true;
4254ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#else
4260594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return false;
4274ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod#endif
4284ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod}
4294ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
4301c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodstatic bool
4311c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod_try_writable_inplace (hb_blob_t *blob)
432388ad037ff399c23c5e24bbcede27e0e35bed07eBehdad Esfahbod{
433cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
434388ad037ff399c23c5e24bbcede27e0e35bed07eBehdad Esfahbod
4351c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (_try_make_writable_inplace_unix (blob))
4360594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return true;
4371c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
438cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
4391c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
4401c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  /* Failed to make writable inplace, mark that */
4411c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->mode = HB_MEMORY_MODE_READONLY;
4420594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return false;
443388ad037ff399c23c5e24bbcede27e0e35bed07eBehdad Esfahbod}
4444ff2a58952f010c6252f06e5f404d6840d257250Behdad Esfahbod
4451c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbodstatic bool
4461c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod_try_writable (hb_blob_t *blob)
447f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod{
4481c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (blob->immutable)
4490594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
450fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbod
4511c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
4520594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return true;
4537f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
4541c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
4550594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return true;
45671e735e915c85536ee4d3035576f7426e8cd19ddBehdad Esfahbod
4571c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
4580594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return true;
459f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod
460fc6c94002dd5478cf9fbdaff12d8374a786c85e1Behdad Esfahbod
461bc71ad4973842f25216b48842a46d6c9cbce6aa3Behdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
4621c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
4631c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  char *new_data;
4641c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
4651c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  new_data = (char *) malloc (blob->length);
4661c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  if (unlikely (!new_data))
4670594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
4687f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
469cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod  DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
4707f3d5c8166e5205e9d9bf8b4b2f31d44387a8006Behdad Esfahbod
4711c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  memcpy (new_data, blob->data, blob->length);
4721c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  _hb_blob_destroy_user_data (blob);
4731c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->mode = HB_MEMORY_MODE_WRITABLE;
4741c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->data = new_data;
4751c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->user_data = new_data;
4761c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod  blob->destroy = free;
4771c9f8717eb12c37c219333cbb0d123e1d2da4896Behdad Esfahbod
4780594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return true;
479f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod}
480