xref: /aoo4110/main/l10ntools/source/wtratree.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_l10ntools.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski 
28*b1cdbd2cSJim Jagielski #include "wtratree.hxx"
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski /** @ATTENTION
33*b1cdbd2cSJim Jagielski 	For reasons of speed, class WordTransTree works with two simple
34*b1cdbd2cSJim Jagielski 	char arrays, sOutput and sInput, instead of secure containers or
35*b1cdbd2cSJim Jagielski 	streams. So be extremely careful, when changing this code!!!
36*b1cdbd2cSJim Jagielski **/
37*b1cdbd2cSJim Jagielski 
38*b1cdbd2cSJim Jagielski 
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski // NOT FULLY DECLARED SERVICES
41*b1cdbd2cSJim Jagielski #include <string.h>
42*b1cdbd2cSJim Jagielski #include <stdio.h>
43*b1cdbd2cSJim Jagielski #include <ctype.h>
44*b1cdbd2cSJim Jagielski #include "wtranode.hxx"
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski const BRANCH_T	BR_END			= 0;
48*b1cdbd2cSJim Jagielski const BRANCH_T	BR_NONALPHA     = 1;
49*b1cdbd2cSJim Jagielski const BRANCH_T	BR_HOTKEY       = 2;
50*b1cdbd2cSJim Jagielski const BRANCH_T	BR_BACKSLASH    = 3;
51*b1cdbd2cSJim Jagielski const BRANCH_T	BR_ALPHABASE    = 4;   	/// @ATTENTION  All branches not valid for words must be smaller than this value!
52*b1cdbd2cSJim Jagielski const BRANCH_T	BR_AE           = 30;
53*b1cdbd2cSJim Jagielski const BRANCH_T	BR_OE           = 31;
54*b1cdbd2cSJim Jagielski const BRANCH_T	BR_UE           = 32;
55*b1cdbd2cSJim Jagielski const BRANCH_T	BR_SZ           = 33;
56*b1cdbd2cSJim Jagielski const BRANCH_T	BR_MAX          = 34;	/// @ATTENTION  Must be updated always!
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski const BRANCH_T	BR_START 		= 0;
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski 
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski 
WordTransTree(CharSet i_nWorkingCharSet)64*b1cdbd2cSJim Jagielski WordTransTree::WordTransTree(CharSet  i_nWorkingCharSet)
65*b1cdbd2cSJim Jagielski 	:	sInput(0),
66*b1cdbd2cSJim Jagielski 		nInputLength(0),
67*b1cdbd2cSJim Jagielski 		pInputEnd(0),
68*b1cdbd2cSJim Jagielski 		sOutput(0),
69*b1cdbd2cSJim Jagielski 		nOutputMaxLength(0),
70*b1cdbd2cSJim Jagielski 		dpParsingTreeTop(0),
71*b1cdbd2cSJim Jagielski 		pUnknownAlpha(0),
72*b1cdbd2cSJim Jagielski 		// cChar2Branch
73*b1cdbd2cSJim Jagielski         c_AE(u_char('\xC4')), c_OE(u_char('\xD6')), c_UE(u_char('\xDC')),
74*b1cdbd2cSJim Jagielski         c_ae(u_char('\xE4')), c_oe(u_char('\xF6')), c_ue(u_char('\xFC')),
75*b1cdbd2cSJim Jagielski 		pInputCurTokenStart(0),
76*b1cdbd2cSJim Jagielski 		pInputPosition(0),
77*b1cdbd2cSJim Jagielski 		pOutputPosition(0),
78*b1cdbd2cSJim Jagielski 		pCurParseNode(0),
79*b1cdbd2cSJim Jagielski 		eCurResult(OK),
80*b1cdbd2cSJim Jagielski 		cCurHotkey(0),
81*b1cdbd2cSJim Jagielski 		cCurHotkeySign(u_char('~'))
82*b1cdbd2cSJim Jagielski {
83*b1cdbd2cSJim Jagielski 	// Initialize parsing tree:
84*b1cdbd2cSJim Jagielski 	pUnknownAlpha = new WTT_Node(BR_ALPHABASE,0,0);	// This will be deleted as part of the parsing tree.
85*b1cdbd2cSJim Jagielski 	for ( UINT8 i = BR_ALPHABASE; i < C_NR_OF_BRANCHES; i++)
86*b1cdbd2cSJim Jagielski 	{
87*b1cdbd2cSJim Jagielski 		pUnknownAlpha->SetBranch(i,pUnknownAlpha);
88*b1cdbd2cSJim Jagielski 	}  // end for
89*b1cdbd2cSJim Jagielski 
90*b1cdbd2cSJim Jagielski 	dpParsingTreeTop = new WTT_Node(BR_START,0,pUnknownAlpha);
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski 	WTT_Node * dpNonAlpha = new WTT_Node(BR_NONALPHA,0,0);
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski 	dpNonAlpha->SetBranch(BR_NONALPHA,dpNonAlpha);
95*b1cdbd2cSJim Jagielski 	dpParsingTreeTop->SetBranch(BR_NONALPHA,dpNonAlpha);
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski 	WTT_Node * dpBackslash = new WTT_Node(BR_BACKSLASH,dpNonAlpha,dpNonAlpha);
98*b1cdbd2cSJim Jagielski 	dpBackslash->SetBranch(BR_END,0);
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski 	dpParsingTreeTop->SetBranch(BR_BACKSLASH,dpBackslash);
101*b1cdbd2cSJim Jagielski 	dpNonAlpha->SetBranch(BR_BACKSLASH,dpBackslash);
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski 	// Initialize character set:
105*b1cdbd2cSJim Jagielski 	SetCharSet(i_nWorkingCharSet);
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski 	if (C_BR_ALPHABASE != BR_ALPHABASE || C_NR_OF_BRANCHES != BR_MAX)
108*b1cdbd2cSJim Jagielski 	{
109*b1cdbd2cSJim Jagielski 		fprintf(stderr, "Assertion failed: file %s line %d.", __FILE__,  __LINE__);
110*b1cdbd2cSJim Jagielski 		exit(1);
111*b1cdbd2cSJim Jagielski 	}
112*b1cdbd2cSJim Jagielski }
113*b1cdbd2cSJim Jagielski 
114*b1cdbd2cSJim Jagielski void
SetCharSet(CharSet i_nWorkingCharSet)115*b1cdbd2cSJim Jagielski WordTransTree::SetCharSet(CharSet i_nWorkingCharSet)
116*b1cdbd2cSJim Jagielski {
117*b1cdbd2cSJim Jagielski     ByteString sConvert("\xC4\xD6\xDC\xE4\xF6\xFC\xDF");
118*b1cdbd2cSJim Jagielski 	const u_char * pConvert = (const u_char * ) ( sConvert.Convert(RTL_TEXTENCODING_MS_1252, i_nWorkingCharSet).GetBuffer() );
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski 	INT16 i = 0;
121*b1cdbd2cSJim Jagielski 	for ( ; i < C_NR_OF_POSSIBLE_CHARS; ++i )
122*b1cdbd2cSJim Jagielski 	{
123*b1cdbd2cSJim Jagielski 		cChar2Branch[i] = BR_NONALPHA;
124*b1cdbd2cSJim Jagielski 	}  // end for
125*b1cdbd2cSJim Jagielski 	for ( i = 'a'; i <= 'z'; ++i )
126*b1cdbd2cSJim Jagielski 	{
127*b1cdbd2cSJim Jagielski 		cChar2Branch[i] = BR_ALPHABASE + i - 'a';
128*b1cdbd2cSJim Jagielski 	}  // end for
129*b1cdbd2cSJim Jagielski 	for ( i = 'A'; i <= 'Z'; ++i )
130*b1cdbd2cSJim Jagielski 	{
131*b1cdbd2cSJim Jagielski 		cChar2Branch[i] = BR_ALPHABASE + i - 'A';
132*b1cdbd2cSJim Jagielski 	}  // end for
133*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[0]] = BR_AE;
134*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[1]] = BR_OE;
135*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[2]] = BR_UE;
136*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[3]] = BR_AE;
137*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[4]] = BR_OE;
138*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[5]] = BR_UE;
139*b1cdbd2cSJim Jagielski 	cChar2Branch[pConvert[6]] = BR_SZ;
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski 	cChar2Branch[u_char('~')] = BR_HOTKEY;
142*b1cdbd2cSJim Jagielski 	cChar2Branch[u_char('&')] = BR_HOTKEY;
143*b1cdbd2cSJim Jagielski 
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski 	c_AE = pConvert[0];
146*b1cdbd2cSJim Jagielski 	c_OE = pConvert[1];
147*b1cdbd2cSJim Jagielski 	c_UE = pConvert[2];
148*b1cdbd2cSJim Jagielski 	c_ae = pConvert[3];
149*b1cdbd2cSJim Jagielski 	c_oe = pConvert[4];
150*b1cdbd2cSJim Jagielski 	c_ue = pConvert[5];
151*b1cdbd2cSJim Jagielski }
152*b1cdbd2cSJim Jagielski 
~WordTransTree()153*b1cdbd2cSJim Jagielski WordTransTree::~WordTransTree()
154*b1cdbd2cSJim Jagielski {
155*b1cdbd2cSJim Jagielski 	delete dpParsingTreeTop;
156*b1cdbd2cSJim Jagielski 	if (sOutput != 0)
157*b1cdbd2cSJim Jagielski 		delete [] sOutput;
158*b1cdbd2cSJim Jagielski }
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski void
AddWordPair(const ByteString & i_sOldString,const ByteString & i_sReplaceString)161*b1cdbd2cSJim Jagielski WordTransTree::AddWordPair(	const ByteString &		i_sOldString,
162*b1cdbd2cSJim Jagielski 							const ByteString &		i_sReplaceString )
163*b1cdbd2cSJim Jagielski {
164*b1cdbd2cSJim Jagielski 	if (i_sOldString.Len() == 0)
165*b1cdbd2cSJim Jagielski 		return;
166*b1cdbd2cSJim Jagielski 
167*b1cdbd2cSJim Jagielski 	pCurParseNode = dpParsingTreeTop;
168*b1cdbd2cSJim Jagielski 	WTT_Node * pBranch = 0;
169*b1cdbd2cSJim Jagielski 	char cBranch = 0;
170*b1cdbd2cSJim Jagielski 
171*b1cdbd2cSJim Jagielski 	for ( constr pOld = i_sOldString.GetBuffer();
172*b1cdbd2cSJim Jagielski 		  *pOld != 0;
173*b1cdbd2cSJim Jagielski 		  pOld++ )
174*b1cdbd2cSJim Jagielski 	{
175*b1cdbd2cSJim Jagielski 		cBranch = CalculateBranch(*pOld);
176*b1cdbd2cSJim Jagielski 		pBranch = pCurParseNode->GetNextNode(cBranch);
177*b1cdbd2cSJim Jagielski 		if (pBranch == 0 || pBranch == pUnknownAlpha)
178*b1cdbd2cSJim Jagielski 		{
179*b1cdbd2cSJim Jagielski 			pBranch = new WTT_Node(cBranch,0,pUnknownAlpha);
180*b1cdbd2cSJim Jagielski 			pCurParseNode->SetBranch(cBranch,pBranch);
181*b1cdbd2cSJim Jagielski 		}
182*b1cdbd2cSJim Jagielski 		pCurParseNode = pBranch;
183*b1cdbd2cSJim Jagielski 	}	// end for
184*b1cdbd2cSJim Jagielski 	pCurParseNode->SetAsTokenToReplace(i_sReplaceString);
185*b1cdbd2cSJim Jagielski }
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski void
InitTransformation(const char * i_sInput,UINT32 i_nInputLength,UINT32 i_nOutputMaxLength)188*b1cdbd2cSJim Jagielski WordTransTree::InitTransformation( const char *	i_sInput,
189*b1cdbd2cSJim Jagielski 								   UINT32		i_nInputLength,
190*b1cdbd2cSJim Jagielski 								   UINT32		i_nOutputMaxLength )
191*b1cdbd2cSJim Jagielski {
192*b1cdbd2cSJim Jagielski 	sInput = (const u_char *)i_sInput;
193*b1cdbd2cSJim Jagielski 	nInputLength = i_nInputLength;
194*b1cdbd2cSJim Jagielski 	pInputEnd = &sInput[i_nInputLength];
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski 	pInputCurTokenStart = sInput;
197*b1cdbd2cSJim Jagielski 	pInputPosition = sInput;
198*b1cdbd2cSJim Jagielski 
199*b1cdbd2cSJim Jagielski 	if (nOutputMaxLength < i_nOutputMaxLength)
200*b1cdbd2cSJim Jagielski 	{
201*b1cdbd2cSJim Jagielski 		if (sOutput != 0)
202*b1cdbd2cSJim Jagielski 			delete [] sOutput;
203*b1cdbd2cSJim Jagielski 		sOutput = new unsigned char[i_nOutputMaxLength];
204*b1cdbd2cSJim Jagielski 		nOutputMaxLength = i_nOutputMaxLength;
205*b1cdbd2cSJim Jagielski 	}
206*b1cdbd2cSJim Jagielski 	pOutputPosition = sOutput;
207*b1cdbd2cSJim Jagielski }
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski /**	pInputCurTokenStart and CurParseNode are updated just when
210*b1cdbd2cSJim Jagielski 	starting this function. After its end they must not be changed
211*b1cdbd2cSJim Jagielski 	till this functon is called again.
212*b1cdbd2cSJim Jagielski 	Outside this function pInputPositon and pOutputPosition are both
213*b1cdbd2cSJim Jagielski 	on the first not transformed char in their respective array.
214*b1cdbd2cSJim Jagielski **/
215*b1cdbd2cSJim Jagielski WordTransTree::E_Result
TransformNextToken()216*b1cdbd2cSJim Jagielski WordTransTree::TransformNextToken()
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski 	pInputCurTokenStart = pInputPosition;
219*b1cdbd2cSJim Jagielski 	pCurParseNode = dpParsingTreeTop;
220*b1cdbd2cSJim Jagielski 	cCurHotkey = 0;
221*b1cdbd2cSJim Jagielski     eCurResult = OK;
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski 	WTT_Node * pBranch = 0;
224*b1cdbd2cSJim Jagielski 	UINT8 cBranch = 0;
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski 	for ( pCurParseNode = dpParsingTreeTop;
227*b1cdbd2cSJim Jagielski 		  pInputPosition != pInputEnd;
228*b1cdbd2cSJim Jagielski 		  ++pInputPosition )
229*b1cdbd2cSJim Jagielski 	{
230*b1cdbd2cSJim Jagielski 		cBranch = CalculateBranch(*pInputPosition);
231*b1cdbd2cSJim Jagielski 		pBranch = pCurParseNode->GetNextNode( cBranch );
232*b1cdbd2cSJim Jagielski 		if (pBranch != 0)
233*b1cdbd2cSJim Jagielski 		{
234*b1cdbd2cSJim Jagielski 			pCurParseNode = pBranch;
235*b1cdbd2cSJim Jagielski 		}
236*b1cdbd2cSJim Jagielski 		else
237*b1cdbd2cSJim Jagielski 		{
238*b1cdbd2cSJim Jagielski 			if (cBranch == BR_HOTKEY)   // current letter is '~' or '&'.
239*b1cdbd2cSJim Jagielski 			{
240*b1cdbd2cSJim Jagielski 				// Logic of the following. There are 9 possible cases -
241*b1cdbd2cSJim Jagielski 				// A = alphabetic letter, NA = non alphabetic, TB = token begin,
242*b1cdbd2cSJim Jagielski 				// Eot = end of text:
243*b1cdbd2cSJim Jagielski 				//	 1.	A~A          set hotkey to following letter, continue
244*b1cdbd2cSJim Jagielski 				//	 2.	A~NA         token end
245*b1cdbd2cSJim Jagielski 				//	 3.	A~Eot        token end
246*b1cdbd2cSJim Jagielski 				//	 4.	NA~A         token end
247*b1cdbd2cSJim Jagielski 				//	 5.	NA~NA        continue
248*b1cdbd2cSJim Jagielski 				//	 6.	A~Eof        continue
249*b1cdbd2cSJim Jagielski 				//	 7.	TB~A         set hotkey to following letter, continue
250*b1cdbd2cSJim Jagielski 				//	 8.	TB~NA        continue
251*b1cdbd2cSJim Jagielski 				//	 9.	TB~Eot       continue
252*b1cdbd2cSJim Jagielski 
253*b1cdbd2cSJim Jagielski 				// bNext and Prev are true, if there are alphabetic letters:
254*b1cdbd2cSJim Jagielski 				sal_Bool bNext =  pInputPosition + 1 != pInputEnd
255*b1cdbd2cSJim Jagielski 									?   CalculateBranch(pInputPosition[1]) >= BR_ALPHABASE
256*b1cdbd2cSJim Jagielski 									: 	sal_False;
257*b1cdbd2cSJim Jagielski 				sal_Bool bPrev = pCurParseNode->Value() >= BR_ALPHABASE;
258*b1cdbd2cSJim Jagielski 
259*b1cdbd2cSJim Jagielski 				if ( bNext && (bPrev || pCurParseNode == dpParsingTreeTop) )
260*b1cdbd2cSJim Jagielski 				{   // case 1. and 7.
261*b1cdbd2cSJim Jagielski 					Handle_Hotkey();
262*b1cdbd2cSJim Jagielski 					continue;
263*b1cdbd2cSJim Jagielski 				}
264*b1cdbd2cSJim Jagielski 				else if  (!bPrev && !bNext)
265*b1cdbd2cSJim Jagielski 				{   // case 5.,6.,8.,9.
266*b1cdbd2cSJim Jagielski 					continue;
267*b1cdbd2cSJim Jagielski 				}
268*b1cdbd2cSJim Jagielski 
269*b1cdbd2cSJim Jagielski 				// Case 2.,3.,4. :
270*b1cdbd2cSJim Jagielski 				// 	so this should be handled as an end of a token.
271*b1cdbd2cSJim Jagielski 			}
272*b1cdbd2cSJim Jagielski 			if (pCurParseNode->TokenType() == WTT_Node::token_to_keep)
273*b1cdbd2cSJim Jagielski 			{
274*b1cdbd2cSJim Jagielski 				Handle_TokenToKeep();
275*b1cdbd2cSJim Jagielski 				return eCurResult;
276*b1cdbd2cSJim Jagielski 			}
277*b1cdbd2cSJim Jagielski 			else
278*b1cdbd2cSJim Jagielski 			{
279*b1cdbd2cSJim Jagielski 				Handle_TokenToTransform();
280*b1cdbd2cSJim Jagielski 				return eCurResult;
281*b1cdbd2cSJim Jagielski 			}	// endif (pCurParseNode->TokenType() == WTT_Node::token_to_keep)
282*b1cdbd2cSJim Jagielski 		} 	// endif (pBranch == 0) else
283*b1cdbd2cSJim Jagielski 	}	// end for
284*b1cdbd2cSJim Jagielski 
285*b1cdbd2cSJim Jagielski 	// If here, the text end is reached
286*b1cdbd2cSJim Jagielski 	if (pCurParseNode->TokenType() == WTT_Node::token_to_keep)
287*b1cdbd2cSJim Jagielski 	{
288*b1cdbd2cSJim Jagielski 		Handle_TokenToKeep();
289*b1cdbd2cSJim Jagielski 		return eCurResult;
290*b1cdbd2cSJim Jagielski 	}
291*b1cdbd2cSJim Jagielski 	else
292*b1cdbd2cSJim Jagielski 	{
293*b1cdbd2cSJim Jagielski 		Handle_TokenToTransform();
294*b1cdbd2cSJim Jagielski 		return eCurResult;
295*b1cdbd2cSJim Jagielski 	}
296*b1cdbd2cSJim Jagielski }
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski ByteString
CurReplacingString() const299*b1cdbd2cSJim Jagielski WordTransTree::CurReplacingString() const
300*b1cdbd2cSJim Jagielski {
301*b1cdbd2cSJim Jagielski 	return pCurParseNode->ReplaceString();
302*b1cdbd2cSJim Jagielski }
303*b1cdbd2cSJim Jagielski 
304*b1cdbd2cSJim Jagielski void
Handle_Hotkey()305*b1cdbd2cSJim Jagielski WordTransTree::Handle_Hotkey()
306*b1cdbd2cSJim Jagielski {
307*b1cdbd2cSJim Jagielski 	if (cCurHotkey == 0) 	// Avoid to replace the first found hotkey by
308*b1cdbd2cSJim Jagielski 	                        //   a later one - though this shouldn't happen anyway.
309*b1cdbd2cSJim Jagielski 	{
310*b1cdbd2cSJim Jagielski 		cCurHotkey = (pInputPosition+1) != pInputEnd ? pInputPosition[1] : 0;
311*b1cdbd2cSJim Jagielski 		cCurHotkeySign = *pInputPosition;
312*b1cdbd2cSJim Jagielski 	}
313*b1cdbd2cSJim Jagielski }
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski void
Handle_TokenToKeep()316*b1cdbd2cSJim Jagielski WordTransTree::Handle_TokenToKeep()
317*b1cdbd2cSJim Jagielski {
318*b1cdbd2cSJim Jagielski 	UINT32 nTokenLength = pInputPosition-pInputCurTokenStart;
319*b1cdbd2cSJim Jagielski 
320*b1cdbd2cSJim Jagielski 	memcpy(pOutputPosition,pInputCurTokenStart,nTokenLength);
321*b1cdbd2cSJim Jagielski 
322*b1cdbd2cSJim Jagielski 	pOutputPosition += nTokenLength;
323*b1cdbd2cSJim Jagielski 	*pOutputPosition = '\0';
324*b1cdbd2cSJim Jagielski }
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski void
Handle_TokenToTransform()327*b1cdbd2cSJim Jagielski WordTransTree::Handle_TokenToTransform()
328*b1cdbd2cSJim Jagielski {
329*b1cdbd2cSJim Jagielski 	sal_Bool bHaveHotkey = CalculateBranch(cCurHotkey) >= BR_ALPHABASE;
330*b1cdbd2cSJim Jagielski 	const ByteString & rReplace = pCurParseNode->ReplaceString();
331*b1cdbd2cSJim Jagielski 
332*b1cdbd2cSJim Jagielski 	// Find position of hotkey in replace-string:
333*b1cdbd2cSJim Jagielski 	sal_uInt16 nHotkeyPos = bHaveHotkey
334*b1cdbd2cSJim Jagielski 							?	rReplace.Search(char(cCurHotkey))
335*b1cdbd2cSJim Jagielski 							:	STRING_NOTFOUND;
336*b1cdbd2cSJim Jagielski 	if (nHotkeyPos == STRING_NOTFOUND && bHaveHotkey)
337*b1cdbd2cSJim Jagielski 	{
338*b1cdbd2cSJim Jagielski 		if (cCurHotkey < 128)
339*b1cdbd2cSJim Jagielski 		{
340*b1cdbd2cSJim Jagielski 			if (islower(cCurHotkey))
341*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(toupper(char(cCurHotkey)));
342*b1cdbd2cSJim Jagielski 			else
343*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(tolower(char(cCurHotkey)));
344*b1cdbd2cSJim Jagielski 		}
345*b1cdbd2cSJim Jagielski 		else	// cCurHotkey >= 128
346*b1cdbd2cSJim Jagielski 		{
347*b1cdbd2cSJim Jagielski 			if (cCurHotkey == c_ae)
348*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_AE));
349*b1cdbd2cSJim Jagielski 			else if (cCurHotkey == c_oe)
350*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_OE));
351*b1cdbd2cSJim Jagielski 			else if (cCurHotkey == c_ue)
352*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_UE));
353*b1cdbd2cSJim Jagielski 			else if (cCurHotkey == c_AE)
354*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_ae));
355*b1cdbd2cSJim Jagielski 			else if (cCurHotkey == c_OE)
356*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_oe));
357*b1cdbd2cSJim Jagielski 			else if (cCurHotkey == c_UE)
358*b1cdbd2cSJim Jagielski 				nHotkeyPos = rReplace.Search(char(c_ue));
359*b1cdbd2cSJim Jagielski 		}	// endif (cCurHotkey < 128) else
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski 		if (nHotkeyPos == STRING_NOTFOUND)
362*b1cdbd2cSJim Jagielski 		{
363*b1cdbd2cSJim Jagielski 			eCurResult = HOTKEY_LOST;
364*b1cdbd2cSJim Jagielski 			bHaveHotkey = sal_False;
365*b1cdbd2cSJim Jagielski 		}
366*b1cdbd2cSJim Jagielski 	} 	// endif (nHotkeyPos == STRING_NOT_FOUND && bHaveHotkey)
367*b1cdbd2cSJim Jagielski 
368*b1cdbd2cSJim Jagielski 
369*b1cdbd2cSJim Jagielski 	UINT32 nOutputTokenLength = rReplace.Len() + (bHaveHotkey ? 1 : 0);
370*b1cdbd2cSJim Jagielski 
371*b1cdbd2cSJim Jagielski 	if (bHaveHotkey)
372*b1cdbd2cSJim Jagielski 	{
373*b1cdbd2cSJim Jagielski 		memcpy( pOutputPosition,
374*b1cdbd2cSJim Jagielski 				pCurParseNode->ReplaceString().GetBuffer(),
375*b1cdbd2cSJim Jagielski 				nHotkeyPos );
376*b1cdbd2cSJim Jagielski 		*(pOutputPosition + nHotkeyPos) = cCurHotkeySign;
377*b1cdbd2cSJim Jagielski 		memcpy( pOutputPosition + nHotkeyPos + 1,
378*b1cdbd2cSJim Jagielski 				pCurParseNode->ReplaceString().GetBuffer() + nHotkeyPos,
379*b1cdbd2cSJim Jagielski 				nOutputTokenLength - nHotkeyPos - 1);
380*b1cdbd2cSJim Jagielski 	}
381*b1cdbd2cSJim Jagielski 	else
382*b1cdbd2cSJim Jagielski 	{
383*b1cdbd2cSJim Jagielski 		memcpy( pOutputPosition,
384*b1cdbd2cSJim Jagielski 				pCurParseNode->ReplaceString().GetBuffer(),
385*b1cdbd2cSJim Jagielski 				nOutputTokenLength );
386*b1cdbd2cSJim Jagielski 	}
387*b1cdbd2cSJim Jagielski 
388*b1cdbd2cSJim Jagielski 	// Convert first letter into upper if necessary:
389*b1cdbd2cSJim Jagielski 	u_char cInStart = CalculateBranch(*pInputCurTokenStart) == BR_HOTKEY
390*b1cdbd2cSJim Jagielski 							? 	pInputCurTokenStart[1]
391*b1cdbd2cSJim Jagielski 							:	pInputCurTokenStart[0] ;
392*b1cdbd2cSJim Jagielski 	u_char * pOutStart = nHotkeyPos == 0
393*b1cdbd2cSJim Jagielski 							? 	pOutputPosition + 1
394*b1cdbd2cSJim Jagielski 							:	pOutputPosition ;
395*b1cdbd2cSJim Jagielski 	if (isupper(cInStart) || cInStart > 127)
396*b1cdbd2cSJim Jagielski 	{   // Possibly cInStart is upper character:
397*b1cdbd2cSJim Jagielski 		if (isupper(cInStart) || cInStart == c_AE || cInStart == c_OE || cInStart == c_UE)
398*b1cdbd2cSJim Jagielski 		{	// Surely cInStart is upper character:
399*b1cdbd2cSJim Jagielski 			u_char cOutStart = *pOutStart;
400*b1cdbd2cSJim Jagielski 			if (cOutStart < 128)
401*b1cdbd2cSJim Jagielski 				*pOutStart = toupper(cOutStart);
402*b1cdbd2cSJim Jagielski 			else if (cOutStart == c_ae)
403*b1cdbd2cSJim Jagielski 				*pOutStart = c_AE;
404*b1cdbd2cSJim Jagielski 			else if (cOutStart == c_oe)
405*b1cdbd2cSJim Jagielski 				*pOutStart = c_OE;
406*b1cdbd2cSJim Jagielski 			else if (cOutStart == c_ue)
407*b1cdbd2cSJim Jagielski 				*pOutStart = c_UE;
408*b1cdbd2cSJim Jagielski 		}
409*b1cdbd2cSJim Jagielski 	}  	// endif (isupper(cInStart) || cInStart > 127)
410*b1cdbd2cSJim Jagielski 
411*b1cdbd2cSJim Jagielski 	pOutputPosition += nOutputTokenLength;
412*b1cdbd2cSJim Jagielski 	*pOutputPosition = '\0';
413*b1cdbd2cSJim Jagielski }
414*b1cdbd2cSJim Jagielski 
415