public static void _Tests(cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cQuotedPrintableDecoder), nameof(_Tests)); if (LTest("testNow's the time = \r\n", "for all folk to come=\t \t \r\n", " to the aid of their country. \t\r\n") != "Now's the time for all folk to come to the aid of their country.\r\n") { throw new cTestsException($"{nameof(cQuotedPrintableDecoder)}.1"); } string LTest(params string[] pLines) { var lMC = new cMethodControl(-1, System.Threading.CancellationToken.None); var lWriteSizer = new cBatchSizer(new cBatchSizerConfiguration(1, 10, 1000, 1)); using (var lStream = new MemoryStream()) { cDecoder lDecoder = new cQuotedPrintableDecoder(lStream); int lOffset = 4; foreach (var lLine in pLines) { lDecoder.WriteAsync(lMC, new cBytes(lLine), lOffset, lWriteSizer, lContext).Wait(); lOffset = 0; } lDecoder.FlushAsync(lMC, lWriteSizer, lContext).Wait(); return(new string(System.Text.Encoding.UTF8.GetChars(lStream.GetBuffer(), 0, (int)lStream.Length))); } } }
private async Task ZFetchBodyAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUID pUID, iMessageHandle pMessageHandle, cSection pSection, eDecodingRequired pDecoding, Stream pStream, cProgress pProgress, cBatchSizer pWriteSizer, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchBodyAsync), pMC, pMailboxHandle, pUID, pMessageHandle, pSection, pDecoding); if (pSection == null) { throw new ArgumentNullException(nameof(pSection)); } if (pStream == null) { throw new ArgumentNullException(nameof(pStream)); } if (pProgress == null) { throw new ArgumentNullException(nameof(pProgress)); } if (pWriteSizer == null) { throw new ArgumentNullException(nameof(pWriteSizer)); } if (!pStream.CanWrite) { throw new ArgumentOutOfRangeException(nameof(pStream)); } // work out if binary can/should be used or not bool lBinary = _Capabilities.Binary && pSection.TextPart == eSectionTextPart.all && pDecoding != eDecodingRequired.none; cDecoder lDecoder; if (lBinary || pDecoding == eDecodingRequired.none) { lDecoder = new cIdentityDecoder(pStream); } else if (pDecoding == eDecodingRequired.base64) { lDecoder = new cBase64Decoder(pStream); } else if (pDecoding == eDecodingRequired.quotedprintable) { lDecoder = new cQuotedPrintableDecoder(pStream); } else { throw new cContentTransferDecodingException("required decoding not supported", lContext); } uint lOrigin = 0; Stopwatch lStopwatch = new Stopwatch(); while (true) { int lLength = mFetchBodyReadSizer.Current; lStopwatch.Restart(); cBody lBody; if (pUID == null) { lBody = await ZFetchBodyAsync(pMC, pMessageHandle, lBinary, pSection, lOrigin, (uint)lLength, lContext).ConfigureAwait(false); } else { lBody = await ZUIDFetchBodyAsync(pMC, pMailboxHandle, pUID, lBinary, pSection, lOrigin, (uint)lLength, lContext).ConfigureAwait(false); } lStopwatch.Stop(); // store the time taken so the next fetch is a better size mFetchBodyReadSizer.AddSample(lBody.Bytes.Count, lStopwatch.ElapsedMilliseconds); uint lBodyOrigin = lBody.Origin ?? 0; // the body that we get may start before the place that we asked for int lOffset = (int)(lOrigin - lBodyOrigin); // write the bytes await lDecoder.WriteAsync(pMC, lBody.Bytes, lOffset, pWriteSizer, lContext).ConfigureAwait(false); // update progress pProgress.Increment(lBody.Bytes.Count - lOffset, lContext); // if the body we got was the whole body, we are done if (lBody.Origin == null) { break; } // if we got less bytes than asked for then we will assume that we are at the end if (lBody.Bytes.Count - lOffset < lLength) { break; } // set the start point for the next fetch lOrigin = lBodyOrigin + (uint)lBody.Bytes.Count; } await lDecoder.FlushAsync(pMC, pWriteSizer, lContext).ConfigureAwait(false); }