private bool ZProcessDataResponse(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandPipeline), nameof(ZProcessDataResponse)); if (!pCursor.SkipBytes(kProcessResponseAsteriskSpace)) { return(false); } lContext.TraceVerbose("got data"); if (pCursor.SkipBytes(kProcessResponseOKSpace)) { lContext.TraceVerbose("got information"); mResponseTextProcessor.Process(eResponseTextContext.information, pCursor, mActiveCommands, lContext); return(true); } if (pCursor.SkipBytes(kProcessResponseNoSpace)) { lContext.TraceVerbose("got a warning"); mResponseTextProcessor.Process(eResponseTextContext.warning, pCursor, mActiveCommands, lContext); return(true); } if (pCursor.SkipBytes(kProcessResponseBadSpace)) { lContext.TraceVerbose("got a protocol error"); mResponseTextProcessor.Process(eResponseTextContext.protocolerror, pCursor, mActiveCommands, lContext); return(true); } if (pCursor.SkipBytes(kProcessResponseCapabilitySpace)) { if (mState == eState.connected) { if (pCursor.ProcessCapability(out var lCapabilities, out var lAuthenticationMechanisms, lContext) && pCursor.Position.AtEnd) { lContext.TraceVerbose("got capabilities: {0} {1}", lCapabilities, lAuthenticationMechanisms); mCapabilities = lCapabilities; mAuthenticationMechanisms = lAuthenticationMechanisms; } else { lContext.TraceWarning("likely malformed capability"); } } else { lContext.TraceWarning("capability response received at the wrong time - not processed"); } return(true); }
public override eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cNamespaceDataProcessor), nameof(ProcessData)); if (!pCursor.SkipBytes(kNamespaceSpace)) { return(eProcessDataResult.notprocessed); } if (ZProcessData(pCursor, out var lPersonal, lContext) && pCursor.SkipByte(cASCII.SPACE) && ZProcessData(pCursor, out var lOtherUsers, lContext) && pCursor.SkipByte(cASCII.SPACE) && ZProcessData(pCursor, out var lShared, lContext) && pCursor.Position.AtEnd ) { lContext.TraceVerbose("got namespaces"); NamespaceNames = new cNamespaceNames(lPersonal, lOtherUsers, lShared); mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.Namespaces), lContext); return(eProcessDataResult.processed); } lContext.TraceWarning("likely malformed namespace"); return(eProcessDataResult.notprocessed); }
public bool Process(cBytesCursor pCursor, out cResponseData rResponseData, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cResponseDataParserLSub), nameof(Process)); if (!pCursor.SkipBytes(kLSubSpace)) { rResponseData = null; return(false); } if (!pCursor.GetFlags(out var lFlags) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.GetMailboxDelimiter(out var lDelimiter) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.GetAString(out IList <byte> lEncodedMailboxPath) || !pCursor.Position.AtEnd || !cMailboxName.TryConstruct(lEncodedMailboxPath, lDelimiter, mUTF8Enabled, out var lMailboxName)) { lContext.TraceWarning("likely malformed lsub response"); rResponseData = null; return(true); } rResponseData = new cResponseDataLSub(lMailboxName, !lFlags.Contains(@"\Noselect", StringComparer.InvariantCultureIgnoreCase)); return(true); }
private static bool ZGetId(cBytesCursor pCursor, out cId rServerId, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIdDataProcessor), nameof(ZGetId)); if (pCursor.SkipBytes(cBytesCursor.Nil)) { rServerId = null; return(true); } if (!pCursor.SkipByte(cASCII.LPAREN)) { rServerId = null; return(false); } Dictionary <string, string> lDictionary = new Dictionary <string, string>(); try { bool lFirst = true; while (true) { if (pCursor.SkipByte(cASCII.RPAREN)) { break; } if (lFirst) { lFirst = false; } else if (!pCursor.SkipByte(cASCII.SPACE)) { rServerId = null; return(false); } if (!pCursor.GetString(out string lField) || !pCursor.SkipByte(cASCII.SPACE)) { rServerId = null; return(false); } if (!pCursor.GetNString(out string lValue)) { rServerId = null; return(false); } lDictionary[lField] = lValue; } rServerId = new cId(lDictionary); return(true); } catch (Exception e) { lContext.TraceException("error when constructing the id dictionary", e); rServerId = null; return(false); } }
private async Task <eIdleProcessResponsesTerminatedBy> ZIdleProcessResponsesAsync(bool pMonitorBackgroundReleaser, Task pCountdownTask, cCommandTag pTag, bool pExpectContinueRequest, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandPipeline), nameof(ZIdleProcessResponsesAsync), pMonitorBackgroundReleaser, pTag, pExpectContinueRequest); Task lBackgroundReleaserTask; if (pMonitorBackgroundReleaser) { lBackgroundReleaserTask = mBackgroundReleaser.GetAwaitReleaseTask(lContext); } else { lBackgroundReleaserTask = null; } while (true) { Task lBuildResponseTask = mConnection.GetBuildResponseTask(lContext); Task lTask = await mBackgroundAwaiter.AwaitAny(lBuildResponseTask, lBackgroundReleaserTask, pCountdownTask).ConfigureAwait(false); if (ReferenceEquals(lTask, lBackgroundReleaserTask)) { return(eIdleProcessResponsesTerminatedBy.backgroundreleaser); } if (ReferenceEquals(lTask, pCountdownTask)) { return(eIdleProcessResponsesTerminatedBy.countdowntask); } var lResponse = mConnection.GetResponse(lContext); mSynchroniser.InvokeNetworkReceive(lResponse, lContext); var lCursor = new cBytesCursor(lResponse); if (lCursor.SkipBytes(kPlusSpace)) { if (!pExpectContinueRequest) { throw new cUnexpectedServerActionException(fCapabilities.idle, "unexpected continuation request", lContext); } mResponseTextProcessor.Process(eResponseTextContext.continuerequest, lCursor, null, lContext); return(eIdleProcessResponsesTerminatedBy.continuerequest); } if (ZProcessDataResponse(lCursor, lContext)) { continue; } if (pTag != null && ZProcessCommandCompletionResponse(lCursor, pTag, false, null, lContext) != null) { return(eIdleProcessResponsesTerminatedBy.commandcompletion); } lContext.TraceError("unrecognised response: {0}", lResponse); } }
private async Task ZBackgroundTaskProcessResponseAsync(cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandPipeline), nameof(ZBackgroundTaskProcessResponseAsync)); var lResponse = mConnection.GetResponse(lContext); mSynchroniser.InvokeNetworkReceive(lResponse, lContext); var lCursor = new cBytesCursor(lResponse); if (lCursor.SkipBytes(kPlusSpace)) { var lCurrentCommand = mCurrentCommand; if (lCurrentCommand == null || !lCurrentCommand.WaitingForContinuationRequest) { throw new cUnexpectedServerActionException(0, "unexpected continuation request", lContext); } if (lCurrentCommand.IsAuthentication) { await ZProcessChallengeAsync(lCursor, lContext).ConfigureAwait(false); } else { mResponseTextProcessor.Process(eResponseTextContext.continuerequest, lCursor, lCurrentCommand.Hook, lContext); lCurrentCommand.WaitingForContinuationRequest = false; } return; } lock (mPipelineLock) { if (ZProcessDataResponse(lCursor, lContext)) { return; } if (ZBackgroundTaskProcessActiveCommandCompletion(lCursor, lContext)) { return; } if (mCurrentCommand != null && ZBackgroundTaskProcessCommandCompletion(lCursor, mCurrentCommand, lContext)) { if (mCurrentCommand.IsAuthentication) { mCurrentCommand = null; } return; } } lContext.TraceError("unrecognised response: {0}", lResponse); }
internal static bool TryConstruct(IList <byte> pValue, out cHeaderFieldImportance rImportance) { if (pValue == null) { rImportance = null; return(false); } eImportance lImportance; cBytesCursor lCursor = new cBytesCursor(pValue); lCursor.SkipRFC822CFWS(); if (lCursor.SkipBytes(kLow)) { lImportance = eImportance.low; } else if (lCursor.SkipBytes(kNormal)) { lImportance = eImportance.normal; } else if (lCursor.SkipBytes(kHigh)) { lImportance = eImportance.high; } else { rImportance = null; return(false); } lCursor.SkipRFC822CFWS(); if (lCursor.Position.AtEnd) { rImportance = new cHeaderFieldImportance(new cBytes(pValue), lImportance); return(true); } rImportance = null; return(false); }
public eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(ProcessData)); if (mSelectedMailbox != null) { var lBookmark = pCursor.Position; var lResult = mSelectedMailbox.ProcessData(pCursor, lContext); if (lResult != eProcessDataResult.notprocessed) { return(lResult); } pCursor.Position = lBookmark; } if (pCursor.SkipBytes(kStatusSpace)) { if (!pCursor.GetAString(out string lEncodedMailboxPath) || !pCursor.SkipBytes(cBytesCursor.SpaceLParen) || !ZProcessDataStatusAttributes(pCursor, out var lStatus, lContext) || !pCursor.SkipByte(cASCII.RPAREN) || !pCursor.Position.AtEnd) { lContext.TraceWarning("likely malformed status response"); return(eProcessDataResult.notprocessed); } var lItem = ZItem(lEncodedMailboxPath); lItem.UpdateStatus(lStatus, lContext); if (!ReferenceEquals(mSelectedMailbox?.MailboxHandle, lItem)) { lItem.UpdateMailboxStatus(lContext); } return(eProcessDataResult.processed); } return(eProcessDataResult.notprocessed); }
public eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSelectedMailboxCache), nameof(ProcessData)); if (pCursor.GetNZNumber(out _, out var lNumber) && pCursor.SkipBytes(kSpaceExpunge) && pCursor.Position.AtEnd) { lContext.TraceVerbose("got expunge: {0}", lNumber); ZExpunge((int)lNumber, lContext); return(eProcessDataResult.processed); } return(eProcessDataResult.notprocessed); }
public override eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cEnableCommandHook), nameof(ProcessData)); if (!pCursor.SkipBytes(kEnabled)) { return(eProcessDataResult.notprocessed); } fEnableableExtensions lEnabledExtensions = fEnableableExtensions.none; while (true) { if (!pCursor.SkipByte(cASCII.SPACE)) { break; } if (!pCursor.GetToken(cCharset.Atom, null, null, out cByteList lAtom)) { lContext.TraceWarning("likely malformed enabled: not an atom list?"); return(eProcessDataResult.notprocessed); } lContext.TraceVerbose("got an enabled for {0}", lAtom); if (cASCII.Compare(lAtom, kEnableExtensionUTF8, false)) { lEnabledExtensions = lEnabledExtensions | fEnableableExtensions.utf8; } // more here as required else { lContext.TraceError("unknown extension enabled: {0}", lAtom); } } if (!pCursor.Position.AtEnd) { lContext.TraceWarning("likely malformed enabled: not at end?"); return(eProcessDataResult.notprocessed); } mEnabledExtensions |= lEnabledExtensions; return(eProcessDataResult.processed); }
private bool ZProcessData(cBytesCursor pCursor, out List <cNamespaceName> rNames, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cNamespaceDataProcessor), nameof(ZProcessData)); if (pCursor.SkipBytes(cBytesCursor.Nil)) { rNames = null; return(true); } if (!pCursor.SkipByte(cASCII.LPAREN)) { rNames = null; return(false); } rNames = new List <cNamespaceName>(); while (true) { if (!pCursor.SkipByte(cASCII.LPAREN) || !pCursor.GetString(out IList <byte> lEncodedPrefix) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.GetMailboxDelimiter(out var lDelimiter) || !ZProcessNamespaceExtension(pCursor) || !pCursor.SkipByte(cASCII.RPAREN) ) { rNames = null; return(false); } if (!cNamespaceName.TryConstruct(lEncodedPrefix, lDelimiter, mUTF8Enabled, out var lNamespaceName)) { rNames = null; return(false); } rNames.Add(lNamespaceName); if (pCursor.SkipByte(cASCII.RPAREN)) { return(true); } } }
public bool Process(cBytesCursor pCursor, out cResponseData rResponseData, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cResponseDataParserSelect), nameof(Process)); if (pCursor.SkipBytes(kFlagsSpace)) { if (pCursor.GetFlags(out var lRawFlags) && pCursor.Position.AtEnd && cFetchableFlags.TryConstruct(lRawFlags, out var lFlags)) { rResponseData = new cResponseDataFlags(lFlags); } else { lContext.TraceWarning("likely malformed flags response"); rResponseData = null; } return(true); }
public override eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandHookBaseSearch), nameof(ProcessData)); if (!pCursor.SkipBytes(kSearch)) { return(eProcessDataResult.notprocessed); } cUIntList lMSNs = new cUIntList(); while (true) { if (!pCursor.SkipByte(cASCII.SPACE)) { break; } if (!pCursor.GetNZNumber(out _, out var lMSN)) { lContext.TraceWarning("likely malformed search: not an nz-number list?"); return(eProcessDataResult.notprocessed); } lMSNs.Add(lMSN); } if (!pCursor.Position.AtEnd) { lContext.TraceWarning("likely malformed search: not at end?"); return(eProcessDataResult.notprocessed); } if (mMSNs == null) { mMSNs = lMSNs; } else { mMSNs.AddRange(lMSNs); } return(eProcessDataResult.processed); }
public override eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIdDataProcessor), nameof(ProcessData)); if (pCursor.SkipBytes(kIdSpace)) { if (ZGetId(pCursor, out var lServerId, lContext) && pCursor.Position.AtEnd) { lContext.TraceVerbose("got id: {0}", lServerId); mServerId = lServerId; mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.ServerId), lContext); return(eProcessDataResult.processed); } lContext.TraceWarning("likely malformed id response"); } return(eProcessDataResult.notprocessed); }
private static eProcessStatusAttributeResult ZProcessDataStatusAttribute(cBytesCursor pCursor, cBytes pAttributeSpace, ref ulong?rNumber, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(ZProcessDataStatusAttribute)); if (!pCursor.SkipBytes(pAttributeSpace)) { return(eProcessStatusAttributeResult.notprocessed); } if (pCursor.GetNumber(out var lNumber)) { lContext.TraceVerbose("got {0}", lNumber); rNumber = lNumber; return(eProcessStatusAttributeResult.processed); } lContext.TraceWarning("likely malformed status-att-list-item: no number?"); return(eProcessStatusAttributeResult.error); }
public async Task <sGreeting> ConnectAsync(cMethodControl pMC, cServer pServer, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandPipeline), nameof(ConnectAsync), pMC, pServer); if (mDisposed) { throw new ObjectDisposedException(nameof(cCommandPipeline)); } if (mState != eState.notconnected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotUnconnected); } mState = eState.connecting; try { await mConnection.ConnectAsync(pMC, pServer, lContext).ConfigureAwait(false); using (var lAwaiter = new cAwaiter(pMC)) { while (true) { lContext.TraceVerbose("waiting"); await lAwaiter.AwaitAny(mConnection.GetBuildResponseTask(lContext)).ConfigureAwait(false); var lResponse = mConnection.GetResponse(lContext); mSynchroniser.InvokeNetworkReceive(lResponse, lContext); var lCursor = new cBytesCursor(lResponse); if (lCursor.SkipBytes(kGreetingAsteriskSpaceOKSpace)) { var lHook = new cCommandHookInitial(); cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingok, lCursor, lHook, lContext); lContext.TraceVerbose("got ok: {0}", lResponseText); mState = eState.connected; mBackgroundTask = ZBackgroundTaskAsync(lContext); mCapabilities = lHook.Capabilities; mAuthenticationMechanisms = lHook.AuthenticationMechanisms; return(new sGreeting(eGreetingType.ok, null)); } if (lCursor.SkipBytes(kGreetingAsteriskSpacePreAuthSpace)) { var lHook = new cCommandHookInitial(); cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingpreauth, lCursor, lHook, lContext); lContext.TraceVerbose("got preauth: {0}", lResponseText); mState = eState.connected; mBackgroundTask = ZBackgroundTaskAsync(lContext); mCapabilities = lHook.Capabilities; mAuthenticationMechanisms = lHook.AuthenticationMechanisms; return(new sGreeting(eGreetingType.preauth, lResponseText)); } if (lCursor.SkipBytes(kGreetingAsteriskSpaceBYESpace)) { cResponseText lResponseText = mResponseTextProcessor.Process(eResponseTextContext.greetingbye, lCursor, null, lContext); lContext.TraceError("got bye: {0}", lResponseText); mConnection.Disconnect(lContext); mState = eState.stopped; return(new sGreeting(eGreetingType.bye, lResponseText)); } lContext.TraceError("unrecognised response: {0}", lResponse); } } } catch (Exception) { mConnection.Disconnect(lContext); mState = eState.stopped; throw; } }
private static bool ZTryConstruct(cHeaderFieldNames pNames, bool pNot, IList <byte> pBytes, out cHeaderFields rFields) { if (pBytes == null) { rFields = null; return(false); } cBytesCursor lCursor = new cBytesCursor(pBytes); List <cHeaderField> lFields = new List <cHeaderField>(); while (true) { if (!lCursor.GetRFC822FieldName(out var lName)) { break; } lCursor.SkipRFC822WSP(); if (!lCursor.SkipByte(cASCII.COLON)) { rFields = null; return(false); } if (!lCursor.GetRFC822FieldValue(out var lValue)) { rFields = null; return(false); } if (lName.Equals(kHeaderFieldName.References, StringComparison.InvariantCultureIgnoreCase)) { if (cHeaderFieldMsgIds.TryConstruct(lName, lValue, out var lReferences)) { lFields.Add(lReferences); } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } else if (lName.Equals(kHeaderFieldName.Importance, StringComparison.InvariantCultureIgnoreCase)) { if (cHeaderFieldImportance.TryConstruct(lValue, out var lImportance)) { lFields.Add(lImportance); } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } if (!lCursor.Position.AtEnd && !lCursor.SkipBytes(cBytesCursor.CRLF)) { rFields = null; return(false); } rFields = new cHeaderFields(pNames, pNot, lFields); return(true); }
public static void _Tests_RFC822(cTrace.cContext pParentContext) { cBytesCursor lCursor; string lString; DateTime lDate; cByteList lByteList; // tests for WSP lCursor = new cBytesCursor("x \t y \t\r\n\tz"); if (!lCursor.SkipByte(cASCII.x) || !lCursor.SkipRFC822WSP() || lCursor.SkipRFC822WSP() || !lCursor.SkipByte(cASCII.y) || !lCursor.SkipRFC822FWS() || lCursor.SkipRFC822FWS() || !lCursor.SkipByte(cASCII.z)) { throw new cTestsException("skip wsp 1"); } lCursor = new cBytesCursor("x \t y \t\r\n\tz"); if (!lCursor.SkipByte(cASCII.x) || !lCursor.SkipRFC822FWS() || lCursor.SkipRFC822FWS() || !lCursor.SkipByte(cASCII.y) || !lCursor.SkipRFC822FWS() || !lCursor.SkipByte(cASCII.z)) { throw new cTestsException("skip wsp 2"); } lCursor = new cBytesCursor("x \t\r\ny \t\r\n\t\r\n z"); if (!lCursor.SkipByte(cASCII.x) || !lCursor.SkipRFC822FWS() || lCursor.SkipRFC822FWS() || !lCursor.SkipBytes(new cBytes("\r\ny")) || !lCursor.SkipRFC822FWS() || !lCursor.SkipByte(cASCII.z)) { throw new cTestsException("skip wsp 3"); } lCursor = new cBytesCursor("Muhammed.(I am the greatest) Ali\r\n @(the)Vegas.WBA"); if (!lCursor.GetToken(cCharset.Atom, null, null, out lString) || lString != "Muhammed." || !lCursor.SkipRFC822CFWS() || !lCursor.GetToken(cCharset.Atom, null, null, out lString) || lString != "Ali" || !lCursor.SkipRFC822CFWS() || !lCursor.SkipByte(cASCII.AT) || !lCursor.SkipRFC822CFWS() || !lCursor.GetToken(cCharset.Atom, null, null, out lString) || lString != "Vegas.WBA") { throw new cTestsException("skip cfws 1"); } lCursor = new cBytesCursor("(I am \r\n the(xx\\)\\\\\\() gre \t() \tatest)"); if (!lCursor.SkipRFC822CFWS() || !lCursor.Position.AtEnd) { throw new cTestsException("skip cfws 2"); } // TODO: more tests for failure cases // tests for IMF date (these examples from rfc 5322) lCursor = new cBytesCursor("Fri, 21 Nov 1997 09:55:06 -0600 x Tue, 1 Jul 2003 10:52:37 +0200 x Thu, 13 Feb 1969 23:32:54 -0330 x Thu,\r\n\t13\r\n\t Feb\r\n\t 1969\r\n\t23:32\r\n\t\t\t-0330 (Newfoundland Time) x 21 Nov 97 09:55:06 GMT x Fri, 21 Nov 1997 09(comment): 55 : 06 -0600 x"); if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(1997, 11, 21, 15, 55, 06) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 1"); } if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(2003, 7, 1, 8, 52, 37) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 2"); } if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(1969, 2, 14, 3, 02, 54) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 3"); } if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(1969, 2, 14, 3, 02, 00) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 4"); } if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(1997, 11, 21, 9, 55, 06) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 5"); } if (!lCursor.GetRFC822DateTime(out lDate) || lDate != new DateTime(1997, 11, 21, 15, 55, 06) || !lCursor.SkipByte(cASCII.x)) { throw new cTestsException("imf date 6"); } // TODO: more tests for failure cases and alphanumeric zones // Wed, 17 Jul 1996 02:23:25 -0700 (PDT) // header values lCursor = new cBytesCursor(" \t \r\nHeader \t: \r\n\t \t\r\n\r\n"); if (lCursor.GetRFC822FieldName(out lString) || !lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != " \t ") { throw new cTestsException("header 1.1"); } if (!lCursor.GetRFC822FieldName(out lString) || lString != "Header" || !lCursor.SkipRFC822WSP() || !lCursor.SkipByte(cASCII.COLON) || !lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != " \t \t") { throw new cTestsException("header 1.2"); } lCursor = new cBytesCursor("Header \t : \r\n \t\r\nFred"); if (!lCursor.GetRFC822FieldName(out lString) || lString != "Header" || !lCursor.SkipRFC822WSP() || !lCursor.SkipByte(cASCII.COLON) || !lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != " \t") { throw new cTestsException("header 2.1"); } lCursor = new cBytesCursor("Header:\r\n this is \r\n the\tvalue \t\r\n"); if (!lCursor.GetRFC822FieldName(out lString) || lString != "Header" || lCursor.SkipRFC822WSP() || !lCursor.SkipByte(cASCII.COLON) || !lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != " this is the\tvalue \t") { throw new cTestsException("header 3.1"); } lCursor = new cBytesCursor("Header:\r\n should \r\n fail \t\r\n more stuff"); if (!lCursor.GetRFC822FieldName(out lString) || lString != "Header" || lCursor.SkipRFC822WSP() || !lCursor.SkipByte(cASCII.COLON) || lCursor.GetRFC822FieldValue(out lByteList)) { throw new cTestsException("header 4.1"); } // atoms lCursor = new cBytesCursor(" \t \r\n Header \tAtom(comment) \r\nAt?Om\tAt!om:{Atom} \t\r\n\r\n"); if (!lCursor.GetRFC822Atom(out lString) || lString != "Header" || !lCursor.GetRFC822Atom(out lString) || lString != "Atom") { throw new cTestsException("atom 1.1"); } if (!lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF)) { throw new cTestsException("atom 1.2"); } if (!lCursor.GetRFC822Atom(out lString) || lString != "At?Om") { throw new cTestsException("atom 1.3"); } if (!lCursor.GetRFC822Atom(out lString) || lString != "At!om") { throw new cTestsException("atom 1.4"); } if (lCursor.GetRFC822Atom(out lString)) { throw new cTestsException("atom 1.5.1"); } if (!lCursor.SkipByte(cASCII.COLON)) { throw new cTestsException("atom 1.5.2"); } if (!lCursor.GetRFC822Atom(out lString) || lString != "{Atom}") { throw new cTestsException("atom 1.6"); } if (!lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF) || !lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF) || !lCursor.Position.AtEnd) { throw new cTestsException("atom 1.7"); } // quoted strings lCursor = new cBytesCursor(" \t \r\n \"Header\r\n with FWS\" \t\"Atom(not a \\\"comment\\\")\" \r\n\"At?Om\"\t\"At!om:{Atom}\" \"\r\n\tFWS beginning and end\r\n\t\" \t\r\n\r\n"); if (!lCursor.GetRFC822QuotedString(out lString) || lString != "Header with FWS" || !lCursor.GetRFC822QuotedString(out lString) || lString != "Atom(not a \"comment\")") { throw new cTestsException("quoted string 1.1"); } if (!lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF)) { throw new cTestsException("quoted string 1.2"); } if (!lCursor.GetRFC822QuotedString(out lString) || lString != "At?Om") { throw new cTestsException("quoted string 1.3"); } if (!lCursor.GetRFC822QuotedString(out lString) || lString != "At!om:{Atom}") { throw new cTestsException("quoted string 1.4"); } if (!lCursor.GetRFC822QuotedString(out lString) || lString != "\tFWS beginning and end\t") { throw new cTestsException("quoted string 1.5"); } if (lCursor.GetRFC822QuotedString(out lString)) { throw new cTestsException("quoted string 1.6.1"); } if (!lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF) || !lCursor.SkipByte(cASCII.CR) || !lCursor.SkipByte(cASCII.LF) || !lCursor.Position.AtEnd) { throw new cTestsException("quoted string 1.6.2"); } // mix lCursor = new cBytesCursor(" \t \r\n Header \tA"); if (lCursor.GetRFC822QuotedString(out lString) || lCursor.Position.Byte != 0 || !lCursor.GetRFC822Atom(out lString) || lString != "Header" || !lCursor.SkipByte(cASCII.A)) { throw new cTestsException("mix 1.1"); } lCursor = new cBytesCursor(" \t \r\n \"Header\" \tA"); if (lCursor.GetRFC822Atom(out lString) || lCursor.Position.Byte != 0 || !lCursor.GetRFC822QuotedString(out lString) || lString != "Header" || !lCursor.SkipByte(cASCII.A)) { throw new cTestsException("mix 1.2"); } // domain literal lCursor = new cBytesCursor(" \t (there is a domain\r\n literal coming up(and\tit'll\r\n\tbe a good one)) \r\n [Header] \r\n ( now with with FWS ) [ \t \r\n\t the.name.com \r\n ] (now with embedded FWS) [ \t \r\n\t the \t name \r\n com \r\n ] (with quotes and utf8) [ \\[ fr€d ] (something invalid) [ [ ] \r\n"); if (!lCursor.GetDomainLiteral(out lString) || lString != "[Header]") { throw new cTestsException("domain literal 1.1"); } if (!lCursor.GetDomainLiteral(out lString) || lString != "[the.name.com]") { throw new cTestsException("domain literal 1.2"); } if (!lCursor.GetDomainLiteral(out lString) || lString != "[the name com]") { throw new cTestsException("domain literal 1.3"); } if (!lCursor.GetDomainLiteral(out lString) || lString != "[[ fr€d]") { throw new cTestsException("domain literal 1.4"); } if (lCursor.GetDomainLiteral(out lString)) { throw new cTestsException("domain literal 1.5"); } if (!lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != "[ [ ] ") { throw new cTestsException("domain literal 1.6"); } // domain lCursor = new cBytesCursor(" \t (first a dot-atom form) fred.angus.bart (now a obs form) frxd \t . angxs . \t bxrt (now a\r\n literal) [ 192.168.1.1 ] \r\nNextHeader"); if (!lCursor.GetRFC822Domain(out lString) || lString != "fred.angus.bart") { throw new cTestsException("domain 1.1"); } if (!lCursor.GetRFC822Domain(out lString) || lString != "frxd.angxs.bxrt") { throw new cTestsException("domain 1.2"); } if (!lCursor.GetRFC822Domain(out lString) || lString != "[192.168.1.1]") { throw new cTestsException("domain 1.3"); } if (!lCursor.GetRFC822FieldValue(out lByteList) || lByteList.Count != 0) { throw new cTestsException("domain 1.4"); } if (lCursor.GetRestAsString() != "NextHeader") { throw new cTestsException("domain 1.5"); } // local part lCursor = new cBytesCursor(" \t (first a dot-atom form) fred.angus.bart (now a obs form) frxd \t . angxs . \t bxrt (now a\r\n quoted string) \"th€ local part as a string\" (then a second obsolete form) \"fr€d\" \t . angxs . \t \"bzrt\" \r\n "); if (!lCursor.GetRFC822LocalPart(out lString) || lString != "fred.angus.bart") { throw new cTestsException("local part 1.1"); } if (!lCursor.GetRFC822LocalPart(out lString) || lString != "frxd.angxs.bxrt") { throw new cTestsException("local part 1.2"); } if (!lCursor.GetRFC822LocalPart(out lString) || lString != "th€ local part as a string") { throw new cTestsException("local part 1.3"); } if (!lCursor.GetRFC822LocalPart(out lString) || lString != "fr€d.angxs.bzrt") { throw new cTestsException("local part 1.4"); } if (!lCursor.Position.AtEnd) { throw new cTestsException("local part 1.5"); } lCursor = new cBytesCursor(" \t (edge case) fred.angus.bart . [] \r\nNextHeader"); if (!lCursor.GetRFC822LocalPart(out lString) || lString != "fred.angus.bart") { throw new cTestsException("local part 2.1"); } if (!lCursor.GetRFC822FieldValue(out lByteList) || cTools.UTF8BytesToString(lByteList) != ". [] ") { throw new cTestsException("local part 2.2"); } // message id lCursor = new cBytesCursor(" \r\n\t (one) <*****@*****.**> <*****@*****.**> <*****@*****.**> <1234 @ local(blah) .machine .example> "); if (!lCursor.GetRFC822MsgId(out lString) || lString != "*****@*****.**") { throw new cTestsException("msgid 1.1"); } if (!lCursor.GetRFC822MsgId(out lString) || lString != "*****@*****.**") { throw new cTestsException("msgid 1.2"); } if (!lCursor.GetRFC822MsgId(out lString) || lString != "*****@*****.**") { throw new cTestsException("msgid 1.3"); } if (!lCursor.GetRFC822MsgId(out lString) || lString != "*****@*****.**") { throw new cTestsException("msgid 1.4"); } }
public bool Process(cBytesCursor pCursor, out cResponseData rResponseData, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cResponseDataParserESearch), nameof(Process)); if (!pCursor.SkipBytes(kESearch)) { rResponseData = null; return(false); } if (pCursor.Position.AtEnd) { rResponseData = new cResponseDataESearch(null, false, null); return(true); } bool lSetParsedAs = false; // just in case there is another response that starts with the string "ESEARCH" IList <byte> lTag; if (pCursor.SkipBytes(kSpaceLParenTAGSpace)) { if (!pCursor.GetString(out lTag) || !pCursor.SkipByte(cASCII.RPAREN)) { rResponseData = null; return(true); } lSetParsedAs = true; } else { lTag = null; } bool lUID; if (pCursor.SkipBytes(kSpaceUID)) { lUID = true; lSetParsedAs = true; } else { lUID = false; } cSequenceSet lSequenceSet = null; while (true) { if (!pCursor.SkipByte(cASCII.SPACE)) { break; } lSetParsedAs = true; if (!pCursor.GetToken(cCharset.Atom, null, null, out cByteList lName) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.ProcessExtendedValue(out var lValue) ) { rResponseData = null; return(true); } if (cASCII.Compare(lName, kAll, false) && lValue is cExtendedValue.cSequenceSetEV lSequenceSetEV) { lSequenceSet = lSequenceSetEV.SequenceSet; } } if (!pCursor.Position.AtEnd) { rResponseData = null; return(lSetParsedAs); } rResponseData = new cResponseDataESearch(lTag, lUID, lSequenceSet); return(true); }
public bool Process(cBytesCursor pCursor, out cResponseData rResponseData, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cResponseDataParserList), nameof(Process)); if (!pCursor.SkipBytes(kListSpace)) { rResponseData = null; return(false); } if (!pCursor.GetFlags(out var lFlags) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.GetMailboxDelimiter(out var lDelimiter) || !pCursor.SkipByte(cASCII.SPACE) || !pCursor.GetAString(out IList <byte> lEncodedMailboxPath) || !ZProcessExtendedItems(pCursor, out var lExtendedItems) || !pCursor.Position.AtEnd) { lContext.TraceWarning("likely malformed list response"); rResponseData = null; return(true); } if (lEncodedMailboxPath.Count == 0) { if (lFlags.Count == 0 && lExtendedItems.Count == 0) { if (lDelimiter == null) { rResponseData = new cResponseDataListDelimiter(); } else { rResponseData = new cResponseDataListDelimiter((char)lDelimiter.Value); } } else { lContext.TraceWarning("likely malformed list delimiter response"); rResponseData = null; } } else { if (cMailboxName.TryConstruct(lEncodedMailboxPath, lDelimiter, mUTF8Enabled, out var lMailboxName)) { fListFlags lListFlags = 0; if (lFlags.Contains(@"\Noinferiors", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.noinferiors | fListFlags.hasnochildren; } if (lFlags.Contains(@"\Noselect", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.noselect; } if (lFlags.Contains(@"\Marked", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.marked; } if (lFlags.Contains(@"\Unmarked", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.unmarked; } if (lFlags.Contains(@"\NonExistent", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.noselect | fListFlags.nonexistent; } if (lFlags.Contains(@"\Subscribed", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.subscribed; } if (lFlags.Contains(@"\Remote", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.remote; } if (lFlags.Contains(@"\HasChildren", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.haschildren; } if (lFlags.Contains(@"\HasNoChildren", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.hasnochildren; } if (lFlags.Contains(@"\All", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.all; } if (lFlags.Contains(@"\Archive", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.archive; } if (lFlags.Contains(@"\Drafts", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.drafts; } if (lFlags.Contains(@"\Flagged", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.flagged; } if (lFlags.Contains(@"\Junk", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.junk; } if (lFlags.Contains(@"\Sent", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.sent; } if (lFlags.Contains(@"\Trash", StringComparer.InvariantCultureIgnoreCase)) { lListFlags |= fListFlags.trash; } bool lHasSubscribedChildren = false; foreach (var lItem in lExtendedItems) { if (lItem.Tag.Equals("childinfo", StringComparison.InvariantCultureIgnoreCase) && lItem.Value.Contains("subscribed", StringComparison.InvariantCultureIgnoreCase)) { lHasSubscribedChildren = true; break; } } rResponseData = new cResponseDataListMailbox(lMailboxName, lListFlags, lHasSubscribedChildren); } else { lContext.TraceWarning("likely malformed list mailbox response"); rResponseData = null; } } return(true); }