diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressEntryWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressEntryWrapper.cs index 0212065..57101c4 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressEntryWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressEntryWrapper.cs @@ -8,21 +8,12 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - class AddressEntryWrapper : ComWrapper, IAddressEntry + class AddressEntryWrapper : ComWrapper, IAddressEntry { - private NSOutlook.AddressEntry _item; - - internal AddressEntryWrapper(NSOutlook.AddressEntry item) + internal AddressEntryWrapper(NSOutlook.AddressEntry item) : base(item) { - this._item = item; } internal NSOutlook.AddressEntry RawItem { get { return _item; } } - - protected override void DoRelease() - { - ComRelease.Release(_item); - _item = null; - } } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs index 4c234c0..f578ccc 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs @@ -25,20 +25,16 @@ using System.Threading.Tasks; namespace Acacia.Stubs.OutlookWrappers { - public abstract class ComWrapper : IComWrapper + abstract class RawComWrapper : IComWrapper { - - /// - /// Creates a wrapper. - /// - internal ComWrapper() + protected RawComWrapper() { Interlocked.Increment(ref Statistics.CreatedWrappers); this._createdTrace = new System.Diagnostics.StackTrace(); MustRelease = true; } - ~ComWrapper() + ~RawComWrapper() { Interlocked.Increment(ref Statistics.DeletedWrappers); if (!_isDisposed) @@ -71,4 +67,27 @@ namespace Acacia.Stubs.OutlookWrappers abstract protected void DoRelease(); } + + abstract class ComWrapper : RawComWrapper + { + protected ItemType _item { get; private set; } + + /// + /// Creates a wrapper. + /// + protected ComWrapper(ItemType item) + { + this._item = item; + } + + override protected void DoRelease() + { + if (MustRelease) + { + ComRelease.Release(_item); + _item = default(ItemType); + } + } + + } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/CommandBarsWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/CommandBarsWrapper.cs index 492ffd2..c01a6b7 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/CommandBarsWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/CommandBarsWrapper.cs @@ -10,7 +10,7 @@ using stdole; namespace Acacia.Stubs.OutlookWrappers { - class CommandBarsWrapper : ComWrapper, ICommandBars + class CommandBarsWrapper : ComWrapper, ICommandBars { private class MSOCommand : IMSOCommand { @@ -37,23 +37,13 @@ namespace Acacia.Stubs.OutlookWrappers } } - private NSOffice.CommandBars _item; - - public CommandBarsWrapper(NSOffice.CommandBars item) + public CommandBarsWrapper(NSOffice.CommandBars item) : base(item) { - this._item = item; } public IMSOCommand GetMso(string id) { return new MSOCommand(this, id); } - - // TODO: make TypedComWrapper - protected override void DoRelease() - { - ComRelease.Release(_item); - _item = null; - } } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ExplorerWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ExplorerWrapper.cs index c02ca0f..cd7556a 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ExplorerWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ExplorerWrapper.cs @@ -8,19 +8,10 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - class ExplorerWrapper : ComWrapper, IExplorer + class ExplorerWrapper : ComWrapper, IExplorer { - private NSOutlook.Explorer _item; - - public ExplorerWrapper(NSOutlook.Explorer item) + public ExplorerWrapper(NSOutlook.Explorer item) : base(item) { - this._item = item; - } - - protected override void DoRelease() - { - ComRelease.Release(_item); - _item = null; } public ICommandBars GetCommandBars() diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs index d19678b..782e570 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs @@ -26,7 +26,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - public class FolderWrapper : OutlookWrapper, IFolder + class FolderWrapper : OutlookWrapper, IFolder { public FolderWrapper(NSOutlook.MAPIFolder folder) : @@ -124,22 +124,20 @@ namespace Acacia.Stubs.OutlookWrappers #region Enumeration - public class ItemsEnumerator : ComWrapper, IEnumerator + public class ItemsEnumerator : ComWrapper, IEnumerator where ItemType : IItem { - private NSOutlook.Items _items; private IEnumerator _enum; private ItemType _last; - public ItemsEnumerator(NSOutlook.Folder _folder, string field, bool descending) + public ItemsEnumerator(NSOutlook.Folder folder, string field, bool descending) : base(folder.Items) { // TODO: can _items be released here already? - this._items = _folder.Items; if (field != null) { - this._items.Sort("[" + field + "]", descending); + this._item.Sort("[" + field + "]", descending); } - this._enum = _items.GetEnumerator(); + this._enum = _item.GetEnumerator(); } protected override void DoRelease() @@ -152,11 +150,7 @@ namespace Acacia.Stubs.OutlookWrappers ComRelease.Release(_enum); _enum = null; } - if (_items != null) - { - ComRelease.Release(_items); - _items = null; - } + base.DoRelease(); } public ItemType Current diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs index 0e86002..eb95a3b 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs @@ -8,7 +8,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - abstract public class OutlookItemWrapper : OutlookWrapper + abstract class OutlookItemWrapper : OutlookWrapper { public OutlookItemWrapper(ItemType item) : diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs index c444b3d..d798c10 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs @@ -29,37 +29,28 @@ namespace Acacia.Stubs.OutlookWrappers /// /// Helper for Outlook wrapper implementations /// - abstract public class OutlookWrapper : ComWrapper + abstract class OutlookWrapper : ComWrapper { #region Construction / Destruction - protected ItemType _item; - /// /// Creates a wrapper. /// - internal OutlookWrapper(ItemType item) + internal OutlookWrapper(ItemType item) : base(item) { - this._item = item; } protected override void DoRelease() { + // Always release props, as we allocated that if (_props != null) { ComRelease.Release(_props); _props = null; } - if (MustRelease) - { - if (_item != null) - { - ComRelease.Release(_item); - _item = default(ItemType); - } - } + base.DoRelease(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/RecipientWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/RecipientWrapper.cs index 673e1ce..ea4b032 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/RecipientWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/RecipientWrapper.cs @@ -8,23 +8,14 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - class RecipientWrapper : ComWrapper, IRecipient + class RecipientWrapper : ComWrapper, IRecipient { - private NSOutlook.Recipient _item; - - internal RecipientWrapper(NSOutlook.Recipient item) + internal RecipientWrapper(NSOutlook.Recipient item) : base(item) { - this._item = item; } internal NSOutlook.Recipient RawItem { get { return _item; } } - protected override void DoRelease() - { - ComRelease.Release(_item); - _item = null; - } - public bool IsResolved { get diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs index 1e26dae..4366c1f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/SearchWrapper.cs @@ -24,7 +24,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - class SearchWrapper : ComWrapper, ISearch + class SearchWrapper : ComWrapper, ISearch where ItemType : IItem { private interface SearchTerm @@ -151,21 +151,13 @@ namespace Acacia.Stubs.OutlookWrappers } private readonly List terms = new List(); - private NSOutlook.Items _items; /// /// Constructor. /// /// The items to search. The new object takes ownership - public SearchWrapper(NSOutlook.Items items) + public SearchWrapper(NSOutlook.Items items) : base(items) { - this._items = items; - } - - protected override void DoRelease() - { - ComRelease.Release(_items); - _items = null; } public ISearchOperator AddOperator(SearchOperator oper) @@ -187,7 +179,7 @@ namespace Acacia.Stubs.OutlookWrappers List values = new List(); string filter = MakeFilter(); - object value = _items.Find(filter); + object value = _item.Find(filter); while(value != null) { if (values.Count < maxResults) @@ -204,7 +196,7 @@ namespace Acacia.Stubs.OutlookWrappers // Release if not returned. Keep looping to release any others ComRelease.Release(value); } - value = _items.FindNext(); + value = _item.FindNext(); } return values; } @@ -212,7 +204,7 @@ namespace Acacia.Stubs.OutlookWrappers public ItemType SearchOne() { // Wrap manages com object in value - object value = _items.Find(MakeFilter()); + object value = _item.Find(MakeFilter()); if (value == null) return default(ItemType); return Mapping.Wrap(value); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs index e0ea714..5f15f21 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs @@ -25,7 +25,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - public class StorageItemWrapper : OutlookItemWrapper, IStorageItem + class StorageItemWrapper : OutlookItemWrapper, IStorageItem { public StorageItemWrapper(NSOutlook.StorageItem item) : diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs index 675c292..2425db0 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs @@ -24,37 +24,28 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.Stubs.OutlookWrappers { - class StoreWrapper : ComWrapper, IStore + class StoreWrapper : ComWrapper, IStore { internal static IStore Wrap(NSOutlook.Store store) { return store == null ? null : new StoreWrapper(store); } - private NSOutlook.Store _store; - - private StoreWrapper(NSOutlook.Store store) + private StoreWrapper(NSOutlook.Store store) : base(store) { - this._store = store; - } - - protected override void DoRelease() - { - ComRelease.Release(_store); - _store = null; } public IFolder GetRootFolder() { // FolderWrapper manages the returned Folder - return new FolderWrapper((NSOutlook.Folder)_store.GetRootFolder()); + return new FolderWrapper((NSOutlook.Folder)_item.GetRootFolder()); } public IItem GetItemFromID(string id) { using (ComRelease com = new ComRelease()) { - NSOutlook.NameSpace nmspace = com.Add(_store.Session); + NSOutlook.NameSpace nmspace = com.Add(_item.Session); // Get the item; the wrapper manages it object o = nmspace.GetItemFromID(id); @@ -62,17 +53,17 @@ namespace Acacia.Stubs.OutlookWrappers } } - public string DisplayName { get { return _store.DisplayName; } } - public string StoreID { get { return _store.StoreID; } } + public string DisplayName { get { return _item.DisplayName; } } + public string StoreID { get { return _item.StoreID; } } - public bool IsFileStore { get { return _store.IsDataFileStore; } } - public string FilePath { get { return _store.FilePath; } } + public bool IsFileStore { get { return _item.IsDataFileStore; } } + public string FilePath { get { return _item.FilePath; } } public void EmptyDeletedItems() { using (ComRelease com = new ComRelease()) { - NSOutlook.MAPIFolder f = _store.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems); + NSOutlook.MAPIFolder f = _item.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems); if (f != null) { com.Add(f); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs index 59569be..3c7fa7d 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs @@ -223,17 +223,15 @@ namespace Acacia.Utils } } - private class MailEventHooker : ComWrapper + private class MailEventHooker : ComWrapper { - private NSOutlook.ItemEvents_10_Event _itemEvents; private readonly MailEvents _events; // TODO: remove id and debug logging private int _id; private static int nextId; - public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) + public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) : base(itemEvents) { - this._itemEvents = itemEvents; this._id = ++nextId; this._events = events; HookEvents(true); @@ -250,23 +248,23 @@ namespace Acacia.Utils { if (add) { - _itemEvents.BeforeDelete += HandleBeforeDelete; - _itemEvents.Forward += HandleForward; - _itemEvents.Read += HandleRead; - _itemEvents.Reply += HandleReply; - _itemEvents.ReplyAll += HandleReplyAll; - _itemEvents.Unload += HandleUnload; - _itemEvents.Write += HandleWrite; + _item.BeforeDelete += HandleBeforeDelete; + _item.Forward += HandleForward; + _item.Read += HandleRead; + _item.Reply += HandleReply; + _item.ReplyAll += HandleReplyAll; + _item.Unload += HandleUnload; + _item.Write += HandleWrite; } else { - _itemEvents.BeforeDelete -= HandleBeforeDelete; - _itemEvents.Forward -= HandleForward; - _itemEvents.Read -= HandleRead; - _itemEvents.Reply -= HandleReply; - _itemEvents.ReplyAll -= HandleReplyAll; - _itemEvents.Unload -= HandleUnload; - _itemEvents.Write -= HandleWrite; + _item.BeforeDelete -= HandleBeforeDelete; + _item.Forward -= HandleForward; + _item.Read -= HandleRead; + _item.Reply -= HandleReply; + _item.ReplyAll -= HandleReplyAll; + _item.Unload -= HandleUnload; + _item.Write -= HandleWrite; } } @@ -279,25 +277,25 @@ namespace Acacia.Utils private void HandleForward(object response, ref bool cancel) { Logger.Instance.Debug(this, "HandleForward: {0}", _id); - _events.OnForward(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); + _events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); } private void HandleRead() { Logger.Instance.Debug(this, "HandleRead: {0}", _id); - _events.OnRead(_itemEvents as NSOutlook.MailItem); + _events.OnRead(_item as NSOutlook.MailItem); } private void HandleReply(object response, ref bool cancel) { Logger.Instance.Debug(this, "HandleReply: {0}", _id); - _events.OnReply(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); + _events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); } private void HandleReplyAll(object response, ref bool cancel) { Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id); - _events.OnReplyAll(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); + _events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); } private void HandleUnload() @@ -311,7 +309,7 @@ namespace Acacia.Utils private void HandleWrite(ref bool cancel) { Logger.Instance.Debug(this, "HandleWrite: {0}", _id); - _events.OnWrite(_itemEvents, ref cancel); + _events.OnWrite(_item, ref cancel); } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs index 57ce3a0..d1efbec 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/Connect/ZPushConnection.cs @@ -252,7 +252,7 @@ namespace Acacia.ZPush.Connect } } - private class Request : ComWrapper + private class Request : RawComWrapper { private const string ACTIVESYNC_URL = "https://{0}/Microsoft-Server-ActiveSync?DeviceId={1}&Cmd={2}&User={3}&DeviceType={4}"; diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs index 23eed64..1f3d42f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs @@ -26,6 +26,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook; namespace Acacia.ZPush { + // TODO: make this contain Folder instead of inheriting, then FolderWrapper needn't be public public class ZPushFolder : FolderWrapper { private readonly NSOutlook.Items _items;