@@ -748,189 +748,58 @@ async Task<SearchResults> SearchAsync (string query, bool doAsync, CancellationT
748
748
return SearchAsync ( query , true , cancellationToken ) ;
749
749
}
750
750
751
- async Task < IList < UniqueId > > SearchAsync ( SearchQuery query , bool doAsync , bool retry , CancellationToken cancellationToken )
752
- {
753
- var args = new List < object > ( ) ;
754
- string charset ;
755
-
756
- if ( query == null )
757
- throw new ArgumentNullException ( nameof ( query ) ) ;
758
-
759
- CheckState ( true , false ) ;
760
-
761
- var optimized = query . Optimize ( new ImapSearchQueryOptimizer ( ) ) ;
762
- var expr = BuildQueryExpression ( optimized , args , out charset ) ;
763
- var command = "UID SEARCH " ;
764
-
765
- if ( ( Engine . Capabilities & ImapCapabilities . ESearch ) != 0 )
766
- command += "RETURN (ALL) " ;
767
-
768
- if ( charset != null && args . Count > 0 && ! Engine . UTF8Enabled )
769
- command += "CHARSET " + charset + " " ;
770
-
771
- command += expr + "\r \n " ;
772
-
773
- var ic = new ImapCommand ( Engine , cancellationToken , this , command , args . ToArray ( ) ) ;
774
- if ( ( Engine . Capabilities & ImapCapabilities . ESearch ) != 0 )
775
- ic . RegisterUntaggedHandler ( "ESEARCH" , ESearchMatchesAsync ) ;
776
-
777
- // Note: always register the untagged SEARCH handler because some servers will brokenly
778
- // respond with "* SEARCH ..." instead of "* ESEARCH ..." even when using the extended
779
- // search syntax.
780
- ic . RegisterUntaggedHandler ( "SEARCH" , SearchMatchesAsync ) ;
781
- ic . UserData = new SearchResults ( UidValidity , SortOrder . Ascending ) ;
782
-
783
- Engine . QueueCommand ( ic ) ;
784
-
785
- await Engine . RunAsync ( ic , doAsync ) . ConfigureAwait ( false ) ;
786
-
787
- ProcessResponseCodes ( ic , null ) ;
788
-
789
- if ( ic . Response != ImapCommandResponse . Ok ) {
790
- if ( retry && IsBadCharset ( ic , charset ) )
791
- return await SearchAsync ( query , doAsync , false , cancellationToken ) . ConfigureAwait ( false ) ;
792
-
793
- throw ImapCommandException . Create ( "SEARCH" , ic ) ;
794
- }
795
-
796
- return ( ( SearchResults ) ic . UserData ) . UniqueIds ;
797
- }
798
-
799
- /// <summary>
800
- /// Search the folder for messages matching the specified query.
801
- /// </summary>
802
- /// <remarks>
803
- /// The returned array of unique identifiers can be used with methods such as
804
- /// <see cref="IMailFolder.GetMessage(UniqueId,CancellationToken,ITransferProgress)"/>.
805
- /// </remarks>
806
- /// <returns>An array of matching UIDs.</returns>
807
- /// <param name="query">The search query.</param>
808
- /// <param name="cancellationToken">The cancellation token.</param>
809
- /// <exception cref="System.ArgumentNullException">
810
- /// <paramref name="query"/> is <c>null</c>.
811
- /// </exception>
812
- /// <exception cref="System.NotSupportedException">
813
- /// One or more search terms in the <paramref name="query"/> are not supported by the IMAP server.
814
- /// </exception>
815
- /// <exception cref="System.ObjectDisposedException">
816
- /// The <see cref="ImapClient"/> has been disposed.
817
- /// </exception>
818
- /// <exception cref="ServiceNotConnectedException">
819
- /// The <see cref="ImapClient"/> is not connected.
820
- /// </exception>
821
- /// <exception cref="ServiceNotAuthenticatedException">
822
- /// The <see cref="ImapClient"/> is not authenticated.
823
- /// </exception>
824
- /// <exception cref="FolderNotOpenException">
825
- /// The <see cref="ImapFolder"/> is not currently open.
826
- /// </exception>
827
- /// <exception cref="System.OperationCanceledException">
828
- /// The operation was canceled via the cancellation token.
829
- /// </exception>
830
- /// <exception cref="System.IO.IOException">
831
- /// An I/O error occurred.
832
- /// </exception>
833
- /// <exception cref="ImapProtocolException">
834
- /// The server's response contained unexpected tokens.
835
- /// </exception>
836
- /// <exception cref="ImapCommandException">
837
- /// The server replied with a NO or BAD response.
838
- /// </exception>
839
- public override IList < UniqueId > Search ( SearchQuery query , CancellationToken cancellationToken = default ( CancellationToken ) )
840
- {
841
- return SearchAsync ( query , false , true , cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
842
- }
843
-
844
- /// <summary>
845
- /// Asynchronously search the folder for messages matching the specified query.
846
- /// </summary>
847
- /// <remarks>
848
- /// The returned array of unique identifiers can be used with methods such as
849
- /// <see cref="IMailFolder.GetMessage(UniqueId,CancellationToken,ITransferProgress)"/>.
850
- /// </remarks>
851
- /// <returns>An array of matching UIDs.</returns>
852
- /// <param name="query">The search query.</param>
853
- /// <param name="cancellationToken">The cancellation token.</param>
854
- /// <exception cref="System.ArgumentNullException">
855
- /// <paramref name="query"/> is <c>null</c>.
856
- /// </exception>
857
- /// <exception cref="System.NotSupportedException">
858
- /// One or more search terms in the <paramref name="query"/> are not supported by the IMAP server.
859
- /// </exception>
860
- /// <exception cref="System.ObjectDisposedException">
861
- /// The <see cref="ImapClient"/> has been disposed.
862
- /// </exception>
863
- /// <exception cref="ServiceNotConnectedException">
864
- /// The <see cref="ImapClient"/> is not connected.
865
- /// </exception>
866
- /// <exception cref="ServiceNotAuthenticatedException">
867
- /// The <see cref="ImapClient"/> is not authenticated.
868
- /// </exception>
869
- /// <exception cref="FolderNotOpenException">
870
- /// The <see cref="ImapFolder"/> is not currently open.
871
- /// </exception>
872
- /// <exception cref="System.OperationCanceledException">
873
- /// The operation was canceled via the cancellation token.
874
- /// </exception>
875
- /// <exception cref="System.IO.IOException">
876
- /// An I/O error occurred.
877
- /// </exception>
878
- /// <exception cref="ImapProtocolException">
879
- /// The server's response contained unexpected tokens.
880
- /// </exception>
881
- /// <exception cref="ImapCommandException">
882
- /// The server replied with a NO or BAD response.
883
- /// </exception>
884
- public override Task < IList < UniqueId > > SearchAsync ( SearchQuery query , CancellationToken cancellationToken = default ( CancellationToken ) )
885
- {
886
- return SearchAsync ( query , true , true , cancellationToken ) ;
887
- }
888
-
889
751
async Task < SearchResults > SearchAsync ( SearchOptions options , SearchQuery query , bool doAsync , bool retry , CancellationToken cancellationToken )
890
752
{
891
- var args = new List < object > ( ) ;
892
- string charset ;
893
-
894
753
if ( query == null )
895
754
throw new ArgumentNullException ( nameof ( query ) ) ;
896
755
897
756
CheckState ( true , false ) ;
898
757
899
- if ( ( Engine . Capabilities & ImapCapabilities . ESearch ) == 0 )
758
+ if ( options != SearchOptions . None && ( Engine . Capabilities & ImapCapabilities . ESearch ) == 0 )
900
759
throw new NotSupportedException ( "The IMAP server does not support the ESEARCH extension." ) ;
901
760
761
+ var args = new List < object > ( ) ;
902
762
var optimized = query . Optimize ( new ImapSearchQueryOptimizer ( ) ) ;
903
- var expr = BuildQueryExpression ( optimized , args , out charset ) ;
904
- var command = "UID SEARCH RETURN (" ;
905
-
906
- if ( options != SearchOptions . All && options != 0 ) {
907
- if ( ( options & SearchOptions . All ) != 0 )
908
- command += "ALL " ;
909
- if ( ( options & SearchOptions . Relevancy ) != 0 )
910
- command += "RELEVANCY " ;
911
- if ( ( options & SearchOptions . Count ) != 0 )
912
- command += "COUNT " ;
913
- if ( ( options & SearchOptions . Min ) != 0 )
914
- command += "MIN " ;
915
- if ( ( options & SearchOptions . Max ) != 0 )
916
- command += "MAX " ;
917
- command = command . TrimEnd ( ) ;
763
+ var expr = BuildQueryExpression ( optimized , args , out string charset ) ;
764
+ var command = "UID SEARCH " ;
765
+
766
+ if ( ( Engine . Capabilities & ImapCapabilities . ESearch ) != 0 ) {
767
+ command += "RETURN (" ;
768
+
769
+ if ( options != SearchOptions . All && options != SearchOptions . None ) {
770
+ if ( ( options & SearchOptions . All ) != 0 )
771
+ command += "ALL " ;
772
+ if ( ( options & SearchOptions . Relevancy ) != 0 )
773
+ command += "RELEVANCY " ;
774
+ if ( ( options & SearchOptions . Count ) != 0 )
775
+ command += "COUNT " ;
776
+ if ( ( options & SearchOptions . Min ) != 0 )
777
+ command += "MIN " ;
778
+ if ( ( options & SearchOptions . Max ) != 0 )
779
+ command += "MAX " ;
780
+ command = command . TrimEnd ( ) ;
781
+ } else {
782
+ command += "ALL" ;
783
+ }
784
+
785
+ command += ") " ;
918
786
}
919
- command += ") " ;
920
787
921
788
if ( charset != null && args . Count > 0 && ! Engine . UTF8Enabled )
922
789
command += "CHARSET " + charset + " " ;
923
790
924
791
command += expr + "\r \n " ;
925
792
926
793
var ic = new ImapCommand ( Engine , cancellationToken , this , command , args . ToArray ( ) ) ;
927
- ic . RegisterUntaggedHandler ( "ESEARCH" , ESearchMatchesAsync ) ;
794
+ ic . UserData = new SearchResults ( UidValidity , SortOrder . Ascending ) ;
795
+
796
+ if ( ( Engine . Capabilities & ImapCapabilities . ESearch ) != 0 )
797
+ ic . RegisterUntaggedHandler ( "ESEARCH" , ESearchMatchesAsync ) ;
928
798
929
799
// Note: always register the untagged SEARCH handler because some servers will brokenly
930
800
// respond with "* SEARCH ..." instead of "* ESEARCH ..." even when using the extended
931
801
// search syntax.
932
802
ic . RegisterUntaggedHandler ( "SEARCH" , SearchMatchesAsync ) ;
933
- ic . UserData = new SearchResults ( UidValidity ) ;
934
803
935
804
Engine . QueueCommand ( ic ) ;
936
805
@@ -1338,9 +1207,6 @@ async Task<IList<UniqueId>> SortAsync (SearchQuery query, IList<OrderBy> orderBy
1338
1207
1339
1208
async Task < SearchResults > SortAsync ( SearchOptions options , SearchQuery query , IList < OrderBy > orderBy , bool doAsync , bool retry , CancellationToken cancellationToken )
1340
1209
{
1341
- var args = new List < object > ( ) ;
1342
- string charset ;
1343
-
1344
1210
if ( query == null )
1345
1211
throw new ArgumentNullException ( nameof ( query ) ) ;
1346
1212
@@ -1352,35 +1218,47 @@ async Task<SearchResults> SortAsync (SearchOptions options, SearchQuery query, I
1352
1218
1353
1219
CheckState ( true , false ) ;
1354
1220
1355
- if ( ( Engine . Capabilities & ImapCapabilities . ESort ) == 0 )
1221
+ if ( options != SearchOptions . None && ( Engine . Capabilities & ImapCapabilities . ESort ) == 0 )
1356
1222
throw new NotSupportedException ( "The IMAP server does not support the ESORT extension." ) ;
1357
1223
1224
+ var args = new List < object > ( ) ;
1358
1225
var optimized = query . Optimize ( new ImapSearchQueryOptimizer ( ) ) ;
1359
- var expr = BuildQueryExpression ( optimized , args , out charset ) ;
1226
+ var expr = BuildQueryExpression ( optimized , args , out string charset ) ;
1360
1227
var order = BuildSortOrder ( orderBy ) ;
1228
+ var command = "UID SORT " ;
1361
1229
1362
- var command = "UID SORT RETURN (" ;
1363
- if ( options != SearchOptions . All && options != 0 ) {
1364
- if ( ( options & SearchOptions . All ) != 0 )
1365
- command += "ALL " ;
1366
- if ( ( options & SearchOptions . Relevancy ) != 0 )
1367
- command += "RELEVANCY " ;
1368
- if ( ( options & SearchOptions . Count ) != 0 )
1369
- command += "COUNT " ;
1370
- if ( ( options & SearchOptions . Min ) != 0 )
1371
- command += "MIN " ;
1372
- if ( ( options & SearchOptions . Max ) != 0 )
1373
- command += "MAX " ;
1374
- command = command . TrimEnd ( ) ;
1230
+ if ( ( Engine . Capabilities & ImapCapabilities . ESort ) != 0 ) {
1231
+ command += "RETURN (" ;
1232
+
1233
+ if ( options != SearchOptions . All && options != SearchOptions . None ) {
1234
+ if ( ( options & SearchOptions . All ) != 0 )
1235
+ command += "ALL " ;
1236
+ if ( ( options & SearchOptions . Relevancy ) != 0 )
1237
+ command += "RELEVANCY " ;
1238
+ if ( ( options & SearchOptions . Count ) != 0 )
1239
+ command += "COUNT " ;
1240
+ if ( ( options & SearchOptions . Min ) != 0 )
1241
+ command += "MIN " ;
1242
+ if ( ( options & SearchOptions . Max ) != 0 )
1243
+ command += "MAX " ;
1244
+ command = command . TrimEnd ( ) ;
1245
+ } else {
1246
+ command += "ALL" ;
1247
+ }
1248
+
1249
+ command += ") " ;
1375
1250
}
1376
- command += ") " ;
1377
1251
1378
1252
command += order + " " + ( charset ?? "US-ASCII" ) + " " + expr + "\r \n " ;
1379
1253
1380
1254
var ic = new ImapCommand ( Engine , cancellationToken , this , command , args . ToArray ( ) ) ;
1381
- ic . RegisterUntaggedHandler ( "ESEARCH" , ESearchMatchesAsync ) ;
1382
1255
ic . UserData = new SearchResults ( UidValidity ) ;
1383
1256
1257
+ if ( ( Engine . Capabilities & ImapCapabilities . ESort ) != 0 )
1258
+ ic . RegisterUntaggedHandler ( "ESEARCH" , ESearchMatchesAsync ) ;
1259
+ else
1260
+ ic . RegisterUntaggedHandler ( "SORT" , SearchMatchesAsync ) ;
1261
+
1384
1262
Engine . QueueCommand ( ic ) ;
1385
1263
1386
1264
await Engine . RunAsync ( ic , doAsync ) . ConfigureAwait ( false ) ;
0 commit comments