/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Hunspell, based on MySpell.
 *
 * The Initial Developers of the Original Code are
 * Kevin Hendricks (MySpell) and Németh László (Hunspell).
 * Portions created by the Initial Developers are Copyright (C) 2002-2005
 * the Initial Developers. All Rights Reserved.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
/*
 * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
 * And Contributors.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. All modifications to the source code must be clearly marked as
 *    such.  Binary redistributions based on modified source code
 *    must be clearly marked as modified versions in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <limits>
#include <sstream>

#include "hashmgr.hxx"
#include "csutil.hxx"
#include "atypes.hxx"

// build a hash table from a munched word list

#ifdef HUNSPELL_CHROME_CLIENT
HashMgr::HashMgr(hunspell::BDictReader* reader)
    : bdict_reader(reader),
#else
HashMgr::HashMgr(const char* tpath, const char* apath, const char* key)
    :
#endif
      tablesize(0),
      tableptr(NULL),
      flag_mode(FLAG_CHAR),
      complexprefixes(0),
      utf8(0),
      forbiddenword(FORBIDDENWORD)  // forbidden word signing flag
      ,
      numaliasf(0),
      aliasf(NULL),
      aliasflen(0),
      numaliasm(0),
      aliasm(NULL) {
  langnum = 0;
  csconv = 0;
#ifdef HUNSPELL_CHROME_CLIENT
  // No tables to load, just the AF lines.
  load_config(NULL, NULL);
  int ec = LoadAFLines();
#else
  load_config(apath, key);
  int ec = load_tables(tpath, key);
#endif
  if (ec) {
    /* error condition - what should we do here */
    HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n", ec);
    free(tableptr);
    //keep tablesize to 1 to fix possible division with zero
    tablesize = 1;
    tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*));
    if (!tableptr) {
      tablesize = 0;
    }
  }
}

HashMgr::~HashMgr() {
  if (tableptr) {
    // now pass through hash table freeing up everything
    // go through column by column of the table
    for (int i = 0; i < tablesize; i++) {
      struct hentry* pt = tableptr[i];
      struct hentry* nt = NULL;
      while (pt) {
        nt = pt->next;
        if (pt->astr &&
            (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen)))
          free(pt->astr);
        free(pt);
        pt = nt;
      }
    }
    free(tableptr);
  }
  tablesize = 0;

  if (aliasf) {
    for (int j = 0; j < (numaliasf); j++)
      free(aliasf[j]);
    free(aliasf);
    aliasf = NULL;
    if (aliasflen) {
      free(aliasflen);
      aliasflen = NULL;
    }
  }
  if (aliasm) {
    for (int j = 0; j < (numaliasm); j++)
      free(aliasm[j]);
    free(aliasm);
    aliasm = NULL;
  }

#ifndef OPENOFFICEORG
#ifndef MOZILLA_CLIENT
  if (utf8)
    free_utf_tbl();
#endif
#endif

#ifdef HUNSPELL_CHROME_CLIENT
  EmptyHentryCache();
  for (std::vector<std::string*>::iterator it = pointer_to_strings_.begin();
       it != pointer_to_strings_.end(); ++it) {
    delete *it;
  }
#endif
#ifdef MOZILLA_CLIENT
  delete[] csconv;
#endif
}

#ifdef HUNSPELL_CHROME_CLIENT
void HashMgr::EmptyHentryCache() {
  // We need to delete each cache entry, and each additional one in the linked
  // list of homonyms.
  for (HEntryCache::iterator i = hentry_cache.begin();
       i != hentry_cache.end(); ++i) {
    hentry* cur = i->second;
    while (cur) {
      hentry* next = cur->next_homonym;
      DeleteHashEntry(cur);
      cur = next;
    }
  }
  hentry_cache.clear();
}
#endif

// lookup a root word in the hashtable

struct hentry* HashMgr::lookup(const char* word) const {
#ifdef HUNSPELL_CHROME_CLIENT
  int affix_ids[hunspell::BDict::MAX_AFFIXES_PER_WORD];
  int affix_count = bdict_reader->FindWord(word, affix_ids);
  if (affix_count == 0) { // look for custom added word
    std::map<base::StringPiece, int>::const_iterator iter = 
      custom_word_to_affix_id_map_.find(word);
    if (iter != custom_word_to_affix_id_map_.end()) {
      affix_count = 1;
      affix_ids[0] = iter->second;
    }
  }

  static const int kMaxWordLen = 128;
  static char word_buf[kMaxWordLen];
  // To take account of null-termination, we use upto 127.
  strncpy(word_buf, word, kMaxWordLen - 1);

  return AffixIDsToHentry(word_buf, affix_ids, affix_count);
#else
  struct hentry* dp;
  if (tableptr) {
    dp = tableptr[hash(word)];
    if (!dp)
      return NULL;
    for (; dp != NULL; dp = dp->next) {
      if (strcmp(word, dp->word) == 0)
        return dp;
    }
  }
  return NULL;
#endif
}

