gecko-dev/layout/style/nsCSSKeywords.cpp

145 lines
3.8 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsCSSKeywords.h"
#include "nsString.h"
#include "nsAVLTree.h"
// define an array of all CSS keywords
#define CSS_KEY(_key) #_key,
const char* kCSSRawKeywords[] = {
#include "nsCSSKeywordList.h"
};
#undef CSS_KEY
struct KeywordNode {
KeywordNode(void)
: mStr(),
mEnum(eCSSKeyword_UNKNOWN)
{}
KeywordNode(const nsStr& aStringValue, nsCSSKeyword aEnumValue)
: mStr(),
mEnum(aEnumValue)
{ // point to the incomming buffer
// note that the incomming buffer may really be 2 byte
nsStr::Initialize(mStr, aStringValue.mStr, aStringValue.mCapacity,
aStringValue.mLength, aStringValue.mCharSize, PR_FALSE);
}
nsCAutoString mStr;
nsCSSKeyword mEnum;
};
class KeywordComparitor: public nsAVLNodeComparitor {
public:
virtual ~KeywordComparitor(void) {}
virtual PRInt32 operator()(void* anItem1,void* anItem2) {
KeywordNode* one = (KeywordNode*)anItem1;
KeywordNode* two = (KeywordNode*)anItem2;
return one->mStr.Compare(two->mStr, PR_TRUE);
}
};
static PRInt32 gTableRefCount;
static KeywordNode* gKeywordArray;
static nsAVLTree* gKeywordTree;
static KeywordComparitor* gComparitor;
static nsCString* kNullStr;
void
nsCSSKeywords::AddRefTable(void)
{
if (0 == gTableRefCount++) {
if (! gKeywordArray) {
gKeywordArray = new KeywordNode[eCSSKeyword_COUNT];
gComparitor = new KeywordComparitor();
if (gComparitor) {
gKeywordTree = new nsAVLTree(*gComparitor, nsnull);
}
if (gKeywordArray && gKeywordTree) {
PRInt32 index = -1;
while (++index < PRInt32(eCSSKeyword_COUNT)) {
gKeywordArray[index].mStr = kCSSRawKeywords[index];
gKeywordArray[index].mStr.ReplaceChar('_', '-');
gKeywordArray[index].mEnum = nsCSSKeyword(index);
gKeywordTree->AddItem(&(gKeywordArray[index]));
}
}
}
kNullStr = new nsCString();
}
}
void
nsCSSKeywords::ReleaseTable(void)
{
if (0 == --gTableRefCount) {
if (gKeywordArray) {
delete [] gKeywordArray;
gKeywordArray = nsnull;
}
if (gKeywordTree) {
delete gKeywordTree;
gKeywordTree = nsnull;
}
if (gComparitor) {
delete gComparitor;
gComparitor = nsnull;
}
delete kNullStr;
}
}
nsCSSKeyword
nsCSSKeywords::LookupKeyword(const nsStr& aKeyword)
{
NS_ASSERTION(gKeywordTree, "no lookup table, needs addref");
if (gKeywordTree) {
KeywordNode node(aKeyword, eCSSKeyword_UNKNOWN);
KeywordNode* found = (KeywordNode*)gKeywordTree->FindItem(&node);
if (found) {
NS_ASSERTION(found->mStr.EqualsIgnoreCase(aKeyword), "bad tree");
return found->mEnum;
}
}
return eCSSKeyword_UNKNOWN;
}
const nsCString&
nsCSSKeywords::GetStringValue(nsCSSKeyword aKeyword)
{
NS_ASSERTION(gKeywordArray, "no lookup table, needs addref");
if ((eCSSKeyword_UNKNOWN < aKeyword) &&
(aKeyword < eCSSKeyword_COUNT) && gKeywordArray) {
return gKeywordArray[aKeyword].mStr;
}
else {
return *kNullStr;
}
}