diff --git a/src/glsl/blob.c b/src/glsl/blob.c index a4003cf7178..dd4341be961 100644 --- a/src/glsl/blob.c +++ b/src/glsl/blob.c @@ -100,6 +100,21 @@ blob_create(void *mem_ctx) return blob; } +bool +blob_overwrite_bytes(struct blob *blob, + size_t offset, + const void *bytes, + size_t to_write) +{ + /* Detect an attempt to overwrite data out of bounds. */ + if (offset < 0 || blob->size - offset < to_write) + return false; + + memcpy(blob->data + offset, bytes, to_write); + + return true; +} + bool blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write) { @@ -134,6 +149,14 @@ blob_write_uint32(struct blob *blob, uint32_t value) return blob_write_bytes(blob, &value, sizeof(value)); } +bool +blob_overwrite_uint32 (struct blob *blob, + size_t offset, + uint32_t value) +{ + return blob_overwrite_bytes(blob, offset, &value, sizeof(value)); +} + bool blob_write_uint64(struct blob *blob, uint64_t value) { diff --git a/src/glsl/blob.h b/src/glsl/blob.h index af32d22e498..ec903ec140f 100644 --- a/src/glsl/blob.h +++ b/src/glsl/blob.h @@ -107,6 +107,24 @@ blob_write_bytes (struct blob *blob, const void *bytes, size_t to_write); uint8_t * blob_reserve_bytes (struct blob *blob, size_t to_write); +/** + * Overwrite some data previously written to the blob. + * + * Writes data to an existing portion of the blob at an offset of \offset. + * This data range must have previously been written to the blob by one of the + * blob_write_* calls. + * + * For example usage, see blob_overwrite_uint32 + * + * \return True unless the requested offset or offset+to_write lie outside + * the current blob's size. + */ +bool +blob_overwrite_bytes (struct blob *blob, + size_t offset, + const void *bytes, + size_t to_write); + /** * Add a uint32_t to a blob. * @@ -120,6 +138,31 @@ blob_reserve_bytes (struct blob *blob, size_t to_write); bool blob_write_uint32 (struct blob *blob, uint32_t value); +/** + * Overwrite a uint32_t previously written to the blob. + * + * Writes a uint32_t value to an existing portion of the blob at an offset of + * \offset. This data range must have previously been written to the blob by + * one of the blob_write_* calls. + * + * + * The expected usage is something like the following pattern: + * + * size_t offset; + * + * offset = blob->size; + * blob_write_uint32 (blob, 0); // placeholder + * ... various blob write calls, writing N items ... + * blob_overwrite_uint32 (blob, offset, N); + * + * \return True unless the requested position or position+to_write lie outside + * the current blob's size. + */ +bool +blob_overwrite_uint32 (struct blob *blob, + size_t offset, + uint32_t value); + /** * Add a uint64_t to a blob. *