| author | Sebastian Brannstrom <sebastianb@symbian.org> | 
| Wed, 28 Jul 2010 14:18:09 +0100 | |
| branch | RCL_3 | 
| changeset 138 | 31659d49b2e7 | 
| parent 112 | 004508c4f714 | 
| permissions | -rw-r--r-- | 
| 2 | 1 | /* | 
| 2 | * Copyright (c) 2007-2010 Sebastian Brannstrom, Lars Persson, EmbedDev AB | |
| 3 | * | |
| 4 | * All rights reserved. | |
| 5 | * This component and the accompanying materials are made available | |
| 6 | * under the terms of the License "Eclipse Public License v1.0" | |
| 7 | * which accompanies this distribution, and is available | |
| 8 | * at the URL "http://www.eclipse.org/legal/epl-v10.html". | |
| 9 | * | |
| 10 | * Initial Contributors: | |
| 11 | * EmbedDev AB - initial contribution. | |
| 12 | * | |
| 13 | * Contributors: | |
| 14 | * | |
| 15 | * Description: | |
| 16 | * | |
| 17 | */ | |
| 18 | ||
| 19 | #include <e32std.h> | |
| 20 | #include <e32base.h> | |
| 21 | #include <TXTETEXT.H> // for ELineBreak | |
| 22 | #include "PodcastUtils.h" | |
| 23 | #include "debug.h" | |
| 24 | #include "FeedEngine.h" // for KMaxDescriptionLength | |
| 25 | ||
| 26 | EXPORT_C void PodcastUtils::FixProtocolsL(TDes &aUrl) | |
| 27 | 	{
 | |
| 28 | HBufC* urlCopy = aUrl.AllocLC(); | |
| 29 | TPtr urlCopyPtr (urlCopy->Des()); | |
| 30 | urlCopyPtr.LowerCase(); | |
| 31 | ||
| 32 | // url is always present so access that | |
| 33 | // Some pod links are written in format itpc://mylink.net/podcast.xml | |
| 34 | // Symbian HTTP stack does not like itpc:// | |
| 35 | // Try to use a HTTP instead. | |
| 36 | TInt p = urlCopyPtr.Find(KItpcPrefix); | |
| 37 | if (p >= 0) | |
| 38 | 		{
 | |
| 39 | aUrl.Delete(p, KItpcPrefix().Length()); | |
| 40 | } | |
| 41 | ||
| 42 | // Some pod links are written in format pcast://mylink.net/podcast.xml | |
| 43 | // Symbian HTTP stack does not like itpc:// | |
| 44 | // Try to use a HTTP instead. | |
| 45 | p = urlCopyPtr.Find(KPcastPrefix); | |
| 46 | if (p >= 0) | |
| 47 | 		{
 | |
| 48 | aUrl.Delete(p, KPcastPrefix().Length()); | |
| 49 | } | |
| 50 | ||
| 51 | // The URL must start with http://, otherwise the HTTP stack fails. | |
| 52 | TInt pos = urlCopyPtr.Find(KURLPrefix); | |
| 53 | if (pos == KErrNotFound) | |
| 54 | 		{
 | |
| 55 | HBufC* newUrl = HBufC::NewL(aUrl.Length() + KURLPrefix().Length()); | |
| 56 | TPtr ptr = newUrl->Des(); | |
| 57 | ptr.Append(KURLPrefix()); | |
| 58 | ptr.Append(aUrl); | |
| 59 | ||
| 60 | // replace the url buffer | |
| 61 | aUrl.Copy(*newUrl); | |
| 62 | delete newUrl; | |
| 63 | } | |
| 64 | ||
| 65 | CleanupStack::PopAndDestroy(urlCopy); | |
| 66 | } | |
| 67 | ||
| 68 | ||
| 69 | EXPORT_C void PodcastUtils::CleanHtmlL(TDes &str) | |
| 70 | {
 | |
| 21 | 71 | |
| 72 | if (str.Length() == 0) | |
| 73 | 		{
 | |
| 74 | return; | |
| 75 | } | |
| 76 | ||
| 18 | 77 | // miscellaneous cleanup | 
| 2 | 78 | const TChar KLineBreak(CEditableText::ELineBreak); | 
| 79 | _LIT(KNewLine, "\n"); | |
| 19 | 80 | _LIT(KNewLineWindows, "\r\n"); | 
| 2 | 81 | ReplaceString(str, KNewLine, KNullDesC); | 
| 19 | 82 | ReplaceString(str, KNewLineWindows, KNullDesC); | 
| 18 | 83 | |
| 84 | // strip out HTML tags | |
| 85 | ||
| 2 | 86 | 	TInt startPos = str.Locate('<');
 | 
| 87 | 	TInt endPos = str.Locate('>');
 | |
| 88 | HBufC* tmpBuf = HBufC::NewLC(KMaxDescriptionLength); | |
| 89 | TPtr tmp(tmpBuf->Des()); | |
| 90 | 	while (startPos != KErrNotFound && endPos != KErrNotFound && endPos > startPos) {
 | |
| 91 | 		//DP1("Cleaning out %S", &str.Mid(startPos, endPos-startPos+1));
 | |
| 92 | tmp.Copy(str.Left(startPos)); | |
| 93 | TPtrC ptr=str.Mid(startPos, endPos-startPos+1); | |
| 94 | _LIT(KHtmlBr, "<br>"); | |
| 95 | _LIT(KHtmlBr2, "<br />"); | |
| 96 | _LIT(KHtmlBr3, "<br/>"); | |
| 97 | _LIT(KHtmlP, "<p>"); | |
| 98 | if (ptr.CompareF(KHtmlBr)== 0 || ptr.CompareF(KHtmlBr2)== 0 || ptr.CompareF(KHtmlBr3)== 0) | |
| 99 | 			{
 | |
| 100 | tmp.Append(KLineBreak); | |
| 101 | } | |
| 102 | else if (ptr.CompareF(KHtmlP) == 0) | |
| 103 | 			{
 | |
| 104 | tmp.Append(KLineBreak); | |
| 105 | tmp.Append(KLineBreak); | |
| 106 | } | |
| 107 | ||
| 108 | 		if (str.Length() > endPos+1) {
 | |
| 109 | tmp.Append(str.Mid(endPos+1)); | |
| 110 | } | |
| 111 | ||
| 112 | str.Copy(tmp); | |
| 113 | 		startPos = str.Locate('<');
 | |
| 114 | 		endPos = str.Locate('>');
 | |
| 115 | } | |
| 18 | 116 | |
| 117 | // change HTML encoded chars to unicode | |
| 118 | 	startPos = str.Locate('&');
 | |
| 119 | 	endPos = str.Locate(';');
 | |
| 120 | while (startPos != KErrNotFound && endPos != KErrNotFound && endPos > startPos) | |
| 121 | 		{
 | |
| 122 | TPtrC ptr(str.Mid(startPos+1, endPos-startPos)); | |
| 123 | // check for whitespace | |
| 124 | 		if (ptr.Locate(' ') == KErrNotFound)
 | |
| 125 | 			{
 | |
| 126 | // numerical constant | |
| 127 | if (ptr[0] == '#') | |
| 128 | 				{ 
 | |
| 129 | TUint length = endPos - startPos; | |
| 130 | if (length > 2) | |
| 131 | 					{
 | |
| 132 | tmp.Copy(str.Left(startPos)); | |
| 133 | ptr.Set(str.Mid(startPos+2, length-2)); | |
| 134 | ||
| 135 | TUint charCode = 0; | |
| 136 | ||
| 137 | if (ptr[0] == 'x') | |
| 138 | 						{
 | |
| 139 | // hexadecimal | |
| 140 | ptr.Set(ptr.Mid(1)); | |
| 141 | TLex16 lex(ptr); | |
| 142 | lex.Val(charCode, EHex); | |
| 143 | } | |
| 144 | else | |
| 145 | 						{
 | |
| 146 | //decimal | |
| 147 | TLex16 lex(ptr); | |
| 148 | lex.Val(charCode, EDecimal); | |
| 149 | } | |
| 150 | ||
| 151 | TChar charChar(charCode); | |
| 152 | tmp.Append(charChar); | |
| 153 | tmp.Append(str.Mid(endPos+1)); | |
| 154 | str.Copy(tmp); | |
| 155 | } | |
| 156 | } | |
| 157 | // literal constant | |
| 158 | else | |
| 159 | 				{
 | |
| 160 | _LIT(KAmp, "amp;"); | |
| 161 | _LIT(KQuot, "quot;"); | |
| 162 | _LIT(KNbsp, "nbsp;"); | |
| 163 | _LIT(KCopy, "copy;"); | |
| 164 | ||
| 165 | // copy start of string | |
| 166 | tmp.Copy(str.Left(startPos)); | |
| 167 | ||
| 168 | if (ptr.CompareF(KAmp) == 0) | |
| 169 | 					{
 | |
| 170 | 					tmp.Append('&');
 | |
| 171 | } | |
| 172 | else if (ptr.CompareF(KQuot) == 0) | |
| 173 | 					{
 | |
| 174 | 					tmp.Append('"');
 | |
| 175 | } | |
| 176 | else if (ptr.CompareF(KNbsp) == 0) | |
| 177 | 					{
 | |
| 178 | 					tmp.Append(' ');
 | |
| 179 | } | |
| 180 | else if (ptr.CompareF(KCopy) == 0) | |
| 181 | 					{
 | |
| 182 | 					tmp.Append('\xA9');
 | |
| 183 | } | |
| 184 | ||
| 185 | // copy end of string | |
| 186 | tmp.Append(str.Mid(endPos+1)); | |
| 187 | str.Copy(tmp); | |
| 188 | } | |
| 189 | } | |
| 190 | ||
| 191 | 		TInt newPos = str.Mid(startPos+1).Locate('&');
 | |
| 192 | ||
| 193 | if (newPos != KErrNotFound) | |
| 194 | 			{
 | |
| 195 | startPos = startPos+1 + newPos; | |
| 196 | 			endPos = str.Locate(';');
 | |
| 197 | } | |
| 198 | else | |
| 199 | 			{
 | |
| 200 | startPos = KErrNotFound; | |
| 201 | endPos = KErrNotFound; | |
| 202 | } | |
| 203 | } | |
| 204 | ||
| 2 | 205 | CleanupStack::PopAndDestroy(tmpBuf); | 
| 19 | 206 | |
| 112 | 207 | if(str.Length()>1) | 
| 208 | 		{
 | |
| 209 | // chop away newlines at start | |
| 210 | 		while ((str[0] == KLineBreak) )  {
 | |
| 211 | str = str.Mid(1); | |
| 212 | } | |
| 213 | ||
| 214 | // chop away newlines at end | |
| 19 | 215 | |
| 112 | 216 | 		while ((str[str.Length()-1] == KLineBreak)) {
 | 
| 217 | str = str.Left(str.Length()-1); | |
| 218 | } | |
| 19 | 219 | |
| 112 | 220 | str.Trim(); | 
| 221 | } | |
| 2 | 222 | } | 
| 223 | ||
| 15 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 224 | EXPORT_C void PodcastUtils::RemoveAllFormatting(TDes & aString) | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 225 | 	{
 | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 226 | // check for combination first so we prevent adding two spaces | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 227 | 	ReplaceString(aString,_L("\r\n"), _L(" "));
 | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 228 | |
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 229 | 	ReplaceString(aString,_L("\n"), _L(" "));
 | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 230 | 	ReplaceString(aString,_L("\r"), _L(" "));
 | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 231 | |
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 232 | } | 
| 
93d9f66bf50b
Cleaning description better for second line in search results
 teknolog parents: 
