(root)/
glib-2.79.0/
gio/
gconverter.c
       1  /* GIO - GLib Input, Output and Streaming Library
       2   *
       3   * Copyright (C) 2009 Red Hat, Inc.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   *
      20   * Author: Alexander Larsson <alexl@redhat.com>
      21   */
      22  
      23  #include "config.h"
      24  #include "gconverter.h"
      25  #include "glibintl.h"
      26  
      27  
      28  /**
      29   * GConverter:
      30   *
      31   * `GConverter` is an interface for streaming conversions.
      32   *
      33   * `GConverter` is implemented by objects that convert
      34   * binary data in various ways. The conversion can be
      35   * stateful and may fail at any place.
      36   *
      37   * Some example conversions are: character set conversion,
      38   * compression, decompression and regular expression
      39   * replace.
      40   *
      41   * Since: 2.24
      42   */
      43  
      44  
      45  typedef GConverterIface GConverterInterface;
      46  G_DEFINE_INTERFACE (GConverter, g_converter, G_TYPE_OBJECT)
      47  
      48  static void
      49  g_converter_default_init (GConverterInterface *iface)
      50  {
      51  }
      52  
      53  /**
      54   * g_converter_convert:
      55   * @converter: a #GConverter.
      56   * @inbuf: (array length=inbuf_size) (element-type guint8): the buffer
      57   *         containing the data to convert.
      58   * @inbuf_size: the number of bytes in @inbuf
      59   * @outbuf: (element-type guint8) (array length=outbuf_size) (not nullable): a
      60   *    buffer to write converted data in.
      61   * @outbuf_size: the number of bytes in @outbuf, must be at least one
      62   * @flags: a #GConverterFlags controlling the conversion details
      63   * @bytes_read: (out) (not nullable): will be set to the number of bytes read
      64   *    from @inbuf on success
      65   * @bytes_written: (out) (not nullable): will be set to the number of bytes
      66   *    written to @outbuf on success
      67   * @error: location to store the error occurring, or %NULL to ignore
      68   *
      69   * This is the main operation used when converting data. It is to be called
      70   * multiple times in a loop, and each time it will do some work, i.e.
      71   * producing some output (in @outbuf) or consuming some input (from @inbuf) or
      72   * both. If its not possible to do any work an error is returned.
      73   *
      74   * Note that a single call may not consume all input (or any input at all).
      75   * Also a call may produce output even if given no input, due to state stored
      76   * in the converter producing output.
      77   *
      78   * If any data was either produced or consumed, and then an error happens, then
      79   * only the successful conversion is reported and the error is returned on the
      80   * next call.
      81   *
      82   * A full conversion loop involves calling this method repeatedly, each time
      83   * giving it new input and space output space. When there is no more input
      84   * data after the data in @inbuf, the flag %G_CONVERTER_INPUT_AT_END must be set.
      85   * The loop will be (unless some error happens) returning %G_CONVERTER_CONVERTED
      86   * each time until all data is consumed and all output is produced, then
      87   * %G_CONVERTER_FINISHED is returned instead. Note, that %G_CONVERTER_FINISHED
      88   * may be returned even if %G_CONVERTER_INPUT_AT_END is not set, for instance
      89   * in a decompression converter where the end of data is detectable from the
      90   * data (and there might even be other data after the end of the compressed data).
      91   *
      92   * When some data has successfully been converted @bytes_read and is set to
      93   * the number of bytes read from @inbuf, and @bytes_written is set to indicate
      94   * how many bytes was written to @outbuf. If there are more data to output
      95   * or consume (i.e. unless the %G_CONVERTER_INPUT_AT_END is specified) then
      96   * %G_CONVERTER_CONVERTED is returned, and if no more data is to be output
      97   * then %G_CONVERTER_FINISHED is returned.
      98   *
      99   * On error %G_CONVERTER_ERROR is returned and @error is set accordingly.
     100   * Some errors need special handling:
     101   *
     102   * %G_IO_ERROR_NO_SPACE is returned if there is not enough space
     103   * to write the resulting converted data, the application should
     104   * call the function again with a larger @outbuf to continue.
     105   *
     106   * %G_IO_ERROR_PARTIAL_INPUT is returned if there is not enough
     107   * input to fully determine what the conversion should produce,
     108   * and the %G_CONVERTER_INPUT_AT_END flag is not set. This happens for
     109   * example with an incomplete multibyte sequence when converting text,
     110   * or when a regexp matches up to the end of the input (and may match
     111   * further input). It may also happen when @inbuf_size is zero and
     112   * there is no more data to produce.
     113   *
     114   * When this happens the application should read more input and then
     115   * call the function again. If further input shows that there is no
     116   * more data call the function again with the same data but with
     117   * the %G_CONVERTER_INPUT_AT_END flag set. This may cause the conversion
     118   * to finish as e.g. in the regexp match case (or, to fail again with
     119   * %G_IO_ERROR_PARTIAL_INPUT in e.g. a charset conversion where the
     120   * input is actually partial).
     121   *
     122   * After g_converter_convert() has returned %G_CONVERTER_FINISHED the
     123   * converter object is in an invalid state where its not allowed
     124   * to call g_converter_convert() anymore. At this time you can only
     125   * free the object or call g_converter_reset() to reset it to the
     126   * initial state.
     127   *
     128   * If the flag %G_CONVERTER_FLUSH is set then conversion is modified
     129   * to try to write out all internal state to the output. The application
     130   * has to call the function multiple times with the flag set, and when
     131   * the available input has been consumed and all internal state has
     132   * been produced then %G_CONVERTER_FLUSHED (or %G_CONVERTER_FINISHED if
     133   * really at the end) is returned instead of %G_CONVERTER_CONVERTED.
     134   * This is somewhat similar to what happens at the end of the input stream,
     135   * but done in the middle of the data.
     136   *
     137   * This has different meanings for different conversions. For instance
     138   * in a compression converter it would mean that we flush all the
     139   * compression state into output such that if you uncompress the
     140   * compressed data you get back all the input data. Doing this may
     141   * make the final file larger due to padding though. Another example
     142   * is a regexp conversion, where if you at the end of the flushed data
     143   * have a match, but there is also a potential longer match. In the
     144   * non-flushed case we would ask for more input, but when flushing we
     145   * treat this as the end of input and do the match.
     146   *
     147   * Flushing is not always possible (like if a charset converter flushes
     148   * at a partial multibyte sequence). Converters are supposed to try
     149   * to produce as much output as possible and then return an error
     150   * (typically %G_IO_ERROR_PARTIAL_INPUT).
     151   *
     152   * Returns: a #GConverterResult, %G_CONVERTER_ERROR on error.
     153   *
     154   * Since: 2.24
     155   **/
     156  GConverterResult
     157  g_converter_convert (GConverter *converter,
     158  		     const void *inbuf,
     159  		     gsize       inbuf_size,
     160  		     void       *outbuf,
     161  		     gsize       outbuf_size,
     162  		     GConverterFlags flags,
     163  		     gsize      *bytes_read,
     164  		     gsize      *bytes_written,
     165  		     GError    **error)
     166  {
     167    GConverterIface *iface;
     168  
     169    g_return_val_if_fail (G_IS_CONVERTER (converter), G_CONVERTER_ERROR);
     170    g_return_val_if_fail (inbuf != NULL || inbuf_size == 0, G_CONVERTER_ERROR);
     171    g_return_val_if_fail (outbuf != NULL, G_CONVERTER_ERROR);
     172    g_return_val_if_fail (outbuf_size > 0, G_CONVERTER_ERROR);
     173    g_return_val_if_fail (bytes_read != NULL, G_CONVERTER_ERROR);
     174    g_return_val_if_fail (bytes_written != NULL, G_CONVERTER_ERROR);
     175    g_return_val_if_fail (error == NULL || *error == NULL, G_CONVERTER_ERROR);
     176  
     177    *bytes_read = 0;
     178    *bytes_written = 0;
     179  
     180    iface = G_CONVERTER_GET_IFACE (converter);
     181  
     182    return (* iface->convert) (converter,
     183  			     inbuf, inbuf_size,
     184  			     outbuf, outbuf_size,
     185  			     flags,
     186  			     bytes_read, bytes_written, error);
     187  }
     188  
     189  /**
     190   * g_converter_reset:
     191   * @converter: a #GConverter.
     192   *
     193   * Resets all internal state in the converter, making it behave
     194   * as if it was just created. If the converter has any internal
     195   * state that would produce output then that output is lost.
     196   *
     197   * Since: 2.24
     198   **/
     199  void
     200  g_converter_reset (GConverter *converter)
     201  {
     202    GConverterIface *iface;
     203  
     204    g_return_if_fail (G_IS_CONVERTER (converter));
     205  
     206    iface = G_CONVERTER_GET_IFACE (converter);
     207  
     208    (* iface->reset) (converter);
     209  }