gfx/graphite2/src/inc/Rule.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*  GRAPHITE2 LICENSING
     3     Copyright 2011, SIL International
     4     All rights reserved.
     6     This library is free software; you can redistribute it and/or modify
     7     it under the terms of the GNU Lesser General Public License as published
     8     by the Free Software Foundation; either version 2.1 of License, or
     9     (at your option) any later version.
    11     This program is distributed in the hope that it will be useful,
    12     but WITHOUT ANY WARRANTY; without even the implied warranty of
    13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14     Lesser General Public License for more details.
    16     You should also have received a copy of the GNU Lesser General Public
    17     License along with this library in the file named "LICENSE".
    18     If not, write to the Free Software Foundation, 51 Franklin Street, 
    19     Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
    20     internet at http://www.fsf.org/licenses/lgpl.html.
    22 Alternatively, the contents of this file may be used under the terms of the
    23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
    24 License, as published by the Free Software Foundation, either version 2
    25 of the License or (at your option) any later version.
    26 */
    28 #pragma once
    30 #include "inc/Code.h"
    31 #include "inc/Slot.h"
    33 namespace graphite2 {
    35 struct Rule {
    36   const vm::Machine::Code * constraint, 
    37                  * action;
    38   unsigned short   sort;
    39   byte             preContext;
    40 #ifndef NDEBUG
    41   uint16           rule_idx;
    42 #endif
    44   Rule() : constraint(0), action(0), sort(0), preContext(0) {}
    45   ~Rule();
    47   CLASS_NEW_DELETE;
    49 private:
    50   Rule(const Rule &);
    51   Rule & operator = (const Rule &);
    52 };
    54 inline Rule::~Rule()
    55 {
    56   delete constraint;
    57   delete action;
    58 }
    61 struct RuleEntry
    62 {
    63   const Rule   * rule;
    65   inline
    66   bool operator < (const RuleEntry &r) const
    67   {
    68     const unsigned short lsort = rule->sort, rsort = r.rule->sort;
    69     return lsort > rsort || (lsort == rsort && rule < r.rule);
    70   }
    72   inline
    73   bool operator == (const RuleEntry &r) const
    74   {
    75     return rule == r.rule;
    76   }
    77 };
    80 struct State
    81 {
    82   const RuleEntry     * rules,
    83                       * rules_end;
    85   bool   empty() const;
    86 };
    88 inline
    89 bool State::empty() const
    90 {
    91     return rules_end == rules;
    92 }
    95 class SlotMap
    96 {
    97 public:
    98   enum {MAX_SLOTS=64};
    99   SlotMap(Segment & seg);
   101   Slot       * * begin();
   102   Slot       * * end();
   103   size_t         size() const;
   104   unsigned short context() const;
   105   void           reset(Slot &, unsigned short);
   107   Slot * const & operator[](int n) const;
   108   Slot       * & operator [] (int);
   109   void           pushSlot(Slot * const slot);
   110   void           collectGarbage();
   112   Slot         * highwater() { return m_highwater; }
   113   void           highwater(Slot *s) { m_highwater = s; m_highpassed = false; }
   114   bool           highpassed() const { return m_highpassed; }
   115   void           highpassed(bool v) { m_highpassed = v; }
   117   Segment &    segment;
   118 private:
   119   Slot         * m_slot_map[MAX_SLOTS+1];
   120   unsigned short m_size;
   121   unsigned short m_precontext;
   122   Slot         * m_highwater;
   123   bool           m_highpassed;
   124 };
   127 class FiniteStateMachine
   128 {
   129 public:
   130   enum {MAX_RULES=128};
   132 private:
   133   class Rules
   134   {
   135   public:
   136       Rules();
   137       void              clear();
   138       const RuleEntry * begin() const;
   139       const RuleEntry * end() const;
   140       size_t            size() const;
   142       void accumulate_rules(const State &state);
   144   private:
   145       RuleEntry * m_begin, 
   146                 * m_end,
   147                   m_rules[MAX_RULES*2];
   148   };
   150 public:
   151   FiniteStateMachine(SlotMap & map, json * logger);
   152   void      reset(Slot * & slot, const short unsigned int max_pre_ctxt);
   154   Rules     rules;
   155   SlotMap   & slots;
   156   json    * const dbgout;
   157 };
   160 inline
   161 FiniteStateMachine::FiniteStateMachine(SlotMap& map, json * logger)
   162 : slots(map),
   163   dbgout(logger)
   164 {
   165 }
   167 inline
   168 void FiniteStateMachine::reset(Slot * & slot, const short unsigned int max_pre_ctxt)
   169 {
   170   rules.clear();
   171   int ctxt = 0;
   172   for (; ctxt != max_pre_ctxt && slot->prev(); ++ctxt, slot = slot->prev());
   173   slots.reset(*slot, ctxt);
   174 }
   176 inline
   177 FiniteStateMachine::Rules::Rules()
   178   : m_begin(m_rules), m_end(m_rules)
   179 {
   180 }
   182 inline
   183 void FiniteStateMachine::Rules::clear()
   184 {
   185   m_end = m_begin;
   186 }
   188 inline
   189 const RuleEntry * FiniteStateMachine::Rules::begin() const
   190 {
   191   return m_begin;
   192 }
   194 inline
   195 const RuleEntry * FiniteStateMachine::Rules::end() const
   196 {
   197   return m_end;
   198 }
   200 inline
   201 size_t FiniteStateMachine::Rules::size() const
   202 {
   203   return m_end - m_begin;
   204 }
   206 inline
   207 void FiniteStateMachine::Rules::accumulate_rules(const State &state)
   208 {
   209   // Only bother if there are rules in the State object.
   210   if (state.empty()) return;
   212   // Merge the new sorted rules list into the current sorted result set.
   213   const RuleEntry * lre = begin(), * rre = state.rules;
   214   RuleEntry * out = m_rules + (m_begin == m_rules)*MAX_RULES;    
   215   const RuleEntry * const lrend = out + MAX_RULES,
   216                   * const rrend = state.rules_end;
   217   m_begin = out; 
   218   while (lre != end() && out != lrend)
   219   {
   220     if (*lre < *rre)      *out++ = *lre++;
   221     else if (*rre < *lre) { *out++ = *rre++; }
   222     else                { *out++ = *lre++; ++rre; }
   224     if (rre == rrend)
   225     { 
   226       while (lre != end() && out != lrend) { *out++ = *lre++; }
   227       m_end = out;
   228       return;
   229     }
   230   }
   231   while (rre != rrend && out != lrend) { *out++ = *rre++; }
   232   m_end = out;
   233 }
   235 inline
   236 SlotMap::SlotMap(Segment & seg)
   237 : segment(seg), m_size(0), m_precontext(0), m_highwater(0), m_highpassed(false)
   238 {
   239     m_slot_map[0] = 0;
   240 }
   242 inline
   243 Slot * * SlotMap::begin()
   244 {
   245   return &m_slot_map[1]; // allow map to go 1 before slot_map when inserting
   246                          // at start of segment.
   247 }
   249 inline
   250 Slot * * SlotMap::end()
   251 {
   252   return m_slot_map + m_size + 1;
   253 }
   255 inline
   256 size_t SlotMap::size() const
   257 {
   258   return m_size;
   259 }
   261 inline
   262 short unsigned int SlotMap::context() const
   263 {
   264   return m_precontext;
   265 }
   267 inline
   268 void SlotMap::reset(Slot & slot, short unsigned int ctxt)
   269 {
   270   m_size = 0;
   271   m_precontext = ctxt;
   272   *m_slot_map = slot.prev();
   273 }
   275 inline
   276 void SlotMap::pushSlot(Slot*const slot)
   277 {
   278   m_slot_map[++m_size] = slot;
   279 }
   281 inline
   282 Slot * const & SlotMap::operator[](int n) const
   283 {
   284   return m_slot_map[n + 1];
   285 }
   287 inline
   288 Slot * & SlotMap::operator[](int n)
   289 {
   290   return m_slot_map[n + 1];
   291 }
   293 } // namespace graphite2

mercurial