1251881Speter/** 2251881Speter * @copyright 3251881Speter * ==================================================================== 4251881Speter * Licensed to the Apache Software Foundation (ASF) under one 5251881Speter * or more contributor license agreements. See the NOTICE file 6251881Speter * distributed with this work for additional information 7251881Speter * regarding copyright ownership. The ASF licenses this file 8251881Speter * to you under the Apache License, Version 2.0 (the 9251881Speter * "License"); you may not use this file except in compliance 10251881Speter * with the License. You may obtain a copy of the License at 11251881Speter * 12251881Speter * http://www.apache.org/licenses/LICENSE-2.0 13251881Speter * 14251881Speter * Unless required by applicable law or agreed to in writing, 15251881Speter * software distributed under the License is distributed on an 16251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17251881Speter * KIND, either express or implied. See the License for the 18251881Speter * specific language governing permissions and limitations 19251881Speter * under the License. 20251881Speter * ==================================================================== 21251881Speter * @endcopyright 22251881Speter * 23251881Speter * @file svn_temp_serializer.h 24251881Speter * @brief Helper API for serializing _temporarily_ data structures. 25251881Speter * 26251881Speter * @note This API is intended for efficient serialization and duplication 27251881Speter * of temporary, e.g. cached, data structures ONLY. It is not 28251881Speter * suitable for persistent data. 29251881Speter */ 30251881Speter 31251881Speter#ifndef SVN_TEMP_SERIALIZER_H 32251881Speter#define SVN_TEMP_SERIALIZER_H 33251881Speter 34251881Speter#include "svn_string.h" 35251881Speter 36251881Speter#ifdef __cplusplus 37251881Speterextern "C" { 38251881Speter#endif /* __cplusplus */ 39251881Speter 40251881Speter/* forward declaration */ 41251881Speterstruct svn_stringbuf_t; 42251881Speter 43251881Speter/** 44251881Speter * The amount of extra memory allocated by #svn_temp_serializer__init for 45251881Speter * the internal buffer in addition to its suggested_buffer_size parameter. 46251881Speter * To allocate a 512 buffer, including overhead, just specify a size of 47251881Speter * 512 - SVN_TEMP_SERIALIZER__OVERHEAD. 48251881Speter */ 49251881Speter#define SVN_TEMP_SERIALIZER__OVERHEAD (sizeof(svn_stringbuf_t) + 1) 50251881Speter 51251881Speter/** 52251881Speter * Opaque structure controlling the serialization process and holding the 53251881Speter * intermediate as well as final results. 54251881Speter */ 55251881Spetertypedef struct svn_temp_serializer__context_t svn_temp_serializer__context_t; 56251881Speter 57251881Speter/** 58251881Speter * Begin the serialization process for the @a source_struct and all objects 59251881Speter * referenced from it. @a struct_size must match the result of @c sizeof() 60251881Speter * of the actual structure. Due to the generic nature of the init function 61251881Speter * we can't determine the structure size as part of the function. 62251881Speter * 63251881Speter * It is possible to specify a @c NULL source_struct in which case the first 64251881Speter * call to svn_temp_serializer__push() will provide the root struct. 65251881Speter * Alternatively, one may even call svn_temp_serializer__add_string() 66251881Speter * but there is generally no point in doing so because the result will be 67251881Speter * simple string object in a #svn_stringbuf_t. 68251881Speter * 69251881Speter * You may suggest a larger initial buffer size in @a suggested_buffer_size 70251881Speter * to minimize the number of internal buffer re-allocations during the 71251881Speter * serialization process. All allocations will be made from @a pool. 72251881Speter * 73251881Speter * Pointers within the structure will be replaced by their serialized 74251881Speter * representation when the respective strings or sub-structures get 75251881Speter * serialized. This scheme allows only for tree-like, i.e. non-circular 76251881Speter * data structures. 77251881Speter * 78251881Speter * @return the serialization context. 79251881Speter */ 80251881Spetersvn_temp_serializer__context_t * 81251881Spetersvn_temp_serializer__init(const void *source_struct, 82251881Speter apr_size_t struct_size, 83251881Speter apr_size_t suggested_buffer_size, 84251881Speter apr_pool_t *pool); 85251881Speter 86251881Speter/** 87251881Speter * Continue the serialization process of the @a source_struct that has 88251881Speter * already been serialized to @a buffer but contains references to new 89251881Speter * objects yet to serialize. I.e. this function allows you to append 90251881Speter * data to serialized structures returned by svn_temp_serializer__get(). 91251881Speter * 92251881Speter * The current size of the serialized data is given in @a currently_used. 93251881Speter * If the allocated data buffer is actually larger, you may specifiy that 94251881Speter * size in @a currently_allocated to prevent unnecessary re-allocations. 95251881Speter * Otherwise, set it to 0. 96251881Speter * 97251881Speter * All allocations will be made from @a pool. 98251881Speter * 99251881Speter * Please note that only sub-structures of @a source_struct may be added. 100251881Speter * To add item referenced from other parts of the buffer, serialize from 101251881Speter * @a source_struct first, get the result from svn_temp_serializer__get() 102251881Speter * and call svn_temp_serializer__init_append for the next part. 103251881Speter * 104251881Speter * @return the serialization context. 105251881Speter */ 106251881Spetersvn_temp_serializer__context_t * 107251881Spetersvn_temp_serializer__init_append(void *buffer, 108251881Speter void *source_struct, 109251881Speter apr_size_t currently_used, 110251881Speter apr_size_t currently_allocated, 111251881Speter apr_pool_t *pool); 112251881Speter 113251881Speter/** 114251881Speter * Begin serialization of a referenced sub-structure within the 115251881Speter * serialization @a context. @a source_struct must be a reference to the 116251881Speter * pointer in the original parent structure so that the correspondence in 117251881Speter * the serialized structure can be established. @a struct_size must match 118251881Speter * the result of @c sizeof() of the actual structure. 119251881Speter * 120251881Speter * Only in case that svn_temp_serializer__init() has not been provided 121251881Speter * with a root structure and this is the first call after the initialization, 122251881Speter * @a source_struct will point to a reference to the root structure instead 123251881Speter * of being related to some other. 124251881Speter * 125251881Speter * Sub-structures and strings will be added in a FIFO fashion. If you need 126251881Speter * add further sub-structures on the same level, you need to call 127251881Speter * svn_serializer__pop() to realign the serialization context. 128251881Speter */ 129251881Spetervoid 130251881Spetersvn_temp_serializer__push(svn_temp_serializer__context_t *context, 131251881Speter const void * const * source_struct, 132251881Speter apr_size_t struct_size); 133251881Speter 134251881Speter/** 135251881Speter * End the serialization of the current sub-structure. The serialization 136251881Speter * @a context will be focused back on the parent structure. You may then 137251881Speter * add further sub-structures starting from that level. 138251881Speter * 139251881Speter * It is not necessary to call this function just for symmetry at the end 140251881Speter * of the serialization process. 141251881Speter */ 142251881Spetervoid 143251881Spetersvn_temp_serializer__pop(svn_temp_serializer__context_t *context); 144251881Speter 145251881Speter/** 146251881Speter * Serialize a string referenced from the current structure within the 147251881Speter * serialization @a context. @a s must be a reference to the @c char* 148251881Speter * pointer in the original structure so that the correspondence in the 149251881Speter * serialized structure can be established. 150251881Speter * 151251881Speter * Only in case that svn_temp_serializer__init() has not been provided 152251881Speter * with a root structure and this is the first call after the initialization, 153251881Speter * @a s will not be related to some struct. 154251881Speter */ 155251881Spetervoid 156251881Spetersvn_temp_serializer__add_string(svn_temp_serializer__context_t *context, 157251881Speter const char * const * s); 158251881Speter 159251881Speter/** 160251881Speter * Set the serialized representation of the pointer @a ptr inside the 161251881Speter * current structure within the serialization @a context to @c NULL. 162251881Speter * This is particularly useful if the pointer is not @c NULL in the 163251881Speter * source structure. 164251881Speter */ 165251881Spetervoid 166251881Spetersvn_temp_serializer__set_null(svn_temp_serializer__context_t *context, 167251881Speter const void * const * ptr); 168251881Speter 169251881Speter/** 170251881Speter * @return the number of bytes currently used in the serialization buffer 171251881Speter * of the given serialization @a context. 172251881Speter */ 173251881Speterapr_size_t 174251881Spetersvn_temp_serializer__get_length(svn_temp_serializer__context_t *context); 175251881Speter 176251881Speter/** 177251881Speter * @return a reference to the data buffer containing the data serialialized 178251881Speter * so far in the given serialization @a context. 179251881Speter */ 180251881Speterstruct svn_stringbuf_t * 181251881Spetersvn_temp_serializer__get(svn_temp_serializer__context_t *context); 182251881Speter 183251881Speter/** 184251881Speter * Deserialization is straightforward: just copy the serialized buffer to 185251881Speter * a natively aligned memory location (APR pools will take care of that 186251881Speter * automatically) and resolve all pointers to sub-structures. 187251881Speter * 188251881Speter * To do the latter, call this function for each of these pointers, giving 189251881Speter * the start address of the copied buffer in @a buffer and a reference to 190251881Speter * the pointer to resolve in @a ptr. 191251881Speter */ 192251881Spetervoid 193251881Spetersvn_temp_deserializer__resolve(void *buffer, void **ptr); 194251881Speter 195251881Speter/** 196251881Speter * Similar to svn_temp_deserializer__resolve() but instead of modifying 197251881Speter * the buffer content, the resulting pointer is passed back to the caller 198251881Speter * as the return value. 199251881Speter */ 200251881Speterconst void * 201251881Spetersvn_temp_deserializer__ptr(const void *buffer, const void *const *ptr); 202251881Speter 203251881Speter#ifdef __cplusplus 204251881Speter} 205251881Speter#endif /* __cplusplus */ 206251881Speter 207251881Speter#endif /* SVN_TEMP_SERIALIZER_H */ 208