Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/xpcom/ds/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 5 kB image not shown  

Quelle  nsStaticNameTable.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/* Class to manage lookup of static names in a table. */

#include "mozilla/HashFunctions.h"
#include "mozilla/TextUtils.h"

#include "nsCRT.h"

#include "nscore.h"
#include "nsISupportsImpl.h"

#include "nsStaticNameTable.h"

using namespace mozilla;

struct NameTableKey {
  NameTableKey(const nsDependentCString aNameArray[], const nsCString* aKeyStr)
      : mNameArray(aNameArray), mIsUnichar(false) {
    mKeyStr.m1b = aKeyStr;
  }

  NameTableKey(const nsDependentCString aNameArray[], const nsString* aKeyStr)
      : mNameArray(aNameArray), mIsUnichar(true) {
    mKeyStr.m2b = aKeyStr;
  }

  const nsDependentCString* mNameArray;
  union {
    const nsCString* m1b;
    const nsString* m2b;
  } mKeyStr;
  bool mIsUnichar;
};

struct NameTableEntry : public PLDHashEntryHdr {
  int32_t mIndex;
};

static bool matchNameKeysCaseInsensitive(const PLDHashEntryHdr* aHdr,
                                         const void* aVoidKey) {
  auto entry = static_cast<const NameTableEntry*>(aHdr);
  auto key = static_cast<const NameTableKey*>(aVoidKey);
  const nsDependentCString* name = &key->mNameArray[entry->mIndex];

  return key->mIsUnichar ? key->mKeyStr.m2b->LowerCaseEqualsASCII(
                               name->get(), name->Length())
                         : key->mKeyStr.m1b->LowerCaseEqualsASCII(
                               name->get(), name->Length());
}

/*
 * caseInsensitiveHashKey is just like PLDHashTable::HashStringKey except it
 * uses (*s & ~0x20) instead of simply *s.  This means that "aFOO" and
 * "afoo" and "aFoo" will all hash to the same thing.  It also means
 * that some strings that aren't case-insensensitively equal will hash
 * to the same value, but it's just a hash function so it doesn't
 * matter.
 */

static PLDHashNumber caseInsensitiveStringHashKey(const void* aKey) {
  PLDHashNumber h = 0;
  const NameTableKey* tableKey = static_cast<const NameTableKey*>(aKey);
  if (tableKey->mIsUnichar) {
    for (const char16_t* s = tableKey->mKeyStr.m2b->get(); *s != '\0'; s++) {
      h = AddToHash(h, *s & ~0x20);
    }
  } else {
    for (const unsigned char* s = reinterpret_cast<const unsigned char*>(
             tableKey->mKeyStr.m1b->get());
         *s != '\0'; s++) {
      h = AddToHash(h, *s & ~0x20);
    }
  }
  return h;
}

static const struct PLDHashTableOps nametable_CaseInsensitiveHashTableOps = {
    caseInsensitiveStringHashKey,
    matchNameKeysCaseInsensitive,
    PLDHashTable::MoveEntryStub,
    PLDHashTable::ClearEntryStub,
    nullptr,
};

nsStaticCaseInsensitiveNameTable::nsStaticCaseInsensitiveNameTable(
    const charconst aNames[], int32_t aLength)
    : mNameArray(nullptr),
      mNameTable(&nametable_CaseInsensitiveHashTableOps, sizeof(NameTableEntry),
                 aLength),
      mNullStr("") {
  MOZ_COUNT_CTOR(nsStaticCaseInsensitiveNameTable);

  MOZ_ASSERT(aNames, "null name table");
  MOZ_ASSERT(aLength, "0 length");

  mNameArray =
      (nsDependentCString*)moz_xmalloc(aLength * sizeof(nsDependentCString));

  for (int32_t index = 0; index < aLength; ++index) {
    const char* raw = aNames[index];
#ifdef DEBUG
    {
      // verify invariants of contents
      nsAutoCString temp1(raw);
      nsDependentCString temp2(raw);
      ToLowerCase(temp1);
      MOZ_ASSERT(temp1.Equals(temp2), "upper case char in table");
      MOZ_ASSERT(IsAsciiNullTerminated(raw),
                 "non-ascii string in table -- "
                 "case-insensitive matching won't work right");
    }
#endif
    // use placement-new to initialize the string object
    nsDependentCString* strPtr = &mNameArray[index];
    new (strPtr) nsDependentCString(raw);

    NameTableKey key(mNameArray, strPtr);

    auto entry = static_cast<NameTableEntry*>(mNameTable.Add(&key, fallible));
    if (!entry) {
      continue;
    }

    // If the entry already exists it's unlikely but possible that its index is
    // zero, in which case this assertion won't fail. But if the index is
    // non-zero (highly likely) then it will fail. In other words, this
    // assertion is likely but not guaranteed to detect if an entry is already
    // used.
    MOZ_ASSERT(entry->mIndex == 0, "Entry already exists!");

    entry->mIndex = index;
  }
  mNameTable.MarkImmutable();
}

nsStaticCaseInsensitiveNameTable::~nsStaticCaseInsensitiveNameTable() {
  // manually call the destructor on placement-new'ed objects
  for (uint32_t index = 0; index < mNameTable.EntryCount(); index++) {
    mNameArray[index].~nsDependentCString();
  }
  free((void*)mNameArray);
  MOZ_COUNT_DTOR(nsStaticCaseInsensitiveNameTable);
}

int32_t nsStaticCaseInsensitiveNameTable::Lookup(
    const nsACString& aName) const {
  NS_ASSERTION(mNameArray, "not inited");

  const nsCString& str = PromiseFlatCString(aName);

  NameTableKey key(mNameArray, &str);
  auto entry = static_cast<NameTableEntry*>(mNameTable.Search(&key));

  return entry ? entry->mIndex : nsStaticCaseInsensitiveNameTable::NOT_FOUND;
}

int32_t nsStaticCaseInsensitiveNameTable::Lookup(const nsAString& aName) const {
  NS_ASSERTION(mNameArray, "not inited");

  const nsString& str = PromiseFlatString(aName);

  NameTableKey key(mNameArray, &str);
  auto entry = static_cast<NameTableEntry*>(mNameTable.Search(&key));

  return entry ? entry->mIndex : nsStaticCaseInsensitiveNameTable::NOT_FOUND;
}

const nsCString& nsStaticCaseInsensitiveNameTable::GetStringValue(
    int32_t aIndex) {
  NS_ASSERTION(mNameArray, "not inited");

  if ((NOT_FOUND < aIndex) && ((uint32_t)aIndex < mNameTable.EntryCount())) {
    return mNameArray[aIndex];
  }
  return mNullStr;
}

91%


¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.