|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Send/Expect Algorithms |
|
15 // |
|
16 // |
|
17 |
|
18 #include "ATSTD.H" |
|
19 #include "SCHAT.H" |
|
20 #include "mSLOGGER.H" |
|
21 |
|
22 CCommChatString* CCommChatString::NewL(const TDesC8& aDes, TBool aIsPartialLine) |
|
23 { |
|
24 CCommChatString* cs = new (ELeave) CCommChatString; |
|
25 CleanupStack::PushL(cs); |
|
26 cs->CreateL(aDes, aIsPartialLine); |
|
27 CleanupStack::Pop(); |
|
28 return cs; |
|
29 } |
|
30 |
|
31 CCommChatString::CCommChatString() |
|
32 { |
|
33 } |
|
34 |
|
35 CCommChatString::~CCommChatString() |
|
36 { |
|
37 } |
|
38 |
|
39 void CCommChatString::CreateL(const TDesC8& aDes, TBool aIsPartialLine) |
|
40 { |
|
41 iIsPartialLine = aIsPartialLine; |
|
42 iMatch.Set(aDes); |
|
43 } |
|
44 |
|
45 // |
|
46 // CCommChatter |
|
47 // |
|
48 CCommChatter::CCommChatter(MCommChatNotify* aNotify, TInt aPriority) |
|
49 : CTimer(aPriority), iNotify(aNotify) |
|
50 { |
|
51 CActiveScheduler::Add(this); |
|
52 iList.SetOffset(_FOFF(CCommChatString,iLink)); |
|
53 } |
|
54 |
|
55 CCommChatter::~CCommChatter() |
|
56 { |
|
57 DeleteAllAndStop(); |
|
58 User::Free(iBuffer); |
|
59 } |
|
60 |
|
61 void CCommChatter::CreateL(TInt aBufSize) |
|
62 { |
|
63 CTimer::ConstructL(); |
|
64 iBuffer = (TText8*)User::AllocL(aBufSize); |
|
65 iBufferEnd = (iBuffer+aBufSize)-1; |
|
66 ClearBuffer(); |
|
67 } |
|
68 |
|
69 void CCommChatter::ClearBuffer() |
|
70 // |
|
71 // Empty history |
|
72 // |
|
73 { |
|
74 iLastChar = iBuffer; |
|
75 iLineStart = iBuffer; |
|
76 iInDelimiter = ETrue; // as though the last character was the end of a line |
|
77 } |
|
78 |
|
79 void CCommChatter::ClearCurrentLine() |
|
80 // |
|
81 // Remove current line, which is always at the end of the buffer |
|
82 // |
|
83 { |
|
84 iLastChar = iLineStart; |
|
85 iInDelimiter = ETrue; // as though the last character was the end of a line |
|
86 } |
|
87 |
|
88 TPtrC8 CCommChatter::Buffer() const |
|
89 { |
|
90 return TPtrC8(iBuffer, iLastChar-iBuffer); |
|
91 } |
|
92 |
|
93 TPtrC8 CCommChatter::CurrentLine() const |
|
94 { |
|
95 TInt len=iLastChar-iLineStart; |
|
96 if (len>0 && iInDelimiter) |
|
97 len-=1; |
|
98 return TPtrC8(iLineStart, len); |
|
99 } |
|
100 |
|
101 void CCommChatter::AddCharL(TText8 aChar) |
|
102 // |
|
103 // Add a character to the history buffer |
|
104 // Scan all strings to find any matches that may |
|
105 // be completed. |
|
106 // |
|
107 { |
|
108 // Prevent reading of multiple delimiters into buffer |
|
109 if (iInDelimiter && (aChar == '\r' || aChar == '\n')) |
|
110 return; |
|
111 |
|
112 *iLastChar++=aChar; |
|
113 if (iLastChar>=iBufferEnd) |
|
114 { |
|
115 iLastChar = iBufferEnd; // Discarding characters at this point |
|
116 } |
|
117 |
|
118 if (aChar=='\r' || aChar=='\n') |
|
119 { |
|
120 if (iInDelimiter) |
|
121 return; // still in delimiting sequence |
|
122 iInDelimiter=ETrue; |
|
123 } |
|
124 else |
|
125 { |
|
126 if (iInDelimiter) |
|
127 { |
|
128 iInDelimiter=EFalse; |
|
129 iLineStart=iLastChar-1; |
|
130 } |
|
131 if (iPartLineMatchers==0) |
|
132 return; // wait for end of line before trying to match |
|
133 } |
|
134 |
|
135 // Scan for matching expect string |
|
136 |
|
137 TPtrC8 line(CurrentLine()); |
|
138 CCommChatString* cs; |
|
139 TDblQueIter<CCommChatString> iter(iList); |
|
140 |
|
141 if (iInDelimiter) |
|
142 { |
|
143 // Simple match at end of line - test all strings |
|
144 while (cs = iter++, cs!=NULL) |
|
145 { |
|
146 if (line.Match(cs->iMatch)==0) |
|
147 { |
|
148 LOGTEXT2(_L8("SChat:\tFound match against =>%S<"), &cs->iMatch); |
|
149 iNotify->ChatStringMatchL(cs); |
|
150 cs = iter; // In case user removed cs; |
|
151 } |
|
152 } |
|
153 } |
|
154 else |
|
155 { |
|
156 // partial match - use only selected matchers |
|
157 while (cs = iter++, cs!=NULL) |
|
158 { |
|
159 if (cs->iIsPartialLine && line.Match(cs->iMatch)==0) |
|
160 { |
|
161 LOGTEXT2(_L8("SChat:\tFound match against partial line =>%S<"), &cs->iMatch); |
|
162 iNotify->ChatStringMatchL(cs); |
|
163 cs = iter; // In case user removed cs; |
|
164 } |
|
165 } |
|
166 } |
|
167 } |
|
168 |
|
169 void CCommChatter::RunL() |
|
170 { |
|
171 iNotify->ChatTimeout(); |
|
172 } |
|
173 |
|
174 CCommChatString* CCommChatter::AddStringL(const TDesC8& aString, TBool aPartLine) |
|
175 { |
|
176 CCommChatString* chatString=CCommChatString::NewL(aString,aPartLine); |
|
177 iList.AddLast(*chatString); |
|
178 if (aPartLine) |
|
179 iPartLineMatchers+=1; |
|
180 return chatString; |
|
181 } |
|
182 |
|
183 void CCommChatter::RemoveString(CCommChatString* aString) |
|
184 { |
|
185 _LIT(KCCommChatterPanic, "GSMTSY-CHAT"); |
|
186 aString->iLink.Deque(); |
|
187 if (aString->iIsPartialLine) |
|
188 { |
|
189 iPartLineMatchers-=1; |
|
190 __ASSERT_ALWAYS(iPartLineMatchers>=0, User::Panic(KCCommChatterPanic,1)); |
|
191 } |
|
192 } |
|
193 |
|
194 void CCommChatter::DeleteAllAndStop() |
|
195 { |
|
196 StopTimer(); |
|
197 CCommChatString* cs; |
|
198 while (!iList.IsEmpty()) |
|
199 { |
|
200 cs = iList.First(); |
|
201 RemoveString(cs); |
|
202 delete cs; |
|
203 } |
|
204 iPartLineMatchers=0; |
|
205 } |
|
206 |
|
207 void CCommChatter::StartTimer(const TTimeIntervalMicroSeconds32 aTimeout) |
|
208 { |
|
209 if (IsActive()) |
|
210 Cancel(); |
|
211 After(aTimeout); |
|
212 } |
|
213 |
|
214 void CCommChatter::StopTimer() |
|
215 { |
|
216 Cancel(); |
|
217 } |