Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of LibParserUtils.
  3.  * Licensed under the MIT License,
  4.  *                http://www.opensource.org/licenses/mit-license.php
  5.  * Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
  6.  */
  7.  
  8. #include <string.h>
  9.  
  10. #include "charset/aliases.h"
  11. #include "charset/codecs/codec_impl.h"
  12.  
  13. extern parserutils_charset_handler charset_ascii_codec_handler;
  14. extern parserutils_charset_handler charset_8859_codec_handler;
  15. extern parserutils_charset_handler charset_ext8_codec_handler;
  16. extern parserutils_charset_handler charset_utf8_codec_handler;
  17. extern parserutils_charset_handler charset_utf16_codec_handler;
  18.  
  19. static parserutils_charset_handler *handler_table[] = {
  20.         &charset_utf8_codec_handler,
  21.         &charset_utf16_codec_handler,
  22.         &charset_8859_codec_handler,
  23.         &charset_ext8_codec_handler,
  24.         &charset_ascii_codec_handler,
  25.         NULL,
  26. };
  27.  
  28. /**
  29.  * Create a charset codec
  30.  *
  31.  * \param charset  Target charset
  32.  * \param alloc    Memory (de)allocation function
  33.  * \param pw       Pointer to client-specific private data (may be NULL)
  34.  * \param codec    Pointer to location to receive codec instance
  35.  * \return PARSERUTILS_OK on success,
  36.  *         PARSERUTILS_BADPARM on bad parameters,
  37.  *         PARSERUTILS_NOMEM on memory exhaustion,
  38.  *         PARSERUTILS_BADENCODING on unsupported charset
  39.  */
  40. parserutils_error parserutils_charset_codec_create(const char *charset,
  41.                 parserutils_alloc alloc, void *pw,
  42.                 parserutils_charset_codec **codec)
  43. {
  44.         parserutils_charset_codec *c;
  45.         parserutils_charset_handler **handler;
  46.         const parserutils_charset_aliases_canon * canon;
  47.         parserutils_error error;
  48.  
  49.         if (charset == NULL || alloc == NULL || codec == NULL)
  50.                 return PARSERUTILS_BADPARM;
  51.  
  52.         /* Canonicalise parserutils_charset name. */
  53.         canon = parserutils__charset_alias_canonicalise(charset,
  54.                         strlen(charset));
  55.         if (canon == NULL)
  56.                 return PARSERUTILS_BADENCODING;
  57.  
  58.         /* Search for handler class */
  59.         for (handler = handler_table; *handler != NULL; handler++) {
  60.                 if ((*handler)->handles_charset(canon->name))
  61.                         break;
  62.         }
  63.  
  64.         /* None found */
  65.         if ((*handler) == NULL)
  66.                 return PARSERUTILS_BADENCODING;
  67.  
  68.         /* Instantiate class */
  69.         error = (*handler)->create(canon->name, alloc, pw, &c);
  70.         if (error != PARSERUTILS_OK)
  71.                 return error;
  72.  
  73.         /* and initialise it */
  74.         c->mibenum = canon->mib_enum;
  75.  
  76.         c->errormode = PARSERUTILS_CHARSET_CODEC_ERROR_LOOSE;
  77.  
  78.         c->alloc = alloc;
  79.         c->alloc_pw = pw;
  80.  
  81.         *codec = c;
  82.  
  83.         return PARSERUTILS_OK;
  84. }
  85.  
  86. /**
  87.  * Destroy a charset codec
  88.  *
  89.  * \param codec  The codec to destroy
  90.  * \return PARSERUTILS_OK on success, appropriate error otherwise
  91.  */
  92. parserutils_error parserutils_charset_codec_destroy(
  93.                 parserutils_charset_codec *codec)
  94. {
  95.         if (codec == NULL)
  96.                 return PARSERUTILS_BADPARM;
  97.  
  98.         codec->handler.destroy(codec);
  99.  
  100.         codec->alloc(codec, 0, codec->alloc_pw);
  101.  
  102.         return PARSERUTILS_OK;
  103. }
  104.  
  105. /**
  106.  * Configure a charset codec
  107.  *
  108.  * \param codec   The codec to configure
  109.  * \param type    The codec option type to configure
  110.  * \param params  Option-specific parameters
  111.  * \return PARSERUTILS_OK on success, appropriate error otherwise
  112.  */
  113. parserutils_error parserutils_charset_codec_setopt(
  114.                 parserutils_charset_codec *codec,
  115.                 parserutils_charset_codec_opttype type,
  116.                 parserutils_charset_codec_optparams *params)
  117. {
  118.         if (codec == NULL || params == NULL)
  119.                 return PARSERUTILS_BADPARM;
  120.  
  121.         switch (type) {
  122.         case PARSERUTILS_CHARSET_CODEC_ERROR_MODE:
  123.                 codec->errormode = params->error_mode.mode;
  124.                 break;
  125.         }
  126.  
  127.         return PARSERUTILS_OK;
  128. }
  129.  
  130. /**
  131.  * Encode a chunk of UCS-4 data into a codec's charset
  132.  *
  133.  * \param codec      The codec to use
  134.  * \param source     Pointer to pointer to source data
  135.  * \param sourcelen  Pointer to length (in bytes) of source data
  136.  * \param dest       Pointer to pointer to output buffer
  137.  * \param destlen    Pointer to length (in bytes) of output buffer
  138.  * \return PARSERUTILS_OK on success, appropriate error otherwise.
  139.  *
  140.  * source, sourcelen, dest and destlen will be updated appropriately on exit
  141.  */
  142. parserutils_error parserutils_charset_codec_encode(
  143.                 parserutils_charset_codec *codec,
  144.                 const uint8_t **source, size_t *sourcelen,
  145.                 uint8_t **dest, size_t *destlen)
  146. {
  147.         if (codec == NULL || source == NULL || *source == NULL ||
  148.                         sourcelen == NULL || dest == NULL || *dest == NULL ||
  149.                         destlen == NULL)
  150.                 return PARSERUTILS_BADPARM;
  151.  
  152.         return codec->handler.encode(codec, source, sourcelen, dest, destlen);
  153. }
  154.  
  155. /**
  156.  * Decode a chunk of data in a codec's charset into UCS-4
  157.  *
  158.  * \param codec      The codec to use
  159.  * \param source     Pointer to pointer to source data
  160.  * \param sourcelen  Pointer to length (in bytes) of source data
  161.  * \param dest       Pointer to pointer to output buffer
  162.  * \param destlen    Pointer to length (in bytes) of output buffer
  163.  * \return PARSERUTILS_OK on success, appropriate error otherwise.
  164.  *
  165.  * source, sourcelen, dest and destlen will be updated appropriately on exit
  166.  *
  167.  * Call this with a source length of 0 to flush any buffers.
  168.  */
  169. parserutils_error parserutils_charset_codec_decode(
  170.                 parserutils_charset_codec *codec,
  171.                 const uint8_t **source, size_t *sourcelen,
  172.                 uint8_t **dest, size_t *destlen)
  173. {
  174.         if (codec == NULL || source == NULL || *source == NULL ||
  175.                         sourcelen == NULL || dest == NULL || *dest == NULL ||
  176.                         destlen == NULL)
  177.                 return PARSERUTILS_BADPARM;
  178.  
  179.         return codec->handler.decode(codec, source, sourcelen, dest, destlen);
  180. }
  181.  
  182. /**
  183.  * Clear a charset codec's encoding state
  184.  *
  185.  * \param codec  The codec to reset
  186.  * \return PARSERUTILS_OK on success, appropriate error otherwise
  187.  */
  188. parserutils_error parserutils_charset_codec_reset(
  189.                 parserutils_charset_codec *codec)
  190. {
  191.         if (codec == NULL)
  192.                 return PARSERUTILS_BADPARM;
  193.  
  194.         return codec->handler.reset(codec);
  195. }
  196.  
  197.