// add a word to the hash table (private)
int HashMgr::add_word(const std::string& in_word,
                      int wcl,
                      unsigned short* aff,
                      int al,
                      const std::string* in_desc,
                      bool onlyupcase) {
// TODO: The following 40 lines or so are actually new. Should they be included?
#ifndef HUNSPELL_CHROME_CLIENT
  const std::string* word = &in_word;
  const std::string* desc = in_desc;

  std::string *word_copy = NULL;
  std::string *desc_copy = NULL;
  if (!ignorechars.empty() || complexprefixes) {
    word_copy = new std::string(in_word);

    if (!ignorechars.empty()) {
      if (utf8) {
        wcl = remove_ignored_chars_utf(*word_copy, ignorechars_utf16);
      } else {
        remove_ignored_chars(*word_copy, ignorechars);
      }
    }

    if (complexprefixes) {
      if (utf8)
        wcl = reverseword_utf(*word_copy);
      else
        reverseword(*word_copy);

      if (in_desc && !aliasm) {
        desc_copy = new std::string(*in_desc);

        if (complexprefixes) {
          if (utf8)
            reverseword_utf(*desc_copy);
          else
            reverseword(*desc_copy);
        }
        desc = desc_copy;
      }
    }

    word = word_copy;
  }

  bool upcasehomonym = false;
  int descl = desc ? (aliasm ? sizeof(char*) : desc->size() + 1) : 0;
  // variable-length hash record with word and optional fields
  struct hentry* hp =
      (struct hentry*)malloc(sizeof(struct hentry) + word->size() + descl);
  if (!hp) {
    delete desc_copy;
    delete word_copy;
    return 1;
  }

  char* hpw = hp->word;
  strcpy(hpw, word->c_str());

  int i = hash(hpw);

  hp->blen = (unsigned char)word->size();
  hp->clen = (unsigned char)wcl;
  hp->alen = (short)al;
  hp->astr = aff;
  hp->next = NULL;
  hp->next_homonym = NULL;

  // store the description string or its pointer
  if (desc) {
    hp->var = H_OPT;
    if (aliasm) {
      hp->var += H_OPT_ALIASM;
      store_pointer(hpw + word->size() + 1, get_aliasm(atoi(desc->c_str())));
    } else {
      strcpy(hpw + word->size() + 1, desc->c_str());
    }
    if (strstr(HENTRY_DATA(hp), MORPH_PHON))
      hp->var += H_OPT_PHON;
  } else
    hp->var = 0;

  struct hentry* dp = tableptr[i];
  if (!dp) {
    tableptr[i] = hp;
    delete desc_copy;
    delete word_copy;
    return 0;
  }
  while (dp->next != NULL) {
    if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) {
      // remove hidden onlyupcase homonym
      if (!onlyupcase) {
        if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
          free(dp->astr);
          dp->astr = hp->astr;
          dp->alen = hp->alen;
          free(hp);
          delete desc_copy;
          delete word_copy;
          return 0;
        } else {
          dp->next_homonym = hp;
        }
      } else {
        upcasehomonym = true;
      }
    }
    dp = dp->next;
  }
  if (strcmp(hp->word, dp->word) == 0) {
    // remove hidden onlyupcase homonym
    if (!onlyupcase) {
      if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
        free(dp->astr);
        dp->astr = hp->astr;
        dp->alen = hp->alen;
        free(hp);
        delete desc_copy;
        delete word_copy;
        return 0;
      } else {
        dp->next_homonym = hp;
      }
    } else {
      upcasehomonym = true;
    }
  }
  if (!upcasehomonym) {
    dp->next = hp;
  } else {
    // remove hidden onlyupcase homonym
    if (hp->astr)
      free(hp->astr);
    free(hp);
  }

  delete desc_copy;
  delete word_copy;
#else
  std::map<base::StringPiece, int>::iterator iter =
      custom_word_to_affix_id_map_.find(in_word);
  if (iter == custom_word_to_affix_id_map_.end()) {  // word needs to be added
    std::string* new_string_word = new std::string(in_word);
    pointer_to_strings_.push_back(new_string_word);
    base::StringPiece sp(*(new_string_word));
    custom_word_to_affix_id_map_[sp] = 0; // no affixes for custom words
    return 1;
  }
#endif
  return 0;
}

int HashMgr::add_hidden_capitalized_word(const std::string& word,
                                         int wcl,
                                         unsigned short* flags,
                                         int flagslen,
                                         const std::string* dp,
                                         int captype) {
  if (flags == NULL)
    flagslen = 0;

  // add inner capitalized forms to handle the following allcap forms:
  // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
  // Allcaps with suffixes: CIA's -> CIA'S
  if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
       ((captype == ALLCAP) && (flagslen != 0))) &&
      !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
    unsigned short* flags2 =
        (unsigned short*)malloc(sizeof(unsigned short) * (flagslen + 1));
    if (!flags2)
      return 1;
    if (flagslen)
      memcpy(flags2, flags, flagslen * sizeof(unsigned short));
    flags2[flagslen] = ONLYUPCASEFLAG;
    if (utf8) {
      std::string st;
      std::vector<w_char> w;
      u8_u16(w, word);
      mkallsmall_utf(w, langnum);
      mkinitcap_utf(w, langnum);
      u16_u8(st, w);
      return add_word(st, wcl, flags2, flagslen + 1, dp, true);
    } else {
      std::string new_word(word);
      mkallsmall(new_word, csconv);
      mkinitcap(new_word, csconv);
      int ret = add_word(new_word, wcl, flags2, flagslen + 1, dp, true);
      return ret;
    }
  }
  return 0;
}

