2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Common / RemoteEvent.cs
1 /*
2  *      Firebird ADO.NET Data provider for .NET and     Mono 
3  * 
4  *         The contents of this file are subject to     the     Initial 
5  *         Developer's Public License Version 1.0 (the "License"); 
6  *         you may not use this file except     in compliance with the 
7  *         License.     You     may     obtain a copy of the License at 
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
9  *
10  *         Software     distributed     under the License is distributed on     
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
12  *         express or implied.  See     the     License for     the     specific 
13  *         language     governing rights and limitations under the License.
14  * 
15  *      Copyright (c) 2002,     2004 Carlos     Guzman Alvarez
16  *      All     Rights Reserved.
17  */
18
19 using System;
20 using System.Collections.Specialized;
21
22 namespace FirebirdSql.Data.Common
23 {
24         #region Delegates
25
26         internal delegate void EventCountsCallback();
27
28         #endregion
29
30         internal class RemoteEvent
31         {
32                 #region Callbacks
33
34                 public EventCountsCallback EventCountsCallback
35                 {
36                         get     { return this.eventCountsCallback; }
37                         set     { this.eventCountsCallback = value;     }
38                 }
39
40                 #endregion
41
42                 #region Fields
43
44                 private EventCountsCallback     eventCountsCallback;
45
46                 private IDatabase                       db;
47                 private int                                     localId;
48                 private int                                     remoteId;
49                 private StringCollection        events;
50                 private bool                            initialCounts;
51                 private int[]                           previousCounts;
52                 private int[]                           actualCounts;
53
54                 #endregion
55
56                 #region Properties
57
58                 public IDatabase Database
59                 {
60                         get     { return this.db; }
61                 }
62
63                 public int LocalId
64                 {
65                         get     { return this.localId; }
66                         set     { this.localId = value; }
67                 }
68
69                 public int RemoteId
70                 {
71                         get     { return this.remoteId; }
72                         set     { this.remoteId = value; }
73                 }
74
75                 public StringCollection Events
76                 {
77                         get
78                         {
79                                 if (this.events == null)
80                                 {
81                                         this.events     = new StringCollection();
82                                 }
83
84                                 return this.events;
85                         }
86                 }
87
88                 public bool     HasChanges
89                 {
90                         get
91                         {
92                                 if (this.actualCounts == null && this.previousCounts == null)
93                                 {
94                                         return false;
95                                 }
96                                 else if (this.actualCounts != null && this.previousCounts == null)
97                                 {
98                                         return true;
99                                 }
100                                 else if (this.actualCounts.Length != this.previousCounts.Length)
101                                 {
102                                         return true;
103                                 }
104                                 
105                                 for     (int i = 0;     i <     this.actualCounts.Length; i++)
106                                 {
107                                         if (this.actualCounts[i] !=     this.previousCounts[i])
108                                         {
109                                                 return true;
110                                         }
111                                 }
112
113                                 return false;
114                         }
115                 }
116
117                 public int[] PreviousCounts
118                 {
119                         get     { return this.previousCounts; }
120                 }
121
122                 public int[] ActualCounts
123                 {
124                         get     { return this.actualCounts;     }
125                 }
126
127                 #endregion
128
129                 #region Constructors
130
131                 public RemoteEvent(IDatabase db) : this(db,     0, 0, null)
132                 {
133                 }
134
135                 public RemoteEvent(IDatabase db, int localId, int remoteId,     StringCollection events)
136                 {
137                         this.db                 = db;
138                         this.localId    = localId;
139                         this.remoteId   = remoteId;
140                         this.events             = events;
141                 }
142
143                 #endregion
144
145                 #region Methods
146
147                 public void     QueueEvents()
148                 {
149                         lock (this.db)
150                         {
151                                 this.db.QueueEvents(this);
152                         }
153                 }
154
155                 public void     CancelEvents()
156                 {
157                         lock (this.db)
158                         {
159                                 this.db.CancelEvents(this);
160                                 this.ResetCounts();
161                         }
162                 }
163
164                 public void     ResetCounts()
165                 {
166                         this.initialCounts      = false;
167                         this.actualCounts       = null;
168                         this.previousCounts     = null;
169                 }
170
171                 public void     EventCounts(byte[] buffer)
172                 {
173                         int             pos                             = 1;
174                         Charset charset                 = this.db.Charset;
175
176                         if (buffer != null)
177                         {
178                                 if (this.initialCounts)
179                                 {
180                                         this.previousCounts     = this.actualCounts;
181                                 }
182
183                                 this.actualCounts =     new     int[this.events.Count];
184
185                                 while (pos < buffer.Length)
186                                 {
187                                         int     length = buffer[pos++];
188                                         string eventName = charset.GetString(buffer, pos, length);
189
190                                         pos     += length;
191
192                                         int     index = this.events.IndexOf(eventName);
193                                         if (index != -1)
194                                         {
195                                                 this.actualCounts[index] = BitConverter.ToInt32(buffer, pos) - 1;
196                                         }
197
198                                         pos     += 4;
199                                 }
200
201                                 if (!this.initialCounts)
202                                 {
203                                         this.QueueEvents();
204                                         this.initialCounts = true;
205                                 }
206                                 else
207                                 {
208                                         if (this.EventCountsCallback != null)
209                                         {
210                                                 this.EventCountsCallback();
211                                         }
212                                 }
213                         }
214                 }
215
216                 public EventParameterBuffer     ToEpb()
217                 {
218                         EventParameterBuffer epb = this.db.CreateEventParameterBuffer();
219
220                         epb.Append(IscCodes.EPB_version1);
221
222                         for     (int i = 0;     i <     this.events.Count; i++)
223                         {
224                                 if (this.actualCounts != null)
225                                 {
226                                         epb.Append(this.events[i], this.actualCounts[i] + 1);
227                                 }
228                                 else
229                                 {
230                                         epb.Append(this.events[i], 0);
231                                 }
232                         }
233
234                         return epb;
235                 }
236
237                 #endregion
238         }
239 }