/* Ensure that the size of a given memory buffer is at least MINIMUM_SIZE * bytes. If *SIZE is already greater than or equal to MINIMUM_SIZE, * this function does nothing. * * If *SIZE is 0, the allocated buffer size will be MINIMUM_SIZE * rounded up to the nearest APR alignment boundary. Otherwse, *SIZE * will be multiplied by a power of two such that the result is * greater or equal to MINIMUM_SIZE. The pointer to the new buffer * will be returned in *DATA, and its size in *SIZE. */ static APR_INLINE void membuf_ensure(void **data, apr_size_t *size, apr_size_t minimum_size, apr_pool_t *pool) { if (minimum_size > *size) { apr_size_t new_size = *size; if (new_size == 0) /* APR will increase odd allocation sizes to the next * multiple for 8, for instance. Take advantage of that * knowledge and allow for the extra size to be used. */ new_size = minimum_size; else while (new_size < minimum_size) { /* new_size is aligned; doubling it should keep it aligned */ const apr_size_t prev_size = new_size; new_size *= 2; /* check for apr_size_t overflow */ if (prev_size > new_size) { new_size = minimum_size; break; } } membuf_create(data, size, new_size, pool); } }
svn_stringbuf_t * svn_stringbuf_create_ensure(apr_size_t blocksize, apr_pool_t *pool) { void *mem; svn_stringbuf_t *new_string; ++blocksize; /* + space for '\0' */ /* Allocate memory for svn_string_t and data in one chunk. */ membuf_create(&mem, &blocksize, blocksize + sizeof(*new_string), pool); /* Initialize header and string */ new_string = mem; new_string->data = (char*)mem + sizeof(*new_string); new_string->data[0] = '\0'; new_string->len = 0; new_string->blocksize = blocksize - sizeof(*new_string); new_string->pool = pool; return new_string; }
int CompileAspPage(lua_State *L, const char *asp_path, const struct AspEngineConfig *config, char **error_message) { int requires_recompilation = 0; struct _stat asp_file_stat; struct _stat luac_file_stat; char cache_path[MAX_PATH]; char lua_file[MAX_PATH]; char luac_file[MAX_PATH]; struct membuf *lua_content; lua_State *LL; int result; struct ReaderState reader_state; int use_cache; assert(((!config->cache_lua && !config->cache_luac) || ((config->cache_lua || config->cache_luac)) && config->root_path && config->cache_path)); if (error_message != NULL) *error_message = NULL; if (config->cache_path && !RetargetPath(config->root_path, asp_path, config->cache_path, cache_path)) { use_cache = config->cache_lua || config->cache_luac; } else { use_cache = 0; } if (_stat(asp_path, &asp_file_stat) != 0) { if (error_message) *error_message = strdup(strerror(errno)); return errno; } requires_recompilation = 1; if (use_cache) { CreateDirectories(cache_path); strcat(strcpy(lua_file, cache_path), ".lua"); strcat(strcpy(luac_file, cache_path), ".luac"); if (_stat(luac_file, &luac_file_stat) == 0) { if (asp_file_stat.st_mtime < luac_file_stat.st_mtime) requires_recompilation = 0; } } if (requires_recompilation) { lua_content = GenerateLuaFile(asp_path, (use_cache && config->cache_lua) ? lua_file : NULL, error_message); if (lua_content == NULL) return 1; } else { FILE *luac_fp = fopen(luac_file, "rb"); if (luac_fp == NULL) { if (error_message) *error_message = strdup(strerror(errno)); return 1; } lua_content = membuf_create(luac_file_stat.st_size, _dup(_fileno(luac_fp)), 1, 0); fclose(luac_fp); } reader_state.ptr = (char *)membuf_begin(lua_content); reader_state.end = (char *)membuf_end(lua_content); LL = L ? L : luaL_newstate(); result = lua_load(LL, StringStreamReader, &reader_state, asp_path, NULL); if (result != LUA_OK) { membuf_close(lua_content); if (error_message) *error_message = strdup(lua_tostring(LL, -1)); if (L == NULL) lua_close(LL); return 1; } membuf_close(lua_content); if (use_cache && requires_recompilation && config->cache_luac) { struct FileWriterState writer_state; writer_state.fp = fopen(luac_file, "wb"); if (writer_state.fp != NULL) { lua_dump(LL, FileWriter, &writer_state); fclose(writer_state.fp); } } if (L != NULL) { result = lua_pcall(LL, 0, 0, 0); if (result && error_message) *error_message = strdup(lua_tostring(LL, -1)); } else { lua_close(LL); } return result; }
void svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool) { membuf_create(&membuf->data, &membuf->size, size, pool); membuf->pool = pool; }
static struct membuf *GenerateLuaFile(const char *asp_path, const char *lua_path, char **error_message) { FILE *fp; struct stat asp_file_stat; const char *asp_content; const char *asp_content_begin_ptr; struct membuf *lua_content; size_t estimated_size; int lua_fd = -1; struct ParserData parser_data; if (error_message) *error_message = NULL; fp = fopen(asp_path, "rt"); if (fp == NULL) { if (error_message) *error_message = strdup(strerror(errno)); return NULL; } fstat(_fileno(fp), &asp_file_stat); asp_content = (const char *)mmap(NULL, asp_file_stat.st_size, PROT_READ, MAP_PRIVATE, _fileno(fp), 0); if (asp_content == NULL) { if (error_message) *error_message = strdup("mmap failed."); fclose(fp); return NULL; } // Check for BOM and skip if present asp_content_begin_ptr = asp_content; if (asp_file_stat.st_size >= 3) { if (strncmp(asp_content_begin_ptr, "\xEF\xBB\xBF", 3) == 0) asp_content_begin_ptr += 3; } if (lua_path != NULL) { FILE *lua_fp; lua_fp = fopen(lua_path, "wt"); if (lua_fp != NULL) { lua_fd = _dup(_fileno(lua_fp)); fclose(lua_fp); } } estimated_size = asp_file_stat.st_size * 4; lua_content = membuf_create(estimated_size, lua_fd, 0, 1); parser_data.buf = lua_content; parser_data.handler = WriteToBufferCallback; GenerateProlog(parser_data.handler, &parser_data); ParseBuffer(asp_content_begin_ptr, asp_file_stat.st_size, ParserEventHandler, &parser_data); GenerateEpilog(parser_data.handler, &parser_data); munmap(asp_content, asp_file_stat.st_size); fclose(fp); return lua_content; }