|
1 // Copyright (c) 2003-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 // |
|
15 |
|
16 #include <cfutil.h> |
|
17 #include <cfextras.h> |
|
18 #include <elements/cfmacro.h> |
|
19 #include <cflog.h> |
|
20 #include <cfforwardmsg.h> |
|
21 |
|
22 |
|
23 |
|
24 #ifdef _DEBUG |
|
25 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
26 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
27 _LIT(KSpecAssert_ElemCommsFwcftl, "ElemCommsFwcftl."); |
|
28 #endif |
|
29 |
|
30 using namespace CommsFW; |
|
31 |
|
32 EXPORT_C TInt CCFModuleChannelHandler::Send(const CommsFW::TCFMessage &aMessage) |
|
33 /** Send a message on the outgoing channel, blocks until the message has been sent. |
|
34 The rootserver is expected to run at high priority and retrieve pending messages |
|
35 quickly, also this exchange usually only happens at module startup and shutdown so |
|
36 it can usually be considered safe to block here. |
|
37 @param aMessage Message to send on the outgoing channel. |
|
38 @publishedPartner |
|
39 @released |
|
40 */ |
|
41 { |
|
42 TRequestStatus status; |
|
43 iChannelPair.NotifySpaceAvailable(status); |
|
44 User::WaitForRequest(status); |
|
45 return iChannelPair.Send(aMessage); |
|
46 } |
|
47 |
|
48 EXPORT_C CCFModuleChannelHandler::~CCFModuleChannelHandler() |
|
49 /** D'tor. Dequeues this instance from the active scheduler. |
|
50 @publishedPartner |
|
51 @released |
|
52 */ |
|
53 { |
|
54 Cancel(); |
|
55 } |
|
56 |
|
57 EXPORT_C CCFModuleChannelHandler::CCFModuleChannelHandler(TInt aPriority):CActive(aPriority) |
|
58 /** C'tor. Initialise the parent CActive. |
|
59 @publishedPartner |
|
60 @released |
|
61 */ |
|
62 { |
|
63 // Do nothing |
|
64 } |
|
65 |
|
66 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageDiscover(const CommsFW::TCFDiscoverMsg& aMessage) |
|
67 /** Default implementation of the TCFDiscoverMsg message. It will send a response indicating |
|
68 there is no sub-modules in this module. Should be overridden if sub-modules are present in the module. |
|
69 @param aMessage The Discovery message which has been received from the Rootserver. |
|
70 @publishedPartner |
|
71 @released |
|
72 */ |
|
73 { |
|
74 // Default is no submodules, so we just return KErrNone |
|
75 TCFDiscoverRespMsg resp(aMessage.Identifier(), KErrNone, EFalse); |
|
76 TInt err = Send(resp); |
|
77 if(KErrNone != err) |
|
78 { |
|
79 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageDiscover(): Send returned %d"), err); |
|
80 CFChannelError(err); |
|
81 } |
|
82 } |
|
83 |
|
84 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageBind(const CommsFW::TCFBindMsg& aMessage) |
|
85 /** Default implementation of the TCFBindMsg message. It will send a response indicating |
|
86 there is no submodules to bind to in this module. Should be overridden if sub-modules are present |
|
87 in the module. |
|
88 @param aMessage The Bind message which has been received from the Rootserver. |
|
89 @publishedPartner |
|
90 @released |
|
91 */ |
|
92 { |
|
93 // Default is no submodules, so we just return KErrNotFound |
|
94 TCFBindCompleteMsg resp(aMessage.Identifier(), KErrNotFound); |
|
95 TInt err = Send(resp); |
|
96 if(KErrNone != err) |
|
97 { |
|
98 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageBind(): Send returned %d"), err); |
|
99 CFChannelError(err); |
|
100 } |
|
101 } |
|
102 |
|
103 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageUnbind(const CommsFW::TCFUnbindMsg& aMessage) |
|
104 /** Default implementation of the TCFUnbindMsg message. It will send a response indicating |
|
105 there is no submodules to unbind from in this module. Should be overridden if sub-modules are present |
|
106 in the module. |
|
107 @param aMessage The Unbind message which has been received from the Rootserver. |
|
108 @publishedPartner |
|
109 @released |
|
110 */ |
|
111 { |
|
112 // Default is no submodules, so we just return KErrNotFound |
|
113 TCFUnbindCompleteMsg resp(aMessage.Identifier(), KErrNotFound); |
|
114 TInt err = Send(resp); |
|
115 if(KErrNone != err) |
|
116 { |
|
117 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageUnbind(): Send returned %d"), err); |
|
118 CFChannelError(err); |
|
119 } |
|
120 } |
|
121 |
|
122 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageShutdown(const CommsFW::TCFShutdownMsg& aMessage) |
|
123 /** Default implementation of the TCFShutdownMsg message. it will do nothing. Should be overridden |
|
124 if the module supports Shutdown. |
|
125 @param aMessage The Shutdown message which has been received from the Rootserver. |
|
126 @publishedPartner |
|
127 @released |
|
128 */ |
|
129 { |
|
130 (void) aMessage; // Avoid compiler warnings |
|
131 } |
|
132 |
|
133 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageForward(const CommsFW::TCFForwardMsg& aMessage) |
|
134 /** Default implementation of the CFMessageForward message. it will do nothing. Should be overridden |
|
135 if the module supports Message Forwarding. |
|
136 @param aMessage The Forward message which has been received from the Rootserver. |
|
137 @publishedPartner |
|
138 @released |
|
139 */ |
|
140 { |
|
141 aMessage.Msg().Complete( KErrNotSupported ); |
|
142 } |
|
143 |
|
144 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageUnknown(const CommsFW::TCFMessage& aMessage) |
|
145 /** Default implementation for handling unknown messages. it will do nothing. Should be overridden |
|
146 if the module wants to implement some handling for receiving unknown messages. |
|
147 @param aMessage The message which has been received from the Rootserver. |
|
148 @publishedPartner |
|
149 @released |
|
150 */ |
|
151 { |
|
152 (void) aMessage; // Avoid compiler warnings |
|
153 } |
|
154 |
|
155 EXPORT_C void CCFModuleChannelHandler::ConstructL(CommsFW::RCFChannel::TMsgQueues &aRxQueues, CommsFW::RCFChannel::TMsgQueues &aTxQueues) |
|
156 /** Second level constructor, must be called from derived implementations or the module |
|
157 will PANIC when attempting to use the channels. |
|
158 @param aRxQueues Queues on which to listen for incoming messages. |
|
159 @param aTxQueues Queues on which to send outgoing messages. |
|
160 @publishedPartner |
|
161 @released |
|
162 */ |
|
163 { |
|
164 TInt ret; |
|
165 if((ret = iChannelPair.CreateRecv(aRxQueues)) != KErrNone || |
|
166 (ret = iChannelPair.CreateSend(aTxQueues)) != KErrNone) |
|
167 { |
|
168 User::Leave(ret); |
|
169 } |
|
170 CActiveScheduler::Add(this); |
|
171 SetActive(); |
|
172 iChannelPair.NotifyDataAvailable(*this); |
|
173 } |
|
174 |
|
175 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::DoCancel() |
|
176 /** Cancel function, will be called during destruction. Closes the channels contained. |
|
177 @internalComponent |
|
178 */ |
|
179 { |
|
180 iChannelPair.CancelDataAvailable(); |
|
181 iChannelPair.CloseNonGracefully(); |
|
182 } |
|
183 |
|
184 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFChannelError(TInt aError) |
|
185 /** Called when errors are encountered on using the channels. Does nothing but |
|
186 creating a log entry for [CommsFw,Warning]. Should be overridden if the module |
|
187 wants to supports handling of errors. |
|
188 @param aError The errorcode. |
|
189 @publishedPartner |
|
190 @released |
|
191 */ |
|
192 { |
|
193 // Do nothing is default, maybe instead we should panic? |
|
194 (void) aError; |
|
195 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("ERROR CCFModuleChannelHandler::CFChannelError(%d)!"), aError); |
|
196 } |
|
197 |
|
198 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::RunL() |
|
199 /** Receive a message and register for listening for more data on the incoming channel. |
|
200 wants to supports handling of errors. |
|
201 @internalComponent |
|
202 */ |
|
203 { |
|
204 if (iStatus != KErrNone) |
|
205 { |
|
206 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::RunL(): NotifyDataAvailable returned %d"), iStatus.Int()); |
|
207 CFChannelError(iStatus.Int()); |
|
208 return; |
|
209 } |
|
210 |
|
211 // No error. Take the message from the channel. |
|
212 TCFMessage msg; |
|
213 TInt err(iChannelPair.Receive(msg)); |
|
214 if (KErrNone != err) |
|
215 { |
|
216 __CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::RunL(): Receive returned %d"), iStatus.Int()); |
|
217 CFChannelError(err); |
|
218 return; |
|
219 } |
|
220 |
|
221 switch (msg.Code()) |
|
222 { |
|
223 case TCFCommsMessage::ECodeDiscover: |
|
224 CFMessageDiscover(reinterpret_cast<const TCFDiscoverMsg&>(msg)); |
|
225 break; |
|
226 |
|
227 case TCFCommsMessage::ECodeBind: |
|
228 CFMessageBind(reinterpret_cast<const TCFBindMsg&>(msg)); |
|
229 break; |
|
230 |
|
231 case TCFCommsMessage::ECodeUnbind: |
|
232 CFMessageUnbind(reinterpret_cast<const TCFUnbindMsg&>(msg)); |
|
233 break; |
|
234 |
|
235 case TCFCommsMessage::ECodeShutdown: |
|
236 CFMessageShutdown(reinterpret_cast<const TCFShutdownMsg&>(msg)); |
|
237 break; |
|
238 |
|
239 case TCFCommsMessage::ECodeForward: |
|
240 CFMessageForward(reinterpret_cast<const TCFForwardMsg&>(msg)); |
|
241 break; |
|
242 |
|
243 default: |
|
244 CFMessageUnknown(msg); |
|
245 break; |
|
246 } |
|
247 |
|
248 //Pend again |
|
249 SetActive(); |
|
250 iChannelPair.NotifyDataAvailable(*this); |
|
251 } |
|
252 |
|
253 |
|
254 EXPORT_C TBool CommsFW::GetVarFromIniData(const TDesC8& aIniData, const TDesC8& aSection, const TDesC8& aVarName, TPtrC8& aResult) |
|
255 /** Find a variable's value given a section name and a var name. |
|
256 @param aSection The section to search. |
|
257 @param aVarName The name to find. |
|
258 @param aResult The value. |
|
259 @return Success or fail. |
|
260 */ |
|
261 { |
|
262 __ASSERT_DEBUG(aSection.Length() <= KMaxIniDataSectionNameLength, User::Panic(KSpecAssert_ElemCommsFwcftl, 1)); |
|
263 __ASSERT_DEBUG(aVarName.Length() <= KMaxIniDataSectionNameLength, User::Panic(KSpecAssert_ElemCommsFwcftl, 2)); |
|
264 |
|
265 TBuf8<KMaxIniDataSectionNameLength + 2> sectionToken; // 2 extra chars for [sectionName] |
|
266 TInt sectionStart = 0; |
|
267 TInt sectionLen = 0; // reassure compiler |
|
268 TPtrC8 section; |
|
269 // Sections are optional |
|
270 if(aSection.Length() > 0) |
|
271 { |
|
272 _LIT8(KSectionTokenString,"[%S]"); |
|
273 sectionToken.Format(KSectionTokenString,&aSection); |
|
274 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
275 sectionStart = aIniData.FindF(sectionToken); |
|
276 #else |
|
277 sectionStart = aIniData.Find(sectionToken); |
|
278 #endif |
|
279 if (sectionStart == KErrNotFound) |
|
280 return EFalse; |
|
281 section.Set(aIniData.Mid(sectionStart)); |
|
282 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
283 sectionStart += section.FindF(TPtrC8(_S8("]"))); |
|
284 #else |
|
285 sectionStart += section.Find(TPtrC8(_S8("]"))); |
|
286 #endif |
|
287 if (sectionStart == KErrNotFound) |
|
288 return EFalse; |
|
289 sectionStart++; |
|
290 section.Set(aIniData.Mid(sectionStart)); |
|
291 |
|
292 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
293 sectionLen = section.FindF(TPtrC8(_S8("["))); |
|
294 #else |
|
295 sectionLen = section.Find(TPtrC8(_S8("["))); |
|
296 #endif |
|
297 if (sectionLen == KErrNotFound) |
|
298 sectionLen = section.Length(); |
|
299 } |
|
300 else |
|
301 { |
|
302 sectionLen = aIniData.Length(); |
|
303 } |
|
304 TInt pos = 0; |
|
305 FOREVER |
|
306 { |
|
307 section.Set(aIniData.Mid(sectionStart, sectionLen)); |
|
308 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
309 pos = section.FindF(aVarName); |
|
310 #else |
|
311 pos = section.Find(aVarName); |
|
312 #endif |
|
313 if (pos==KErrNotFound) |
|
314 return EFalse; |
|
315 // Check that the token is at the start of the line, to avoid finding |
|
316 // substrings or commented statements). If it isn't then continue |
|
317 // searching from that point |
|
318 TUint8 precedingChar; |
|
319 if (pos == 0 || |
|
320 (precedingChar = section[pos - 1]) == '\n' || |
|
321 precedingChar == '\r') |
|
322 { |
|
323 break; |
|
324 } |
|
325 sectionStart += (pos + 1); |
|
326 sectionLen -= (pos + 1); |
|
327 } |
|
328 |
|
329 section.Set(section.Mid(pos)); |
|
330 // Found token - now find position of '=' |
|
331 pos = section.Locate('='); |
|
332 if((KErrNotFound==pos) || ((pos+1)==section.Length())) |
|
333 { |
|
334 return EFalse; |
|
335 } |
|
336 |
|
337 // Shrink section to start after'=' |
|
338 TLex8 lex(section.Mid(++pos)); |
|
339 section.Set(section.Mid(pos)); |
|
340 // sectionStart+=pos; |
|
341 |
|
342 // Set length of section to be to end of line or end of file |
|
343 TInt length=section.Locate('\r'); |
|
344 if(length==KErrNotFound) |
|
345 { |
|
346 (void)lex.NextToken(); |
|
347 length=lex.MarkedToken().Length(); |
|
348 } |
|
349 aResult.Set(section.Ptr(), length); |
|
350 return(ETrue); |
|
351 } |
|
352 |
|
353 //@TODO - why Configurator can't move to using same? |
|
354 EXPORT_C TBool CommsFW::GetVarFromIniData(const TDesC8& aIniData, const TDesC8 &aSection, const TDesC8 &aVarName, TInt &aResult) |
|
355 { |
|
356 TPtrC8 ptr; |
|
357 if (CommsFW::GetVarFromIniData(aIniData, aSection, aVarName, ptr)) |
|
358 { |
|
359 TUint32 result; |
|
360 if (CommsFW::ConvertVal(ptr, result)==KErrNone) |
|
361 { |
|
362 aResult = result; |
|
363 return(ETrue); |
|
364 } |
|
365 } |
|
366 return(EFalse); |
|
367 } |
|
368 |
|
369 // |
|
370 // COwnEntryList |
|
371 // |
|
372 |
|
373 EXPORT_C COwnEntryList::TOwnEntry::TOwnEntry(const TParse& aPath, const TEntry& aEntry) |
|
374 { |
|
375 TPtr fullName(iName.Des()); |
|
376 fullName.Copy(aPath.DriveAndPath()); |
|
377 fullName.Append(aEntry.iName); |
|
378 } |
|
379 |
|
380 EXPORT_C COwnEntryList::COwnEntryList(TInt aGranularity) |
|
381 : iArray(aGranularity) |
|
382 { |
|
383 } |
|
384 |
|
385 EXPORT_C COwnEntryList::~COwnEntryList() |
|
386 { |
|
387 iArray.Close(); |
|
388 } |
|
389 |
|
390 /* |
|
391 EXPORT_C COwnEntryList* COwnEntryList::NewL(TInt aGranularity) |
|
392 { |
|
393 COwnEntryList* self = new(ELeave) COwnEntryList(aGranularity); |
|
394 CleanupStack::PushL(self); |
|
395 if(aDir) |
|
396 { |
|
397 self->AddL(*aDir); |
|
398 } |
|
399 CleanupStack::Pop(self); |
|
400 return self; |
|
401 } |
|
402 */ |
|
403 |
|
404 EXPORT_C TInt COwnEntryList::Count() const |
|
405 { |
|
406 return iArray.Count(); |
|
407 } |
|
408 |
|
409 EXPORT_C const COwnEntryList::TOwnEntry& COwnEntryList::operator[](TInt anIndex) const |
|
410 { |
|
411 return iArray[anIndex]; |
|
412 } |
|
413 |
|
414 EXPORT_C void COwnEntryList::AddL(const TOwnEntry& aEntry) |
|
415 { |
|
416 User::LeaveIfError(iArray.Append(aEntry)); |
|
417 } |
|
418 |
|
419 EXPORT_C void COwnEntryList::AddL(const COwnEntryList& aDir) |
|
420 { |
|
421 const TInt cnt = aDir.Count(); |
|
422 for(TInt i = 0; i < cnt; ++i) |
|
423 { |
|
424 AddL(aDir[i]); |
|
425 } |
|
426 } |
|
427 |
|
428 EXPORT_C void COwnEntryList::WildScanAcrossDrivesL(const TDesC& aDir, const TDesC& aFileMask) |
|
429 { |
|
430 iArray.Reset(); |
|
431 TAutoClose<RFs> fs; |
|
432 User::LeaveIfError(fs.iObj.Connect()); |
|
433 fs.PushL(); |
|
434 TFindFile ff(fs.iObj); |
|
435 TParse fullEntry; |
|
436 CDir* dir; |
|
437 if(ff.FindWildByDir(aFileMask, aDir, dir) == KErrNone) |
|
438 { |
|
439 do |
|
440 { |
|
441 const TInt cnt = dir->Count(); |
|
442 for(TInt i = 0; i < cnt; ++i) |
|
443 { |
|
444 const TEntry& entry = (*dir)[i]; |
|
445 fullEntry.Set(entry.iName, &ff.File(), NULL); |
|
446 AddL(TOwnEntry(fullEntry, entry)); |
|
447 } |
|
448 delete dir; |
|
449 } |
|
450 while(ff.FindWild(dir) == KErrNone); |
|
451 } |
|
452 fs.Pop(); |
|
453 } |
|
454 |
|
455 EXPORT_C void COwnEntryList::UniqueWildScanAcrossDrivesL(const TDesC& aDir, const TDesC& aFileMask) |
|
456 /** |
|
457 * Function is used to scan unique files from drives starting from Y: to A: then last Z:. The scanning |
|
458 * is done by module name.Files with unique name module name will be scanned.This function is used by Rootserver to |
|
459 * scan cmi files unique by name.It can be used by other internal components for the similar use. |
|
460 * |
|
461 * @internalComponent |
|
462 */ |
|
463 { |
|
464 iArray.Reset(); |
|
465 TAutoClose<RFs> fs; |
|
466 User::LeaveIfError(fs.iObj.Connect()); |
|
467 fs.PushL(); |
|
468 TFindFile ff(fs.iObj); |
|
469 TParse fullEntry; |
|
470 CDir* dir; |
|
471 RArray<TEntry> files; |
|
472 TBool found; |
|
473 if(ff.FindWildByDir(aFileMask, aDir, dir) == KErrNone) |
|
474 { |
|
475 do |
|
476 { |
|
477 const TInt cnt = dir->Count(); |
|
478 for(TInt i = 0; i < cnt; ++i) |
|
479 { |
|
480 const TEntry& entry = (*dir)[i]; |
|
481 if(files.Count()!=0) |
|
482 { |
|
483 found = EFalse; |
|
484 for( TInt Index=0;Index<files.Count();Index++) |
|
485 { |
|
486 if(files[Index].iName.CompareF(entry.iName)==0) |
|
487 { |
|
488 found = ETrue; |
|
489 } |
|
490 } |
|
491 if(!found) |
|
492 { |
|
493 files.Append(entry); |
|
494 fullEntry.Set(entry.iName, &ff.File(), NULL); |
|
495 AddL(TOwnEntry(fullEntry, entry)); |
|
496 } |
|
497 } |
|
498 else |
|
499 { |
|
500 files.Append(entry); |
|
501 fullEntry.Set(entry.iName, &ff.File(), NULL); |
|
502 AddL(TOwnEntry(fullEntry, entry)); |
|
503 } |
|
504 |
|
505 } |
|
506 delete dir; |
|
507 |
|
508 } |
|
509 while(ff.FindWild(dir) == KErrNone); |
|
510 } |
|
511 files.Close(); |
|
512 fs.Pop(); |
|
513 } |
|
514 |
|
515 // |
|
516 // class RCFHeap |
|
517 // |
|
518 |
|
519 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE) |
|
520 |
|
521 void RCFSharedHeap::WalkFunc(TAny* aContext, TCellType aType, TAny* aBase, TInt /*aSize*/) |
|
522 { |
|
523 (void)aBase; |
|
524 if(aType == EGoodAllocatedCell) |
|
525 { |
|
526 TLogInfo* logInfo = reinterpret_cast<TLogInfo*>(aContext); |
|
527 __CFLOG_VAR((logInfo->iSubSystem, logInfo->iComponent, _L8(" 0x%x"), (TUint) aBase + (TUint) RHeap::EAllocCellSize)); |
|
528 |
|
529 #ifdef SYMBIAN_TRACE_ENABLE |
|
530 TLogTextBuf buf; |
|
531 TBool loggingSuccess = EFalse; |
|
532 if(logInfo->iSubSystem.Length() < KMaxLogTextLength) |
|
533 { |
|
534 buf.Append(logInfo->iSubSystem); |
|
535 _LIT8(KSpace, " "); |
|
536 if(buf.Length() + KSpace().Length() < KMaxLogTextLength) |
|
537 { |
|
538 buf.Append(KSpace); |
|
539 if(buf.Length() + logInfo->iComponent.Length() < KMaxLogTextLength) |
|
540 { |
|
541 buf.Append(logInfo->iComponent); |
|
542 if(buf.Length() + KSpace().Length() < KMaxLogTextLength) |
|
543 { |
|
544 buf.Append(KSpace); |
|
545 _LIT8(KHexNumberFormat, " 0x%x"); |
|
546 buf.AppendFormatIgnoreOverflow(KHexNumberFormat, (TUint) aBase + (TUint) RHeap::EAllocCellSize); |
|
547 loggingSuccess = UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, 0, buf.Ptr(), buf.Length()); |
|
548 } |
|
549 } |
|
550 } |
|
551 } |
|
552 if(loggingSuccess == EFalse) //May happen if buffer length exceeds KMaxLogTextLength due to longer names of logInfo->iSubSystem and/or logInfo->iComponent |
|
553 //Atleast the below log helps to identify that there is a leak |
|
554 { |
|
555 _LIT8(KCantLogNames, "??? ??? 0x%x"); //Atleast this should fit |
|
556 buf.Zero(); |
|
557 buf.AppendFormatIgnoreOverflow(KCantLogNames, (TUint) aBase + (TUint) RHeap::EAllocCellSize); |
|
558 loggingSuccess = UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, 0, buf.Ptr(), buf.Length()); |
|
559 } |
|
560 #endif //SYMBIAN_TRACE_ENABLE |
|
561 } |
|
562 } |
|
563 |
|
564 #endif //defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE) |
|
565 |
|
566 EXPORT_C TInt RCFSharedHeap::AccessCount() const |
|
567 { |
|
568 return iAccessCount; |
|
569 } |
|
570 |
|
571 EXPORT_C void RCFSharedHeap::LogAllocatedCells(const TDesC8& aSubSystem, const TDesC8& aComponent) |
|
572 { |
|
573 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE) |
|
574 TLogInfo logInfo(aSubSystem, aComponent); |
|
575 DebugFunction(EWalk, (TAny*)WalkFunc, &logInfo); |
|
576 #else |
|
577 (void) aSubSystem; |
|
578 (void) aComponent; |
|
579 #endif |
|
580 } |
|
581 |
|
582 |
|
583 // |
|
584 // Other utils |
|
585 // |
|
586 |
|
587 namespace CommsFW |
|
588 { |
|
589 |
|
590 EXPORT_C TInt ConvertVal(const TDesC8& aVar, TUint32& aResult) |
|
591 { |
|
592 TPtrC8 ptr(aVar); |
|
593 TRadix radix; |
|
594 _LIT8(KHexPrefix, "0x"); |
|
595 if(ptr.Left(2).CompareF(KHexPrefix) == 0) |
|
596 { |
|
597 ptr.Set(ptr.Mid(2)); |
|
598 radix = EHex; |
|
599 } |
|
600 else |
|
601 { |
|
602 radix = EDecimal; |
|
603 } |
|
604 TLex8 lex(ptr); |
|
605 TUint32 result; |
|
606 TInt err = lex.Val(result, radix); |
|
607 if (err==KErrNone) |
|
608 { |
|
609 aResult = result; |
|
610 } |
|
611 return err; |
|
612 } |
|
613 |
|
614 EXPORT_C TInt ConvertVal(const TDesC8& aVar, TUint16& aResult) |
|
615 { |
|
616 TUint32 result = 0xFFFFFFFF; |
|
617 TInt err = ConvertVal(aVar, result); |
|
618 if (err==KErrNone && result<=0xFFFF) |
|
619 { |
|
620 aResult = result; |
|
621 } |
|
622 return err; |
|
623 } |
|
624 |
|
625 } |
|
626 |
|
627 |