First public contribution.
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include <wtlsnames.h>
24 _LIT(KWTLSStructuredTextFieldSeparator, ";");
25 _LIT(KWTLSStructuredTextAssignmentCharacter, "=");
26 const TInt KWTLSTextHeaderLength = 3;
28 EXPORT_C CWTLSName* CWTLSName::NewL(const TDesC8& aBinaryData)
31 return CWTLSName::NewL(aBinaryData, pos);
34 EXPORT_C CWTLSName* CWTLSName::NewLC(const TDesC8& aBinaryData)
37 return CWTLSName::NewLC(aBinaryData, pos);
40 EXPORT_C CWTLSName* CWTLSName::NewL(const TDesC8& aBinaryData, TInt& aPos)
42 CWTLSName* self = CWTLSName::NewLC(aBinaryData, aPos);
47 EXPORT_C CWTLSName* CWTLSName::NewLC(const TDesC8& aBinaryData, TInt& aPos)
49 CWTLSName* self = new(ELeave) CWTLSName;
50 CleanupStack::PushL(self);
51 self->ConstructL(aBinaryData, aPos);
55 EXPORT_C CWTLSName* CWTLSName::NewL(const CWTLSName& aName)
57 CWTLSName* self = CWTLSName::NewLC(aName);
62 EXPORT_C CWTLSName* CWTLSName::NewLC(const CWTLSName& aName)
64 CWTLSName* self = new(ELeave) CWTLSName;
65 CleanupStack::PushL(self);
66 self->ConstructL(aName);
70 CWTLSName::CWTLSName()
74 void CWTLSName::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
76 if ((aBinaryData.Length() - aPos) < 1)
78 User::Leave(KErrArgument);
80 iNameType = aBinaryData[aPos];
86 AllocTextDataL(aBinaryData, aPos);
91 AllocNameDataL(aBinaryData, aPos);
96 User::Leave(KErrNotSupported);
101 void CWTLSName::ConstructL(const CWTLSName& aName)
103 iNameType = aName.iNameType;
104 iNameData = aName.iNameData->AllocL();
107 EXPORT_C CWTLSName::~CWTLSName()
112 void CWTLSName::AllocTextDataL(const TDesC8& aBinaryData, TInt& aPos)
114 if ((aBinaryData.Length() - aPos) < KWTLSTextHeaderLength)
116 User::Leave(KErrArgument);
118 TInt nameLength = (aBinaryData[aPos+2] + KWTLSTextHeaderLength);
119 if ((aBinaryData.Length() ) < (aPos+nameLength))
121 User::Leave(KErrArgument);
123 iNameData = aBinaryData.Mid(aPos, nameLength).AllocL();
127 void CWTLSName::AllocNameDataL(const TDesC8& aBinaryData, TInt& aPos)
129 if ((aBinaryData.Length() - aPos) < 1)
131 User::Leave(KErrArgument);
133 TUint8 nameLength = aBinaryData[aPos];
135 if (aBinaryData.Length() - (aPos + nameLength) < 0)
137 User::Leave(KErrArgument);
139 iNameData = aBinaryData.Mid(aPos, nameLength).AllocL();
143 EXPORT_C TBool CWTLSName::ExactMatchL(const CWTLSName& aName) const
145 //hmmm, in the absence of any matching rules, just match the bytes...
146 return (*(iNameData) == *(aName.iNameData));
149 EXPORT_C TWTLSNameType CWTLSName::NameType() const
154 EXPORT_C TPtrC8 CWTLSName::NameData() const
159 EXPORT_C HBufC* CWTLSName::DisplayNameL() const
165 CWTLSStructuredText* sText = NULL;
166 TRAPD(err, sText = CWTLSStructuredText::NewL(*iNameData));
169 if (err != KErrArgument)
175 CWTLSText* text = CWTLSText::NewLC(*iNameData);
176 HBufC* res = text->Name().AllocL();
177 CleanupStack::PopAndDestroy();//text
183 CleanupStack::PushL(sText);
184 HBufC* res = sText->DisplayNameL();
185 CleanupStack::PopAndDestroy();//sText
191 CX500DistinguishedName* dN = CX500DistinguishedName::NewLC(*iNameData);
192 HBufC* res = dN->DisplayNameL();
193 CleanupStack::PopAndDestroy();//dN
198 User::Leave(KErrNotSupported);
199 return NULL;//never gets to here...
204 //************************************************************************//
206 EXPORT_C CWTLSText* CWTLSText::NewL(const TDesC8& aBinaryData)
209 return CWTLSText::NewL(aBinaryData, pos);
212 EXPORT_C CWTLSText* CWTLSText::NewLC(const TDesC8& aBinaryData)
215 return CWTLSText::NewLC(aBinaryData, pos);
218 EXPORT_C CWTLSText* CWTLSText::NewL(const TDesC8& aBinaryData, TInt& aPos)
220 CWTLSText* self = CWTLSText::NewLC(aBinaryData, aPos);
225 EXPORT_C CWTLSText* CWTLSText::NewLC(const TDesC8& aBinaryData, TInt& aPos)
227 CWTLSText* self = new(ELeave) CWTLSText;
228 CleanupStack::PushL(self);
229 self->ConstructL(aBinaryData, aPos);
233 EXPORT_C CWTLSText::~CWTLSText()
238 EXPORT_C TBool CWTLSText::ExactMatchL(const CWTLSText& aName) const
240 //subtle difference between this byte-match and
241 //CWTLSName::ExactMatchL(...) is that this should successfully match 2 names that
242 //are the same which were encoded using different character sets...
243 return (*iName == *(aName.iName));
246 EXPORT_C TPtrC CWTLSText::Name() const
251 EXPORT_C TWTLSCharSet CWTLSText::CharacterSet() const
253 return iCharacterSet;
256 CWTLSText::CWTLSText()
260 void CWTLSText::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
262 if ((aBinaryData.Length() - aPos) < 3)
264 User::Leave(KErrArgument);
266 TWTLSDecUnsignedInteger decInt;
267 iCharacterSet = decInt.DecodeShortL(aBinaryData, aPos, 2);
268 TUint8 nameLength = aBinaryData[aPos];
270 if (aBinaryData.Length() < (aPos + nameLength))
272 User::Leave(KErrArgument);
274 TPtrC8 ptr = aBinaryData.Mid(aPos, nameLength);
275 //only works for latin-1 here...
276 iName = HBufC::NewL(ptr.Length());
277 switch (iCharacterSet)
279 case KWTLSLatin1CharSet://=latin-1
281 TPtr pRes = iName->Des();
286 case KWTLSUTF8CharSet:
288 TPtr pRes = iName->Des();
289 User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(pRes, ptr));
294 User::Leave(KErrNotSupported);
299 TWTLSStructuredTextField::TWTLSStructuredTextField(const TDesC& aType, const TDesC& aValue)
300 :iType(aType), iValue(aValue)
304 EXPORT_C TPtrC TWTLSStructuredTextField::Type() const
309 EXPORT_C TPtrC TWTLSStructuredTextField::Value() const
314 //Structured text class
315 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewL(const TDesC8& aBinaryData)
318 return CWTLSStructuredText::NewL(aBinaryData, pos);
321 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewLC(const TDesC8& aBinaryData)
324 return CWTLSStructuredText::NewLC(aBinaryData, pos);
327 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewL(const TDesC8& aBinaryData, TInt& aPos)
329 CWTLSStructuredText* self = CWTLSStructuredText::NewLC(aBinaryData, aPos);
334 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewLC(const TDesC8& aBinaryData, TInt& aPos)
336 CWTLSStructuredText* self = new(ELeave) CWTLSStructuredText;
337 CleanupStack::PushL(self);
338 self->ConstructL(aBinaryData, aPos);
342 EXPORT_C CWTLSStructuredText::~CWTLSStructuredText()
347 EXPORT_C HBufC* CWTLSStructuredText::DisplayNameL() const
349 if (iFields->Count() > 3)
351 return iFields->At(3).Value().AllocL();
355 return iFields->At(1).Value().AllocL();
359 //accessors for defined fields
360 EXPORT_C TPtrC CWTLSStructuredText::ServiceName() const
362 //construction ensures iFields must have at least 3 elements
363 return iFields->At(0).Value();
366 EXPORT_C TPtrC CWTLSStructuredText::Organization() const
368 //construction ensures iFields must have at least 3 elements
369 return iFields->At(1).Value();
372 EXPORT_C TPtrC CWTLSStructuredText::Country() const
374 //construction ensures iFields must have at least 3 elements
375 return iFields->At(2).Value();
378 EXPORT_C TInt CWTLSStructuredText::Count() const
380 return iFields->Count();
383 EXPORT_C const TWTLSStructuredTextField* CWTLSStructuredText::FieldByName(const TDesC& aType) const
385 TInt count = iFields->Count();
386 for (TInt i = 0; i < count; i++)
388 TWTLSStructuredTextField* field = &(iFields->At(i));
389 if (field->Type() == aType)
397 EXPORT_C const TWTLSStructuredTextField& CWTLSStructuredText::FieldByIndex(TInt aIndex) const
399 return iFields->At(aIndex);
402 CWTLSStructuredText::CWTLSStructuredText()
406 void CWTLSStructuredText::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
408 CWTLSText::ConstructL(aBinaryData, aPos);
409 iFields = new(ELeave) CArrayFixFlat<TWTLSStructuredTextField> (4);
411 TInt end = iName->Length();
412 AddFieldValueL(KWTLSServiceName, pos);
413 AddFieldValueL(KWTLSOrganizationName, pos);
414 AddFieldValueL(KWTLSCountryName, pos);
417 AddFieldValueL(KWTLSCommonName, pos);
425 void CWTLSStructuredText::AddFieldValueL(const TDesC& aFieldName, TInt& aPos)
427 TPtrC startOfData = iName->Right(iName->Length() - aPos);
428 TPtrC value = GetFieldL(startOfData, aPos);
429 TWTLSStructuredTextField field(aFieldName, value);
430 iFields->AppendL(field);
433 void CWTLSStructuredText::AddFieldL(TInt& aPos)
435 TPtrC startOfData = iName->Right(iName->Length() - aPos);
436 TPtrC fieldData = GetFieldL(startOfData, aPos);
437 TInt fieldLength = fieldData.Length();
438 TInt endType = fieldData.FindF(KWTLSStructuredTextAssignmentCharacter);
439 if ((endType == KErrNotFound) || ((endType+1) == fieldLength))
441 User::Leave(KErrArgument);
443 TPtrC type = fieldData.Left(endType);
444 TPtrC value = fieldData.Right( fieldLength - (endType+1) );
445 TWTLSStructuredTextField field(type, value);
446 iFields->AppendL(field);
449 TPtrC CWTLSStructuredText::GetFieldL(TDesC& aString, TInt& aPos)
451 //aString = where we've got up to
452 //aPos = start of this chunk of name data
454 TBool done = GetSubFieldL(aString, length);
457 TPtrC remainder = aString.Right(aString.Length() - (length));
459 done = GetSubFieldL(remainder, increment);
464 //disallow zero-length field values
465 User::Leave(KErrArgument);
468 if (length < aString.Length())
470 //if we're not on the last field, skip the ';' character
473 return aString.Left(length);
476 TBool CWTLSStructuredText::GetSubFieldL(TDesC& aString, TInt& aPos)
478 //fields in structured text are separated by ';'. If this character appears
479 //in the field text it's represented by ';;'. so, the string 'symbian;systems' would
480 //be encoded as 'symbian;;systems'.
482 //starting at the start of aString, this function sets 'aPos' to the position after the
483 //first occurrence of ';' in aString. If the character following ';' is also ';' it returns
484 //EFalse (meaning, this sub-field isn't a whole field), otherwise it returns ETrue.
486 aPos = aString.FindF(KWTLSStructuredTextFieldSeparator);
487 if (aPos == KErrNotFound)
489 aPos = aString.Length();
493 //separator char mustn't be last char
494 if (aPos == (aString.Length() -1))
496 User::Leave(KErrArgument);
500 //if the next char is ';', skip it and return EFalse
501 TPtrC next = aString.Mid(aPos + 1, 1);
502 if (next == KWTLSStructuredTextFieldSeparator)
507 //if it isn't, that's the end of the field