// detect captype and modify word length for UTF-8 encoding
int HashMgr::get_clen_and_captype(const std::string& word, int* captype) {
  int len;
  if (utf8) {
    std::vector<w_char> dest_utf;
    len = u8_u16(dest_utf, word);
    *captype = get_captype_utf8(dest_utf, langnum);
  } else {
    len = word.size();
    *captype = get_captype(word, csconv);
  }
  return len;
}

// remove word (personal dictionary function for standalone applications)
int HashMgr::remove(const std::string& word) {
#ifdef HUNSPELL_CHROME_CLIENT
  std::map<base::StringPiece, int>::iterator iter =
      custom_word_to_affix_id_map_.find(word);
  if (iter != custom_word_to_affix_id_map_.end())
      custom_word_to_affix_id_map_.erase(iter);
#else
  struct hentry* dp = lookup(word.c_str());
  while (dp) {
    if (dp->alen == 0 || !TESTAFF(dp->astr, forbiddenword, dp->alen)) {
      unsigned short* flags =
          (unsigned short*)malloc(sizeof(unsigned short) * (dp->alen + 1));
      if (!flags)
        return 1;
      for (int i = 0; i < dp->alen; i++)
        flags[i] = dp->astr[i];
      flags[dp->alen] = forbiddenword;
      free(dp->astr);
      dp->astr = flags;
      dp->alen++;
      std::sort(flags, flags + dp->alen);
    }
    dp = dp->next_homonym;
  }
#endif
  return 0;
}

/* remove forbidden flag to add a personal word to the hash */
int HashMgr::remove_forbidden_flag(const std::string& word) {
  struct hentry* dp = lookup(word.c_str());
  if (!dp)
    return 1;
  while (dp) {
    if (dp->astr && TESTAFF(dp->astr, forbiddenword, dp->alen)) {
      if (dp->alen == 1)
        dp->alen = 0;  // XXX forbidden words of personal dic.
      else {
        unsigned short* flags2 =
            (unsigned short*)malloc(sizeof(unsigned short) * (dp->alen - 1));
        if (!flags2)
          return 1;
        int i, j = 0;
        for (i = 0; i < dp->alen; i++) {
          if (dp->astr[i] != forbiddenword)
            flags2[j++] = dp->astr[i];
        }
        dp->alen--;
        free(dp->astr);
        dp->astr = flags2;  // XXX allowed forbidden words
      }
    }
    dp = dp->next_homonym;
  }
  return 0;
}

// add a custom dic. word to the hash table (public)
int HashMgr::add(const std::string& word) {
  if (remove_forbidden_flag(word)) {
    int captype;
    int al = 0;
    unsigned short* flags = NULL;
    int wcl = get_clen_and_captype(word, &captype);
    add_word(word, wcl, flags, al, NULL, false);
    return add_hidden_capitalized_word(word, wcl, flags, al, NULL,
                                       captype);
  }
  return 0;
}

int HashMgr::add_with_affix(const std::string& word, const std::string& example) {
  // detect captype and modify word length for UTF-8 encoding
  struct hentry* dp = lookup(example.c_str());
  remove_forbidden_flag(word);
  if (dp && dp->astr) {
    int captype;
    int wcl = get_clen_and_captype(word, &captype);
    if (aliasf) {
      add_word(word, wcl, dp->astr, dp->alen, NULL, false);
    } else {
      unsigned short* flags =
          (unsigned short*)malloc(dp->alen * sizeof(unsigned short));
      if (flags) {
        memcpy((void*)flags, (void*)dp->astr,
               dp->alen * sizeof(unsigned short));
        add_word(word, wcl, flags, dp->alen, NULL, false);
      } else
        return 1;
    }
    return add_hidden_capitalized_word(word, wcl, dp->astr,
                                       dp->alen, NULL, captype);
  }
  return 1;
}

// walk the hash table entry by entry - null at end
// initialize: col=-1; hp = NULL; hp = walk_hashtable(&col, hp);
struct hentry* HashMgr::walk_hashtable(int& col, struct hentry* hp) const {
#ifdef HUNSPELL_CHROME_CLIENT
  // Return NULL if dictionary is not valid.
  if (!bdict_reader->IsValid())
    return NULL;

  // This function is only ever called by one place and not nested. We can
  // therefore keep static state between calls and use |col| as a "reset" flag
  // to avoid changing the API. It is set to -1 for the first call.
  // Allocate the iterator on the heap to prevent an exit time destructor.
  static hunspell::WordIterator& word_iterator =
      *new hunspell::WordIterator(bdict_reader->GetAllWordIterator());
  if (col < 0) {
    col = 1;
    word_iterator = bdict_reader->GetAllWordIterator();
  }

  int affix_ids[hunspell::BDict::MAX_AFFIXES_PER_WORD];
  static const int kMaxWordLen = 128;
  static char word[kMaxWordLen];
  int affix_count = word_iterator.Advance(word, kMaxWordLen, affix_ids);
  if (affix_count == 0)
    return NULL;
  short word_len = static_cast<short>(strlen(word));

