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 Hubbub.
  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 "utils/utils.h"
  9. #include "tokeniser/entities.h"
  10.  
  11. /** Node in our entity tree */
  12. typedef struct hubbub_entity_node {
  13.         /* Do not reorder this without fixing make-entities.pl */
  14.         uint8_t split;  /**< Data to split on */
  15.         int32_t lt;     /**< Subtree for data less than split */
  16.         int32_t eq;     /**< Subtree for data equal to split */
  17.         int32_t gt;     /**< Subtree for data greater than split */
  18.         uint32_t value; /**< Data for this node */
  19. } hubbub_entity_node;
  20.  
  21. #include "entities.inc"
  22.  
  23. /**
  24.  * Step-wise search for a key in our entity tree
  25.  *
  26.  * \param c        Character to look for
  27.  * \param result   Pointer to location for result
  28.  * \param context  Pointer to location for search context
  29.  * \return HUBBUB_OK if key found,
  30.  *         HUBBUB_NEEDDATA if more steps are required
  31.  *         HUBBUB_INVALID if nothing matches
  32.  *
  33.  * The value pointed to by ::context must be NULL for the first call.
  34.  * Thereafter, pass in the same value as returned by the previous call.
  35.  * The context is opaque to the caller and should not be inspected.
  36.  *
  37.  * The location pointed to by ::result will be set to NULL unless a match
  38.  * is found.
  39.  */
  40. static hubbub_error hubbub_entity_tree_search_step(uint8_t c,
  41.                 uint32_t *result, int32_t *context)
  42. {
  43.         bool match = false;
  44.         int32_t p;
  45.  
  46.         if (result == NULL || context == NULL)
  47.                 return HUBBUB_BADPARM;
  48.  
  49.         if (*context == -1) {
  50.                 p = dict_root;
  51.         } else {
  52.                 p = *context;
  53.         }
  54.  
  55.         while (p != -1) {
  56.                 if (c < dict[p].split) {
  57.                         p = dict[p].lt;
  58.                 } else if (c == dict[p].split) {
  59.                         if (dict[p].split == '\0') {
  60.                                 match = true;
  61.                                 p = -1;
  62.                         } else if (dict[p].eq != -1 && dict[dict[p].eq].split == '\0') {
  63.                                 match = true;
  64.                                 *result = dict[dict[p].eq].value;
  65.                                 p = dict[p].eq;
  66.                         } else if (dict[p].value != 0) {
  67.                                 match = true;
  68.                                 *result = dict[p].value;
  69.                                 p = dict[p].eq;
  70.                         } else {
  71.                                 p = dict[p].eq;
  72.                         }
  73.  
  74.                         break;
  75.                 } else {
  76.                         p = dict[p].gt;
  77.                 }
  78.         }
  79.  
  80.         *context = p;
  81.  
  82.         return (match) ? HUBBUB_OK :
  83.                         (p == -1) ? HUBBUB_INVALID : HUBBUB_NEEDDATA;
  84. }
  85.  
  86. /**
  87.  * Step-wise search for an entity in the dictionary
  88.  *
  89.  * \param c        Character to look for
  90.  * \param result   Pointer to location for result
  91.  * \param context  Pointer to location for search context
  92.  * \return HUBBUB_OK if key found,
  93.  *         HUBBUB_NEEDDATA if more steps are required
  94.  *         HUBBUB_INVALID if nothing matches
  95.  *
  96.  * The value pointed to by ::context should be -1 for the first call.
  97.  * Thereafter, pass in the same value as returned by the previous call.
  98.  * The context is opaque to the caller and should not be inspected.
  99.  *
  100.  * The location pointed to by ::result will be set to U+FFFD unless a match
  101.  * is found.
  102.  */
  103. hubbub_error hubbub_entities_search_step(uint8_t c, uint32_t *result,
  104.                 int32_t *context)
  105. {
  106.         if (result == NULL)
  107.                 return HUBBUB_BADPARM;
  108.  
  109.         *result = 0xFFFD;
  110.        
  111.         return hubbub_entity_tree_search_step(c, result, context);
  112. }
  113.