From 3daa63693c2f8f9cc3c7fa41ef1e4d69bd67b3cc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 16 Jan 2008 16:33:22 +0000 Subject: [PATCH] [cairo-svg-surface] Review error propagation during surface creation. Track the error during surface creation so that it can be returned to the user via _cairo_surface_create_in_error(). --- src/cairo-svg-surface.c | 124 +++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index df59ef748..2c3cb5893 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -118,11 +118,12 @@ typedef struct { cairo_meta_surface_t *meta; } cairo_meta_snapshot_t; -static cairo_svg_document_t * -_cairo_svg_document_create (cairo_output_stream_t *stream, - double width, - double height, - cairo_svg_version_t version); +static cairo_status_t +_cairo_svg_document_create (cairo_output_stream_t *stream, + double width, + double height, + cairo_svg_version_t version, + cairo_svg_document_t **document_out); static cairo_status_t _cairo_svg_document_destroy (cairo_svg_document_t *document); @@ -173,13 +174,11 @@ cairo_svg_surface_create_for_stream (cairo_write_func_t write_func, double width, double height) { - cairo_status_t status; cairo_output_stream_t *stream; stream = _cairo_output_stream_create (write_func, NULL, closure); - status = _cairo_output_stream_get_status (stream); - if (status) - return _cairo_surface_create_in_error (status); + if (_cairo_output_stream_get_status (stream)) + return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); } @@ -208,13 +207,11 @@ cairo_svg_surface_create (const char *filename, double width, double height) { - cairo_status_t status; cairo_output_stream_t *stream; stream = _cairo_output_stream_create_for_filename (filename); - status = _cairo_output_stream_get_status (stream); - if (status) - return _cairo_surface_create_in_error (status); + if (_cairo_output_stream_get_status (stream)) + return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); } @@ -330,7 +327,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, { cairo_svg_surface_t *surface; cairo_surface_t *paginated; - cairo_status_t status; + cairo_status_t status, status_ignored; surface = malloc (sizeof (cairo_svg_surface_t)); if (surface == NULL) @@ -351,8 +348,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, surface->is_base_clip_emitted = FALSE; surface->xml_node = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (surface->xml_node)) - goto CLEANUP_DOCUMENT; + status = _cairo_output_stream_get_status (surface->xml_node); + if (status) + goto CLEANUP; _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t)); @@ -362,8 +360,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, "style=\"opacity: 1; stroke: none; " "fill: rgb(0,0,0);\"/>\n", width, height); - if (_cairo_output_stream_get_status (surface->xml_node)) - goto CLEANUP_STREAM; + status = _cairo_output_stream_get_status (surface->xml_node); + if (status) + goto CLEANUP; } surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; @@ -375,17 +374,18 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, surface->width, surface->height, &cairo_svg_surface_paginated_backend); - if (! paginated->status) + status = paginated->status; + if (status == CAIRO_STATUS_SUCCESS) return paginated; /* ignore status as we are on the error path */ -CLEANUP_STREAM: - status = _cairo_output_stream_destroy (surface->xml_node); -CLEANUP_DOCUMENT: - status = _cairo_svg_document_destroy (document); +CLEANUP: + status_ignored = _cairo_output_stream_destroy (surface->xml_node); + status_ignored = _cairo_svg_document_destroy (document); free (surface); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + + return _cairo_surface_create_in_error (status); } static cairo_surface_t * @@ -394,15 +394,18 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream, double height, cairo_svg_version_t version) { - cairo_svg_document_t *document; + cairo_svg_document_t *document = NULL; /* silence compiler */ cairo_surface_t *surface; cairo_status_t status; - document = _cairo_svg_document_create (stream, width, height, version); - if (document == NULL) { + status = _cairo_svg_document_create (stream, + width, height, version, + &document); + if (status) { + surface = _cairo_surface_create_in_error (status); /* consume the output stream on behalf of caller */ status = _cairo_output_stream_destroy (stream); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + return surface; } surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA, @@ -426,20 +429,21 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface) unsigned int i; cairo_svg_page_t page; cairo_output_stream_t *stream; + cairo_status_t status; stream = _cairo_memory_stream_create (); - if (stream->status) + if (_cairo_output_stream_get_status (stream)) { + status = _cairo_output_stream_destroy (stream); return NULL; + } page.surface_id = surface->id; page.clip_level = surface->clip_level; page.xml_node = surface->xml_node; - if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS) - { - cairo_status_t status = _cairo_output_stream_destroy (stream); + if (_cairo_array_append (&surface->page_set, &page)) { + status = _cairo_output_stream_destroy (stream); return NULL; - (void) status; } surface->xml_node = stream; @@ -1954,8 +1958,8 @@ _cairo_svg_surface_paint (void *abstract_surface, } surface->xml_node = _cairo_memory_stream_create (); - status = _cairo_output_stream_get_status (surface->xml_node); - if (status) { + if (_cairo_output_stream_get_status (surface->xml_node)) { + status = _cairo_output_stream_destroy (surface->xml_node); surface->xml_node = NULL; return status; } @@ -2000,9 +2004,8 @@ _cairo_svg_surface_mask (void *abstract_surface, * document->xml_node_defs so we need to write the mask element to * a temporary stream and then copy that to xml_node_defs. */ mask_stream = _cairo_memory_stream_create (); - status = _cairo_output_stream_get_status (mask_stream); - if (status) - return status; + if (_cairo_output_stream_get_status (mask_stream)) + return _cairo_output_stream_destroy (mask_stream); _cairo_output_stream_printf (mask_stream, "\n" @@ -2240,28 +2243,29 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = { _cairo_svg_surface_fill_stroke }; -static cairo_svg_document_t * -_cairo_svg_document_create (cairo_output_stream_t *output_stream, - double width, - double height, - cairo_svg_version_t version) +static cairo_status_t +_cairo_svg_document_create (cairo_output_stream_t *output_stream, + double width, + double height, + cairo_svg_version_t version, + cairo_svg_document_t **document_out) { cairo_svg_document_t *document; - cairo_status_t status; + cairo_status_t status, status_ignored; if (output_stream->status) - return NULL; + return output_stream->status; document = malloc (sizeof (cairo_svg_document_t)); - if (document == NULL) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } + if (document == NULL) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); /* The use of defs for font glyphs imposes no per-subset limit. */ document->font_subsets = _cairo_scaled_font_subsets_create_scaled (); - if (document->font_subsets == NULL) + if (document->font_subsets == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_DOCUMENT; + } document->output_stream = output_stream; document->refcount = 1; @@ -2279,12 +2283,14 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->mask_id = 0; document->xml_node_defs = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (document->xml_node_defs)) - goto CLEANUP_FONT_SUBSETS; + status = _cairo_output_stream_get_status (document->xml_node_defs); + if (status) + goto CLEANUP_NODE_DEFS; document->xml_node_glyphs = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (document->xml_node_glyphs)) - goto CLEANUP_NODE_DEFS; + status = _cairo_output_stream_get_status (document->xml_node_glyphs); + if (status) + goto CLEANUP_NODE_GLYPHS; document->alpha_filter = FALSE; @@ -2293,15 +2299,17 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->svg_version = version; - return document; + *document_out = document; + return CAIRO_STATUS_SUCCESS; + CLEANUP_NODE_GLYPHS: + status_ignored = _cairo_output_stream_destroy (document->xml_node_glyphs); CLEANUP_NODE_DEFS: - status = _cairo_output_stream_destroy (document->xml_node_defs); - CLEANUP_FONT_SUBSETS: + status_ignored = _cairo_output_stream_destroy (document->xml_node_defs); _cairo_scaled_font_subsets_destroy (document->font_subsets); CLEANUP_DOCUMENT: free (document); - return NULL; + return status; } static cairo_svg_document_t *