  // Since hunspell 1.2.8, an hentry struct becomes a variable-length struct,
  // i.e. a struct which uses its array 'word[1]' as a variable-length array.
  // As noted above, this function is not nested. So, we just use a static
  // struct which consists of an hentry and a char[kMaxWordLen], and initialize
  // the static struct and return it for now.
  // No need to create linked lists for the extra affixes.
  static struct {
    hentry entry;
    char word[kMaxWordLen];
  } hash_entry;

  return InitHashEntry(&hash_entry.entry, sizeof(hash_entry),
                       &word[0], word_len, affix_ids[0]);
#else
  if (hp && hp->next != NULL)
    return hp->next;
  for (col++; col < tablesize; col++) {
    if (tableptr[col])
      return tableptr[col];
  }
  // null at end and reset to start
  col = -1;
  return NULL;
#endif
}

// load a munched word list and build a hash table on the fly
int HashMgr::load_tables(const char* tpath, const char* key) {
#ifndef HUNSPELL_CHROME_CLIENT
  // open dictionary file
  FileMgr* dict = new FileMgr(tpath, key);
  if (dict == NULL)
    return 1;

  // first read the first line of file to get hash table size */
  std::string ts;
  if (!dict->getline(ts)) {
    HUNSPELL_WARNING(stderr, "error: empty dic file %s\n", tpath);
    delete dict;
    return 2;
  }
  mychomp(ts);

  /* remove byte order mark */
  if (ts.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
    ts.erase(0, 3);
  }

  tablesize = atoi(ts.c_str());

  int nExtra = 5 + USERWORD;

  if (tablesize <= 0 ||
      (tablesize >= (std::numeric_limits<int>::max() - 1 - nExtra) /
                        int(sizeof(struct hentry*)))) {
    HUNSPELL_WARNING(
        stderr, "error: line 1: missing or bad word count in the dic file\n");
    delete dict;
    return 4;
  }
  tablesize += nExtra;
  if ((tablesize % 2) == 0)
    tablesize++;

  // allocate the hash table
  tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*));
  if (!tableptr) {
    delete dict;
    return 3;
  }

  // loop through all words on much list and add to hash
  // table and create word and affix strings

  while (dict->getline(ts)) {
    mychomp(ts);
    // split each line into word and morphological description
    size_t dp_pos = 0;
    while ((dp_pos = ts.find(':', dp_pos)) != std::string::npos) {
      if ((dp_pos > 3) && (ts[dp_pos - 3] == ' ' || ts[dp_pos - 3] == '\t')) {
        for (dp_pos -= 3; dp_pos > 0 && (ts[dp_pos-1] == ' ' || ts[dp_pos-1] == '\t'); --dp_pos)
          ;
        if (dp_pos == 0) {  // missing word
          dp_pos = std::string::npos;
        } else {
          ++dp_pos;
        }
        break;
      }
      ++dp_pos;
    }

    // tabulator is the old morphological field separator
    size_t dp2_pos = ts.find('\t');
    if (dp2_pos != std::string::npos && (dp_pos == std::string::npos || dp2_pos < dp_pos)) {
      dp_pos = dp2_pos + 1;
    }

    std::string dp;
    if (dp_pos != std::string::npos) {
      dp.assign(ts.substr(dp_pos));
      ts.resize(dp_pos - 1);
    }

    // split each line into word and affix char strings
    // "\/" signs slash in words (not affix separator)
    // "/" at beginning of the line is word character (not affix separator)
    size_t ap_pos = ts.find('/');
    while (ap_pos != std::string::npos) {
      if (ap_pos == 0) {
        ++ap_pos;
        continue;
      } else if (ts[ap_pos - 1] != '\\')
        break;
      // replace "\/" with "/"
      ts.erase(ap_pos - 1, 1);
      ap_pos = ts.find('/', ap_pos);
    }

    unsigned short* flags;
    int al;
    if (ap_pos != std::string::npos && ap_pos != ts.size()) {
      std::string ap(ts.substr(ap_pos + 1));
      ts.resize(ap_pos);
      if (aliasf) {
        int index = atoi(ap.c_str());
        al = get_aliasf(index, &flags, dict);
        if (!al) {
          HUNSPELL_WARNING(stderr, "error: line %d: bad flag vector alias\n",
                           dict->getlinenum());
        }
      } else {
        al = decode_flags(&flags, ap.c_str(), dict);
        if (al == -1) {
          HUNSPELL_WARNING(stderr, "Can't allocate memory.\n");
          delete dict;
          return 6;
        }
        std::sort(flags, flags + al);
      }
    } else {
      al = 0;
      flags = NULL;
    }

    int captype;
    int wcl = get_clen_and_captype(ts, &captype);
    const std::string *dp_str = dp.empty() ? NULL : &dp;
    // add the word and its index plus its capitalized form optionally
    if (add_word(ts, wcl, flags, al, dp_str, false) ||
        add_hidden_capitalized_word(ts, wcl, flags, al, dp_str, captype)) {
      delete dict;
      return 5;
    }
  }

  delete dict;
#endif
  return 0;
}

