summaryrefslogtreecommitdiff
path: root/indra/llui/llkeywords.h
blob: 09378e408bb0b7fc55464101cebb705ce8709613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/** 
 * @file llkeywords.h
 * @brief Keyword list for LSL
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 * 
 * Copyright (c) 2001-2009, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#ifndef LL_LLKEYWORDS_H
#define LL_LLKEYWORDS_H


#include "llstring.h"
#include "v3color.h"
#include <map>
#include <list>
#include <deque>
#include "llpointer.h"

class LLTextSegment;
typedef LLPointer<LLTextSegment> LLTextSegmentPtr;

class LLKeywordToken
{
public:
	enum TOKEN_TYPE { WORD, LINE, TWO_SIDED_DELIMITER, ONE_SIDED_DELIMITER };

	LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip ) 
		:
		mType( type ),
		mToken( token ),
		mColor( color ),
		mToolTip( tool_tip )
	{
	}

	S32					getLength() const		{ return mToken.size(); }
	BOOL				isHead(const llwchar* s) const;
	const LLWString&	getToken() const		{ return mToken; }
	const LLColor3&		getColor() const		{ return mColor; }
	TOKEN_TYPE			getType()  const		{ return mType; }
	const LLWString&	getToolTip() const		{ return mToolTip; }

#ifdef _DEBUG
	void		dump();
#endif

private:
	TOKEN_TYPE	mType;
	LLWString	mToken;
	LLColor3	mColor;
	LLWString	mToolTip;
};

class LLKeywords
{
public:
	LLKeywords();
	~LLKeywords();

	BOOL		loadFromFile(const std::string& filename);
	BOOL		isLoaded() const	{ return mLoaded; }

	void		findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor, class LLTextEditor& editor );

	// Add the token as described
	void addToken(LLKeywordToken::TOKEN_TYPE type,
					const std::string& key,
					const LLColor3& color,
					const std::string& tool_tip = LLStringUtil::null);
	
	// This class is here as a performance optimization.
	// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>.
	// This worked, but caused a performance bottleneck due to memory allocation and string copies
	//  because it's not possible to search such a map without creating an LLWString.
	// Using this class as the map index instead allows us to search using segments of an existing
	//  text run without copying them first, which greatly reduces overhead in LLKeywords::findSegments().
	class WStringMapIndex
	{
	public:
		// copy constructor
		WStringMapIndex(const WStringMapIndex& other);
		// constructor from a string (copies the string's data into the new object)
		WStringMapIndex(const LLWString& str);
		// constructor from pointer and length
		// NOTE: does NOT copy data, caller must ensure that the lifetime of the pointer exceeds that of the new object!
		WStringMapIndex(const llwchar *start, size_t length);
		~WStringMapIndex();
		bool operator<(const WStringMapIndex &other) const;
	private:
		void copyData(const llwchar *start, size_t length);
		const llwchar *mData;
		size_t mLength;
		bool mOwner;
	};

	typedef std::map<WStringMapIndex, LLKeywordToken*> word_token_map_t;
	typedef word_token_map_t::const_iterator keyword_iterator_t;
	keyword_iterator_t begin() const { return mWordTokenMap.begin(); }
	keyword_iterator_t end() const { return mWordTokenMap.end(); }

#ifdef _DEBUG
	void		dump();
#endif

private:
	LLColor3	readColor(const std::string& s);
	void		insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor);
	void		insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor);

	BOOL		mLoaded;
	word_token_map_t mWordTokenMap;
	typedef std::deque<LLKeywordToken*> token_list_t;
	token_list_t mLineTokenList;
	token_list_t mDelimiterTokenList;
};

#endif  // LL_LLKEYWORDS_H