/// <summary> /// Initialize the list of root folders. /// </summary> private void InitializeFolders(Guid parentId) { lock (DataModel.SyncRoot) { LambdaComparer <FolderTreeNode> folderTreeNodeComparer = new LambdaComparer <FolderTreeNode>((l, r) => l.Entity.Name.CompareTo(r.Entity.Name)); List <FolderTreeNode> folders = new List <FolderTreeNode>(); EntityRow parentEntityRow = DataModel.Entity.EntityKey.Find(parentId); foreach (EntityTreeRow entityTreeRow in parentEntityRow.GetEntityTreeRowsByFK_Entity_EntityTree_ParentId()) { FolderTreeNode folderTreeNode = new FolderTreeNode() { Entity = new Entity(entityTreeRow.EntityRowByFK_Entity_EntityTree_ChildId) }; Int32 index = folders.BinarySearch(folderTreeNode, folderTreeNodeComparer); if (index < 0) { index = ~index; } folders.Insert(index, folderTreeNode); } this.Dispatcher.BeginInvoke(new Action(() => this.Folders = folders), DispatcherPriority.Normal); } }
/// <summary> /// Initialize the list of root folders. /// </summary> private void InitializeFolders() { lock (DataModel.SyncRoot) { LambdaComparer <FolderTreeNode> folderTreeNodeComparer = new LambdaComparer <FolderTreeNode>((l, r) => l.Entity.Name.CompareTo(r.Entity.Name)); List <FolderTreeNode> folders = new List <FolderTreeNode>(); EntityRow userEntityRow = DataModel.Entity.EntityKey.Find(UserContext.Instance.UserId); foreach (EntityTreeRow entityTreeRow in userEntityRow.GetEntityTreeRowsByFK_Entity_EntityTree_ParentId()) { FolderTreeNode folderTreeNode = new FolderTreeNode(entityTreeRow); Int32 index = folders.BinarySearch(folderTreeNode, folderTreeNodeComparer); if (index < 0) { index = ~index; } folders.Insert(index, folderTreeNode); } this.Dispatcher.BeginInvoke(new Action(delegate() { this.Folders = folders; this.ExpandFolder(); }), DispatcherPriority.Normal); } }
static IList <GameObject> SortByX(GameObject[] os) { var objects = new SortedList <Vector3, GameObject>(LambdaComparer.Create((Vector3 a, Vector3 b) => { if (a.y < b.y) { return(-1); } if (a.y == b.y && a.x < b.x) { return(-1); } if (a.y == b.y && a.x == b.x) { return(0); } return(1); })); foreach (var o in Selection.gameObjects) { objects.Add(o.transform.localPosition, o); } return(objects.Values); }
public void Classes_with_single_non_equal_compared_value_are_different() { _right.IntegerValue = -1; var comparer = new LambdaComparer<ClassWithProperties>(x => x.IntegerValue); Assert.IsFalse(comparer.Equals(_left, _right)); }
public void Classes_with_multiple_compared_values_for_which_only_the_first_is_equal_are_different() { _right.StringValue = null; var comparer = new LambdaComparer<ClassWithProperties>(x => x.IntegerValue, x => x.StringValue); Assert.IsFalse(comparer.Equals(_left, _right)); }
public void TestDistincUntilChanged() { var nums = new[] { 1, 1, 2, 2, 3, 3 }; nums .DistinctUntilChanged(LambdaComparer.Factory <int>((i1, i2) => i1 == i2)) .Do(Console.WriteLine) .Count(); }
public static void sort <T_Type>( T_Type[] inoutArray, int inStartIndex, int inLength, System.Func <T_Type, T_Type, Comparation> inLambda) { XUtils.check(null != inLambda); System.Array.Sort(inoutArray, inStartIndex, inLength, LambdaComparer <T_Type> .getForLambda(inLambda) ); }
public void Classes_with_single_compared_null_value_are_equal() { _right.StringValue = null; _left.StringValue = null; var comparer = new LambdaComparer<ClassWithProperties>(x => x.StringValue); Assert.IsTrue(comparer.Equals(_left, _right)); }
public static void AreEqual <T>(this Assert assert, T expected, T actual, CompareFunc <T> compareFunc) { var comparer = new LambdaComparer <T>(compareFunc); CollectionAssert.AreEqual( new[] { expected }, new[] { actual }, comparer, $"\nExpected: <{expected}>.\nActual: <{actual}>."); }
static void FileMatch1(int count) { var comparer = new LambdaComparer<Item>((x,y)=>x.Name == y.Name); using (var traker = new TimeTick(string.Format("Test1 - Using Intersect ", count, count * 3))) { var items = LeftItems.Intersect(RightItems, comparer); traker.Stop(items.Count()); } }
public void hashCode_should_be_the_func_result() { var compare = new LambdaComparer <Person>((x, y) => x.firstname == y.firstname, z => z.age.GetHashCode()); var p = new Person { age = 1 }; Console.WriteLine(compare.GetHashCode(p)); Assert.Equal(p.age.GetHashCode(), compare.GetHashCode(p)); }
public float time(float d) { int i = Array.BinarySearch(this.d, Tuple.Create(0f, d) , LambdaComparer.Create((Tuple <float, float> a, Tuple <float, float> b) => Comparer <float> .Default.Compare(a.Item2, b.Item2))); if (i >= 0) { return(this.d[i].Item1); } i = -i - 1; return(d.InvLerp(this.d[i - 1].Item2, this.d[i].Item2).Lerp(this.d[i - 1].Item1, this.d[i].Item1)); }
public float distance(float t) { int i = Array.BinarySearch(d, Tuple.Create(t, 0f) , LambdaComparer.Create((Tuple <float, float> a, Tuple <float, float> b) => Comparer <float> .Default.Compare(a.Item1, b.Item1))); if (i >= 0) { return(d[i].Item2); } i = -i - 1; return(t.InvLerp(d[i - 1].Item1, d[i].Item1).Lerp(d[i - 1].Item2, d[i].Item2)); }
public void Equals_given_same_reference_returns_True() { // arrange object object1 = new object(); object object2 = object1; IEqualityComparer<object> comparer = new LambdaComparer<object>((x, y) => x.Equals(y)); // act bool equals = comparer.Equals(object1, object2); // assert Assert.IsTrue(equals); }
public void Equals_given_true_predicate_returns_True() { // arrange DateTime dateTime1 = DateTime.Today; DateTime dateTime2 = DateTime.Today; IEqualityComparer<DateTime> comparer = new LambdaComparer<DateTime>((x, y) => x.Equals(y)); // act bool equals = comparer.Equals(dateTime1, dateTime2); // assert Assert.IsTrue(equals); }
public void Equals_given_false_predicate_returns_False() { // arrange DateTime dateTime1 = DateTime.MinValue; DateTime dateTime2 = DateTime.MaxValue; IEqualityComparer<DateTime> comparer = new LambdaComparer<DateTime>((x, y) => x.Equals(y)); // act bool equals = comparer.Equals(dateTime1, dateTime2); // assert Assert.IsFalse(equals); }
public void TransferToDifferentPQTest() { var q1 = new PriorityQueueExtended <CPersonWithIndex>(sm_peopleWithIndex); var q2 = new PriorityQueueOptimized <CPersonWithIndex>(q1, LambdaComparer <CPersonWithIndex> .FromFunc((_l, _r) => _r.Age - _l.Age)); var arr1 = q1.ToArray(); var arr2 = q2.ToArray(); Assert.AreEqual(arr1.Length, arr2.Length, "Array lengths aren't equal"); for (var i = 0; i < arr1.Length; i++) { var j = arr1.Length - i - 1; Assert.AreEqual(arr1[i], arr2[j], "The objects are not equal at index " + i + " / " + j); } }
/// <summary> /// Sorts the source collection using custom sort criteria. /// </summary> /// <remarks> /// Please note that your compare function needs to take care about /// proper conversion of types to be comparable! /// </remarks> /// <param name="source"> /// The source collection to sort. /// </param> /// <param name="args"> /// Sort criteria to use. /// </param> /// <returns> /// A sorted array containing collection elements. /// </returns> public object Execute(ICollection source, object[] args) { if (source == null || source.Count == 0) { return(source); } if (args == null || args.Length != 1) { throw new ArgumentException("compare expression is a required argument for orderBy"); } var arg = args[0]; IComparer comparer = null; if (arg is string) { var expCompare = Expression.Parse((string)arg); comparer = new SimpleExpressionComparer(expCompare); } else if (arg is IComparer) { comparer = (IComparer)arg; } else if (arg is LambdaExpressionNode) { var fnCompare = (LambdaExpressionNode)arg; if (fnCompare.ArgumentNames.Length != 2) { throw new ArgumentException("compare function must accept 2 arguments"); } comparer = new LambdaComparer(fnCompare); } else if (arg is Delegate) { comparer = new DelegateComparer((Delegate)arg); } AssertUtils.ArgumentNotNull(comparer, "comparer", "orderBy(comparer) argument 'comparer' does not evaluate to a supported type"); var list = new ArrayList(source); list.Sort(comparer); return(list); }
/// <summary> /// Sorts the source collection using custom sort criteria. /// </summary> /// <remarks> /// Please note that your compare function needs to take care about /// proper conversion of types to be comparable! /// </remarks> /// <param name="source"> /// The source collection to sort. /// </param> /// <param name="args"> /// Sort criteria to use. /// </param> /// <returns> /// A sorted array containing collection elements. /// </returns> public object Execute(ICollection source, object[] args) { if (source == null || source.Count == 0) { return source; } if (args == null || args.Length != 1) { throw new ArgumentException("compare expression is a required argument for orderBy"); } var arg = args[0]; IComparer comparer = null; if (arg is string) { var expCompare = Expression.Parse((string) arg); comparer = new SimpleExpressionComparer(expCompare); } else if (arg is IComparer) { comparer = (IComparer) arg; } else if (arg is LambdaExpressionNode) { var fnCompare = (LambdaExpressionNode) arg; if (fnCompare.ArgumentNames.Length != 2) { throw new ArgumentException("compare function must accept 2 arguments"); } comparer = new LambdaComparer(fnCompare); } else if (arg is Delegate) { comparer = new DelegateComparer((Delegate) arg); } AssertUtils.ArgumentNotNull(comparer, "comparer", "orderBy(comparer) argument 'comparer' does not evaluate to a supported type"); var list = new ArrayList(source); list.Sort(comparer); return list; }
/// <summary> /// Initialize the list of root folders. /// </summary> private void InitializeFolders() { lock (DataModel.SyncRoot) { LambdaComparer <FolderTreeNode> folderTreeNodeComparer = new LambdaComparer <FolderTreeNode>((l, r) => l.Entity.Name.CompareTo(r.Entity.Name)); List <FolderTreeNode> folders = new List <FolderTreeNode>(); var entities = DataModel.Entity.Where(row => (row.GetFolderRows().Length > 0 || row.GetBlotterRows().Length > 0)); foreach (EntityRow entityRow in entities) { Boolean topLevel = true; // Determine whether a folder/blotter has any parent folders or blotters. foreach (EntityTreeRow entityTreeRow in entityRow.GetEntityTreeRowsByFK_Entity_EntityTree_ChildId()) { EntityRow parent = entityTreeRow.EntityRowByFK_Entity_EntityTree_ParentId; if (parent.GetFolderRows().Length > 0 || parent.GetBlotterRows().Length > 0) { topLevel = false; break; } } // If they don't add them to our list. if (topLevel) { FolderTreeNode folderTreeNode = new FolderTreeNode(entityRow); Int32 index = folders.BinarySearch(folderTreeNode, folderTreeNodeComparer); if (index < 0) { index = ~index; } folders.Insert(index, folderTreeNode); } } this.Dispatcher.BeginInvoke(new Action(() => this.Folders = folders), DispatcherPriority.Normal); } }
/// <summary> /// Working job /// </summary> /// <param name="sender">Object</param> /// <param name="e">Argument to the work (none there)</param> private void Bw_DoWork(object sender, DoWorkEventArgs e) { ReportProgress(0, null); NDSAdvanScene xmlAvant = new NDSAdvanScene(); xmlAvant.Load(_xmlAvant); NDSAdvanScene xmlApres = new NDSAdvanScene(); xmlApres.Load(_xmlApres); ReportProgress(0, "Calculating Differences ..."); IEqualityComparer <NDS_Rom> comparerCRC = new LambdaComparer <NDS_Rom>( (o, n) => o.RomCRC == n.RomCRC); List <NDS_Rom> diffAll = xmlApres.DataBase.Except(xmlAvant.DataBase, comparerCRC).ToList(); ReportProgress(45, string.Format("Found {0} differences", diffAll.Count)); IEqualityComparer <NDS_Rom> comparerRomNumber = new LambdaComparer <NDS_Rom>( (o, n) => o.ReleaseNumber == n.ReleaseNumber); List <NDS_Rom> diffNew = xmlApres.DataBase.Except(xmlAvant.DataBase, comparerRomNumber).ToList(); ReportProgress(90, string.Format("Found {0} new Roms", diffNew.Count)); List <NDS_Rom> diffModified = diffAll.Except(diffNew).ToList(); ReportProgress(100, string.Format("Found {0} modified Roms", diffModified.Count)); for (int i = 0; i < diffNew.Count; i++) { ReportProgress((i + 1) * 100 / diffAll.Count, string.Format("New Rom : {0}", diffNew[i].Title)); } for (int i = 0; i < diffModified.Count; i++) { ReportProgress((i + 1 + diffNew.Count) * 100 / diffAll.Count, string.Format("Modified Rom : {0}", diffModified[i].Title)); } }
// ---------------------- Lists /// <summary> /// Sorts the elements of a sequence in ascending order according to a key. /// Unlike standard Linq NOT a stable sort. /// </summary> /// <param name="source">A sequence of values to order.</param> /// <param name="keySelector">A function to extract a key from an element.</param> /// <param name="comparer">A Comparer to compare keys.</param> /// <returns>A sequence whose elements are ordered according to a key</returns> public static List <TSource> OrderByF <TSource, TKey>(this List <TSource> source, Func <TSource, TKey> keySelector, IComparer <TKey> comparer = null) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (keySelector == null) { throw Error.ArgumentNull("keySelector"); } if (comparer == null) { comparer = Comparer <TKey> .Default; } List <TSource> result = new List <TSource>(source); LambdaComparer <TSource, TKey> lambdaComparer = new LambdaComparer <TSource, TKey>(keySelector, comparer); result.Sort(lambdaComparer); return(result); }
public ArbitrarySortedDictionary(Func <TVALUE, TSORT> sortFunc) { _SortFunc = sortFunc; Func <SortedDictionaryKey, SortedDictionaryKey, Int32> compFunc = (x, y) => { Int32 sortValComp = 0; if (x.SortVal != null) { sortValComp = x.SortVal.CompareTo(y.SortVal); } if (sortValComp != 0) { return(sortValComp); } if (x.Key != null) { return(x.Key.CompareTo(y.Key)); } return(y.Key == null ? 0 : -1); }; var comparer = new LambdaComparer <SortedDictionaryKey>(compFunc); _SortedKeys = new SortedList <SortedDictionaryKey, TKEY>(comparer); _SortedValues = new SortedList <SortedDictionaryKey, TVALUE>(comparer); }
private static bool CheckDuplicates(ListBox ItemsBox, LambdaComparer comparer) { for (int i = 0; i < ItemsBox.Items.Count; i++) { object item = ItemsBox.Items[i]; if (comparer( (item as ListBoxItem).Tag )) // for certain data formats we must do equal not eq { if (i != 0) { ItemsBox.Items.RemoveAt(i); ItemsBox.Items.Insert(0, item); } return true; } } return false; }
public virtual IEnumerable<Bed> GetUnassignedBeds(IEnumerable<Bed> beds) { var comparer = new LambdaComparer<Bed>((first, second) => first.Code == second.Code); return beds.Except(AssignedBeds, comparer); }
public void Exception_is_thrown_if_no_value_getters_are_specified() { var comparer = new LambdaComparer<ClassWithProperties>(); comparer.Equals(_left, _right); }
/// <summary> /// Send email(s) over SendGrid’s v3 Web API. /// </summary> /// <param name="personalizations">The personalizations.</param> /// <param name="subject">The subject.</param> /// <param name="contents">The contents.</param> /// <param name="from">From.</param> /// <param name="replyTo">The reply to.</param> /// <param name="attachments">The attachments.</param> /// <param name="templateId">The template identifier.</param> /// <param name="sections">The sections.</param> /// <param name="headers">The headers.</param> /// <param name="categories">The categories.</param> /// <param name="customArgs">The custom arguments.</param> /// <param name="sendAt">The send at.</param> /// <param name="batchId">The batch identifier.</param> /// <param name="unsubscribeOptions">The unsubscribe options.</param> /// <param name="ipPoolName">Name of the ip pool.</param> /// <param name="mailSettings">The mail settings.</param> /// <param name="trackingSettings">The tracking settings.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// The message id. /// </returns> /// <exception cref="ArgumentOutOfRangeException">Too many recipients.</exception> /// <exception cref="Exception">Email exceeds the size limit.</exception> public async Task <string> SendAsync( IEnumerable <MailPersonalization> personalizations, string subject, IEnumerable <MailContent> contents, MailAddress from, MailAddress replyTo = null, IEnumerable <Attachment> attachments = null, string templateId = null, IEnumerable <KeyValuePair <string, string> > sections = null, IEnumerable <KeyValuePair <string, string> > headers = null, IEnumerable <string> categories = null, IEnumerable <KeyValuePair <string, string> > customArgs = null, DateTime?sendAt = null, string batchId = null, UnsubscribeOptions unsubscribeOptions = null, string ipPoolName = null, MailSettings mailSettings = null, TrackingSettings trackingSettings = null, CancellationToken cancellationToken = default) { if (personalizations == null || !personalizations.Any()) { throw new ArgumentNullException(nameof(personalizations)); } // This comparer is used to perform case-insensitive comparisons of email addresses var emailAddressComparer = new LambdaComparer <MailAddress>((address1, address2) => address1.Email.Equals(address2.Email, StringComparison.OrdinalIgnoreCase)); // It's important to make a copy of the personalizations to ensure we don't modify the original array var personalizationsCopy = personalizations.Where(p => p != null).ToArray(); foreach (var personalization in personalizationsCopy) { // Avoid duplicate addresses. This is important because SendGrid does not throw any // exception when a recipient is duplicated (which gives you the impression the email // was sent) but it does not actually send the email personalization.To = personalization.To? .Distinct(emailAddressComparer) .ToArray(); personalization.Cc = personalization.Cc? .Distinct(emailAddressComparer) .Except(personalization.To, emailAddressComparer) .ToArray(); personalization.Bcc = personalization.Bcc? .Distinct(emailAddressComparer) .Except(personalization.To, emailAddressComparer) .Except(personalization.Cc, emailAddressComparer) .ToArray(); // SendGrid doesn't like empty arrays if (!(personalization.To?.Any() ?? true)) { personalization.To = null; } if (!(personalization.Cc?.Any() ?? true)) { personalization.Cc = null; } if (!(personalization.Bcc?.Any() ?? true)) { personalization.Bcc = null; } // Surround recipient names with double-quotes if necessary personalization.To = EnsureRecipientsNamesAreQuoted(personalization.To); personalization.Cc = EnsureRecipientsNamesAreQuoted(personalization.Cc); personalization.Bcc = EnsureRecipientsNamesAreQuoted(personalization.Bcc); } // The total number of recipients must be less than 1000. This includes all recipients defined within the to, cc, and bcc parameters, across each object that you include in the personalizations array. var numberOfRecipients = personalizationsCopy.Sum(p => p.To?.Count(r => r != null) ?? 0); numberOfRecipients += personalizationsCopy.Sum(p => p.Cc?.Count(r => r != null) ?? 0); numberOfRecipients += personalizationsCopy.Sum(p => p.Bcc?.Count(r => r != null) ?? 0); if (numberOfRecipients >= 1000) { throw new ArgumentOutOfRangeException("The total number of recipients must be less than 1000"); } // SendGrid throws an unhelpful error when the Bcc email address is an empty string if (mailSettings?.Bcc != null && string.IsNullOrWhiteSpace(mailSettings.Bcc.EmailAddress)) { mailSettings.Bcc.EmailAddress = null; } var isDynamicTemplate = Template.IsDynamic(templateId); var personalizationConverter = new MailPersonalizationConverter(isDynamicTemplate); var data = new JObject(); data.AddPropertyIfValue("from", from); data.AddPropertyIfValue("reply_to", replyTo); data.AddPropertyIfValue("subject", subject); data.AddPropertyIfValue("content", contents); data.AddPropertyIfValue("attachments", attachments); data.AddPropertyIfValue("template_id", templateId); data.AddPropertyIfValue("categories", categories); data.AddPropertyIfValue("send_at", sendAt?.ToUnixTime()); data.AddPropertyIfValue("batch_id", batchId); data.AddPropertyIfValue("asm", unsubscribeOptions); data.AddPropertyIfValue("ip_pool_name", ipPoolName); data.AddPropertyIfValue("mail_settings", mailSettings); data.AddPropertyIfValue("tracking_settings", trackingSettings); data.AddPropertyIfValue("personalizations", personalizationsCopy, personalizationConverter); if (sections != null && sections.Any()) { var sctns = new JObject(); foreach (var section in sections) { sctns.Add(section.Key, section.Value); } data.Add("sections", sctns); } if (headers != null && headers.Any()) { var hdrs = new JObject(); foreach (var header in headers) { hdrs.Add(header.Key, header.Value); } data.Add("headers", hdrs); } if (customArgs != null && customArgs.Any()) { var args = new JObject(); foreach (var customArg in customArgs) { args.Add(customArg.Key, customArg.Value); } data.Add("custom_args", args); } // Sendgrid does not allow emails that exceed 30MB var contentSize = JsonConvert.SerializeObject(data, Formatting.None).Length; if (contentSize > MAX_EMAIL_SIZE) { throw new Exception("Email exceeds the size limit"); } var response = await _client .PostAsync($"{_endpoint}/send") .WithJsonBody(data) .WithCancellationToken(cancellationToken) .AsResponse() .ConfigureAwait(false); if (response.Message.Headers.TryGetValues("X-Message-Id", out IEnumerable <string> values)) { return(values?.FirstOrDefault()); } return(null); }
public void Computed_values_can_be_used_for_comparison() { _left.StringValue = "ABC"; _right.StringValue = "abc"; _left.IntegerValue = 1; _right.IntegerValue = 2; var comparer = new LambdaComparer<ClassWithProperties>( x => x.IntegerValue > 0, x => x.StringValue.ToLower(), x => x.StringValue.ToUpper() + x.IntegerValue / x.IntegerValue, x => true); Assert.IsTrue(comparer.Equals(_left, _right)); }
/// <summary> /// Send email(s) over SendGrid’s v3 Web API. /// </summary> /// <param name="personalizations">The personalizations.</param> /// <param name="subject">The subject.</param> /// <param name="contents">The contents.</param> /// <param name="from">From.</param> /// <param name="replyTo">The reply-to addresses.</param> /// <param name="attachments">The attachments.</param> /// <param name="templateId">The template identifier.</param> /// <param name="headers">The headers.</param> /// <param name="categories">The categories.</param> /// <param name="customArgs">The custom arguments.</param> /// <param name="sendAt">The send at.</param> /// <param name="batchId">The batch identifier.</param> /// <param name="unsubscribeOptions">The unsubscribe options.</param> /// <param name="ipPoolName">Name of the ip pool.</param> /// <param name="mailSettings">The mail settings.</param> /// <param name="trackingSettings">The tracking settings.</param> /// <param name="priority">The priority.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// The message id. /// </returns> /// <exception cref="ArgumentOutOfRangeException">Too many recipients.</exception> /// <exception cref="Exception">Email exceeds the size limit.</exception> public async Task <string> SendAsync( IEnumerable <MailPersonalization> personalizations, string subject, IEnumerable <MailContent> contents, MailAddress from, IEnumerable <MailAddress> replyTo = null, IEnumerable <Attachment> attachments = null, string templateId = null, IEnumerable <KeyValuePair <string, string> > headers = null, IEnumerable <string> categories = null, IEnumerable <KeyValuePair <string, string> > customArgs = null, DateTime?sendAt = null, string batchId = null, UnsubscribeOptions unsubscribeOptions = null, string ipPoolName = null, MailSettings mailSettings = null, TrackingSettings trackingSettings = null, MailPriority priority = MailPriority.Normal, CancellationToken cancellationToken = default) { if (_client?.BaseClient?.DefaultRequestHeaders?.Authorization?.Scheme?.Equals("Basic", StringComparison.OrdinalIgnoreCase) ?? false) { const string errorMessage = "SendGrid does not support Basic authentication when sending transactional emails."; const string diagnosticLog = "This request was not dispatched to SendGrid because the exception returned by their API in this scenario is not clear: 'Permission denied, wrong credentials'."; throw new SendGridException(errorMessage, null, diagnosticLog); } if (personalizations == null || !personalizations.Any()) { throw new ArgumentNullException(nameof(personalizations)); } // This comparer is used to perform case-insensitive comparisons of email addresses var emailAddressComparer = new LambdaComparer <MailAddress>((address1, address2) => address1.Email.Equals(address2.Email, StringComparison.OrdinalIgnoreCase)); // It's important to make a copy of the personalizations to ensure we don't modify the original array var personalizationsCopy = personalizations.Where(p => p != null).ToArray(); foreach (var personalization in personalizationsCopy) { // Make sure the arrays are not null otherwise Linq's 'Except' method will throw a ArgumentNull exception (See GH-286). if (personalization.To == null) { personalization.To = Array.Empty <MailAddress>(); } if (personalization.Cc == null) { personalization.Cc = Array.Empty <MailAddress>(); } if (personalization.Bcc == null) { personalization.Bcc = Array.Empty <MailAddress>(); } // Avoid duplicate addresses. This is important because SendGrid does not throw any // exception when a recipient is duplicated (which gives you the impression the email // was sent) but it does not actually send the email personalization.To = personalization.To .Distinct(emailAddressComparer) .ToArray(); personalization.Cc = personalization.Cc .Distinct(emailAddressComparer) .Except(personalization.To, emailAddressComparer) .ToArray(); personalization.Bcc = personalization.Bcc .Distinct(emailAddressComparer) .Except(personalization.To, emailAddressComparer) .Except(personalization.Cc, emailAddressComparer) .ToArray(); // SendGrid doesn't like empty arrays if (!personalization.To.Any()) { personalization.To = null; } if (!personalization.Cc.Any()) { personalization.Cc = null; } if (!personalization.Bcc.Any()) { personalization.Bcc = null; } // Surround recipient names with double-quotes if necessary personalization.To = EnsureRecipientsNamesAreQuoted(personalization.To); personalization.Cc = EnsureRecipientsNamesAreQuoted(personalization.Cc); personalization.Bcc = EnsureRecipientsNamesAreQuoted(personalization.Bcc); // Indicate if a dynamic template is being used. This is used by MailPersonalizationConverter to generate the appropriate JSON personalization.IsUsedWithDynamicTemplate = Template.IsDynamic(templateId); } // The total number of recipients must be less than 1000. This includes all recipients defined within the to, cc, and bcc parameters, across each object that you include in the personalizations array. var numberOfRecipients = personalizationsCopy.Sum(p => p.To?.Count(r => r != null) ?? 0); numberOfRecipients += personalizationsCopy.Sum(p => p.Cc?.Count(r => r != null) ?? 0); numberOfRecipients += personalizationsCopy.Sum(p => p.Bcc?.Count(r => r != null) ?? 0); if (numberOfRecipients >= 1000) { throw new ArgumentOutOfRangeException(nameof(numberOfRecipients), numberOfRecipients, "The total number of recipients must be less than 1000"); } // Get the priority headers if (!_priorityHeaders.TryGetValue(priority, out KeyValuePair <string, string>[] priorityHeaders)) { throw new Exception($"{priority} is an unknown priority"); } // Combine headers with priority headers making sure not to duplicate priority headers var combinedHeaders = (headers ?? Array.Empty <KeyValuePair <string, string> >()) .Where(kvp => !priorityHeaders.Any(p => p.Key.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase))) .Concat(priorityHeaders); // Remove duplicates from the list of 'reply-to' addresses var cleanReplyTo = replyTo?.Distinct(emailAddressComparer) ?? Enumerable.Empty <MailAddress>(); // SendGrid allows no more than 1000 'reply-to' addresses var numberOfReplyToAddresses = cleanReplyTo.Count(); if (numberOfReplyToAddresses > 1000) { throw new ArgumentOutOfRangeException(nameof(numberOfReplyToAddresses), numberOfReplyToAddresses, "The number of distinct reply-to addresses can't exceed 1000"); } // Serialize the mail message var data = new StrongGridJsonObject(); data.AddProperty("from", from); data.AddProperty("reply_to_list", cleanReplyTo); data.AddProperty("subject", subject); data.AddProperty("content", contents); data.AddProperty("attachments", attachments); data.AddProperty("template_id", templateId); data.AddProperty("categories", categories); data.AddProperty("send_at", sendAt?.ToUnixTime()); data.AddProperty("batch_id", batchId); data.AddProperty("asm", unsubscribeOptions); data.AddProperty("ip_pool_name", ipPoolName); data.AddProperty("mail_settings", mailSettings); data.AddProperty("tracking_settings", trackingSettings); data.AddProperty("personalizations", personalizationsCopy); data.AddProperty("headers", ConvertEnumerationToJson(combinedHeaders)); data.AddProperty("custom_args", ConvertEnumerationToJson(customArgs)); // SendGrid does not allow emails that exceed 30MB var serializedContent = JsonSerializer.Serialize(data, typeof(StrongGridJsonObject), JsonFormatter.SerializationContext); if (serializedContent.Length > MAX_EMAIL_SIZE) { throw new Exception("Email exceeds the size limit"); } // Send the request var response = await _client .PostAsync($"{_endpoint}/send") .WithJsonBody(data) .WithCancellationToken(cancellationToken) .AsResponse() .ConfigureAwait(false); // Get the messageId from the response return(response.Message.Headers.GetValue("X-Message-Id")); }
public virtual IEnumerable <Bed> GetUnassignedBeds(IEnumerable <Bed> beds) { var comparer = new LambdaComparer <Bed>((first, second) => first.Code == second.Code); return(beds.Except(AssignedBeds, comparer)); }
private void ExtractBasicBlocksOfMethod(MethodReference method_reference) { MethodReference original_method_reference = method_reference; _methods_done.Add(original_method_reference.FullName); // MethodReference new_method_reference = original_method_reference.SubstituteMethod2(); // method_reference = new_method_reference != null ? new_method_reference : original_method_reference; MethodDefinition method_definition = method_reference.Resolve(); if (method_definition == null || method_definition.Body == null) { return; } int change_set = Cfg.StartChangeSet(); int instruction_count = method_definition.Body.Instructions.Count; List <INST> split_point = new List <INST>(); CFG.Vertex basic_block = (CFG.Vertex)Cfg.AddVertex(new CFG.Vertex() { Name = Cfg.NewNodeNumber().ToString() }); basic_block._method_definition = method_definition; basic_block._method_reference = original_method_reference; basic_block.Entry = basic_block; basic_block.Exit = basic_block; basic_block.Entry.BlocksOfMethod = new List <CFG.Vertex>(); basic_block.Entry.BlocksOfMethod.Add(basic_block); Cfg.Entries.Add(basic_block); // Add instructions to the basic block, including debugging information. // First, get debugging information on line/column/offset in method. if (!original_method_reference.Module.HasSymbols) { // Try to get symbols, but if none available, don't worry about it. try { original_method_reference.Module.ReadSymbols(); } catch { } } var symbol_reader = original_method_reference.Module.SymbolReader; var method_debug_information = symbol_reader?.Read(method_definition); Collection <SequencePoint> sequence_points = method_debug_information != null ? method_debug_information.SequencePoints : new Collection <SequencePoint>(); Mono.Cecil.Cil.MethodBody body = method_definition.Body; if (body == null) { throw new Exception("Body null, not expecting it to be."); } if (body.Instructions == null) { throw new Exception("Body has instructions collection."); } if (body.Instructions.Count == 0) { throw new Exception("Body instruction count is zero."); } SequencePoint previous_sp = null; for (int j = 0; j < instruction_count; ++j) { Mono.Cecil.Cil.Instruction instruction = body.Instructions[j]; SequencePoint sp = sequence_points.Where(s => { return(s.Offset == instruction.Offset); }).FirstOrDefault(); if (sp == null) { sp = previous_sp; } INST wrapped_instruction = INST.Wrap(instruction, basic_block, sp); basic_block.Instructions.Add(wrapped_instruction); if (sp != null) { previous_sp = sp; } } var instructions_before_splits = basic_block.Instructions.ToList(); // Accumulate targets of jumps. These are split points for block "v". // Accumalated splits are in "leader_list" following this for-loop. for (int j = 0; j < instruction_count; ++j) { INST wrapped_instruction = basic_block.Instructions[j]; Mono.Cecil.Cil.OpCode opcode = wrapped_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { object operand = wrapped_instruction.Operand; // Two cases of branches: // 1) operand is a single instruction; // 2) operand is an array of instructions via a switch instruction. // In doing this type casting, the resulting instructions are turned // into def's, and operands no longer correspond to what was in the original // method. We override the List<> compare to correct this problem. Mono.Cecil.Cil.Instruction single_instruction = operand as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] array_of_instructions = operand as Mono.Cecil.Cil.Instruction[]; if (single_instruction != null) { INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == single_instruction.Offset && basic_block.Instructions[i].OpCode == single_instruction.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } else if (array_of_instructions != null) { foreach (var ins in array_of_instructions) { Debug.Assert(ins != null); INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } } else { throw new Exception("Unknown operand type for basic block partitioning."); } } break; } // Split blocks after certain instructions, too. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Return: case Mono.Cecil.Cil.FlowControl.Throw: { if (flow_control == Mono.Cecil.Cil.FlowControl.Call && !Campy.Utils.Options.IsOn("split_at_calls")) { break; } if (j + 1 < instruction_count) { var ins = basic_block.Instructions[j + 1].Instruction; INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } } break; } } // Get try-catch blocks and add those split points. foreach (var eh in body.ExceptionHandlers) { var start = eh.TryStart; var end = eh.TryEnd; // Split at try start. Instruction ins = start; INST sp = null; for (int i = 0; i < basic_block.Instructions.Count(); ++i) { if (basic_block.Instructions[i].Offset == ins.Offset && basic_block.Instructions[i].OpCode == ins.OpCode) { sp = basic_block.Instructions[i]; break; } } if (sp == null) { throw new Exception("Instruction go to not found."); } bool found = false; foreach (INST split in split_point) { if (split.Offset == sp.Offset && split.OpCode == sp.OpCode) { found = true; break; } } if (!found) { split_point.Add(sp); } } // Note, we assume that these splits are within the same method. // Order the list according to offset from beginning of the method. List <INST> ordered_leader_list = new List <INST>(); for (int j = 0; j < instruction_count; ++j) { // Order jump targets. These denote locations // where to split blocks. However, it's ordered, // so that splitting is done from last instruction in block // to first instruction in block. INST i = basic_block.Instructions[j]; if (split_point.Contains(i, new LambdaComparer <INST>( (INST a, INST b) => { if (a.Offset != b.Offset) { return(false); } if (a.OpCode != b.OpCode) { return(false); } return(true); }))) { ordered_leader_list.Add(i); } } if (ordered_leader_list.Count != split_point.Count) { throw new Exception( "Mono Cecil giving weird results for instruction operand type casting. Size of original split points not the same as order list of split points."); } // Split block at all jump targets. foreach (INST i in ordered_leader_list) { var owner = Cfg.PeekChangeSet(change_set).Where( n => n.Instructions.Where(ins => { if (ins.Offset != i.Offset) { return(false); } if (ins.OpCode != i.OpCode) { return(false); } return(true); } ).Any()).ToList(); // Check if there are multiple nodes with the same instruction or if there isn't // any node found containing the instruction. Either way, it's a programming error. if (owner.Count != 1) { throw new Exception("Cannot find instruction!"); } CFG.Vertex target_node = owner.FirstOrDefault(); var j = target_node.Instructions.FindIndex(a => { if (a.Offset != i.Offset) { return(false); } if (a.OpCode != i.OpCode) { return(false); } return(true); }); CFG.Vertex new_node = Split(target_node, j); } LambdaComparer <Instruction> fixed_comparer = new LambdaComparer <Instruction>( (Instruction a, Instruction b) => a.Offset == b.Offset && a.OpCode == b.OpCode ); // Add in all edges. var list_new_nodes = Cfg.PopChangeSet(change_set); foreach (var node in list_new_nodes) { int node_instruction_count = node.Instructions.Count; INST last_instruction = node.Instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode opcode = last_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; // Add jump edge. switch (flow_control) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { // Two cases: i.Operand is a single instruction, or an array of instructions. if (last_instruction.Operand as Mono.Cecil.Cil.Instruction != null) { // Handel leave instructions with code below. if (!(last_instruction.OpCode.Code == Code.Leave || last_instruction.OpCode.Code == Code.Leave_S)) { Mono.Cecil.Cil.Instruction target_instruction = last_instruction.Operand as Mono.Cecil.Cil.Instruction; CFG.Vertex target_node = list_new_nodes.FirstOrDefault( (CFG.Vertex x) => { if (!fixed_comparer.Equals(x.Instructions.First().Instruction, target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } } else if (last_instruction.Operand as Mono.Cecil.Cil.Instruction[] != null) { foreach (Mono.Cecil.Cil.Instruction target_instruction in (last_instruction.Operand as Mono.Cecil.Cil.Instruction[])) { CFG.Vertex target_node = list_new_nodes.FirstOrDefault( (CFG.Vertex x) => { if (!fixed_comparer.Equals(x.Instructions.First().Instruction, target_instruction)) { return(false); } return(true); }); if (target_node != null) { Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } } } else { throw new Exception("Unknown operand type for conditional branch."); } break; } } // Add fall through edge. switch (flow_control) { //case Mono.Cecil.Cil.FlowControl.Branch: //case Mono.Cecil.Cil.FlowControl.Break: case Mono.Cecil.Cil.FlowControl.Call: case Mono.Cecil.Cil.FlowControl.Cond_Branch: case Mono.Cecil.Cil.FlowControl.Meta: case Mono.Cecil.Cil.FlowControl.Next: case Mono.Cecil.Cil.FlowControl.Phi: case Mono.Cecil.Cil.FlowControl.Throw: { int next = instructions_before_splits.FindIndex( n => { var r = n == last_instruction; return(r); } ); if (next < 0) { break; } next += 1; if (next >= instructions_before_splits.Count) { break; } var next_instruction = instructions_before_splits[next]; var owner = next_instruction.Block; CFG.Vertex target_node = owner; Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } break; case Mono.Cecil.Cil.FlowControl.Return: if (last_instruction.Instruction.OpCode.Code == Code.Endfinally) { // Although the exception handling is like a procedure call, // local variables are all accessible. So, we need to copy stack // values around. In addition, we have to create a fall through // even though there is stack unwinding. int next = instructions_before_splits.FindIndex( n => { var r = n == last_instruction; return(r); } ); if (next < 0) { break; } next += 1; if (next >= instructions_before_splits.Count) { break; } var next_instruction = instructions_before_splits[next]; var owner = next_instruction.Block; CFG.Vertex target_node = owner; Cfg.AddEdge(new CFG.Edge() { From = node, To = target_node }); } break; } } // Get inclusive start/exclusive end ranges of try/catch/finally. Dictionary <int, int> exclusive_eh_range = new Dictionary <int, int>(); foreach (var eh in body.ExceptionHandlers) { int try_start = eh.TryStart.Offset; int eh_end = eh.TryEnd != null ? eh.TryEnd.Offset : 0; if (eh.TryEnd != null && eh.TryEnd.Offset > eh_end) { eh_end = eh.TryEnd.Offset; } if (eh.HandlerEnd != null && eh.HandlerEnd.Offset > eh_end) { eh_end = eh.HandlerEnd.Offset; } exclusive_eh_range[try_start] = eh_end; } // Get inclusive start/inclusive end ranges of try/catch/finally. Dictionary <int, int> inclusive_eh_range = new Dictionary <int, int>(); foreach (var pair in exclusive_eh_range) { int previous_instruction_address = 0; foreach (var i in body.Instructions) { if (pair.Value == i.Offset) { inclusive_eh_range[pair.Key] = previous_instruction_address; break; } previous_instruction_address = i.Offset; } } // Get "finally" blocks for each try, if there is one. Dictionary <int, CFG.Vertex> try_finally_block = new Dictionary <int, CFG.Vertex>(); foreach (var eh in body.ExceptionHandlers) { if (eh.HandlerType == ExceptionHandlerType.Finally) { var finally_entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == eh.HandlerStart.Offset) { return(true); } else { return(false); } }).First(); try_finally_block[eh.TryStart.Offset] = finally_entry_block; } } // Set block properties. foreach (var eh in body.ExceptionHandlers) { var block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == eh.HandlerStart.Offset) { return(true); } else { return(false); } }).First(); block.CatchType = eh.CatchType; block.IsCatch = eh.HandlerType == ExceptionHandlerType.Catch; block.ExceptionHandler = eh; } // Get "try" block for each try. Dictionary <int, CFG.Vertex> try_entry_block = new Dictionary <int, CFG.Vertex>(); foreach (var pair in inclusive_eh_range) { int start = pair.Key; var entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == start) { return(true); } else { return(false); } }).First(); try_entry_block[start] = entry_block; } // Get entry block for each exception handler. Dictionary <int, CFG.Vertex> eh_entry_block = new Dictionary <int, CFG.Vertex>(); foreach (var eh in body.ExceptionHandlers) { int start = eh.HandlerStart.Offset; var entry_block = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == start) { return(true); } else { return(false); } }).First(); eh_entry_block[start] = entry_block; } foreach (var eh in body.ExceptionHandlers) { int start = eh.TryStart.Offset; var try_block = try_entry_block[start]; int eh_start = eh.HandlerStart.Offset; var eh_block = eh_entry_block[eh_start]; if (eh.HandlerType == ExceptionHandlerType.Finally) { continue; } foreach (var prev in list_new_nodes.First()._graph.Predecessors(try_block)) { Cfg.AddEdge(new CFG.Edge() { From = prev, To = eh_block }); } } // Go through all CIL "leave" instructions and draw up edges. Any leave to end of // endfinally block requires edge to finally block, not the following instruction. foreach (var node in list_new_nodes) { int node_instruction_count = node.Instructions.Count; INST leave_instruction = node.Instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode opcode = leave_instruction.OpCode; Mono.Cecil.Cil.FlowControl flow_control = opcode.FlowControl; if (!(leave_instruction.OpCode.Code == Code.Leave || leave_instruction.OpCode.Code == Code.Leave_S)) { continue; } // Link up any leave instructions object operand = leave_instruction.Operand; Mono.Cecil.Cil.Instruction single_instruction = operand as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] array_of_instructions = operand as Mono.Cecil.Cil.Instruction[]; if (single_instruction == null) { throw new Exception("Malformed leave instruction."); } KeyValuePair <int, int> pair = inclusive_eh_range.Where(p => p.Key <= leave_instruction.Instruction.Offset && leave_instruction.Instruction.Offset <= p.Value).FirstOrDefault(); // pair indicates what try/catch/finally block. If not in a try/catch/finally, // draw edge to destination. If the destination is outside try/catch/finally, // draw edge to destination. if (pair.Value == 0 || single_instruction.Offset >= pair.Key && single_instruction.Offset <= pair.Value) { var whereever = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == single_instruction.Offset) { return(true); } else { return(false); } }).First(); Cfg.AddEdge(new CFG.Edge() { From = node, To = whereever }); continue; } if (try_finally_block.ContainsKey(pair.Key)) { Cfg.AddEdge(new CFG.Edge() { From = node, To = try_finally_block[pair.Key] }); } else { var whereever = list_new_nodes.Where( n => { var first = n.Instructions.First().Instruction; if (first.Offset == single_instruction.Offset) { return(true); } else { return(false); } }).First(); Cfg.AddEdge(new CFG.Edge() { From = node, To = whereever }); } } if (Campy.Utils.Options.IsOn("detailed_import_computation_trace")) { Cfg.OutputDotGraph(); } if (Campy.Utils.Options.IsOn("detailed_import_computation_trace")) { Cfg.OutputEntireGraph(); } }
public void Classes_with_multiple_equal_compared_valeus_are_equal() { var comparer = new LambdaComparer<ClassWithProperties>(x => x.IntegerValue, x => x.StringValue); Assert.IsTrue(comparer.Equals(_left, _right)); }
internal static IncrementalValuesProvider <T> WithLambdaComparer <T>(this IncrementalValuesProvider <T> source, Func <T, T, bool> equal, Func <T, int> getHashCode) { var comparer = new LambdaComparer <T>(equal, getHashCode); return(source.WithComparer(comparer)); }
public void AreEqual(Expression left, Expression right) { var exc = new LambdaComparer(); Assert.True(exc.Equals(left, right)); }