// the hash function is a simple load and rotate
// algorithm borrowed
int HashMgr::hash(const char* word) const {
#ifdef HUNSPELL_CHROME_CLIENT
    return 0;
#else
  unsigned long hv = 0;
  for (int i = 0; i < 4 && *word != 0; i++)
    hv = (hv << 8) | (*word++);
  while (*word != 0) {
    ROTATE(hv, ROTATE_LEN);
    hv ^= (*word++);
  }
  return (unsigned long)hv % tablesize;
#endif
}

int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const {
  int len;
  if (flags.empty()) {
    *result = NULL;
    return 0;
  }
  switch (flag_mode) {
    case FLAG_LONG: {  // two-character flags (1x2yZz -> 1x 2y Zz)
      len = flags.size();
      if (len % 2 == 1)
        HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
                         af->getlinenum());
      len /= 2;
      *result = (unsigned short*)malloc(len * sizeof(unsigned short));
      if (!*result)
        return -1;
      for (int i = 0; i < len; i++) {
        (*result)[i] = ((unsigned short)((unsigned char)flags[i * 2]) << 8) +
                       (unsigned char)flags[i * 2 + 1];
      }
      break;
    }
    case FLAG_NUM: {  // decimal numbers separated by comma (4521,23,233 -> 4521
                      // 23 233)
      len = 1;
      unsigned short* dest;
      for (size_t i = 0; i < flags.size(); ++i) {
        if (flags[i] == ',')
          len++;
      }
      *result = (unsigned short*)malloc(len * sizeof(unsigned short));
      if (!*result)
        return -1;
      dest = *result;
      const char* src = flags.c_str();
      for (const char* p = src; *p; p++) {
        if (*p == ',') {
          int i = atoi(src);
          if (i >= DEFAULTFLAGS)
            HUNSPELL_WARNING(
                stderr, "error: line %d: flag id %d is too large (max: %d)\n",
                af->getlinenum(), i, DEFAULTFLAGS - 1);
          *dest = (unsigned short)i;
          if (*dest == 0)
            HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
                             af->getlinenum());
          src = p + 1;
          dest++;
        }
      }
      int i = atoi(src);
      if (i >= DEFAULTFLAGS)
        HUNSPELL_WARNING(stderr,
                         "error: line %d: flag id %d is too large (max: %d)\n",
                         af->getlinenum(), i, DEFAULTFLAGS - 1);
      *dest = (unsigned short)i;
      if (*dest == 0)
        HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
                         af->getlinenum());
      break;
    }
    case FLAG_UNI: {  // UTF-8 characters
      std::vector<w_char> w;
      u8_u16(w, flags);
      len = w.size();
      *result = (unsigned short*)malloc(len * sizeof(unsigned short));
      if (!*result)
        return -1;
      memcpy(*result, &w[0], len * sizeof(short));
      break;
    }
    default: {  // Ispell's one-character flags (erfg -> e r f g)
      unsigned short* dest;
      len = flags.size();
      *result = (unsigned short*)malloc(len * sizeof(unsigned short));
      if (!*result)
        return -1;
      dest = *result;
      for (size_t i = 0; i < flags.size(); ++i) {
        *dest = (unsigned char)flags[i];
        dest++;
      }
    }
  }
  return len;
}

bool HashMgr::decode_flags(std::vector<unsigned short>& result, const std::string& flags, FileMgr* af) const {
  if (flags.empty()) {
    return false;
  }
  switch (flag_mode) {
    case FLAG_LONG: {  // two-character flags (1x2yZz -> 1x 2y Zz)
      size_t len = flags.size();
      if (len % 2 == 1)
        HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
                         af->getlinenum());
      len /= 2;
      result.reserve(result.size() + len);
      for (size_t i = 0; i < len; ++i) {
        result.push_back(((unsigned short)((unsigned char)flags[i * 2]) << 8) +
                         (unsigned char)flags[i * 2 + 1]);
      }
      break;
    }
    case FLAG_NUM: {  // decimal numbers separated by comma (4521,23,233 -> 4521
                      // 23 233)
      const char* src = flags.c_str();
      for (const char* p = src; *p; p++) {
        if (*p == ',') {
          int i = atoi(src);
          if (i >= DEFAULTFLAGS)
            HUNSPELL_WARNING(
                stderr, "error: line %d: flag id %d is too large (max: %d)\n",
                af->getlinenum(), i, DEFAULTFLAGS - 1);
          result.push_back((unsigned short)i);
          if (result.back() == 0)
            HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
                             af->getlinenum());
          src = p + 1;
        }
      }
      int i = atoi(src);
      if (i >= DEFAULTFLAGS)
        HUNSPELL_WARNING(stderr,
                         "error: line %d: flag id %d is too large (max: %d)\n",
                         af->getlinenum(), i, DEFAULTFLAGS - 1);
      result.push_back((unsigned short)i);
      if (result.back() == 0)
        HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
                         af->getlinenum());
      break;
    }
    case FLAG_UNI: {  // UTF-8 characters
      std::vector<w_char> w;
      u8_u16(w, flags);
      size_t len = w.size();
      size_t origsize = result.size();
      result.resize(origsize + len);
      memcpy(&result[origsize], &w[0], len * sizeof(short));
      break;
    }
    default: {  // Ispell's one-character flags (erfg -> e r f g)
      result.reserve(flags.size());
      for (size_t i = 0; i < flags.size(); ++i) {
        result.push_back((unsigned char)flags[i]);
      }
    }
  }
  return true;
}

