internal Task UIDFetchAsync(iMailboxHandle pMailboxHandle, cUID pUID, cSection pSection, eDecodingRequired pDecoding, Stream pStream, cBodyFetchConfiguration pConfiguration) { // note: if it fails bytes could have been written to the stream var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(UIDFetchAsync)); return(ZUIDFetchBodyAsync(pMailboxHandle, pUID, pSection, pDecoding, pStream, pConfiguration, lContext)); }
internal cMessageBodyPart(cSection pSection, cBodyStructureParameters pParameters, string pContentId, cCulturedString pDescription, string pContentTransferEncoding, uint pSizeInBytes, cEnvelope pEnvelope, cBodyPart pBody, cBodyPart pBodyStructure, uint pSizeInLines, cSinglePartExtensionData pExtensionData) : base(kMimeType.Message, kMimeSubType.RFC822, pSection, pParameters, pContentId, pDescription, pContentTransferEncoding, pSizeInBytes, pExtensionData) { Envelope = pEnvelope; mBody = pBody; BodyStructure = pBodyStructure; SizeInLines = pSizeInLines; }
internal cMultiPartBody(IList <cBodyPart> pParts, string pSubType, cSection pSection, cMultiPartExtensionData pExtensionData) : base(kMimeType.Multipart, pSubType, pSection) { Parts = new cBodyParts(pParts); if (SubType.Equals("MIXED", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eMultiPartBodySubTypeCode.mixed; } else if (SubType.Equals("DIGEST", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eMultiPartBodySubTypeCode.digest; } else if (SubType.Equals("ALTERNATIVE", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eMultiPartBodySubTypeCode.alternative; } else if (SubType.Equals("RELATED", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eMultiPartBodySubTypeCode.related; } else { SubTypeCode = eMultiPartBodySubTypeCode.other; } ExtensionData = pExtensionData; }
internal cSinglePartBody(string pType, string pSubType, cSection pSection, cBodyStructureParameters pParameters, string pContentId, cCulturedString pDescription, string pContentTransferEncoding, uint pSizeInBytes, cSinglePartExtensionData pExtensionData) : base(pType, pSubType, pSection) { Parameters = pParameters; ContentId = pContentId; Description = pDescription; ContentTransferEncoding = pContentTransferEncoding ?? throw new ArgumentNullException(nameof(pContentTransferEncoding)); if (ContentTransferEncoding.Equals("7BIT", StringComparison.InvariantCultureIgnoreCase)) { DecodingRequired = eDecodingRequired.none; } else if (ContentTransferEncoding.Equals("8BIT", StringComparison.InvariantCultureIgnoreCase)) { DecodingRequired = eDecodingRequired.none; } else if (ContentTransferEncoding.Equals("BINARY", StringComparison.InvariantCultureIgnoreCase)) { DecodingRequired = eDecodingRequired.none; } else if (ContentTransferEncoding.Equals("QUOTED-PRINTABLE", StringComparison.InvariantCultureIgnoreCase)) { DecodingRequired = eDecodingRequired.quotedprintable; } else if (ContentTransferEncoding.Equals("BASE64", StringComparison.InvariantCultureIgnoreCase)) { DecodingRequired = eDecodingRequired.base64; } else { DecodingRequired = eDecodingRequired.other; // note that rfc 2045 section 6.4 specifies that if 'unknown' then the part has to be treated as application/octet-stream } SizeInBytes = pSizeInBytes; ExtensionData = pExtensionData; }
internal void Fetch(iMessageHandle pMessageHandle, cSection pSection, eDecodingRequired pDecoding, Stream pStream, cBodyFetchConfiguration pConfiguration) { // note: if it fails bytes could have been written to the stream var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(Fetch)); var lTask = ZFetchBodyAsync(pMessageHandle, pSection, pDecoding, pStream, pConfiguration, lContext); mSynchroniser.Wait(lTask, lContext); }
private async Task ZFetchBodyAsync(iMessageHandle pMessageHandle, cSection pSection, eDecodingRequired pDecoding, Stream pStream, cBodyFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZFetchBodyAsync), pMessageHandle, pSection, pDecoding); if (mDisposed) { throw new ObjectDisposedException(nameof(cIMAPClient)); } var lSession = mSession; if (lSession == null || lSession.ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandle == null) { throw new ArgumentNullException(nameof(pMessageHandle)); } if (pSection == null) { throw new ArgumentNullException(nameof(pSection)); } if (pStream == null) { throw new ArgumentNullException(nameof(pStream)); } if (!pStream.CanWrite) { throw new ArgumentOutOfRangeException(nameof(pStream)); } if (pConfiguration == null) { using (var lToken = mCancellationManager.GetToken(lContext)) { var lMC = new cMethodControl(mTimeout, lToken.CancellationToken); var lProgress = new cProgress(); var lWriteSizer = new cBatchSizer(mFetchBodyWriteConfiguration); await lSession.FetchBodyAsync(lMC, pMessageHandle, pSection, pDecoding, pStream, lProgress, lWriteSizer, lContext).ConfigureAwait(false); } } else { var lMC = new cMethodControl(pConfiguration.Timeout, pConfiguration.CancellationToken); var lProgress = new cProgress(mSynchroniser, pConfiguration.Increment); var lWriteSizer = new cBatchSizer(pConfiguration.Write ?? mFetchBodyWriteConfiguration); await lSession.FetchBodyAsync(lMC, pMessageHandle, pSection, pDecoding, pStream, lProgress, lWriteSizer, lContext).ConfigureAwait(false); } }
public readonly cBytes Bytes; // may be null public cBody(bool pBinary, cSection pSection, uint?pOrigin, IList <byte> pBytes) { Binary = pBinary; Section = pSection ?? throw new ArgumentNullException(nameof(pSection)); Origin = pOrigin; if (pBytes == null) { Bytes = null; } else { Bytes = new cBytes(pBytes); } }
internal cTextBodyPart(string pSubType, cSection pSection, cBodyStructureParameters pParameters, string pContentId, cCulturedString pDescription, string pContentTransferEncoding, uint pSizeInBytes, uint pSizeInLines, cSinglePartExtensionData pExtensionData) : base(kMimeType.Text, pSubType, pSection, pParameters, pContentId, pDescription, pContentTransferEncoding, pSizeInBytes, pExtensionData) { if (SubType.Equals("PLAIN", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eTextBodyPartSubTypeCode.plain; } else if (SubType.Equals("HTML", StringComparison.InvariantCultureIgnoreCase)) { SubTypeCode = eTextBodyPartSubTypeCode.html; } else { SubTypeCode = eTextBodyPartSubTypeCode.other; } SizeInLines = pSizeInLines; }
internal cBodyPart(string pType, string pSubType, cSection pSection) { Type = pType ?? throw new ArgumentNullException(nameof(pType)); SubType = pSubType ?? throw new ArgumentNullException(nameof(pSubType)); Section = pSection ?? throw new ArgumentNullException(nameof(pSection)); if (Type.Equals(kMimeType.Text, StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.text; } else if (Type.Equals("IMAGE", StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.image; } else if (Type.Equals("AUDIO", StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.audio; } else if (Type.Equals("VIDEO", StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.video; } else if (Type.Equals("APPLICATION", StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.application; } else if (Type.Equals(kMimeType.Multipart, StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.multipart; } else if (Type.Equals(kMimeType.Message, StringComparison.InvariantCultureIgnoreCase)) { TypeCode = eBodyPartTypeCode.message; } else { TypeCode = eBodyPartTypeCode.other; } }
private async Task <cBody> ZUIDFetchBodyAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUID pUID, bool pBinary, cSection pSection, uint pOrigin, uint pLength, cTrace.cContext pParentContext) { // the caller must have checked that the binary option is compatible with the section (e.g. if binary is true the section can't specify a textpart) // the length must be greater than zero var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZUIDFetchBodyAsync), pMC, pMailboxHandle, pUID, pBinary, pSection, pOrigin, pLength); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pUID == null) { throw new ArgumentNullException(nameof(pUID)); } if (pSection == null) { throw new ArgumentNullException(nameof(pSection)); } using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUID.UIDValidity); lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // this command is msnunsafe // set uidvalidity lBuilder.AddUIDValidity(pUID.UIDValidity); // build command lBuilder.Add(kFetchCommandPartUIDFetchSpace, new cTextCommandPart(pUID.UID)); if (pBinary) { lBuilder.Add(kFetchCommandPartSpaceBinaryPeekLBracket); } else { lBuilder.Add(kFetchCommandPartSpaceBodyPeekLBracket); } lBuilder.Add(pSection, pOrigin, pLength); // hook var lHook = new cCommandHookFetchBodyUID(pBinary, pSection, pOrigin, pUID.UID); lBuilder.Add(lHook); // go var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("uid fetch body success"); if (lHook.Body == null) { throw new cRequestedDataNotReturnedException(lContext); } return(lHook.Body); } if (lHook.Body != null) { lContext.TraceError("received body on a failed uid fetch body"); } fCapabilities lTryIgnoring; if (pBinary) { lTryIgnoring = fCapabilities.binary; } else { lTryIgnoring = 0; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext); } throw new cProtocolErrorException(lResult, lTryIgnoring, lContext); } }
public cCommandHookFetchBodyUID(bool pBinary, cSection pSection, uint pOrigin, uint pUID) : base(pBinary, pSection, pOrigin) { mUID = pUID; }
public cCommandHookFetchBodyMSN(bool pBinary, cSection pSection, uint pOrigin, uint pMSN) : base(pBinary, pSection, pOrigin) { mMSN = pMSN; }
public cCommandHookFetchBody(bool pBinary, cSection pSection, uint pOrigin) { mBinary = pBinary; mSection = pSection; mOrigin = pOrigin; }
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); }
public Task UIDFetchBodyAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUID pUID, cSection pSection, eDecodingRequired pDecoding, Stream pStream, cProgress pProgress, cBatchSizer pWriteSizer, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDFetchBodyAsync), pMC, pMailboxHandle, pUID, pSection, pDecoding); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUID.UIDValidity); // to be repeated inside the select lock return(ZFetchBodyAsync(pMC, pMailboxHandle, pUID, null, pSection, pDecoding, pStream, pProgress, pWriteSizer, lContext)); }