2diff
changeset | 233 | |
| 2 | 234 | EXPORT_C void PodcastUtils::ReplaceString(TDes & aString, const TDesC& aStringToReplace, const TDesC& aReplacement) | 
| 235 | 	{
 | |
| 236 | TInt pos=aString.Find(aStringToReplace); | |
| 237 | TInt offset = 0; | |
| 238 | while (pos != KErrNotFound) | |
| 239 | 		{
 | |
| 240 | aString.Replace(offset+pos, aStringToReplace.Length(), aReplacement); | |
| 241 | offset += pos + aStringToReplace.Length()+1; | |
| 242 | if (offset > aString.Length()) | |
| 243 | 			{
 | |
| 244 | return; | |
| 245 | } | |
| 246 | ||
| 247 | pos=aString.Mid(offset).Find(aStringToReplace); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | EXPORT_C void PodcastUtils::ReplaceChar(TDes & aString, TUint aCharToReplace, TUint aReplacement) | |
| 252 | 	{
 | |
| 253 | TInt strLen=aString.Length(); | |
| 254 | for (TInt i=0; i < strLen; i++) | |
| 255 | 		{
 | |
| 256 | if (aString[i] == aCharToReplace) | |
| 257 | 			{
 | |
| 258 | aString[i] = aReplacement; | |
| 259 | } | |
| 260 | } | |
| 261 | } | |
| 262 | ||
| 263 | EXPORT_C void PodcastUtils::EnsureProperPathName(TFileName &aPath) | |
| 264 | 	{
 | |
| 265 | // from the SDK: The following characters cannot occur in the path: < >: " / |* | |
| 266 | ||
| 267 | ReplaceChar(aPath, '/', '_'); // better not to add \\ in case we have multiple / | |
| 268 | ReplaceChar(aPath, ':', '_'); | |
| 269 | ReplaceChar(aPath, '?', '_'); | |
| 270 | ReplaceChar(aPath, '|', '_'); | |
| 271 | ReplaceChar(aPath, '*', '_'); | |
| 272 | ReplaceChar(aPath, '<', '_'); | |
| 273 | ReplaceChar(aPath, '>', '_'); | |
| 274 | ReplaceChar(aPath, '"', '_'); | |
| 275 | ||
| 276 | 	//buf.Append(_L("\\"));
 | |
| 277 | } | |
| 278 | ||
| 279 | EXPORT_C void PodcastUtils::FileNameFromUrl(const TDesC& aUrl, TFileName &aFileName) | |
| 280 | 	{
 | |
| 281 | 	TInt pos = aUrl.LocateReverse('/');
 | |
| 282 | ||
| 283 | if (pos != KErrNotFound) | |
| 284 | 		{	
 | |
| 285 | TPtrC str = aUrl.Mid(pos+1); | |
| 286 | 		pos = str.Locate('?');
 | |
| 287 | if (pos != KErrNotFound) | |
| 288 | 			{
 | |
| 289 | aFileName.Copy(str.Left(pos)); | |
| 290 | } | |
| 291 | else | |
| 292 | 			{
 | |
| 293 | aFileName.Copy(str); | |
| 294 | } | |
| 295 | } | |
| 296 | 	DP2("FileNameFromUrl in: %S, out: %S", &aUrl, &aFileName);
 | |
| 297 | } | |
| 298 | ||
| 299 | EXPORT_C void PodcastUtils::SQLEncode(TDes &aString) | |
| 300 | 	{
 | |
| 301 | 	ReplaceString(aString, _L("\""), _L("\"\""));
 | |
| 302 | 	//ReplaceString(aString, _L("'"), _L("''"));	
 | |
| 303 | } | |
| 304 | ||
| 305 | EXPORT_C void PodcastUtils::XMLEncode(TDes &aString) | |
| 306 | 	{
 | |
| 307 | 	ReplaceString(aString, _L("\""), _L("""));	
 | |
| 308 | 	ReplaceString(aString, _L("<"), _L("<"));
 | |
| 309 | 	ReplaceString(aString, _L(">"), _L(">"));
 | |
| 310 | 	ReplaceString(aString, _L("&"), _L("&"));
 | |
| 311 | } | |
| 90 | 312 | |
| 313 | EXPORT_C TBool PodcastUtils::IsVideoShow(TDesC &aUrl) | |
| 314 | 	{
 | |
| 315 | if (aUrl.Find(KVideoFormat1) != KErrNotFound || | |
| 316 | aUrl.Find(KVideoFormat2) != KErrNotFound || | |
| 317 | aUrl.Find(KVideoFormat3) != KErrNotFound) | |
| 318 | 		{
 | |
| 319 | return ETrue; | |
| 320 | } | |
| 321 | ||
| 322 | return EFalse; | |
| 323 | } |