unsigned short HashMgr::decode_flag(const char* f) const {
  unsigned short s = 0;
  int i;
  switch (flag_mode) {
    case FLAG_LONG:
      s = ((unsigned short)((unsigned char)f[0]) << 8) + (unsigned char)f[1];
      break;
    case FLAG_NUM:
      i = atoi(f);
      if (i >= DEFAULTFLAGS)
        HUNSPELL_WARNING(stderr, "error: flag id %d is too large (max: %d)\n",
                         i, DEFAULTFLAGS - 1);
      s = (unsigned short)i;
      break;
    case FLAG_UNI: {
      std::vector<w_char> w;
      u8_u16(w, f);
      if (!w.empty())
          memcpy(&s, &w[0], 1 * sizeof(short));
      break;
    }
    default:
      s = *(unsigned char*)f;
  }
  if (s == 0)
    HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
  return s;
}

char* HashMgr::encode_flag(unsigned short f) const {
  if (f == 0)
    return mystrdup("(NULL)");
  std::string ch;
  if (flag_mode == FLAG_LONG) {
    ch.push_back((unsigned char)(f >> 8));
    ch.push_back((unsigned char)(f - ((f >> 8) << 8)));
  } else if (flag_mode == FLAG_NUM) {
    std::ostringstream stream;
    stream << f;
    ch = stream.str();
  } else if (flag_mode == FLAG_UNI) {
    const w_char* w_c = (const w_char*)&f;
    std::vector<w_char> w(w_c, w_c + 1);
    u16_u8(ch, w);
  } else {
    ch.push_back((unsigned char)(f));
  }
  return mystrdup(ch.c_str());
}

// read in aff file and set flag mode
int HashMgr::load_config(const char* affpath, const char* key) {
  int firstline = 1;

  // open the affix file
#ifdef HUNSPELL_CHROME_CLIENT
  hunspell::LineIterator iterator = bdict_reader->GetOtherLineIterator();
  FileMgr * afflst = new FileMgr(&iterator);
#else
  FileMgr* afflst = new FileMgr(affpath, key);
#endif
  if (!afflst) {
    HUNSPELL_WARNING(
        stderr, "Error - could not open affix description file %s\n", affpath);
    return 1;
  }

  // read in each line ignoring any that do not
  // start with a known line type indicator

  std::string line;
  while (afflst->getline(line)) {
    mychomp(line);

    /* remove byte order mark */
    if (firstline) {
      firstline = 0;
      if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
        line.erase(0, 3);
      }
    }

    /* parse in the try string */
    if ((line.compare(0, 4, "FLAG", 4) == 0) && line.size() > 4 && isspace(line[4])) {
      if (flag_mode != FLAG_CHAR) {
        HUNSPELL_WARNING(stderr,
                         "error: line %d: multiple definitions of the FLAG "
                         "affix file parameter\n",
                         afflst->getlinenum());
      }
      if (line.find("long") != std::string::npos)
        flag_mode = FLAG_LONG;
      if (line.find("num") != std::string::npos)
        flag_mode = FLAG_NUM;
      if (line.find("UTF-8") != std::string::npos)
        flag_mode = FLAG_UNI;
      if (flag_mode == FLAG_CHAR) {
        HUNSPELL_WARNING(
            stderr,
            "error: line %d: FLAG needs `num', `long' or `UTF-8' parameter\n",
            afflst->getlinenum());
      }
    }

    if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) {
      std::string st;
      if (!parse_string(line, st, afflst->getlinenum())) {
        delete afflst;
        return 1;
      }
      forbiddenword = decode_flag(st.c_str());
    }

    if (line.compare(0, 3, "SET", 3) == 0) {
      if (!parse_string(line, enc, afflst->getlinenum())) {
        delete afflst;
        return 1;
      }
      if (enc == "UTF-8") {
        utf8 = 1;
#ifndef OPENOFFICEORG
#ifndef MOZILLA_CLIENT
        initialize_utf_tbl();
#endif
#endif
      } else
        csconv = get_current_cs(enc);
    }

    if (line.compare(0, 4, "LANG", 4) == 0) {
      if (!parse_string(line, lang, afflst->getlinenum())) {
        delete afflst;
        return 1;
      }
      langnum = get_lang_num(lang);
    }

    /* parse in the ignored characters (for example, Arabic optional diacritics
     * characters */
    if (line.compare(0, 6, "IGNORE", 6) == 0) {
      if (!parse_array(line, ignorechars, ignorechars_utf16,
                       utf8, afflst->getlinenum())) {
        delete afflst;
        return 1;
      }
    }

    if ((line.compare(0, 2, "AF", 2) == 0) && line.size() > 2 && isspace(line[2])) {
      if (!parse_aliasf(line, afflst)) {
        delete afflst;
        return 1;
      }
    }

    if ((line.compare(0, 2, "AM", 2) == 0) && line.size() > 2 && isspace(line[2])) {
      if (!parse_aliasm(line, afflst)) {
        delete afflst;
        return 1;
      }
    }

    if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0)
      complexprefixes = 1;

    if (((line.compare(0, 3, "SFX", 3) == 0) ||
         (line.compare(0, 3, "PFX", 3) == 0)) && line.size() > 3 && isspace(line[3]))
      break;
  }

  if (csconv == NULL)
    csconv = get_current_cs(SPELL_ENCODING);
  delete afflst;
  return 0;
}

