|
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 // See 6.7 in http://www.ietf.org/rfc/rfc2045.txt |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32svr.h> |
|
19 #include <conarc.h> |
|
20 #include <s32file.h> |
|
21 #include <e32std.h> |
|
22 #include <e32uid.h> |
|
23 #include <u32hal.h> |
|
24 |
|
25 #include "QPCONV.H" |
|
26 |
|
27 // The ASCII character '#' is not encoded into quoted printable format. If it is present along with |
|
28 // the phone number, it gets converted to its corresponding character '=23'. This makes a bit difficult |
|
29 // for the user to identify the exact phone number from a VCard file. Hence the encoding is not performed. |
|
30 |
|
31 #define KLineFeed 10 |
|
32 #define KCarriageReturn 13 |
|
33 #define KEquals '=' |
|
34 #define KSpace ' ' |
|
35 #define KTab 9 |
|
36 #define KExclamationPoint '!' |
|
37 #define KTilde 0x7E |
|
38 #define KDoubleQuotes 0x22 |
|
39 #define KDollarSign 0x24 |
|
40 #define KAtSign 0x40 |
|
41 #define KSquareBracketOpen 0x5B |
|
42 #define KBackSlash 0x5C |
|
43 #define KSquareBracketClose 0x5D |
|
44 #define KCircumflex 0x5E |
|
45 #define KSingleQuote 0x60 |
|
46 #define KCurlyBracketOpen 0x7B |
|
47 #define KOrOperatorSign 0x7C |
|
48 #define KCurlyBracketClose 0x7D |
|
49 #define KQuotedPrintableNewLine _L8("=\r\n") |
|
50 #define KQuotedPrintableCarriageReturn _L8("=0D") |
|
51 #define KQuotedPrintableLineFeed _L8("=0A") |
|
52 |
|
53 // Patchable const data value defined in conarc.cpp |
|
54 IMPORT_C extern const TInt KEnableAllSplCharForQpCnv; |
|
55 |
|
56 |
|
57 // |
|
58 // class CQpToTxtCnv |
|
59 // |
|
60 |
|
61 void CQpToTxtCnv::ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream,MConverterUiObserver* /*aObserver*/) |
|
62 { |
|
63 iReadStream = &aReadStream; |
|
64 iWriteStream = &aWriteStream; |
|
65 |
|
66 iBufferPos = 0; |
|
67 iBuffer.SetMax(); |
|
68 } |
|
69 |
|
70 TBool CQpToTxtCnv::DoConvertL() |
|
71 { |
|
72 // Check if we need to move out the oldest charcter |
|
73 if (iBufferPos == 3) |
|
74 { |
|
75 iBuffer[0] = iBuffer[1]; |
|
76 iBuffer[1] = iBuffer[2]; |
|
77 iBufferPos = 2; |
|
78 } |
|
79 |
|
80 TBuf8<1> character; |
|
81 TRAPD(err, iReadStream->ReadL(character)); |
|
82 if (err == KErrEof) |
|
83 { |
|
84 // Write what we have in the buffer, and exit |
|
85 iWriteStream->WriteL(iBuffer, iBufferPos); |
|
86 return EFalse; |
|
87 } |
|
88 else if (err == KErrNone) |
|
89 { |
|
90 iBuffer[iBufferPos] = character[0]; |
|
91 iBufferPos++; |
|
92 if (iBufferPos == 3) |
|
93 { |
|
94 // Check that we have three characters to compare: |
|
95 if (iBuffer[0] == KEquals) |
|
96 { |
|
97 // Check for special QP codes |
|
98 if (!(iBuffer[1] == KCarriageReturn && iBuffer[2] == KLineFeed)) |
|
99 { |
|
100 // act on the code |
|
101 TLex8 lex(iBuffer); |
|
102 TUint code; |
|
103 (void)lex.Get(); // skip the equals |
|
104 lex.Val(code,EHex); |
|
105 iWriteStream->WriteUint8L(STATIC_CAST(TUint8,code)); |
|
106 } |
|
107 iBufferPos=0; |
|
108 } |
|
109 else if (iBuffer[1] == KCarriageReturn && iBuffer[2] == KLineFeed) |
|
110 { |
|
111 // throw away these characters |
|
112 iBufferPos=0; |
|
113 } |
|
114 else |
|
115 { |
|
116 // Write out the last character in the stream |
|
117 iWriteStream->WriteUint8L(iBuffer[0]); |
|
118 } |
|
119 } |
|
120 } |
|
121 |
|
122 else |
|
123 { |
|
124 // Some other error, let's clear up and go home |
|
125 return EFalse; |
|
126 } |
|
127 return ETrue; |
|
128 } |
|
129 |
|
130 TUid CQpToTxtCnv::Uid() |
|
131 { |
|
132 return KUidQuotedPrintableToText; |
|
133 } |
|
134 |
|
135 TInt CQpToTxtCnv::Capabilities() |
|
136 { |
|
137 return EConvertsObjects; |
|
138 } |
|
139 |
|
140 CQpToTxtCnv::CQpToTxtCnv() |
|
141 {} |
|
142 |
|
143 // |
|
144 // class CTxtToQpCnv |
|
145 // |
|
146 |
|
147 void CTxtToQpCnv::ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream,MConverterUiObserver* /*aObserver*/) |
|
148 { |
|
149 iReadStream = &aReadStream; |
|
150 iWriteStream = &aWriteStream; |
|
151 |
|
152 iLineLen = 0; |
|
153 } |
|
154 |
|
155 TBool CTxtToQpCnv::DoConvertL() |
|
156 { |
|
157 TBuf8<1> character; |
|
158 TRAPD(err, iReadStream->ReadL(character)); |
|
159 if (err == KErrNone) |
|
160 { |
|
161 switch (character[0]) |
|
162 { |
|
163 case KCarriageReturn: |
|
164 iWriteStream->WriteL(KQuotedPrintableCarriageReturn); |
|
165 iLineLen += 3; |
|
166 break; |
|
167 case KLineFeed: |
|
168 iWriteStream->WriteL(KQuotedPrintableLineFeed); |
|
169 iLineLen += 3; |
|
170 break; |
|
171 case KEquals: |
|
172 case KTab: |
|
173 case KSpace: |
|
174 { |
|
175 FormatAndWriteBufferL(character); |
|
176 } |
|
177 break; |
|
178 case KExclamationPoint: |
|
179 case KTilde: |
|
180 case KDoubleQuotes: |
|
181 case KDollarSign: |
|
182 case KAtSign: |
|
183 case KSquareBracketOpen: |
|
184 case KBackSlash: |
|
185 case KSquareBracketClose: |
|
186 case KCircumflex: |
|
187 case KSingleQuote: |
|
188 case KCurlyBracketOpen: |
|
189 case KOrOperatorSign: |
|
190 case KCurlyBracketClose: |
|
191 { |
|
192 if (iEnableAllSplCharForQpCnv) |
|
193 { |
|
194 FormatAndWriteBufferL(character); |
|
195 } |
|
196 else |
|
197 { |
|
198 WriteBufferL(character); |
|
199 } |
|
200 } |
|
201 break; |
|
202 default: |
|
203 if( character[0] > KQuotedPrintableConvertAbove ) |
|
204 { |
|
205 FormatAndWriteBufferL(character); |
|
206 } |
|
207 else |
|
208 { |
|
209 WriteBufferL(character); |
|
210 } |
|
211 break; |
|
212 } |
|
213 |
|
214 // Check to see if the line is getting too long |
|
215 if (iLineLen > 70) |
|
216 { |
|
217 iWriteStream->WriteL(KQuotedPrintableNewLine); |
|
218 iLineLen = 0; |
|
219 } |
|
220 |
|
221 return ETrue; |
|
222 } |
|
223 else |
|
224 { |
|
225 // Exit on end of stream |
|
226 return EFalse; |
|
227 } |
|
228 |
|
229 } |
|
230 |
|
231 void CTxtToQpCnv::FormatAndWriteBufferL(TDes8& aChar) |
|
232 { |
|
233 TBuf8<3> buf; |
|
234 buf.Format(_L8("=%02X"),STATIC_CAST(TUint,aChar[0])); // RFC 2045 states "Uppercase letters must be used; lowercase letters are not allowed", hence the capital 'X' in this format descriptor to the statement |
|
235 iWriteStream->WriteL(buf); |
|
236 iLineLen+=3; |
|
237 } |
|
238 |
|
239 void CTxtToQpCnv::WriteBufferL(TDes8& aChar) |
|
240 { |
|
241 iWriteStream->WriteL(aChar); |
|
242 iLineLen++; |
|
243 } |
|
244 |
|
245 TUid CTxtToQpCnv::Uid() |
|
246 { |
|
247 return KUidTextToQuotedPrintable; |
|
248 } |
|
249 |
|
250 TInt CTxtToQpCnv::Capabilities() |
|
251 { |
|
252 return EConvertsObjects; |
|
253 } |
|
254 |
|
255 CTxtToQpCnv::CTxtToQpCnv():iEnableAllSplCharForQpCnv(KEnableAllSplCharForQpCnv) |
|
256 { |
|
257 #ifdef __WINS__ |
|
258 // KEnableAllSplCharForQpCnv is a Rom patchable constant, so patch for emulator builds can be done by |
|
259 // adding "patchdata_conarc_dll_KEnableAllSplCharForQpCnv X" to epoc.ini file. |
|
260 // When X is set to non zero, the conversion is performed for all the special characters. |
|
261 // When X is set to zero, no conversion is performed in case of the special characters. |
|
262 // Requires licensees to set the patch data value in epoc.ini file. |
|
263 |
|
264 TInt valueOfKEnableAllSplCharForQpCnv = 0; |
|
265 if (UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"patchdata_conarc_dll_KEnableAllSplCharForQpCnv",&valueOfKEnableAllSplCharForQpCnv) == KErrNone) |
|
266 { |
|
267 iEnableAllSplCharForQpCnv = valueOfKEnableAllSplCharForQpCnv; |
|
268 } |
|
269 #endif |
|
270 } |
|
271 |
|
272 |