LCOV - code coverage report
Current view: top level - shumate - shumate-data-source-request.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 99 133 74.4 %
Date: 2024-05-11 21:41:31 Functions: 16 18 88.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 30 61 49.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2023 James Westman <james@jwestman.net>
       3                 :            :  *
       4                 :            :  * This library is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * This library is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :            :  * Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with this library; if not, see <https://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "shumate-data-source-request.h"
      19                 :            : #include "shumate-utils-private.h"
      20                 :            : #include "shumate-profiling-private.h"
      21                 :            : 
      22                 :            : 
      23                 :            : /**
      24                 :            :  * ShumateDataSourceRequest:
      25                 :            :  *
      26                 :            :  * Represents a request to a [class@DataSource] for a tile.
      27                 :            :  *
      28                 :            :  * Data sources can return a tile multiple times. For example, a
      29                 :            :  * [class@TileDownloader] may return cached data first, then later return data
      30                 :            :  * from a network service when it arrives. This allows the map to be rendered
      31                 :            :  * as quickly as possible without waiting for the network unnecessarily.
      32                 :            :  *
      33                 :            :  * Conventional async/finish method pairs don't support multiple returns.
      34                 :            :  * Instead, [method@DataSource.start_request] is available, which returns a
      35                 :            :  * [class@DataSourceRequest] whose properties, [property@DataSourceRequest:data]
      36                 :            :  * and [property@DataSourceRequest:error], update as data becomes available.
      37                 :            :  * The [signal@GObject.Object::notify] signal can be used to watch for these
      38                 :            :  * changes. When the request is done and no more data will be returned,
      39                 :            :  * [property@DataSourceRequest:completed] is set to %TRUE.
      40                 :            :  *
      41                 :            :  * [class@DataSource] implementations can use a subclass of
      42                 :            :  * [class@DataSourceRequest], but the base class should be sufficient in most
      43                 :            :  * cases.
      44                 :            :  *
      45                 :            :  * Since: 1.1
      46                 :            :  */
      47                 :            : 
      48                 :            : 
      49                 :            : typedef struct {
      50                 :            :   GObject parent;
      51                 :            : 
      52                 :            :   ShumateGridPosition pos;
      53                 :            :   GBytes *bytes;
      54                 :            :   GError *error;
      55                 :            : 
      56                 :            :   gboolean completed : 1;
      57                 :            : } ShumateDataSourceRequestPrivate;
      58                 :            : 
      59   [ +  +  +  - ]:        159 : G_DEFINE_TYPE_WITH_PRIVATE (ShumateDataSourceRequest, shumate_data_source_request, G_TYPE_OBJECT)
      60                 :            : 
      61                 :            : enum {
      62                 :            :   PROP_0,
      63                 :            :   PROP_X,
      64                 :            :   PROP_Y,
      65                 :            :   PROP_ZOOM_LEVEL,
      66                 :            :   PROP_DATA,
      67                 :            :   PROP_ERROR,
      68                 :            :   PROP_COMPLETED,
      69                 :            :   N_PROPS
      70                 :            : };
      71                 :            : 
      72                 :            : static GParamSpec *properties [N_PROPS];
      73                 :            : 
      74                 :            : static void
      75                 :          6 : shumate_data_source_request_finalize (GObject *object)
      76                 :            : {
      77                 :          6 :   ShumateDataSourceRequest *self = (ShumateDataSourceRequest *)object;
      78                 :          6 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
      79                 :            : 
      80         [ +  + ]:          6 :   g_clear_pointer (&priv->bytes, g_bytes_unref);
      81                 :          6 :   g_clear_error (&priv->error);
      82                 :            : 
      83                 :          6 :   G_OBJECT_CLASS (shumate_data_source_request_parent_class)->finalize (object);
      84                 :          6 : }
      85                 :            : 
      86                 :            : static void
      87                 :          0 : shumate_data_source_request_get_property (GObject    *object,
      88                 :            :                                           guint       prop_id,
      89                 :            :                                           GValue     *value,
      90                 :            :                                           GParamSpec *pspec)
      91                 :            : {
      92                 :          0 :   ShumateDataSourceRequest *self = SHUMATE_DATA_SOURCE_REQUEST (object);
      93                 :          0 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
      94                 :            : 
      95   [ #  #  #  #  :          0 :   switch (prop_id)
                #  #  # ]
      96                 :            :     {
      97                 :          0 :     case PROP_X:
      98                 :          0 :       g_value_set_int (value, priv->pos.x);
      99                 :          0 :       break;
     100                 :            : 
     101                 :          0 :     case PROP_Y:
     102                 :          0 :       g_value_set_int (value, priv->pos.y);
     103                 :          0 :       break;
     104                 :            : 
     105                 :          0 :     case PROP_ZOOM_LEVEL:
     106                 :          0 :       g_value_set_int (value, priv->pos.zoom);
     107                 :          0 :       break;
     108                 :            : 
     109                 :          0 :     case PROP_DATA:
     110                 :          0 :       g_value_set_boxed (value, priv->bytes);
     111                 :          0 :       break;
     112                 :            : 
     113                 :          0 :     case PROP_ERROR:
     114                 :          0 :       g_value_set_boxed (value, priv->error);
     115                 :          0 :       break;
     116                 :            : 
     117                 :          0 :     case PROP_COMPLETED:
     118                 :          0 :       g_value_set_boolean (value, priv->completed);
     119                 :          0 :       break;
     120                 :            : 
     121                 :          0 :     default:
     122                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     123                 :            :     }
     124                 :          0 : }
     125                 :            : 
     126                 :            : static void
     127                 :         18 : shumate_data_source_request_set_property (GObject      *object,
     128                 :            :                                           guint         prop_id,
     129                 :            :                                           const GValue *value,
     130                 :            :                                           GParamSpec   *pspec)
     131                 :            : {
     132                 :         18 :   ShumateDataSourceRequest *self = SHUMATE_DATA_SOURCE_REQUEST (object);
     133                 :         18 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     134                 :            : 
     135   [ +  +  +  - ]:         18 :   switch (prop_id)
     136                 :            :     {
     137                 :          6 :     case PROP_X:
     138                 :          6 :       priv->pos.x = g_value_get_int (value);
     139                 :          6 :       break;
     140                 :            : 
     141                 :          6 :     case PROP_Y:
     142                 :          6 :       priv->pos.y = g_value_get_int (value);
     143                 :          6 :       break;
     144                 :            : 
     145                 :          6 :     case PROP_ZOOM_LEVEL:
     146                 :          6 :       priv->pos.zoom = g_value_get_int (value);
     147                 :          6 :       break;
     148                 :            : 
     149                 :          0 :     default:
     150                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     151                 :            :     }
     152                 :         18 : }
     153                 :            : 
     154                 :            : static void
     155                 :          4 : shumate_data_source_request_class_init (ShumateDataSourceRequestClass *klass)
     156                 :            : {
     157                 :          4 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     158                 :            : 
     159                 :          4 :   object_class->finalize = shumate_data_source_request_finalize;
     160                 :          4 :   object_class->get_property = shumate_data_source_request_get_property;
     161                 :          4 :   object_class->set_property = shumate_data_source_request_set_property;
     162                 :            : 
     163                 :            :   /**
     164                 :            :    * ShumateDataSourceRequest:x:
     165                 :            :    *
     166                 :            :    * The X coordinate of the requested tile.
     167                 :            :    *
     168                 :            :    * Since: 1.1
     169                 :            :    */
     170                 :          8 :   properties[PROP_X] =
     171                 :          4 :     g_param_spec_int ("x", "x", "x",
     172                 :            :                       G_MININT, G_MAXINT, 0,
     173                 :            :                       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
     174                 :            : 
     175                 :            :   /**
     176                 :            :    * ShumateDataSourceRequest:y:
     177                 :            :    *
     178                 :            :    * The Y coordinate of the requested tile.
     179                 :            :    *
     180                 :            :    * Since: 1.1
     181                 :            :    */
     182                 :          8 :   properties[PROP_Y] =
     183                 :          4 :     g_param_spec_int ("y", "y", "y",
     184                 :            :                       G_MININT, G_MAXINT, 0,
     185                 :            :                       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
     186                 :            : 
     187                 :            :   /**
     188                 :            :    * ShumateDataSourceRequest:zoom-level:
     189                 :            :    *
     190                 :            :    * The zoom level of the requested tile.
     191                 :            :    *
     192                 :            :    * Since: 1.1
     193                 :            :    */
     194                 :          8 :   properties[PROP_ZOOM_LEVEL] =
     195                 :          4 :     g_param_spec_int ("zoom-level", "zoom-level", "zoom-level",
     196                 :            :                       G_MININT, G_MAXINT, 0,
     197                 :            :                       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
     198                 :            : 
     199                 :            :   /**
     200                 :            :    * ShumateDataSourceRequest:data:
     201                 :            :    *
     202                 :            :    * The most recent data for the tile, if available. If an error is emitted,
     203                 :            :    * this will be set to %NULL.
     204                 :            :    *
     205                 :            :    * Since: 1.1
     206                 :            :    */
     207                 :          8 :   properties[PROP_DATA] =
     208                 :          4 :     g_param_spec_boxed ("data", "data", "data",
     209                 :            :                         G_TYPE_BYTES,
     210                 :            :                         G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
     211                 :            : 
     212                 :            :   /**
     213                 :            :    * ShumateDataSourceRequest:error:
     214                 :            :    *
     215                 :            :    * The error that occurred during the request, if any.
     216                 :            :    *
     217                 :            :    * Since: 1.1
     218                 :            :    */
     219                 :          8 :   properties[PROP_ERROR] =
     220                 :          4 :     g_param_spec_boxed ("error", "error", "error",
     221                 :            :                         G_TYPE_ERROR,
     222                 :            :                         G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
     223                 :            : 
     224                 :            :   /**
     225                 :            :    * ShumateDataSourceRequest:completed:
     226                 :            :    *
     227                 :            :    * %TRUE if the request has been completed, otherwise %FALSE. A completed
     228                 :            :    * request will not receive further updates to either
     229                 :            :    * [property@DataSourceRequest:data] or [property@DataSourceRequest:error].
     230                 :            :    *
     231                 :            :    * Since: 1.1
     232                 :            :    */
     233                 :          8 :   properties[PROP_COMPLETED] =
     234                 :          4 :     g_param_spec_boolean ("completed", "completed", "completed",
     235                 :            :                           FALSE,
     236                 :            :                           G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
     237                 :            : 
     238                 :          4 :   g_object_class_install_properties (object_class, N_PROPS, properties);
     239                 :          4 : }
     240                 :            : 
     241                 :            : static void
     242                 :          6 : shumate_data_source_request_init (ShumateDataSourceRequest *self)
     243                 :            : {
     244                 :          6 : }
     245                 :            : 
     246                 :            : /**
     247                 :            :  * shumate_data_source_request_get_x:
     248                 :            :  * @self: a [class@DataSourceRequest]
     249                 :            :  *
     250                 :            :  * Gets the X coordinate of the requested tile.
     251                 :            :  *
     252                 :            :  * Returns: the X coordinate
     253                 :            :  *
     254                 :            :  * Since: 1.1
     255                 :            :  */
     256                 :            : int
     257                 :          3 : shumate_data_source_request_get_x (ShumateDataSourceRequest *self)
     258                 :            : {
     259                 :          3 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     260         [ +  - ]:          3 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), 0);
     261                 :          3 :   return priv->pos.x;
     262                 :            : }
     263                 :            : 
     264                 :            : /**
     265                 :            :  * shumate_data_source_request_get_y:
     266                 :            :  * @self: a [class@DataSourceRequest]
     267                 :            :  *
     268                 :            :  * Gets the Y coordinate of the requested tile.
     269                 :            :  *
     270                 :            :  * Returns: the Y coordinate
     271                 :            :  *
     272                 :            :  * Since: 1.1
     273                 :            :  */
     274                 :            : int
     275                 :          3 : shumate_data_source_request_get_y (ShumateDataSourceRequest *self)
     276                 :            : {
     277                 :          3 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     278         [ +  - ]:          3 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), 0);
     279                 :          3 :   return priv->pos.y;
     280                 :            : }
     281                 :            : 
     282                 :            : /**
     283                 :            :  * shumate_data_source_request_get_zoom_level:
     284                 :            :  * @self: a [class@DataSourceRequest]
     285                 :            :  *
     286                 :            :  * Gets the zoom level of the requested tile.
     287                 :            :  *
     288                 :            :  * Returns: the zoom level
     289                 :            :  *
     290                 :            :  * Since: 1.1
     291                 :            :  */
     292                 :            : int
     293                 :          3 : shumate_data_source_request_get_zoom_level (ShumateDataSourceRequest *self)
     294                 :            : {
     295                 :          3 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     296         [ +  - ]:          3 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), 0);
     297                 :          3 :   return priv->pos.zoom;
     298                 :            : }
     299                 :            : 
     300                 :            : /**
     301                 :            :  * shumate_data_source_request_get_data:
     302                 :            :  * @self: a [class@DataSourceRequest]
     303                 :            :  *
     304                 :            :  * Gets the latest data from the request.
     305                 :            :  *
     306                 :            :  * Returns: (transfer none) (nullable): The latest data, if any.
     307                 :            :  *
     308                 :            :  * Since: 1.1
     309                 :            :  */
     310                 :            : GBytes *
     311                 :         15 : shumate_data_source_request_get_data (ShumateDataSourceRequest *self)
     312                 :            : {
     313                 :         15 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     314         [ +  - ]:         15 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), NULL);
     315                 :         15 :   return priv->bytes;
     316                 :            : }
     317                 :            : 
     318                 :            : /**
     319                 :            :  * shumate_data_source_request_get_error:
     320                 :            :  * @self: a [class@DataSourceRequest]
     321                 :            :  *
     322                 :            :  * Gets the latest error from the request.
     323                 :            :  *
     324                 :            :  * Returns: (transfer none) (nullable): The latest error, if any.
     325                 :            :  *
     326                 :            :  * Since: 1.1
     327                 :            :  */
     328                 :            : GError *
     329                 :          3 : shumate_data_source_request_get_error (ShumateDataSourceRequest *self)
     330                 :            : {
     331                 :          3 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     332         [ +  - ]:          3 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), NULL);
     333                 :          3 :   return priv->error;
     334                 :            : }
     335                 :            : 
     336                 :            : /**
     337                 :            :  * shumate_data_source_request_is_completed:
     338                 :            :  * @self: a [class@DataSourceRequest]
     339                 :            :  *
     340                 :            :  * Gets whether the request has been completed. Completed requests will not
     341                 :            :  * receive new data or errors.
     342                 :            :  *
     343                 :            :  * Returns: %TRUE if the request is completed, otherwise %FALSE
     344                 :            :  *
     345                 :            :  * Since: 1.1
     346                 :            :  */
     347                 :            : gboolean
     348                 :         18 : shumate_data_source_request_is_completed (ShumateDataSourceRequest *self)
     349                 :            : {
     350                 :         18 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     351         [ +  - ]:         18 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self), FALSE);
     352                 :         18 :   return priv->completed;
     353                 :            : }
     354                 :            : 
     355                 :            : /**
     356                 :            :  * shumate_data_source_request_new:
     357                 :            :  * @x: X coordinate of the requested tile
     358                 :            :  * @y: Y coordinate of the requested tile
     359                 :            :  * @zoom_level: Zoom level of the requested tile
     360                 :            :  *
     361                 :            :  * Creates a new [class@DataSourceRequest].
     362                 :            :  *
     363                 :            :  * Only implementations of [vfunc@DataSource.start_request] should need to
     364                 :            :  * construct a new request object.
     365                 :            :  *
     366                 :            :  * Returns: (transfer full): a new [class@DataSourceRequest]
     367                 :            :  *
     368                 :            :  * Since: 1.1
     369                 :            :  */
     370                 :            : ShumateDataSourceRequest *
     371                 :          6 : shumate_data_source_request_new (int x,
     372                 :            :                                  int y,
     373                 :            :                                  int zoom_level)
     374                 :            : {
     375                 :          6 :   return g_object_new (SHUMATE_TYPE_DATA_SOURCE_REQUEST,
     376                 :            :                        "x", x,
     377                 :            :                        "y", y,
     378                 :            :                        "zoom-level", zoom_level,
     379                 :            :                        NULL);
     380                 :            : }
     381                 :            : 
     382                 :            : /**
     383                 :            :  * shumate_data_source_request_emit_data:
     384                 :            :  * @self: a [class@DataSourceRequest]
     385                 :            :  * @data: the data to emit
     386                 :            :  * @complete: %TRUE to also complete the request, %FALSE otherwise
     387                 :            :  *
     388                 :            :  * Emits tile data as a response to the request. This sets the
     389                 :            :  * [property@DataSourceRequest:data] property.
     390                 :            :  *
     391                 :            :  * If @complete is %TRUE, then [property@DataSourceRequest:completed] is set to
     392                 :            :  * %TRUE as well.
     393                 :            :  *
     394                 :            :  * Since: 1.1
     395                 :            :  */
     396                 :            : void
     397                 :         12 : shumate_data_source_request_emit_data (ShumateDataSourceRequest *self,
     398                 :            :                                        GBytes                   *data,
     399                 :            :                                        gboolean                  complete)
     400                 :            : {
     401                 :         12 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     402                 :         12 :   g_autofree char *profiling_desc = NULL;
     403                 :            : 
     404         [ +  - ]:         12 :   g_return_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self));
     405         [ -  + ]:         12 :   g_return_if_fail (data != NULL);
     406         [ -  + ]:         12 :   g_return_if_fail (!priv->completed);
     407                 :            : 
     408   [ +  +  +  - ]:         12 :   if (priv->bytes != NULL && g_bytes_equal (data, priv->bytes))
     409                 :            :     return;
     410                 :            : 
     411         [ +  + ]:         12 :   g_clear_pointer (&priv->bytes, g_bytes_unref);
     412                 :         12 :   priv->bytes = g_bytes_ref (data);
     413                 :            : 
     414         [ +  + ]:         12 :   if (complete)
     415                 :          3 :     priv->completed = TRUE;
     416                 :            : 
     417                 :         12 :   profiling_desc = g_strdup_printf ("(%d, %d) @ %d", priv->pos.x, priv->pos.y, priv->pos.zoom);
     418                 :         24 :   SHUMATE_PROFILE_START_NAMED (emit_data);
     419                 :         12 :   g_object_notify_by_pspec ((GObject *)self, properties[PROP_DATA]);
     420                 :         12 :   SHUMATE_PROFILE_END_NAMED (emit_data, profiling_desc);
     421                 :            : 
     422         [ +  + ]:         12 :   if (complete)
     423                 :          3 :     g_object_notify_by_pspec ((GObject *)self, properties[PROP_COMPLETED]);
     424                 :            : }
     425                 :            : 
     426                 :            : /**
     427                 :            :  * shumate_data_source_request_emit_error:
     428                 :            :  * @self: a [class@DataSourceRequest]
     429                 :            :  * @error: an error
     430                 :            :  *
     431                 :            :  * Emits a fatal error in response to the request. This completes the request,
     432                 :            :  * so no more data or errors can be emitted after this. Non-fatal errors should
     433                 :            :  * not be reported.
     434                 :            :  *
     435                 :            :  * If [property@DataSourceRequest:data] was previously set, it will be cleared.
     436                 :            :  *
     437                 :            :  * Since: 1.1
     438                 :            :  */
     439                 :            : void
     440                 :          3 : shumate_data_source_request_emit_error (ShumateDataSourceRequest *self,
     441                 :            :                                         const GError             *error)
     442                 :            : {
     443                 :          3 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     444                 :            : 
     445         [ +  - ]:          3 :   g_return_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self));
     446         [ -  + ]:          3 :   g_return_if_fail (error != NULL);
     447         [ -  + ]:          3 :   g_return_if_fail (!priv->completed);
     448                 :            : 
     449                 :          3 :   g_clear_error (&priv->error);
     450                 :          3 :   priv->error = g_error_copy (error);
     451                 :            : 
     452                 :          3 :   priv->completed = TRUE;
     453                 :            : 
     454         [ +  - ]:          3 :   if (priv->bytes)
     455                 :            :     {
     456                 :          3 :       g_clear_pointer (&priv->bytes, g_bytes_unref);
     457                 :          3 :       g_object_notify_by_pspec ((GObject *)self, properties[PROP_DATA]);
     458                 :            :     }
     459                 :            : 
     460                 :          3 :   g_object_notify_by_pspec ((GObject *)self, properties[PROP_ERROR]);
     461                 :          3 :   g_object_notify_by_pspec ((GObject *)self, properties[PROP_COMPLETED]);
     462                 :            : }
     463                 :            : 
     464                 :            : /**
     465                 :            :  * shumate_data_source_request_complete:
     466                 :            :  * @self: a [class@DataSourceRequest]
     467                 :            :  *
     468                 :            :  * Marks the request as complete. No more data or errors may be emitted.
     469                 :            :  *
     470                 :            :  * This can only be called if data has been emitted. If there is no data,
     471                 :            :  * use [method@DataSourceRequest.emit_error] instead, which will automatically
     472                 :            :  * complete the request.
     473                 :            :  *
     474                 :            :  * Since: 1.1
     475                 :            :  */
     476                 :            : void
     477                 :          0 : shumate_data_source_request_complete (ShumateDataSourceRequest *self)
     478                 :            : {
     479                 :          0 :   ShumateDataSourceRequestPrivate *priv = shumate_data_source_request_get_instance_private (self);
     480                 :            : 
     481         [ #  # ]:          0 :   g_return_if_fail (SHUMATE_IS_DATA_SOURCE_REQUEST (self));
     482         [ #  # ]:          0 :   g_return_if_fail (!priv->completed);
     483   [ #  #  #  # ]:          0 :   g_return_if_fail (priv->bytes != NULL || priv->error != NULL);
     484                 :            : 
     485                 :          0 :   priv->completed = TRUE;
     486                 :          0 :   g_object_notify_by_pspec ((GObject *)self, properties[PROP_COMPLETED]);
     487                 :            : }

Generated by: LCOV version 1.14