/* parse in the ALIAS table */
bool HashMgr::parse_aliasf(const std::string& line, FileMgr* af) {
  if (numaliasf != 0) {
    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
                     af->getlinenum());
    return false;
  }
  int i = 0;
  int np = 0;
  std::string::const_iterator iter = line.begin();
  std::string::const_iterator start_piece = mystrsep(line, iter);
  while (start_piece != line.end()) {
    switch (i) {
      case 0: {
        np++;
        break;
      }
      case 1: {
        numaliasf = atoi(std::string(start_piece, iter).c_str());
        if (numaliasf < 1) {
          numaliasf = 0;
          aliasf = NULL;
          aliasflen = NULL;
          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
                           af->getlinenum());
          return false;
        }
        aliasf =
            (unsigned short**)malloc(numaliasf * sizeof(unsigned short*));
        aliasflen =
            (unsigned short*)malloc(numaliasf * sizeof(unsigned short));
        if (!aliasf || !aliasflen) {
          numaliasf = 0;
          if (aliasf)
            free(aliasf);
          if (aliasflen)
            free(aliasflen);
          aliasf = NULL;
          aliasflen = NULL;
          return false;
        }
        np++;
        break;
      }
      default:
        break;
    }
    ++i;
    start_piece = mystrsep(line, iter);
  }
  if (np != 2) {
    numaliasf = 0;
    free(aliasf);
    free(aliasflen);
    aliasf = NULL;
    aliasflen = NULL;
    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
                     af->getlinenum());
    return false;
  }

  /* now parse the numaliasf lines to read in the remainder of the table */
  for (int j = 0; j < numaliasf; j++) {
    std::string nl;
    if (!af->getline(nl))
      return false;
    mychomp(nl);
    i = 0;
    aliasf[j] = NULL;
    aliasflen[j] = 0;
    iter = nl.begin();
    start_piece = mystrsep(nl, iter);
    while (start_piece != nl.end()) {
      switch (i) {
        case 0: {
          if (nl.compare(start_piece - nl.begin(), 2, "AF", 2) != 0) {
            numaliasf = 0;
            free(aliasf);
            free(aliasflen);
            aliasf = NULL;
            aliasflen = NULL;
            HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
                             af->getlinenum());
            return false;
          }
          break;
        }
        case 1: {
          std::string piece(start_piece, iter);
          aliasflen[j] =
              (unsigned short)decode_flags(&(aliasf[j]), piece, af);
          std::sort(aliasf[j], aliasf[j] + aliasflen[j]);
          break;
        }
        default:
          break;
      }
      ++i;
      start_piece = mystrsep(nl, iter);
    }
    if (!aliasf[j]) {
      free(aliasf);
      free(aliasflen);
      aliasf = NULL;
      aliasflen = NULL;
      numaliasf = 0;
      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
                       af->getlinenum());
      return false;
    }
  }
  return true;
}

#ifdef HUNSPELL_CHROME_CLIENT
int HashMgr::LoadAFLines()
{
  utf8 = 1;  // We always use UTF-8.

  // Read in all the AF lines which tell us the rules for each affix group ID.
  hunspell::LineIterator iterator = bdict_reader->GetAfLineIterator();
  FileMgr afflst(&iterator);
  std::string line;
  while (afflst.getline(line)) {
    int rv = parse_aliasf(line, &afflst);
    if (rv)
      return rv;
  }

  return 0;
}

hentry* HashMgr::InitHashEntry(hentry* entry,
                               size_t item_size,
                               const char* word,
                               int word_length,
                               int affix_index) const {
  // Return if the given buffer doesn't have enough space for a hentry struct
  // or the given word is too long.
  // Our BDICT cannot handle words longer than (128 - 1) bytes. So, it is
  // better to return an error if the given word is too long and prevent
  // an unexpected result caused by a long word.
  const int kMaxWordLen = 128;
  if (item_size < sizeof(hentry) + word_length + 1 ||
      word_length >= kMaxWordLen)
    return NULL;

  // Initialize a hentry struct with the given parameters, and
  // append the given string at the end of this hentry struct.
  memset(entry, 0, item_size);
  FileMgr af(NULL);
  entry->alen = static_cast<short>(
      const_cast<HashMgr*>(this)->get_aliasf(affix_index, &entry->astr, &af));
  entry->blen = static_cast<unsigned char>(word_length);
  memcpy(&entry->word, word, word_length);

  return entry;
}

hentry* HashMgr::CreateHashEntry(const char* word,
                                 int word_length,
                                 int affix_index) const {
  // Return if the given word is too long.
  // (See the comment in HashMgr::InitHashEntry().)
  const int kMaxWordLen = 128;
  if (word_length >= kMaxWordLen)
    return NULL;

  const size_t kEntrySize = sizeof(hentry) + word_length + 1;
  struct hentry* entry = reinterpret_cast<hentry*>(malloc(kEntrySize));
  if (entry)
    InitHashEntry(entry, kEntrySize, word, word_length, affix_index);

  return entry;
}

void HashMgr::DeleteHashEntry(hentry* entry) const {
  free(entry);
}

hentry* HashMgr::AffixIDsToHentry(char* word,
                                  int* affix_ids, 
                                  int affix_count) const
{
  if (affix_count == 0)
    return NULL;

  HEntryCache& cache = const_cast<HashMgr*>(this)->hentry_cache;
  std::string std_word(word);
  HEntryCache::iterator found = cache.find(std_word);
  if (found != cache.end()) {
    // We must return an existing hentry for the same word if we've previously
    // handed one out. Hunspell will compare pointers in some cases to see if
    // two words it has found are the same.
    return found->second;
  }

  short word_len = static_cast<short>(strlen(word));

  // We can get a number of prefixes per word. There will normally be only one,
  // but if not, there will be a linked list of "hentry"s for the "homonym"s 
  // for the word.
  struct hentry* first_he = NULL;
  struct hentry* prev_he = NULL;  // For making linked list.
  for (int i = 0; i < affix_count; i++) {
    struct hentry* he = CreateHashEntry(word, word_len, affix_ids[i]);
    if (!he)
      break;
    if (i == 0)
      first_he = he;
    if (prev_he)
      prev_he->next_homonym = he;
    prev_he = he;
  }

  cache[std_word] = first_he;  // Save this word in the cache for later.
  return first_he;
}

hentry* HashMgr::GetHentryFromHEntryCache(char* word) {
  HEntryCache& cache = const_cast<HashMgr*>(this)->hentry_cache;
  std::string std_word(word);
  HEntryCache::iterator found = cache.find(std_word);
  if (found != cache.end())
    return found->second;
  else
    return NULL;
}
#endif

int HashMgr::is_aliasf() const {
  return (aliasf != NULL);
}

int HashMgr::get_aliasf(int index, unsigned short** fvec, FileMgr* af) const {
  if ((index > 0) && (index <= numaliasf)) {
    *fvec = aliasf[index - 1];
    return aliasflen[index - 1];
  }
  HUNSPELL_WARNING(stderr, "error: line %d: bad flag alias index: %d\n",
                   af->getlinenum(), index);
  *fvec = NULL;
  return 0;
}

/* parse morph alias definitions */
bool HashMgr::parse_aliasm(const std::string& line, FileMgr* af) {
  if (numaliasm != 0) {
    HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
                     af->getlinenum());
    return false;
  }
  int i = 0;
  int np = 0;
  std::string::const_iterator iter = line.begin();
  std::string::const_iterator start_piece = mystrsep(line, iter);
  while (start_piece != line.end()) {
    switch (i) {
      case 0: {
        np++;
        break;
      }
      case 1: {
        numaliasm = atoi(std::string(start_piece, iter).c_str());
        if (numaliasm < 1) {
          HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
                           af->getlinenum());
          return false;
        }
        aliasm = (char**)malloc(numaliasm * sizeof(char*));
        if (!aliasm) {
          numaliasm = 0;
          return false;
        }
        np++;
        break;
      }
      default:
        break;
    }
    ++i;
    start_piece = mystrsep(line, iter);
  }
  if (np != 2) {
    numaliasm = 0;
    free(aliasm);
    aliasm = NULL;
    HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
                     af->getlinenum());
    return false;
  }

  /* now parse the numaliasm lines to read in the remainder of the table */
  for (int j = 0; j < numaliasm; j++) {
    std::string nl;
    if (!af->getline(nl))
      return false;
    mychomp(nl);
    aliasm[j] = NULL;
    iter = nl.begin();
    i = 0;
    start_piece = mystrsep(nl, iter);
    while (start_piece != nl.end()) {
      switch (i) {
        case 0: {
          if (nl.compare(start_piece - nl.begin(), 2, "AM", 2) != 0) {
            HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
                             af->getlinenum());
            numaliasm = 0;
            free(aliasm);
            aliasm = NULL;
            return false;
          }
          break;
        }
        case 1: {
          // add the remaining of the line
          std::string::const_iterator end = nl.end();
          std::string chunk(start_piece, end);
          if (complexprefixes) {
            if (utf8)
              reverseword_utf(chunk);
            else
              reverseword(chunk);
          }
          aliasm[j] = mystrdup(chunk.c_str());
          break;
        }
        default:
          break;
      }
      ++i;
      start_piece = mystrsep(nl, iter);
    }
    if (!aliasm[j]) {
      numaliasm = 0;
      free(aliasm);
      aliasm = NULL;
      HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
                       af->getlinenum());
      return false;
    }
  }
  return true;
}

int HashMgr::is_aliasm() const {
  return (aliasm != NULL);
}

char* HashMgr::get_aliasm(int index) const {
  if ((index > 0) && (index <= numaliasm))
    return aliasm[index - 1];
  HUNSPELL_WARNING(stderr, "error: bad morph. alias index: %d\n", index);
  return NULL;
}
