diff --git a/2005-jabber-net.csproj b/2005-jabber-net.csproj
index 7d3f30d..83da229 100644
--- a/2005-jabber-net.csproj
+++ b/2005-jabber-net.csproj
@@ -83,10 +83,7 @@
TRACE;DEBUG
- DEBUG;TRACE
- pdbonly
- true
- false
+ TRACE
@@ -144,6 +141,9 @@
Code
+
+ Component
+
Code
@@ -304,6 +304,7 @@
Code
+
Code
@@ -324,6 +325,7 @@
Code
+
@@ -435,13 +437,11 @@
JabberClient.cs
- Designer
RosterManager.cs
- Designer
XmppStream.cs
@@ -450,7 +450,6 @@
JabberService.cs
- Designer
@@ -473,31 +472,14 @@
-
-
-
-
- False
- .NET Framework 2.0 %28x86%29
- true
-
-
- False
- .NET Framework 3.0 %28x86%29
- false
-
-
- False
- .NET Framework 3.5
- false
-
-
-
-
+
{40AC7A7C-D3E5-46DF-B740-06BD9D2A00E1}
netlib.Dns
+
+
+
@@ -507,24 +489,8 @@
false
+ 2.0
- 2.0
- 9.0.21022
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
\ No newline at end of file
diff --git a/2005-jabber-net.csproj.user b/2005-jabber-net.csproj.user
index 6b7aa47..861bb4c 100644
--- a/2005-jabber-net.csproj.user
+++ b/2005-jabber-net.csproj.user
@@ -11,18 +11,6 @@
0
ProjectFiles
0
-
-
-
-
-
-
-
-
-
-
- en-US
- false
false
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
index 7ec6f47..9211c42 100644
--- a/AssemblyInfo.cs
+++ b/AssemblyInfo.cs
@@ -18,7 +18,7 @@
[assembly: AssemblyCompany("Cursive Systems, Inc.")]
[assembly: AssemblyProduct("jabber-net")]
[assembly: AssemblyCopyright("Copyright (c) Cursive, Inc. 2000-2008")]
-[assembly: AssemblyVersion("2.1.0.702")]
+[assembly: AssemblyVersion("2.1.2.760")]
[assembly: AssemblyDelaySign(false)]
[assembly: CLSCompliant(true)]
[assembly: AssemblyKeyFile("../../jabbernet.key")]
diff --git a/ConsoleClient/AssemblyInfo.cs b/ConsoleClient/AssemblyInfo.cs
index 4cb6aab..ba2e543 100644
--- a/ConsoleClient/AssemblyInfo.cs
+++ b/ConsoleClient/AssemblyInfo.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System.Reflection;
diff --git a/ConsoleClient/Main.cs b/ConsoleClient/Main.cs
index 23fe538..8641853 100644
--- a/ConsoleClient/Main.cs
+++ b/ConsoleClient/Main.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -27,7 +27,7 @@ namespace ConsoleClient
///
/// Summary description for Class1.
///
- [SVN(@"$Id: Main.cs 676 2008-06-12 17:05:11Z hildjj $")]
+ [SVN(@"$Id: Main.cs 725 2008-08-06 18:14:18Z hildjj $")]
class Class1
{
[CommandLine("j", "user@host Jabber ID", true)]
diff --git a/Example/AddContact.cs b/Example/AddContact.cs
index 573ebff..44210ea 100644
--- a/Example/AddContact.cs
+++ b/Example/AddContact.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -22,7 +22,7 @@
namespace Example
{
- [SVN(@"$Id: AddContact.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: AddContact.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class AddContact : Form
{
diff --git a/Example/AddGroup.cs b/Example/AddGroup.cs
index b092a86..b1ca38a 100644
--- a/Example/AddGroup.cs
+++ b/Example/AddGroup.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@
namespace Example
{
- [SVN(@"$Id: AddGroup.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: AddGroup.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class AddGroup : Form
{
private System.Windows.Forms.TextBox textBox1;
diff --git a/Example/AssemblyInfo.cs b/Example/AssemblyInfo.cs
index 5c0e83f..41a4b8c 100644
--- a/Example/AssemblyInfo.cs
+++ b/Example/AssemblyInfo.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System.Reflection;
diff --git a/Example/ConferenceForm.cs b/Example/ConferenceForm.cs
index 30d67a0..7a746aa 100644
--- a/Example/ConferenceForm.cs
+++ b/Example/ConferenceForm.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -24,7 +24,7 @@
namespace Example
{
- [SVN(@"$Id: ConferenceForm.cs 580 2008-02-13 21:49:19Z hildjj $")]
+ [SVN(@"$Id: ConferenceForm.cs 733 2008-09-07 23:03:44Z hildjj $")]
public class ConferenceForm : Form
{
private Label label1;
@@ -54,6 +54,14 @@ public DiscoManager DiscoManager
set { m_disco = value; }
}
+ public JID RoomJID
+ {
+ get
+ {
+ return new JID(txtRoom.Text, cmbJID.Text, null);
+ }
+ }
+
public JID RoomAndNick
{
get
@@ -62,14 +70,22 @@ public JID RoomAndNick
}
set
{
- cmbJID.Text = value.Server;
- txtRoom.Text = value.User;
- txtNick.Text = value.Resource;
+ if (value == null)
+ {
+ cmbJID.Text = txtRoom.Text = txtNick.Text = "";
+ }
+ else
+ {
+ cmbJID.Text = value.Server;
+ txtRoom.Text = value.User;
+ txtNick.Text = value.Resource;
+ }
}
}
public string Nick
{
+ get { return txtNick.Text; }
set { txtNick.Text = value; }
}
@@ -213,15 +229,25 @@ private void ConferenceForm_Shown(object sender, EventArgs e)
{
cmbJID.BeginUpdate();
cmbJID.Items.Clear();
- foreach (DiscoNode component in m_disco.Root.Children)
+ if (m_disco != null)
+ m_disco.BeginGetItems(null, GotRoot, null);
+ else
+ cmbJID.EndUpdate();
+ }
+
+ private void GotRoot(DiscoManager sender, DiscoNode node, object state)
+ {
+ if (node.Children != null)
{
- if (component.HasFeature(jabber.protocol.URI.MUC))
- cmbJID.Items.Add(component.JID);
+ foreach (DiscoNode component in node.Children)
+ {
+ if (component.HasFeature(jabber.protocol.URI.MUC))
+ cmbJID.Items.Add(component.JID);
+ }
+ if (cmbJID.Items.Count > 0)
+ cmbJID.SelectedIndex = 0;
}
- if (cmbJID.Items.Count > 0)
- cmbJID.SelectedIndex = 0;
cmbJID.EndUpdate();
}
-
}
}
diff --git a/Example/MainForm.cs b/Example/MainForm.cs
index b0cc2ce..ab987f1 100644
--- a/Example/MainForm.cs
+++ b/Example/MainForm.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -30,7 +30,7 @@ namespace Example
///
/// Summary description for MainForm.
///
- [SVN(@"$Id: MainForm.cs 708 2008-07-17 15:18:45Z hildjj $")]
+ [SVN(@"$Id: MainForm.cs 733 2008-09-07 23:03:44Z hildjj $")]
public class MainForm : Form
{
#region Private Members
@@ -78,6 +78,15 @@ public class MainForm : Form
private ToolStripMenuItem joinConferenceToolStripMenuItem;
private bool m_err = false;
+ private jabber.client.BookmarkManager bmm;
+ private TabPage tpBookmarks;
+ private ListView lvBookmarks;
+ private ColumnHeader chName;
+ private ColumnHeader chNick;
+ private ColumnHeader chAutoJoin;
+ private ToolStripMenuItem bookmarkToolStripMenuItem;
+ private ToolStripMenuItem addToolStripMenuItem;
+ private ToolStripMenuItem removeToolStripMenuItem;
private bool m_connected = false;
#endregion
@@ -138,7 +147,7 @@ protected override void Dispose( bool disposing )
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
- jabber.connection.Ident ident1 = new jabber.connection.Ident();
+ jabber.connection.Ident ident2 = new jabber.connection.Ident();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.sb = new System.Windows.Forms.StatusBar();
this.pnlCon = new System.Windows.Forms.StatusBarPanel();
@@ -149,10 +158,16 @@ private void InitializeComponent()
this.roster = new muzzle.RosterTree();
this.jc = new jabber.client.JabberClient(this.components);
this.pm = new jabber.client.PresenceManager(this.components);
+ this.cm = new jabber.connection.CapsManager(this.components);
+ this.dm = new jabber.connection.DiscoManager(this.components);
this.rm = new jabber.client.RosterManager(this.components);
this.tpServices = new System.Windows.Forms.TabPage();
this.services = new Example.ServiceDisplay();
- this.dm = new jabber.connection.DiscoManager(this.components);
+ this.tpBookmarks = new System.Windows.Forms.TabPage();
+ this.lvBookmarks = new System.Windows.Forms.ListView();
+ this.chName = new System.Windows.Forms.ColumnHeader();
+ this.chNick = new System.Windows.Forms.ColumnHeader();
+ this.chAutoJoin = new System.Windows.Forms.ColumnHeader();
this.tpDebug = new System.Windows.Forms.TabPage();
this.debug = new muzzle.XmppDebugger();
this.mnuPresence = new System.Windows.Forms.ContextMenu();
@@ -171,21 +186,25 @@ private void InitializeComponent()
this.addContactToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeContactToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addGroupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.bookmarkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.windowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.subscribePubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.deletePubSubToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.cm = new jabber.connection.CapsManager(this.components);
this.psm = new jabber.connection.PubSubManager(this.components);
this.idler = new bedrock.util.IdleTime();
this.muc = new jabber.connection.ConferenceManager(this.components);
+ this.bmm = new jabber.client.BookmarkManager(this.components);
((System.ComponentModel.ISupportInitialize)(this.pnlCon)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pnlSSL)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pnlPresence)).BeginInit();
this.tabControl1.SuspendLayout();
this.tpRoster.SuspendLayout();
this.tpServices.SuspendLayout();
+ this.tpBookmarks.SuspendLayout();
this.tpDebug.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
@@ -228,6 +247,7 @@ private void InitializeComponent()
//
this.tabControl1.Controls.Add(this.tpRoster);
this.tabControl1.Controls.Add(this.tpServices);
+ this.tabControl1.Controls.Add(this.tpBookmarks);
this.tabControl1.Controls.Add(this.tpDebug);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 24);
@@ -289,12 +309,35 @@ private void InitializeComponent()
//
// pm
//
+ this.pm.CapsManager = this.cm;
+ this.pm.OverrideFrom = null;
this.pm.Stream = this.jc;
//
+ // cm
+ //
+ this.cm.DiscoManager = this.dm;
+ this.cm.Features = new string[0];
+ this.cm.FileName = "caps.xml";
+ ident2.Category = "client";
+ ident2.Lang = "en";
+ ident2.Name = "Jabber-Net Test Client";
+ ident2.Type = "pc";
+ this.cm.Identities = new jabber.connection.Ident[] {
+ ident2};
+ this.cm.Node = "http://cursive.net/clients/csharp-example";
+ this.cm.OverrideFrom = null;
+ this.cm.Stream = this.jc;
+ //
+ // dm
+ //
+ this.dm.OverrideFrom = null;
+ this.dm.Stream = this.jc;
+ //
// rm
//
this.rm.AutoAllow = jabber.client.AutoSubscriptionHanding.AllowIfSubscribed;
this.rm.AutoSubscribe = true;
+ this.rm.OverrideFrom = null;
this.rm.Stream = this.jc;
this.rm.OnRosterEnd += new bedrock.ObjectHandler(this.rm_OnRosterEnd);
this.rm.OnSubscription += new jabber.client.SubscriptionHandler(this.rm_OnSubscription);
@@ -321,9 +364,46 @@ private void InitializeComponent()
this.services.Stream = this.jc;
this.services.TabIndex = 0;
//
- // dm
+ // tpBookmarks
//
- this.dm.Stream = this.jc;
+ this.tpBookmarks.Controls.Add(this.lvBookmarks);
+ this.tpBookmarks.Location = new System.Drawing.Point(4, 22);
+ this.tpBookmarks.Name = "tpBookmarks";
+ this.tpBookmarks.Size = new System.Drawing.Size(624, 366);
+ this.tpBookmarks.TabIndex = 3;
+ this.tpBookmarks.Text = "Bookmarks";
+ this.tpBookmarks.UseVisualStyleBackColor = true;
+ //
+ // lvBookmarks
+ //
+ this.lvBookmarks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.chName,
+ this.chNick,
+ this.chAutoJoin});
+ this.lvBookmarks.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.lvBookmarks.Location = new System.Drawing.Point(0, 0);
+ this.lvBookmarks.Name = "lvBookmarks";
+ this.lvBookmarks.Size = new System.Drawing.Size(624, 366);
+ this.lvBookmarks.Sorting = System.Windows.Forms.SortOrder.Ascending;
+ this.lvBookmarks.TabIndex = 0;
+ this.lvBookmarks.UseCompatibleStateImageBehavior = false;
+ this.lvBookmarks.View = System.Windows.Forms.View.Details;
+ this.lvBookmarks.DoubleClick += new System.EventHandler(this.lvBookmarks_DoubleClick);
+ this.lvBookmarks.KeyUp += new System.Windows.Forms.KeyEventHandler(this.lvBookmarks_KeyUp);
+ //
+ // chName
+ //
+ this.chName.Text = "Room";
+ this.chName.Width = 198;
+ //
+ // chNick
+ //
+ this.chNick.Text = "Nick";
+ this.chNick.Width = 88;
+ //
+ // chAutoJoin
+ //
+ this.chAutoJoin.Text = "AutoJoin";
//
// tpDebug
//
@@ -342,6 +422,7 @@ private void InitializeComponent()
this.debug.Location = new System.Drawing.Point(0, 0);
this.debug.Name = "debug";
this.debug.OtherColor = System.Drawing.Color.Green;
+ this.debug.OverrideFrom = null;
this.debug.ReceiveColor = System.Drawing.Color.Orange;
this.debug.SendColor = System.Drawing.Color.Blue;
this.debug.Size = new System.Drawing.Size(624, 366);
@@ -377,6 +458,7 @@ private void InitializeComponent()
this.fileToolStripMenuItem,
this.viewToolStripMenuItem,
this.rosterToolStripMenuItem,
+ this.bookmarkToolStripMenuItem,
this.windowToolStripMenuItem,
this.pubSubToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
@@ -484,6 +566,32 @@ private void InitializeComponent()
this.addGroupToolStripMenuItem.Text = "&Add Group";
this.addGroupToolStripMenuItem.Click += new System.EventHandler(this.addGroupToolStripMenuItem_Click);
//
+ // bookmarkToolStripMenuItem
+ //
+ this.bookmarkToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.addToolStripMenuItem,
+ this.removeToolStripMenuItem});
+ this.bookmarkToolStripMenuItem.Name = "bookmarkToolStripMenuItem";
+ this.bookmarkToolStripMenuItem.Size = new System.Drawing.Size(65, 20);
+ this.bookmarkToolStripMenuItem.Text = "Bookmark";
+ //
+ // addToolStripMenuItem
+ //
+ this.addToolStripMenuItem.Name = "addToolStripMenuItem";
+ this.addToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.B)));
+ this.addToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
+ this.addToolStripMenuItem.Text = "Add";
+ this.addToolStripMenuItem.Click += new System.EventHandler(this.addToolStripMenuItem_Click);
+ //
+ // removeToolStripMenuItem
+ //
+ this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
+ this.removeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
+ | System.Windows.Forms.Keys.B)));
+ this.removeToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
+ this.removeToolStripMenuItem.Text = "Remove";
+ this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
+ //
// windowToolStripMenuItem
//
this.windowToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -525,22 +633,9 @@ private void InitializeComponent()
this.deletePubSubToolStripMenuItem.Text = "&Delete";
this.deletePubSubToolStripMenuItem.Click += new System.EventHandler(this.deletePubSubToolStripMenuItem_Click);
//
- // cm
- //
- this.cm.DiscoManager = this.dm;
- this.cm.Features = new string[0];
- this.cm.FileName = "caps.xml";
- ident1.Category = "client";
- ident1.Lang = "en";
- ident1.Name = "Jabber-Net Test Client";
- ident1.Type = "pc";
- this.cm.Identities = new jabber.connection.Ident[] {
- ident1};
- this.cm.Node = "http://cursive.net/clients/csharp-example";
- this.cm.Stream = this.jc;
- //
// psm
//
+ this.psm.OverrideFrom = null;
this.psm.Stream = this.jc;
//
// idler
@@ -551,10 +646,16 @@ private void InitializeComponent()
//
// muc
//
+ this.muc.OverrideFrom = null;
this.muc.Stream = this.jc;
- this.muc.OnRoomConfig += new jabber.connection.ConfigureRoom(this.muc_OnRoomConfig);
- this.muc.OnInvite += new jabber.client.MessageHandler(this.muc_OnInvite);
- this.muc.OnPresenceError += new jabber.connection.RoomPresenceHandler(this.muc_OnPresenceError);
+ //
+ // bmm
+ //
+ this.bmm.ConferenceManager = this.muc;
+ this.bmm.OverrideFrom = null;
+ this.bmm.Stream = this.jc;
+ this.bmm.OnConferenceAdd += new jabber.client.BookmarkConferenceDelegate(this.bmm_OnConferenceAdd);
+ this.bmm.OnConferenceRemove += new jabber.client.BookmarkConferenceDelegate(this.bmm_OnConferenceRemove);
//
// MainForm
//
@@ -575,6 +676,7 @@ private void InitializeComponent()
this.tabControl1.ResumeLayout(false);
this.tpRoster.ResumeLayout(false);
this.tpServices.ResumeLayout(false);
+ this.tpBookmarks.ResumeLayout(false);
this.tpDebug.ResumeLayout(false);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
@@ -629,6 +731,7 @@ private void jc_OnDisconnect(object sender)
pnlSSL.Text = "";
pnlSSL.ToolTipText = "";
connectToolStripMenuItem.Text = "&Connect";
+ lvBookmarks.Items.Clear();
if (!m_err)
pnlCon.Text = "Disconnected";
@@ -640,6 +743,7 @@ private void jc_OnError(object sender, Exception ex)
mnuAway.Enabled = mnuAvailable.Enabled = false;
connectToolStripMenuItem.Text = "&Connect";
idler.Enabled = false;
+ lvBookmarks.Items.Clear();
pnlCon.Text = "Error: " + ex.Message;
}
@@ -1023,7 +1127,7 @@ private void joinConferenceToolStripMenuItem_Click(object sender, EventArgs e)
{
ConferenceForm cf = new ConferenceForm();
cf.DiscoManager = dm;
- cf.Nick = jc.JID.User;
+ cf.Nick = muc.DefaultNick;
if (cf.ShowDialog() != DialogResult.OK)
return;
@@ -1050,5 +1154,71 @@ private void muc_OnInvite(object sender, jabber.protocol.client.Message msg)
Room r = sender as Room;
r.Join();
}
+
+ private void bmm_OnConferenceAdd(jabber.client.BookmarkManager manager, BookmarkConference conference)
+ {
+ string jid = conference.JID;
+ string name = conference.ConferenceName;
+ if (name == null)
+ name = jid;
+ if (lvBookmarks.Items.ContainsKey(jid))
+ lvBookmarks.Items.RemoveByKey(jid);
+ ListViewItem item = lvBookmarks.Items.Add(jid, name, -1);
+ item.SubItems.Add(conference.Nick);
+ item.SubItems.Add(conference.AutoJoin.ToString());
+ item.Tag = conference.JID;
+ }
+
+ private void bmm_OnConferenceRemove(jabber.client.BookmarkManager manager, BookmarkConference conference)
+ {
+ string jid = conference.JID;
+ if (lvBookmarks.Items.ContainsKey(jid))
+ lvBookmarks.Items.RemoveByKey(jid);
+ }
+
+ private void lvBookmarks_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Delete)
+ removeToolStripMenuItem_Click(null, null);
+ }
+
+ private void addToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // pop up AddBookmark dialog
+ ConferenceForm cf = new ConferenceForm();
+ cf.DiscoManager = dm;
+ cf.Nick = muc.DefaultNick;
+ if (cf.ShowDialog() != DialogResult.OK)
+ return;
+ // TODO: add autojoin and name.
+ bmm.AddConference(cf.RoomJID, null, false, cf.Nick);
+ }
+
+ private void removeToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ foreach (ListViewItem lvi in lvBookmarks.SelectedItems)
+ {
+ bmm[(JID)lvi.Tag] = null;
+ }
+ }
+
+ private void lvBookmarks_DoubleClick(object sender, EventArgs e)
+ {
+ if (lvBookmarks.SelectedItems.Count == 0)
+ return;
+ ListViewItem lvi = lvBookmarks.SelectedItems[0];
+
+ JID jid = (JID)lvi.Tag;
+ BookmarkConference conf = bmm[jid];
+ Debug.Assert(conf != null);
+
+ ConferenceForm cf = new ConferenceForm();
+ cf.DiscoManager = dm;
+ cf.RoomAndNick = new JID(jid.User, jid.Server, conf.Nick);
+
+ if (cf.ShowDialog() != DialogResult.OK)
+ return;
+ bmm.AddConference(cf.RoomJID, null, false, cf.Nick);
+ }
}
}
diff --git a/Example/MainForm.resx b/Example/MainForm.resx
index 479db06..178c108 100644
--- a/Example/MainForm.resx
+++ b/Example/MainForm.resx
@@ -120,12 +120,36 @@
339, 17
+
+ 399, 17
+
+
+ 466, 17
+
+
+ 207, 17
+
+
+ 274, 17
+
89, 17
604, 17
+
+ 532, 17
+
+
+ 713, 17
+
+
+ 17, 17
+
+
+ 786, 17
+
@@ -149,25 +173,4 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAA==
-
- 399, 17
-
-
- 274, 17
-
-
- 207, 17
-
-
- 466, 17
-
-
- 532, 17
-
-
- 713, 17
-
-
- 17, 17
-
\ No newline at end of file
diff --git a/Example/PubSubDisplay.cs b/Example/PubSubDisplay.cs
index 52757c3..7158fe0 100644
--- a/Example/PubSubDisplay.cs
+++ b/Example/PubSubDisplay.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -21,7 +21,7 @@
namespace Example
{
- [SVN(@"$Id: PubSubDisplay.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: PubSubDisplay.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class PubSubDisplay : UserControl
{
private ListBox lbID;
diff --git a/Example/PubSubSubscribeForm.cs b/Example/PubSubSubscribeForm.cs
index 37bbe34..bbdc45a 100644
--- a/Example/PubSubSubscribeForm.cs
+++ b/Example/PubSubSubscribeForm.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -21,7 +21,7 @@
namespace Example
{
- [SVN(@"$Id: PubSubSubscribeForm.cs 580 2008-02-13 21:49:19Z hildjj $")]
+ [SVN(@"$Id: PubSubSubscribeForm.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class PubSubSubcribeForm : Form
{
private Label label1;
diff --git a/Example/SendMessage.cs b/Example/SendMessage.cs
index bfe5856..446bcca 100644
--- a/Example/SendMessage.cs
+++ b/Example/SendMessage.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -25,7 +25,7 @@ namespace Example
///
/// Summary description for SendMessage.
///
- [SVN(@"$Id: SendMessage.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SendMessage.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class SendMessage : System.Windows.Forms.Form
{
private jabber.client.JabberClient m_jc;
diff --git a/Example/ServiceDisplay.cs b/Example/ServiceDisplay.cs
index e4245a0..3386335 100644
--- a/Example/ServiceDisplay.cs
+++ b/Example/ServiceDisplay.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@
namespace Example
{
- [SVN(@"$Id: ServiceDisplay.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ServiceDisplay.cs 725 2008-08-06 18:14:18Z hildjj $")]
public class ServiceDisplay : UserControl
{
///
diff --git a/JabberNetInstaller/JabberNetInstaller.wixproj b/JabberNetInstaller/JabberNetInstaller.wixproj
index e63fd6d..a4d0948 100644
--- a/JabberNetInstaller/JabberNetInstaller.wixproj
+++ b/JabberNetInstaller/JabberNetInstaller.wixproj
@@ -98,7 +98,9 @@
-
+
+ C:\Program Files\Windows Installer XML v3\bin\WixUIExtension.dll
+
diff --git a/Makefile b/Makefile
index 2bfe6e3..20c99a4 100644
--- a/Makefile
+++ b/Makefile
@@ -52,11 +52,13 @@ $(BASEDIR)/bedrock/util/ConfigFile.cs \
$(BASEDIR)/bedrock/util/GetOptBase.cs \
$(BASEDIR)/bedrock/util/Version.cs \
$(BASEDIR)/jabber/JID.cs \
+$(BASEDIR)/jabber/client/BookmarkManager.cs \
$(BASEDIR)/jabber/client/JabberClient.cs \
$(BASEDIR)/jabber/client/PresenceManager.cs \
$(BASEDIR)/jabber/client/RosterManager.cs \
$(BASEDIR)/jabber/connection/BindingStanzaStream.cs \
$(BASEDIR)/jabber/connection/CapsManager.cs \
+$(BASEDIR)/jabber/connection/ConferenceManager.cs \
$(BASEDIR)/jabber/connection/DiscoManager.cs \
$(BASEDIR)/jabber/connection/FileMap.cs \
$(BASEDIR)/jabber/connection/HttpStanzaStream.cs \
@@ -95,6 +97,7 @@ $(BASEDIR)/jabber/protocol/client/Presence.cs \
$(BASEDIR)/jabber/protocol/client/ProtocolException.cs \
$(BASEDIR)/jabber/protocol/iq/Agents.cs \
$(BASEDIR)/jabber/protocol/iq/Auth.cs \
+$(BASEDIR)/jabber/protocol/iq/Bookmarks.cs \
$(BASEDIR)/jabber/protocol/iq/Browse.cs \
$(BASEDIR)/jabber/protocol/iq/Disco.cs \
$(BASEDIR)/jabber/protocol/iq/Factory.cs \
@@ -102,6 +105,7 @@ $(BASEDIR)/jabber/protocol/iq/GeoLoc.cs \
$(BASEDIR)/jabber/protocol/iq/Last.cs \
$(BASEDIR)/jabber/protocol/iq/MUC.cs \
$(BASEDIR)/jabber/protocol/iq/OOB.cs \
+$(BASEDIR)/jabber/protocol/iq/Private.cs \
$(BASEDIR)/jabber/protocol/iq/PubSub.cs \
$(BASEDIR)/jabber/protocol/iq/PubSubErrors.cs \
$(BASEDIR)/jabber/protocol/iq/PubSubEvent.cs \
@@ -166,6 +170,7 @@ RESOURCES = \
SYSTEM_REFERENCES = -r:zlib.net.dll \
-r:System.dll \
-r:System.Xml.dll \
+ -r:System.Drawing.dll \
-r:Mono.Security.dll
DEBUGDIR = $(BASEDIR)/bin/debug
diff --git a/VB.Example/MainForm.vb b/VB.Example/MainForm.vb
index 19f9ec0..bf91a72 100644
--- a/VB.Example/MainForm.vb
+++ b/VB.Example/MainForm.vb
@@ -8,7 +8,7 @@
'
' License
'
-' Jabber-Net can be used under either JOSL or the GPL.
+' Jabber-Net is licensed under the LGPL.
' See LICENSE.txt for details.
' --------------------------------------------------------------------------
diff --git a/VB.Example/SendMessage.vb b/VB.Example/SendMessage.vb
index a9b455f..ccfb9ab 100644
--- a/VB.Example/SendMessage.vb
+++ b/VB.Example/SendMessage.vb
@@ -8,7 +8,7 @@
'
' License
'
-' Jabber-Net can be used under either JOSL or the GPL.
+' Jabber-Net is licensed under the LGPL.
' See LICENSE.txt for details.
' --------------------------------------------------------------------------
diff --git a/bedrock/Delegates.cs b/bedrock/Delegates.cs
index 5b99a4f..427f0d5 100644
--- a/bedrock/Delegates.cs
+++ b/bedrock/Delegates.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
diff --git a/bedrock/collections/ByteStack.cs b/bedrock/collections/ByteStack.cs
index 9741057..020c85b 100644
--- a/bedrock/collections/ByteStack.cs
+++ b/bedrock/collections/ByteStack.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -20,7 +20,7 @@ namespace bedrock.collections
/// A type-safe stack for bytes, implemented as a growable
/// buffer.
///
- [SVN(@"$Id: ByteStack.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ByteStack.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ByteStack
{
private const double GROWTH_FACTOR = 1.5d;
diff --git a/bedrock/collections/GraphNode.cs b/bedrock/collections/GraphNode.cs
index 2354c0e..0bf8b3b 100644
--- a/bedrock/collections/GraphNode.cs
+++ b/bedrock/collections/GraphNode.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -20,7 +20,7 @@ namespace bedrock.collections
///
/// A node in a Graph, such as a Tree
///
- [SVN(@"$Id: GraphNode.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: GraphNode.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class GraphNode : IEnumerable
{
private object m_key = null;
diff --git a/bedrock/collections/ISet.cs b/bedrock/collections/ISet.cs
index 0a01fe7..d7df990 100644
--- a/bedrock/collections/ISet.cs
+++ b/bedrock/collections/ISet.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@ namespace bedrock.collections
///
/// Set operations.
///
- [SVN(@"$Id: ISet.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ISet.cs 724 2008-08-06 18:09:25Z hildjj $")]
public interface ISet : ICollection
{
///
diff --git a/bedrock/collections/IndexedTrie.cs b/bedrock/collections/IndexedTrie.cs
index c28b8f4..1f1221b 100644
--- a/bedrock/collections/IndexedTrie.cs
+++ b/bedrock/collections/IndexedTrie.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@ namespace bedrock.collections
/// A Trie that is searchable for substrings. Uses a separate set of indexes
/// to allow entry into the Trie at any point. Yes, this
///
- [SVN(@"$Id: IndexedTrie.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: IndexedTrie.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class IndexedTrie : Trie
{
private Tree m_indexes = new Tree();
diff --git a/bedrock/collections/LinkedList.cs b/bedrock/collections/LinkedList.cs
index 53e840e..0d32cb4 100644
--- a/bedrock/collections/LinkedList.cs
+++ b/bedrock/collections/LinkedList.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.collections
/// in System.Collections. This may be a nicer implementation of Queue
/// than the one in System.Collections, which uses an array. YMMV.
///
- [SVN(@"$Id: LinkedList.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: LinkedList.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class LinkedList : IList
{
private Node m_header = new Node(null, null, null);
diff --git a/bedrock/collections/Set.cs b/bedrock/collections/Set.cs
index d7bcaf8..d6ea350 100644
--- a/bedrock/collections/Set.cs
+++ b/bedrock/collections/Set.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@ namespace bedrock.collections
///
/// The different ways a set can be implemented.
///
- [SVN(@"$Id: Set.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Set.cs 724 2008-08-06 18:09:25Z hildjj $")]
public enum SetImplementation
{
///
@@ -41,7 +41,7 @@ public enum SetImplementation
///
/// Set backed into a Tree.
///
- [SVN(@"$Id: Set.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Set.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Set : ISet
{
private static readonly object s_nothing = new object();
diff --git a/bedrock/collections/SkipList.cs b/bedrock/collections/SkipList.cs
index f64f5df..8873416 100644
--- a/bedrock/collections/SkipList.cs
+++ b/bedrock/collections/SkipList.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.collections
///
/// Summary description for SkipList.
///
- [SVN(@"$Id: SkipList.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SkipList.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SkipList : IEnumerable, IDictionary
{
///
diff --git a/bedrock/collections/StringSet.cs b/bedrock/collections/StringSet.cs
index 6da2a5f..5e246e1 100644
--- a/bedrock/collections/StringSet.cs
+++ b/bedrock/collections/StringSet.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.collections
/// A set of strings, backed into a BitArray. Any given string that is inserted
/// into any instance of a StringSet increases the size of all StringSets over time.
///
- [SVN(@"$Id: StringSet.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: StringSet.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class StringSet : IEnumerable, IEnumerable, ICloneable
{
private BitArray m_bits = null;
diff --git a/bedrock/collections/Tree.cs b/bedrock/collections/Tree.cs
index 9d5556c..8f6c845 100644
--- a/bedrock/collections/Tree.cs
+++ b/bedrock/collections/Tree.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -20,7 +20,7 @@ namespace bedrock.collections
///
/// A basic balanced tree implementation.
///
- [SVN(@"$Id: Tree.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Tree.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Tree : IEnumerable, IDictionary
{
private Node root = null;
diff --git a/bedrock/collections/Trie.cs b/bedrock/collections/Trie.cs
index 34314bb..198ac5f 100644
--- a/bedrock/collections/Trie.cs
+++ b/bedrock/collections/Trie.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -30,7 +30,7 @@ namespace bedrock.collections
/// A trie is a tree structure that implements a radix search. Each node of the tree has a
/// sub-node for each possible next byte.
///
- [SVN(@"$Id: Trie.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Trie.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Trie : IDictionary
{
private static readonly System.Text.Encoding ENCODING = System.Text.Encoding.Default;
diff --git a/bedrock/collections/TrieNode.cs b/bedrock/collections/TrieNode.cs
index e756b02..0fc2b78 100644
--- a/bedrock/collections/TrieNode.cs
+++ b/bedrock/collections/TrieNode.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@ namespace bedrock.collections
///
/// A node in a Trie. This class is public to support traversal via Trie.Traverse().
///
- [SVN(@"$Id: TrieNode.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: TrieNode.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class TrieNode : IEnumerable
{
// Warning: Assumption of 7-bit ASCII encoding!
diff --git a/bedrock/io/BufferAggregate.cs b/bedrock/io/BufferAggregate.cs
index 176539a..fb6a757 100644
--- a/bedrock/io/BufferAggregate.cs
+++ b/bedrock/io/BufferAggregate.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System.Collections;
@@ -21,7 +21,7 @@ namespace bedrock.io
/// Aggregate byte arrays together, so we can parse
/// across IP packet boundaries
///
- [SVN(@"$Id: BufferAggregate.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: BufferAggregate.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class BufferAggregate
{ // RingBuffer of the Nieblung
private class BufNode
diff --git a/bedrock/io/ReadEventStream.cs b/bedrock/io/ReadEventStream.cs
index 81553bd..b0f32b8 100644
--- a/bedrock/io/ReadEventStream.cs
+++ b/bedrock/io/ReadEventStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -21,7 +21,7 @@ namespace bedrock.io
///
/// Wrap a stream, so that OnRead events can be fired.
///
- [SVN(@"$Id: ReadEventStream.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ReadEventStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ReadEventStream : Stream
{
private Stream m_stream;
diff --git a/bedrock/io/ZlibStream.cs b/bedrock/io/ZlibStream.cs
index d88244c..ec0ed0d 100644
--- a/bedrock/io/ZlibStream.cs
+++ b/bedrock/io/ZlibStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.io
///
/// Compression failed.
///
- [SVN(@"$Id: ZlibStream.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ZlibStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class CompressionFailedException : ApplicationException
{
///
@@ -46,7 +46,7 @@ public CompressionFailedException() : base() { }
/// No, System.IO.Compression.GZipStream won't work, because they didn't expose
/// compression levels or flush types.
///
- [SVN(@"$Id: ZlibStream.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ZlibStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ZlibStream : Stream
{
///
diff --git a/bedrock/net/Address.cs b/bedrock/net/Address.cs
index 2f1fd3c..d237e69 100644
--- a/bedrock/net/Address.cs
+++ b/bedrock/net/Address.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -37,7 +37,7 @@ namespace bedrock.net
/// but adds async DNS lookups.
/// TODO: add SRV?
///
- [SVN(@"$Id: Address.cs 659 2008-04-07 19:14:05Z hildjj $")]
+ [SVN(@"$Id: Address.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Address
{
private string m_hostname = null;
@@ -212,7 +212,7 @@ public string Hostname
if (m_hostname != value)
{
m_hostname = value;
- IPAddress.TryParse(m_hostname, out m_ip);
+ IPAddress.TryParse(m_hostname, out m_ip);
}
}
}
diff --git a/bedrock/net/AsyncSocket.cs b/bedrock/net/AsyncSocket.cs
index 1f1191c..66088fb 100644
--- a/bedrock/net/AsyncSocket.cs
+++ b/bedrock/net/AsyncSocket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -36,13 +36,13 @@ namespace bedrock.net
/// An asynchronous socket, which calls a listener class when
/// interesting things happen.
///
- [SVN(@"$Id: AsyncSocket.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: AsyncSocket.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class AsyncSocket : BaseSocket, IComparable
{
///
/// Socket states.
///
- [SVN(@"$Id: AsyncSocket.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: AsyncSocket.cs 724 2008-08-06 18:09:25Z hildjj $")]
private enum SocketState
{
///
diff --git a/bedrock/net/BaseSocket.cs b/bedrock/net/BaseSocket.cs
index 796f96e..6a01323 100644
--- a/bedrock/net/BaseSocket.cs
+++ b/bedrock/net/BaseSocket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
diff --git a/bedrock/net/Exceptions.cs b/bedrock/net/Exceptions.cs
index 6392a6d..cd3bf49 100644
--- a/bedrock/net/Exceptions.cs
+++ b/bedrock/net/Exceptions.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -19,7 +19,7 @@ namespace bedrock.net
///
/// Lame exception, since I couldn't find one I liked.
///
- [SVN(@"$Id: Exceptions.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Exceptions.cs 724 2008-08-06 18:09:25Z hildjj $")]
[Serializable]
public class AsyncSocketConnectionException : System.SystemException
{
diff --git a/bedrock/net/HttpSocket.cs b/bedrock/net/HttpSocket.cs
index 67ba356..ee9d1fb 100644
--- a/bedrock/net/HttpSocket.cs
+++ b/bedrock/net/HttpSocket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -30,7 +30,7 @@ namespace bedrock.net
/// TODO: the BaseSocket parameter in the listener events will always be null for now.
/// TODO: change HttpSocket to be a is-a of AsyncSocket, not has-a.
///
- [SVN(@"$Id: HttpSocket.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: HttpSocket.cs 746 2008-10-28 14:16:19Z hildjj $")]
public class HttpSocket : BaseSocket, ISocketEventListener
{
private class PendingRequest
@@ -86,8 +86,6 @@ public int ContentLength
private bool m_ssl = false;
private AsyncSocket m_sock = null;
- private LinkedList m_queue = new LinkedList();
- private Thread m_thread;
private ParseState m_state = ParseState.START;
private PendingRequest m_current = null;
private bool m_keepRunning = true;
@@ -96,6 +94,7 @@ public int ContentLength
private float m_connectRetrySec = 10.0F;
private int m_maxErrors = 5;
private int m_errorCount = 0;
+ private object m_lock = new Object();
private static readonly byte[] SPACE = ENC.GetBytes(" ");
private static readonly byte[] CRLF = ENC.GetBytes("\r\n");
@@ -109,10 +108,6 @@ public int ContentLength
///
public HttpSocket(ISocketEventListener listener) : base(listener)
{
- m_thread = new Thread(new ThreadStart(ProcessThread));
- m_thread.Name = "HTTP processing thread";
- m_thread.IsBackground = true;
- m_thread.Start();
}
///
@@ -155,41 +150,15 @@ public int MaxErrors
set { m_maxErrors = value; }
}
- private void ProcessThread()
- {
- PendingRequest req;
- while (m_keepRunning)
- {
- lock (m_queue)
- {
- req = null;
- while (m_keepRunning && ((m_queue.Count == 0) || IsPending))
- {
- if (m_keepRunning && (m_addr != null) && !Connected)
- {
- Monitor.Wait(m_queue, (int)(m_connectRetrySec * 1000));
- if (!m_keepRunning)
- return;
- Connect();
- }
- Monitor.Wait(m_queue);
- }
-
- if (!m_keepRunning)
- return;
-
- Debug.Assert(Connected);
- Debug.Assert(m_queue.Count > 0);
- Debug.Assert(!IsPending);
+ private string m_name;
- req = m_queue.First.Value;
- m_queue.RemoveFirst();
- }
- if (req.Method == null)
- Close();
- else
- Send(req);
- }
+ ///
+ /// The name of the socket, for debugging purposes
+ ///
+ public string Name
+ {
+ get { return m_name; }
+ set { m_name = value; }
}
///
@@ -203,16 +172,33 @@ private void ProcessThread()
/// The MIME type of the supplied body
public void Execute(string method, Uri URL, byte[] body, int offset, int len, string contentType)
{
- lock (m_queue)
+ Debug.Assert(!this.IsPending);
+
+ PendingRequest req = new PendingRequest(method, URL, body, offset, len, contentType);
+ if (m_host == null)
+ m_host = req.URI.Host;
+ else if (m_host != req.URI.Host)
+ throw new InvalidOperationException("All requests must got to same host: " + m_host);
+
+ // connect if not yet connected
+ if (req.Method != null)
{
- PendingRequest req = new PendingRequest(method, URL, body, offset, len, contentType);
- if (m_host == null)
- m_host = req.URI.Host;
- else if (m_host != req.URI.Host)
- throw new InvalidOperationException("All requests must got to same host: " + m_host);
- m_queue.AddLast(req);
- Monitor.Pulse(m_queue);
+ lock (m_lock)
+ {
+ if (!Connected)
+ {
+ Connect(req.URI);
+
+ Monitor.Wait(m_lock, (int)(m_connectRetrySec * 1000));
+ if (!m_keepRunning)
+ return;
+
+ Debug.Assert(Connected);
+ Debug.Assert(!IsPending);
+ }
+ }
}
+ Send(req);
}
///
@@ -249,6 +235,8 @@ internal void Connect(Uri uri)
private void Connect()
{
+ m_errorCount = 0;
+
if (!m_keepRunning)
return;
m_state = ParseState.START;
@@ -261,11 +249,11 @@ private void Connect()
///
public override void Close()
{
- m_keepRunning = false;
- lock (m_queue)
+ lock (m_lock)
{
- m_queue.Clear();
- Monitor.Pulse(m_queue);
+ m_keepRunning = false;
+ // in case we closed while waiting for connect
+ Monitor.Pulse(m_lock);
}
if (Connected)
@@ -274,15 +262,19 @@ public override void Close()
}
///
- /// Close the socket after all pending requests are completed.
+ /// Close the socket after any pending request is completed.
///
public void EnqueueClose()
{
- PendingRequest req = new PendingRequest(null, null, null, 0, 0, null);
- lock (m_queue)
+ lock (m_lock)
{
- m_queue.AddLast(req);
- Monitor.Pulse(m_queue);
+ if (!m_keepRunning)
+ return;
+
+ m_keepRunning = false;
+ if (!IsPending)
+ Close();
+ // otherwise, we'll close after the current pending request completes
}
}
@@ -335,6 +327,8 @@ private void Send(PendingRequest req)
byte[] creds = Encoding.ASCII.GetBytes(m_proxyCredentials.UserName + ":" + m_proxyCredentials.Password);
coll.Add("Proxy-Authorization", "Basic " + Convert.ToBase64String(creds));
}
+ coll.Add("X-JN-Name", m_name);
+ coll.Add(HttpRequestHeader.Date, string.Format("{0:r}", DateTime.Now));
coll.Add(HttpRequestHeader.ContentLength, req.Length.ToString());
byte[] headers = coll.ToByteArray();
@@ -350,27 +344,19 @@ private void Send(PendingRequest req)
void ISocketEventListener.OnConnect(BaseSocket sock)
{
- m_errorCount = 0;
-
m_listener.OnConnect(null);
- lock (m_queue)
+ lock (m_lock)
{
- // push back.
- if (m_current != null)
- {
- m_queue.AddFirst(m_current);
- m_current = null;
- }
- Monitor.Pulse(m_queue);
+ Monitor.Pulse(m_lock);
}
}
void ISocketEventListener.OnClose(BaseSocket sock)
{
m_sock = null;
- lock (m_queue)
+ lock (m_lock)
{
- Monitor.Pulse(m_queue);
+ Monitor.Pulse(m_lock);
}
}
@@ -382,9 +368,9 @@ void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
m_listener.OnError(null, ex);
}
- lock (m_queue)
+ lock (m_lock)
{
- Monitor.Pulse(m_queue);
+ Monitor.Pulse(m_lock);
}
}
@@ -443,9 +429,16 @@ private enum ParseState
BODY_CONTINUE
}
+ private void Done()
+ {
+ m_state = ParseState.START;
+ m_current = null;
+ Debug.WriteLine("HTTP Socket " + m_name + " done");
+ }
+
bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
{
- Debug.WriteLine("IN HTTP: " + ENC.GetString(buf, offset, length));
+ Debug.WriteLine("IN HTTP(" + m_name + "): " + ENC.GetString(buf, offset, length));
int i = offset;
string header = null;
int last = offset + length;
@@ -521,17 +514,12 @@ bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int le
goto ERROR;
if (i + len <= last)
{
- m_current = null;
- m_state = ParseState.START;
- if (!m_listener.OnRead(null, buf, i, len))
+ Done();
+ if (!m_listener.OnRead(this, buf, i, len) || !m_keepRunning)
{
Close();
return false;
}
- lock (m_queue)
- {
- Monitor.Pulse(m_queue);
- }
return false;
}
@@ -547,20 +535,15 @@ bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int le
if (m_current.Response.Length == m_current.Response.Capacity)
{
PendingRequest req = m_current;
- m_current = null;
- m_state = ParseState.START;
+ Done();
byte[] resp = req.Response.ToArray();
- if (!m_listener.OnRead(null, resp, 0, resp.Length))
+ if (!m_listener.OnRead(this, resp, 0, resp.Length) || !m_keepRunning)
{
Close();
return false;
}
- lock (m_queue)
- {
- Monitor.Pulse(m_queue);
- }
return false;
}
return true;
diff --git a/bedrock/net/ProxySocket.cs b/bedrock/net/ProxySocket.cs
index 1a77db7..05ffae4 100644
--- a/bedrock/net/ProxySocket.cs
+++ b/bedrock/net/ProxySocket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -22,7 +22,7 @@ namespace bedrock.net
///
/// Proxy object for sockets.
///
- [SVN(@"$Id: ProxySocket.cs 655 2008-04-02 16:46:24Z hildjj $")]
+ [SVN(@"$Id: ProxySocket.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ProxySocket : BaseSocket, ISocketEventListener
{
private BaseSocket m_sock = null;
diff --git a/bedrock/net/ShttpProxy.cs b/bedrock/net/ShttpProxy.cs
index 3042508..959f6d4 100644
--- a/bedrock/net/ShttpProxy.cs
+++ b/bedrock/net/ShttpProxy.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -22,7 +22,7 @@ namespace bedrock.net
///
/// Proxy object for sockets that want to do SHTTP proxying.
///
- [SVN(@"$Id: ShttpProxy.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ShttpProxy.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ShttpProxy : ProxySocket
{
private enum States { None, Connecting, WaitingForAuth, Running, Closed, Error }
diff --git a/bedrock/net/SocketEventListener.cs b/bedrock/net/SocketEventListener.cs
index c7109e7..bc90e02 100644
--- a/bedrock/net/SocketEventListener.cs
+++ b/bedrock/net/SocketEventListener.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -22,7 +22,7 @@ namespace bedrock.net
/// events. This is an interface instead of events in order
/// to preserve symmetry with libbedrock.
///
- [SVN(@"$Id: SocketEventListener.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: SocketEventListener.cs 724 2008-08-06 18:09:25Z hildjj $")]
public interface ISocketEventListener
{
///
@@ -98,7 +98,7 @@ bool OnInvalidCertificate(BaseSocket sock,
///
/// Default, empty implementation of ISocketEventListener
///
- [SVN(@"$Id: SocketEventListener.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: SocketEventListener.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SocketEventListener : ISocketEventListener
{
#region Implementation of ISocketEventListener
diff --git a/bedrock/net/SocketWatcher.cs b/bedrock/net/SocketWatcher.cs
index 2a05e4a..0ce74fc 100644
--- a/bedrock/net/SocketWatcher.cs
+++ b/bedrock/net/SocketWatcher.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -29,7 +29,7 @@ namespace bedrock.net
/// you need to have a place to collect all of the sockets and call poll(). Here, it's just
/// convenience functions.
///
- [SVN(@"$Id: SocketWatcher.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: SocketWatcher.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SocketWatcher : IDisposable
{
private enum State
diff --git a/bedrock/net/Socks4Proxy.cs b/bedrock/net/Socks4Proxy.cs
index d7ff318..f6c93e9 100644
--- a/bedrock/net/Socks4Proxy.cs
+++ b/bedrock/net/Socks4Proxy.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.net
///
/// Proxy object for sockets that want to do SOCKS4 proxying.
///
- [SVN(@"$Id: Socks4Proxy.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: Socks4Proxy.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Socks4Proxy : ProxySocket
{
private enum States { None, Connecting, RequestingProxy, Running, Closed }
diff --git a/bedrock/net/Socks5Proxy.cs b/bedrock/net/Socks5Proxy.cs
index de4c958..cd19cc0 100644
--- a/bedrock/net/Socks5Proxy.cs
+++ b/bedrock/net/Socks5Proxy.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -22,7 +22,7 @@ namespace bedrock.net
///
/// Proxy object for sockets that want to do SOCKS proxying.
///
- [SVN(@"$Id: Socks5Proxy.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Socks5Proxy.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Socks5Proxy : ProxySocket
{
private enum States { None, Connecting, GettingMethods, WaitingForAuth, RequestingProxy, Running, Closed }
diff --git a/bedrock/net/XEP124Socket.cs b/bedrock/net/XEP124Socket.cs
index 616c640..17dfbbf 100644
--- a/bedrock/net/XEP124Socket.cs
+++ b/bedrock/net/XEP124Socket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -34,7 +34,7 @@ namespace bedrock.net
///
/// XEP-0124 Error conditions
///
- [SVN(@"$Id: XEP124Socket.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: XEP124Socket.cs 747 2008-10-28 14:20:45Z hildjj $")]
public class XEP124Exception : WebException
{
///
@@ -51,7 +51,7 @@ public XEP124Exception(string reason)
/// Make a XEP-124 (http://www.xmpp.org/extensions/xep-0124.html) polling "connection" look like a socket.
/// TODO: get rid of the PipeStream, if possible.
///
- [SVN(@"$Id: XEP124Socket.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: XEP124Socket.cs 747 2008-10-28 14:20:45Z hildjj $")]
public class XEP124Socket : BaseSocket, IHttpSocket, IElementSocket, ISocketEventListener
{
///
@@ -62,9 +62,7 @@ public class XEP124Socket : BaseSocket, IHttpSocket, IElementSocket, ISocketEven
private const string CONTENT_TYPE = "text/xml; charset=utf-8";
private const string METHOD = "POST";
- private readonly Object m_lock = new Object();
-
- private readonly int m_hold = 5;
+ private readonly int m_hold = 1;
private int m_wait = 60;
private int m_maxPoll = 30;
private int m_minPoll = 1;
@@ -82,6 +80,9 @@ public class XEP124Socket : BaseSocket, IHttpSocket, IElementSocket, ISocketEven
private Uri m_proxyURI = null;
private NetworkCredential m_proxyCredentials = null;
+ private Thread m_thread = null;
+ private LinkedList m_queue = new LinkedList();
+
private HttpSocket m_sockA = null;
private HttpSocket m_sockB = null;
private HttpSocket m_lastSock = null;
@@ -176,19 +177,117 @@ public override void Accept(Address addr, int backlog)
throw new NotImplementedException("HTTP binding server not implemented");
}
+ private void Enqueue(XmlElement elem)
+ {
+ lock (m_queue)
+ {
+ m_queue.AddLast(elem);
+ Monitor.Pulse(m_queue);
+ }
+ }
+
+ // Must hold lock first.
private HttpSocket GetSocket()
{
- lock (m_lock)
+ // Debug.Assert(!BothPending);
+
+ // Switch to the other socket than the last one, assuming the other socket isn't pending.
+ // If the other socket is pending, use the last one.
+ HttpSocket other = (m_lastSock == m_sockA) ? m_sockB : m_sockA;
+ if (!other.IsPending)
+ m_lastSock = other;
+
+ Debug.WriteLine("Socket: " + m_lastSock.Name);
+ return m_lastSock;
+ }
+
+ private bool BothPending
+ {
+ get { return (m_sockA != null) && (m_sockB != null) &&
+ m_sockA.IsPending && m_sockB.IsPending; }
+ }
+
+ private bool NeitherPending
+ {
+ get { return !m_sockA.IsPending && !m_sockB.IsPending; }
+ }
+
+ private bool BothConnected
+ {
+ get
+ {
+ return (m_sockA != null) && (m_sockB != null) &&
+ m_sockA.Connected && m_sockB.Connected;
+ }
+ }
+
+ private void ProcessThread()
+ {
+ Body body = null;
+ int children = 0;
+
+ while (m_running)
{
- if (m_lastSock == m_sockA)
+ lock (m_queue)
{
- m_lastSock = m_sockB;
+ //if (NeitherPending)
+ // m_queue.AddFirst((XmlElement)null);
+
+ Debug.WriteLine("A: " + m_sockA.IsPending);
+ Debug.WriteLine("b: " + m_sockB.IsPending);
+ while ((m_queue.First == null) || BothPending)
+ {
+ Monitor.Wait(m_queue);
+ if (!m_running)
+ return;
+ }
+
+ // We'll enq nulls to get a poll.
+ // We'll enq a body in order to terminate.
+
+ Debug.Assert(m_queue.First != null);
+ body = m_queue.First.Value as Body;
+ children = 0;
+ if (body != null)
+ // TODO: what to do with leftover stanzas!?
+ m_queue.RemoveFirst();
+ else
+ {
+ body = CreateOpenBodyTag();
+ while (m_queue.First != null)
+ {
+ XmlElement elem = m_queue.First.Value;
+ // ignore nulls. we're going munge together all pending poll requests.
+ if (elem != null)
+ {
+ // if we get to a body in the queue, stop inserting, and wait for the body
+ // to come around again next time.
+ if (elem is Body)
+ break;
+ body.AddChild(elem);
+ children++;
+ }
+ m_queue.RemoveFirst();
+ }
+ }
}
- else
+
+ if (NeitherPending || (children > 0) || (body.Type == BodyType.terminate))
{
- m_lastSock = m_sockA;
+ if (body.RID == -1)
+ body.RID = Interlocked.Increment(ref m_rid);
+
+ byte[] buf = ENC.GetBytes(body.OuterXml);
+ GetSocket().Execute(METHOD, m_uri, buf, 0, buf.Length, CONTENT_TYPE);
+ }
+
+ if (body.Type == BodyType.terminate)
+ {
+ // shutting down.
+ m_sockA.EnqueueClose();
+ m_sockB.EnqueueClose();
+ return;
}
- return m_lastSock;
}
}
@@ -200,17 +299,15 @@ public override void Close()
Body body = CreateOpenBodyTag();
body.Type = BodyType.terminate;
- byte[] buf = ENC.GetBytes(body.OuterXml);
- //m_listener.OnWrite(this, buf, 0, buf.Length);
-
- GetSocket().Execute(METHOD, m_uri, buf, 0, buf.Length, CONTENT_TYPE);
+ Enqueue(body);
- m_sockA.EnqueueClose();
- m_sockB.EnqueueClose();
+ if (m_thread != null)
+ m_thread.Join();
- lock (m_lock)
+ lock (m_queue)
{
m_running = false;
+ m_thread = null;
m_sockA = m_sockB = m_lastSock = null;
}
m_listener.OnClose(this);
@@ -232,6 +329,9 @@ public override void Connect(Address addr)
m_sockA = new HttpSocket(this);
m_sockB = new HttpSocket(this);
+ m_sockA.Name = "A";
+ m_sockB.Name = "B";
+
m_sockA.ProxyURI = m_sockB.ProxyURI = m_proxyURI;
m_sockA.ProxyCredentials = m_sockB.ProxyCredentials = m_proxyCredentials;
@@ -262,7 +362,7 @@ public override void RequestRead()
return;
}
- Write(null);
+ Enqueue(null);
}
///
@@ -334,39 +434,29 @@ public override void Write(byte[] buf, int offset, int len)
///
public void Write(XmlElement elem)
{
- Body body = CreateOpenBodyTag();
- if (elem != null)
- body.AddChild(elem);
-
- byte[] buf = ENC.GetBytes(body.OuterXml);
- //m_listener.OnWrite(this, buf, 0, buf.Length);
-
- GetSocket().Execute(METHOD, m_uri, buf, 0, buf.Length, CONTENT_TYPE);
+ Enqueue(elem);
}
private Body CreateOpenBodyTag()
{
Body body = new Body(m_doc);
- long r = -1L;
if (m_rid == -1L)
{
Random rnd = new Random();
- r = m_rid = (long)rnd.Next();
+ long r = m_rid = (long)rnd.Next();
body.Content = CONTENT_TYPE;
body.To = m_hostid;
body.Wait = m_wait;
body.Hold = m_hold;
body.Lang = m_lang;
+ body.RID = r;
}
else
{
- r = Interlocked.Increment(ref m_rid);
-
body.SID = m_sid;
}
- body.RID = r;
return body;
}
@@ -417,7 +507,7 @@ bool ISocketEventListener.OnAccept(BaseSocket newsocket)
void ISocketEventListener.OnConnect(BaseSocket sock)
{
- lock (m_lock)
+ lock (m_queue)
{
if (!m_running &&
(m_sockA != null) && m_sockA.Connected &&
@@ -425,6 +515,12 @@ void ISocketEventListener.OnConnect(BaseSocket sock)
{
m_running = true;
m_lastSock = m_sockB;
+
+ m_thread = new Thread(ProcessThread);
+ m_thread.IsBackground = true;
+ m_thread.Name = "XEP 124 processing thread";
+ m_thread.Start();
+
m_listener.OnConnect(this);
}
}
@@ -468,6 +564,8 @@ bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int le
return false;
}
+ Debug.WriteLine("OnRead: " + ((HttpSocket)sock).Name);
+
// Parse out the first start tag or empty element, which will be
// .
xpnet.UTF8Encoding e = new xpnet.UTF8Encoding();
@@ -523,10 +621,11 @@ bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int le
return false;
}
- lock (m_lock)
+ lock (m_queue)
{
if (!m_running)
return false;
+
if (b.Type == BodyType.terminate)
{
m_running = false;
@@ -551,6 +650,11 @@ bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int le
}
else
RequestRead();
+
+ lock (m_queue)
+ {
+ Monitor.Pulse(m_queue);
+ }
return true;
}
diff --git a/bedrock/net/XEP25Socket.cs b/bedrock/net/XEP25Socket.cs
index 4aa9999..e802b16 100644
--- a/bedrock/net/XEP25Socket.cs
+++ b/bedrock/net/XEP25Socket.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -28,7 +28,7 @@ namespace bedrock.net
///
/// XEP25 Error conditions
///
- [SVN(@"$Id: XEP25Socket.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: XEP25Socket.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class XEP25Exception : WebException
{
///
@@ -44,7 +44,7 @@ public XEP25Exception(string reason) : base(reason)
/// Make a XEP-25 (http://www.xmpp.org/extensions/xep-0025.html) polling "connection" look like a socket.
/// TODO: get rid of the PipeStream, if possible.
///
- [SVN(@"$Id: XEP25Socket.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: XEP25Socket.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class XEP25Socket : BaseSocket, IHttpSocket
{
private const string CONTENT_TYPE = "application/x-www-form-urlencoded";
diff --git a/bedrock/util/ConfigFile.cs b/bedrock/util/ConfigFile.cs
index bd0d8f8..4522f0f 100644
--- a/bedrock/util/ConfigFile.cs
+++ b/bedrock/util/ConfigFile.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -23,7 +23,7 @@ namespace bedrock.util
///
/// XML configuration file manager.
///
- [SVN(@"$Id: ConfigFile.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ConfigFile.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ConfigFile
{
private string m_file;
diff --git a/bedrock/util/GetOptBase.cs b/bedrock/util/GetOptBase.cs
index 50ea039..68995b9 100644
--- a/bedrock/util/GetOptBase.cs
+++ b/bedrock/util/GetOptBase.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
namespace bedrock.util
@@ -30,7 +30,7 @@ namespace bedrock.util
/// Also, now, you can create an instance of GetOpt, and pass in
/// TODO: Give examples of sublcass and calling example.
///
- [SVN(@"$Id: GetOptBase.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: GetOptBase.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class GetOpt
{
private object m_obj = null;
@@ -469,7 +469,7 @@ public virtual void UsageGUIExit()
///
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method,
AllowMultiple=false)]
- [SVN(@"$Id: GetOptBase.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: GetOptBase.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class CommandLineAttribute : Attribute
{
private string m_commandFlag = null;
diff --git a/bedrock/util/IdleTime.cs b/bedrock/util/IdleTime.cs
index 5e29c7a..f558943 100644
--- a/bedrock/util/IdleTime.cs
+++ b/bedrock/util/IdleTime.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -29,7 +29,7 @@ namespace bedrock.util
///
/// Idle time calculations and notifications.
///
- [SVN(@"$Id: IdleTime.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: IdleTime.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class IdleTime : System.ComponentModel.Component
{
[StructLayout(LayoutKind.Sequential)]
diff --git a/bedrock/util/Version.cs b/bedrock/util/Version.cs
index c8a4a45..cfa78aa 100644
--- a/bedrock/util/Version.cs
+++ b/bedrock/util/Version.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -27,7 +27,7 @@ namespace bedrock.util
///
///
///
- // [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ // [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
AllowMultiple = false,
Inherited = false)]
@@ -300,7 +300,7 @@ public static SourceVersionCollection GetVersion()
///
/// SourceVersionAttribute sta = SourceVersionAttribute.GetVersion(typeof(foo));
///
- [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
AllowMultiple=false, Inherited=false)]
public class StarTeamAttribute : SourceVersionAttribute
@@ -359,7 +359,7 @@ protected override void Parse()
///
/// Version control attribute for RCS and CVS.
///
- [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
AllowMultiple=false, Inherited=false)]
public class RCSAttribute : SourceVersionAttribute
@@ -422,7 +422,7 @@ public string State
/// I don't use this any more, so someone tell me if it breaks with
/// some new release.
///
- [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
AllowMultiple=false, Inherited=false)]
public class SourceSafeAttribute : SourceVersionAttribute
@@ -472,7 +472,7 @@ protected override void Parse()
/// return a list of all of the versioned classes in the
/// current working set.
///
- [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SourceVersionCollection : NameObjectCollectionBase
{
///
@@ -586,7 +586,7 @@ public SourceVersionAttribute this[Type type]
///
/// Version control attribute for Subversion.
///
- [SVN(@"$Id: Version.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: Version.cs 724 2008-08-06 18:09:25Z hildjj $")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct,
AllowMultiple=false, Inherited=false)]
public class SVNAttribute : SourceVersionAttribute
diff --git a/jabber/JID.cs b/jabber/JID.cs
index 38a886b..730ee87 100644
--- a/jabber/JID.cs
+++ b/jabber/JID.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -17,13 +17,14 @@
using System.Diagnostics;
using bedrock.util;
+using System.Text.RegularExpressions;
namespace jabber
{
///
/// Informs the client that an invalid JID was entered.
///
- [SVN(@"$Id: JID.cs 696 2008-06-23 23:58:05Z hildjj $")]
+ [SVN(@"$Id: JID.cs 748 2008-10-28 14:21:07Z hildjj $")]
public class JIDFormatException : ApplicationException
{
///
@@ -65,10 +66,10 @@ protected JIDFormatException(System.Runtime.Serialization.SerializationInfo info
///
/// Provides simple JID management.
///
- [SVN(@"$Id: JID.cs 696 2008-06-23 23:58:05Z hildjj $")]
+ [SVN(@"$Id: JID.cs 748 2008-10-28 14:21:07Z hildjj $")]
[System.ComponentModel.TypeConverter(typeof(JIDTypeConverter))]
[Serializable]
- public class JID : IComparable
+ public class JID : IComparable
{
#if !NO_STRINGPREP
private static readonly stringprep.Profile s_nodeprep = new stringprep.XmppNode();
@@ -117,6 +118,21 @@ public JID(string user, string server, string resource)
}
+ ///
+ /// Builds a new JID, from portions that are guaranteed to already be stringprep'd.
+ ///
+ ///
+ ///
+ ///
+ /// The full user@server/resource JID, so that it doesn't have to be recreated from the parts
+ private JID(string user, string server, string resource, string full)
+ {
+ m_user = user;
+ m_server = server;
+ m_resource = resource;
+ m_JID = full;
+ }
+
private static string build(string user, string server, string resource)
{
Debug.Assert(server != null, "Server must be non-null");
@@ -426,10 +442,121 @@ public string Bare
get
{
parse();
+ if (m_resource == null)
+ return m_JID;
return build(m_user, m_server, null);
}
}
+ ///
+ /// Gets the user@server JID associated with this JID, as a JID.
+ /// Slightly faster than building it yourself, since stringprep
+ /// is avoided.
+ ///
+ public JID BareJID
+ {
+ get
+ {
+ parse();
+ if (m_resource == null)
+ return this; // already bare
+ return new JID(m_user, m_server, null, build(m_user, m_server, null));
+ }
+ }
+
+
+ ///
+ /// XEP-0106 escaping.
+ ///
+ ///
+ public static JID Escape(string user, string server, string resource)
+ {
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ foreach (char c in user)
+ {
+ switch (c)
+ {
+ case ' ':
+ if ((count == 0) || (count == (user.Length - 1)))
+ throw new JIDFormatException();
+ sb.Append("\\20");
+ break;
+ case '"':
+ sb.Append("\\22");
+ break;
+ case '&':
+ sb.Append("\\26");
+ break;
+ case '\'':
+ sb.Append("\\27");
+ break;
+ case '/':
+ sb.Append("\\2f");
+ break;
+ case ':':
+ sb.Append("\\3a");
+ break;
+ case '<':
+ sb.Append("\\3c");
+ break;
+ case '>':
+ sb.Append("\\3e");
+ break;
+ case '@':
+ sb.Append("\\40");
+ break;
+ case '\\':
+ sb.Append("\\5c");
+ break;
+ default:
+ sb.Append(c);
+ break;
+ }
+ count++;
+ }
+ string u = sb.ToString();
+ return new JID(u, server, resource);
+ }
+
+ ///
+ /// Unescape the username portion of a JID, as specified in XEP-106.
+ ///
+ ///
+ public string Unescape()
+ {
+ Regex re = new Regex(@"\\([2-5][0267face])");
+ string u = re.Replace(m_user, new MatchEvaluator(delegate(Match m)
+ {
+ switch (m.Groups[1].Value)
+ {
+ case "20":
+ return " ";
+ case "22":
+ return "\"";
+ case "26":
+ return "&";
+ case "27":
+ return "'";
+ case "2f":
+ return "/";
+ case "3a":
+ return ":";
+ case "3c":
+ return "<";
+ case "3e":
+ return ">";
+ case "40":
+ return "@";
+ case "5c":
+ return "\\";
+ default:
+ return m.Groups[0].Value;
+ }
+ }));
+ return u;
+ }
+
#region Implementation of IComparable
///
/// Compares the current instance with another object of the same type.
@@ -559,6 +686,9 @@ public override bool IsValid(System.ComponentModel.ITypeDescriptorContext contex
///
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
+ if (value == null)
+ return null;
+
string s = value as string;
if (s != null)
{
@@ -582,6 +712,8 @@ public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext
///
public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
+ if (value == null)
+ return null;
if (destinationType == typeof(string))
return value.ToString();
if (destinationType == typeof(JID))
diff --git a/jabber/client/BookmarkManager.cs b/jabber/client/BookmarkManager.cs
new file mode 100644
index 0000000..26954d1
--- /dev/null
+++ b/jabber/client/BookmarkManager.cs
@@ -0,0 +1,293 @@
+/* --------------------------------------------------------------------------
+ * Copyrights
+ *
+ * Portions created by or assigned to Cursive Systems, Inc. are
+ * Copyright (c) 2002-2008 Cursive Systems, Inc. All Rights Reserved. Contact
+ * information for Cursive Systems, Inc. is available at
+ * http://www.cursive.net/.
+ *
+ * License
+ *
+ * Jabber-Net is licensed under the LGPL.
+ * See LICENSE.txt for details.
+ * --------------------------------------------------------------------------*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+
+using bedrock.util;
+using jabber.connection;
+using jabber.protocol.client;
+using jabber.protocol.iq;
+using System.Xml;
+
+namespace jabber.client
+{
+ ///
+ /// A new conference bookmark.
+ ///
+ ///
+ ///
+ public delegate void BookmarkConferenceDelegate(BookmarkManager manager, BookmarkConference conference);
+
+ ///
+ /// Manager bookmarks on the server, with the old-style iq:private.
+ /// TODO: add support for new-style PEP.
+ ///
+ [SVN(@"$Id: BookmarkManager.cs 735 2008-09-07 23:08:30Z hildjj $")]
+ public class BookmarkManager : jabber.connection.StreamComponent
+ {
+ private bool m_autoPrivate = true;
+ private ConferenceManager m_confManager;
+ private Dictionary m_conferences = new Dictionary();
+
+ ///
+ /// Create
+ ///
+ public BookmarkManager()
+ {
+ InitializeComponent();
+ this.OnStreamChanged += new bedrock.ObjectHandler(BookmarkManager_OnStreamChanged);
+ }
+
+ ///
+ /// Create
+ ///
+ ///
+ public BookmarkManager(IContainer container) : this()
+ {
+ container.Add(this);
+ }
+
+ ///
+ /// Automatically request bookmarks using iq:private on login.
+ ///
+ [Category("Bookmarks")]
+ [Description("Automatically request bookmarks using iq:private on login.")]
+ [DefaultValue(true)]
+ public bool AutoPrivate
+ {
+ get { return m_autoPrivate; }
+ set { m_autoPrivate = value; }
+ }
+
+ ///
+ /// A conference bookmark has been .
+ ///
+ [Category("Bookmarks")]
+ [Description("A conference bookmark has been added to the list.")]
+ public event BookmarkConferenceDelegate OnConferenceAdd;
+
+ ///
+ /// A conference bookmark has been removed from the list.
+ ///
+ [Category("Bookmarks")]
+ [Description("A conference bookmark has been removed from the list.")]
+ public event BookmarkConferenceDelegate OnConferenceRemove;
+
+ ///
+ /// A ConferenceManager into which to auto-join conference rooms.
+ ///
+ [Category("Jabber")]
+ public ConferenceManager ConferenceManager
+ {
+ get
+ {
+ // If we are running in the designer, let's try to auto-hook a ConferenceManager
+ if ((m_confManager == null) && DesignMode)
+ {
+ IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
+ this.ConferenceManager = (ConferenceManager)jabber.connection.StreamComponent.GetComponentFromHost(host, typeof(ConferenceManager));
+ }
+ return m_confManager;
+ }
+ set
+ {
+ if ((object)m_confManager == (object)value)
+ return;
+ m_confManager = value;
+ }
+ }
+
+ private void BookmarkManager_OnStreamChanged(object sender)
+ {
+ m_stream.OnDisconnect += new bedrock.ObjectHandler(m_stream_OnDisconnect);
+ m_stream.OnError += new bedrock.ExceptionHandler(m_stream_OnError);
+ JabberClient cli = m_stream as JabberClient;
+ if (cli == null)
+ return;
+
+ cli.OnAuthenticate += new bedrock.ObjectHandler(cli_OnAuthenticate);
+ }
+
+ private void m_stream_OnError(object sender, Exception ex)
+ {
+ m_conferences.Clear();
+ }
+
+ private void m_stream_OnDisconnect(object sender)
+ {
+ m_conferences.Clear();
+ }
+
+ private void cli_OnAuthenticate(object sender)
+ {
+ if (AutoPrivate)
+ {
+ BookmarksIQ biq = new BookmarksIQ(m_stream.Document);
+ biq.Type = IQType.get;
+ m_stream.Tracker.BeginIQ(biq, GotBookmarks, null);
+ }
+ }
+
+ private void GotBookmarks(object sender, IQ iq, object state)
+ {
+ if ((iq == null) || (iq.Type != IQType.result))
+ return;
+
+ Private priv = iq.Query as Private;
+ if (priv == null)
+ return;
+
+ Bookmarks bm = priv.GetChildElement();
+ if (bm == null)
+ return;
+
+ foreach (BookmarkConference conf in bm.GetConferences())
+ {
+ if (conf.JID == null)
+ continue;
+
+ m_conferences[conf.JID] = conf;
+ if (OnConferenceAdd != null)
+ OnConferenceAdd(this, conf);
+ if (conf.AutoJoin && (m_confManager != null))
+ {
+ JID rJID = conf.JID;
+ JID roomAndNick = new JID(rJID.User, rJID.Server, conf.Nick);
+ Room r = m_confManager.GetRoom(roomAndNick);
+ r.Join(conf.Password);
+ }
+ }
+ }
+
+ ///
+ /// Get the details for the given conference bookmark.
+ ///
+ ///
+ ///
+ public BookmarkConference this[JID jid]
+ {
+ get { return m_conferences[jid]; }
+ set
+ {
+ BookmarkConference prev = null;
+ if (value == null)
+ {
+ if (m_conferences.TryGetValue(jid, out prev))
+ {
+ m_conferences.Remove(jid);
+ prev.SetAttribute("remove", "true");
+ }
+ else
+ {
+ // no-op. Setting null on a non-existing JID.
+ return;
+ }
+ }
+ else
+ {
+ m_conferences[jid] = prev = value;
+ }
+
+ BookmarksIQ biq = new BookmarksIQ(m_stream.Document);
+ biq.Type = IQType.set;
+ Bookmarks bm = biq.Bookmarks;
+ foreach (BookmarkConference conf in m_conferences.Values)
+ {
+ bm.AddChild((XmlElement)conf.CloneNode(true, m_stream.Document));
+ }
+ m_stream.Tracker.BeginIQ(biq, BookmarksSet, prev);
+ }
+ }
+
+ private void BookmarksSet(object sender, IQ iq, object state)
+ {
+ if ((iq == null) || (iq.Type != IQType.result))
+ return;
+
+ BookmarkConference prev = state as BookmarkConference;
+ if (prev == null)
+ return;
+
+ if (prev.GetAttribute("remove") == "true")
+ {
+ if (OnConferenceRemove != null)
+ {
+ prev.RemoveAttribute("remove");
+ OnConferenceRemove(this, prev);
+ }
+ }
+ else
+ {
+ if (OnConferenceAdd != null)
+ OnConferenceAdd(this, prev);
+ }
+ }
+
+ ///
+ /// Add a conference room to the bookmark list
+ ///
+ /// The room@service JID of the room
+ /// Human-readable text
+ /// Join on login
+ /// Room nickname. May be null.
+ ///
+ public BookmarkConference AddConference(JID jid, string name, bool autoJoin, string nick)
+ {
+ BookmarkConference c = new BookmarkConference(m_stream.Document);
+ if (jid == null)
+ throw new ArgumentNullException("jid", "JID must not be null in a conference bookmark");
+ c.JID = jid;
+ if ((name != null) && (name != ""))
+ c.ConferenceName = name;
+ c.AutoJoin = autoJoin;
+ if ((nick != null) && (nick != ""))
+ c.Nick = nick;
+ this[jid] = c;
+ return c;
+ }
+
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+
+ #endregion
+ }
+}
diff --git a/jabber/client/JabberClient.cs b/jabber/client/JabberClient.cs
index c82a04d..47420f5 100644
--- a/jabber/client/JabberClient.cs
+++ b/jabber/client/JabberClient.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -51,7 +51,7 @@ namespace jabber.client
/// You can install this in your Toolbox, drop onto a form, a service, and so on.
/// This class hooks into the OnProtocol event and calls the Connect() method.
///
- [SVN(@"$Id: JabberClient.cs 707 2008-07-15 21:49:47Z hildjj $")]
+ [SVN(@"$Id: JabberClient.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class JabberClient : XmppStream
{
private static readonly object[][] DEFAULTS = new object[][] {
@@ -894,7 +894,6 @@ private void JabberClient_OnSASLEnd(Object sender, jabber.protocol.stream.Featur
if (feat["bind", URI.BIND] != null)
{
IQ iq = new IQ(this.Document);
- iq.To = this.Server;
iq.Type = IQType.set;
jabber.protocol.stream.Bind bind = new jabber.protocol.stream.Bind(this.Document);
@@ -907,7 +906,6 @@ private void JabberClient_OnSASLEnd(Object sender, jabber.protocol.stream.Featur
else if (feat["session", URI.SESSION] != null)
{
IQ iq = new IQ(this.Document);
- iq.To = this.Server;
iq.Type = IQType.set;
iq.AddChild(new jabber.protocol.stream.Session(this.Document));
this.Tracker.BeginIQ(iq, new IqCB(GotSession), feat);
@@ -954,7 +952,6 @@ private void GotResource(object sender, IQ iq, object state)
if (feat["session", URI.SESSION] != null)
{
IQ iqs = new IQ(this.Document);
- iqs.To = this.Server;
iqs.Type = IQType.set;
iqs.AddChild(new jabber.protocol.stream.Session(this.Document));
this.Tracker.BeginIQ(iqs, new IqCB(GotSession), feat);
@@ -983,7 +980,7 @@ private void JabberClient_OnStreamInit(Object sender, ElementStream stream)
///
/// Contains the "Getting authorization" information.
///
- [SVN(@"$Id: JabberClient.cs 707 2008-07-15 21:49:47Z hildjj $")]
+ [SVN(@"$Id: JabberClient.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class GetAuthState : jabber.connection.BaseState
{
///
@@ -995,7 +992,7 @@ public class GetAuthState : jabber.connection.BaseState
///
/// Contains the "Setting authorization" information.
///
- [SVN(@"$Id: JabberClient.cs 707 2008-07-15 21:49:47Z hildjj $")]
+ [SVN(@"$Id: JabberClient.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SetAuthState : jabber.connection.BaseState
{
///
@@ -1008,7 +1005,7 @@ public class SetAuthState : jabber.connection.BaseState
/// Informs the client that the JabberClient is in
/// the "Waiting for manual login" state.
///
- [SVN(@"$Id: JabberClient.cs 707 2008-07-15 21:49:47Z hildjj $")]
+ [SVN(@"$Id: JabberClient.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ManualLoginState : jabber.connection.BaseState
{
///
@@ -1022,7 +1019,7 @@ public class ManualLoginState : jabber.connection.BaseState
/// the "Waiting for manual login" state, but when Login()
/// happens, it should try SASL.
///
- [SVN(@"$Id: JabberClient.cs 707 2008-07-15 21:49:47Z hildjj $")]
+ [SVN(@"$Id: JabberClient.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ManualSASLLoginState : jabber.connection.BaseState
{
///
diff --git a/jabber/client/PresenceManager.cs b/jabber/client/PresenceManager.cs
index 79f983d..bea3933 100644
--- a/jabber/client/PresenceManager.cs
+++ b/jabber/client/PresenceManager.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -40,7 +40,7 @@ namespace jabber.client
///
/// Specifies the presence proxy database.
///
- [SVN(@"$Id: PresenceManager.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: PresenceManager.cs 729 2008-09-07 22:59:07Z hildjj $")]
public class PresenceManager : jabber.connection.StreamComponent, IEnumerable
{
///
@@ -97,7 +97,7 @@ public JabberClient Client
}
///
- /// The RosterManager for this view
+ /// The CapsManager for this view
///
[Category("Jabber")]
public CapsManager CapsManager
diff --git a/jabber/client/RosterManager.cs b/jabber/client/RosterManager.cs
index e0352eb..2ced2d7 100644
--- a/jabber/client/RosterManager.cs
+++ b/jabber/client/RosterManager.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -75,7 +75,7 @@ public enum AutoSubscriptionHanding
///
/// Manages the roster of the client.
///
- [SVN(@"$Id: RosterManager.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: RosterManager.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class RosterManager : jabber.connection.StreamComponent, IEnumerable
{
///
@@ -284,18 +284,18 @@ private void cli_OnPresence(object sender, Presence pres)
}
break;
case PresenceType.subscribed:
+ // This is the new ack case.
Presence sub_ack = new Presence(m_stream.Document);
sub_ack.To = pres.From;
sub_ack.Type = PresenceType.subscribed;
- m_stream.Write(sub_ack);
-
+ Write(sub_ack);
break;
case PresenceType.unsubscribe:
// ack. we'll likely get an unsubscribed soon, anyway.
Presence un_ack = new Presence(m_stream.Document);
un_ack.To = pres.From;
un_ack.Type = PresenceType.unsubscribed;
- m_stream.Write(un_ack);
+ Write(un_ack);
break;
case PresenceType.unsubscribed:
bool remove = true;
@@ -364,14 +364,14 @@ public void ReplyAllow(Presence pres)
Presence reply = new Presence(m_stream.Document);
reply.To = pres.From;
reply.Type = PresenceType.subscribed;
- m_stream.Write(reply);
+ Write(reply);
if (m_autoSubscribe)
{
Presence sub = new Presence(m_stream.Document);
sub.To = pres.From;
sub.Type = PresenceType.subscribe;
- m_stream.Write(sub);
+ Write(sub);
}
}
@@ -387,7 +387,7 @@ public void ReplyDeny(Presence pres)
Presence reply = new Presence(m_stream.Document);
reply.To = pres.From;
reply.Type = PresenceType.unsubscribed;
- m_stream.Write(reply);
+ Write(reply);
}
///
@@ -409,7 +409,7 @@ public void Remove(JID jid)
Item item = r.AddItem();
item.JID = jid;
item.Subscription = Subscription.remove;
- m_stream.Write(iq); // ignore response
+ Write(iq); // ignore response
}
///
@@ -424,7 +424,7 @@ public void Modify(Item item)
iq.Type = IQType.set;
Roster r = iq.Instruction;
r.AppendChild(item);
- m_stream.Write(iq); // ignore response
+ Write(iq); // ignore response
}
#region Component Designer generated code
diff --git a/jabber/connection/CapsManager.cs b/jabber/connection/CapsManager.cs
index ad07714..483acfd 100644
--- a/jabber/connection/CapsManager.cs
+++ b/jabber/connection/CapsManager.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -34,7 +34,7 @@ namespace jabber.connection
/// Manages the entity capabilities information for the local connection as well as remote ones.
/// See XEP-0115, version 1.5 for details.
///
- [SVN("$Id: CapsManager.cs 677 2008-06-12 17:13:48Z hildjj $")]
+ [SVN("$Id: CapsManager.cs 730 2008-09-07 23:00:48Z hildjj $")]
public class CapsManager: StreamComponent
{
///
@@ -447,10 +447,12 @@ private void GotCaps(DiscoManager m, DiscoNode node, object state)
return;
string ver = (string)state;
- if (ver != CalculateVer(node))
+ string calc = CalculateVer(node);
+ if (ver != calc)
{
- Debug.WriteLine("WARNING: invalid caps ver hash: " + ver);
- Debug.WriteLine(node.Info.OuterXml);
+ Debug.WriteLine("WARNING: invalid caps ver hash: '" + ver + "' != '" + calc + "'");
+ if (node.Info != null)
+ Debug.WriteLine(node.Info.OuterXml);
return;
}
m_cache[ver] = node.Info;
@@ -513,7 +515,6 @@ public bool IsCaps(IQ iq)
/// The empty info element to fill in.
public void FillInInfo(DiscoInfo info)
{
- info.Node = NodeVer;
foreach (Ident id in Identities)
info.AddIdentity(id.Category, id.Type, id.Name, id.Lang);
foreach (string uri in Features)
@@ -533,7 +534,7 @@ private void jc_OnIQ(object sender, IQ iq)
info = (DiscoInfo)resp.Query;
FillInInfo(info);
- m_stream.Write(resp);
+ Write(resp);
}
///
diff --git a/jabber/connection/CertificatePrompt.cs b/jabber/connection/CertificatePrompt.cs
index b6d1179..8a86768 100644
--- a/jabber/connection/CertificatePrompt.cs
+++ b/jabber/connection/CertificatePrompt.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -32,7 +32,7 @@ namespace jabber.connection
/// Intentionally-ugly form to deal with bad certificates. Because you don't like it, you should catch XmppStream.OnInvalidCertificate,
/// and do something better.
///
- [SVN(@"$Id: CertificatePrompt.cs 614 2008-02-21 20:50:15Z hildjj $")]
+ [SVN(@"$Id: CertificatePrompt.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class CertificatePrompt
#if UI_OK
: Form
diff --git a/jabber/connection/ConferenceManager.cs b/jabber/connection/ConferenceManager.cs
index 1616eab..6cfee3a 100644
--- a/jabber/connection/ConferenceManager.cs
+++ b/jabber/connection/ConferenceManager.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -73,7 +73,7 @@ namespace jabber.connection
///
/// Manages a set of conference rooms
///
- [SVN(@"$Id: ConferenceManager.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ConferenceManager.cs 731 2008-09-07 23:01:31Z hildjj $")]
public class ConferenceManager : StreamComponent
{
///
@@ -81,6 +81,7 @@ public class ConferenceManager : StreamComponent
///
private System.ComponentModel.IContainer components = null;
private Hashtable m_rooms = new Hashtable();
+ private string m_nick = null;
///
/// Creates a new conference manager.
@@ -257,6 +258,25 @@ private void InitializeComponent()
[Category("Manager")]
public event MessageHandler OnInvite;
+ ///
+ /// The default room nickname, if one is not specified. If none
+ /// specified, the user name from the stream JID is used.
+ ///
+ [Category("Manager")]
+ [DefaultValue(null)]
+ public string DefaultNick
+ {
+ get
+ {
+ if (m_nick != null)
+ return m_nick;
+ if ((m_stream == null) || m_stream.JID == null)
+ return null;
+ return m_stream.JID.User;
+ }
+ set { m_nick = value; }
+ }
+
///
/// Joins a conference room.
///
@@ -270,6 +290,9 @@ public Room GetRoom(JID roomAndNick)
if (roomAndNick == null)
throw new ArgumentNullException("roomAndNick");
+ if (roomAndNick.Resource == null)
+ roomAndNick.Resource = DefaultNick;
+
Room r = (Room)m_rooms[roomAndNick];
if (r != null)
return r;
@@ -278,7 +301,7 @@ public Room GetRoom(JID roomAndNick)
if (roomAndNick.Resource == null)
roomAndNick.Resource = m_stream.JID.User;
- r = new Room(this, this.Stream, roomAndNick);
+ r = new Room(this, roomAndNick);
r.OnJoin += OnJoin;
r.OnLeave += OnLeave;
r.OnPresenceError += OnPresenceError;
@@ -365,7 +388,7 @@ public void GetUniqueRoom(string server, string nick, RoomStateEvent callback, o
*/
UniqueIQ iq = new UniqueIQ(m_stream.Document);
iq.To = server;
- m_stream.Tracker.BeginIQ(iq, new IqCB(GotUnique), new UniqueState(nick, callback, state));
+ BeginIQ(iq, new IqCB(GotUnique), new UniqueState(nick, callback, state));
}
private void GotUnique(object sender, IQ iq, object state)
@@ -396,7 +419,7 @@ private void GotUnique(object sender, IQ iq, object state)
///
/// Manages a multi-user conference room. See XEP-0045 (http://www.xmpp.org/extensions/xep-0045.html).
///
- [SVN(@"$Id: ConferenceManager.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ConferenceManager.cs 731 2008-09-07 23:01:31Z hildjj $")]
public class Room
{
private enum STATE
@@ -419,7 +442,7 @@ private enum STATE
/// Bare room JID. room@conference
///
private JID m_room;
- private XmppStream m_stream;
+ //private XmppStream m_stream;
private bool m_default = false;
private ConferenceManager m_manager;
private Message m_subject;
@@ -429,17 +452,16 @@ private enum STATE
///
/// Create.
///
- ///
- ///
+ /// The manager for this room.
/// room@conference/nick, where "nick" is the desred nickname in the room.
- internal Room(ConferenceManager manager, XmppStream stream, JID roomAndNick)
+ internal Room(ConferenceManager manager, JID roomAndNick)
{
m_manager = manager;
- m_stream = stream;
+ XmppStream stream = manager.Stream;
m_jid = roomAndNick;
m_room = new JID(m_jid.User, m_jid.Server, null);
- m_stream.OnProtocol += new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
- JabberClient jc = m_stream as JabberClient;
+ stream.OnProtocol += new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
+ JabberClient jc = stream as JabberClient;
if (jc != null)
jc.OnAfterPresenceOut += new jabber.client.PresenceHandler(m_stream_OnAfterPresenceOut);
}
@@ -530,12 +552,12 @@ public string Subject
get { return m_subject.Subject; }
set
{
- Message m = new Message(m_stream.Document);
+ Message m = new Message(m_manager.Stream.Document);
m.To = m_room;
m.Type = MessageType.groupchat;
m.Subject = value;
m.Body = "/me has changed the subject to: " + value;
- m_stream.Write(m);
+ m_manager.Write(m);
}
}
@@ -573,9 +595,9 @@ public string Nickname
set
{
m_jid = new JID(m_jid.User, m_jid.Server, value);
- Presence p = new Presence(m_stream.Document);
+ Presence p = new Presence(m_manager.Stream.Document);
p.To = m_jid;
- m_stream.Write(p);
+ m_manager.Write(p);
}
}
@@ -607,7 +629,7 @@ private void m_stream_OnAfterPresenceOut(object sender, Presence pres)
{
Presence p = (Presence)pres.CloneNode(true);
p.To = m_room;
- m_stream.Write(p);
+ m_manager.Write(p);
}
private void m_stream_OnProtocol(object sender, System.Xml.XmlElement rp)
@@ -767,8 +789,8 @@ private void OnLeavePresence(Presence p)
if (p.Type != PresenceType.unavailable)
return;
- m_stream.OnProtocol -= new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
- jabber.client.JabberClient jc = m_stream as jabber.client.JabberClient;
+ m_manager.Stream.OnProtocol -= new jabber.protocol.ProtocolHandler(m_stream_OnProtocol);
+ jabber.client.JabberClient jc = m_manager.Stream as jabber.client.JabberClient;
if (jc != null)
jc.OnAfterPresenceOut -= new jabber.client.PresenceHandler(m_stream_OnAfterPresenceOut);
m_manager.RemoveRoom(m_jid); // should cause this object to GC.
@@ -796,17 +818,17 @@ public void Configure()
*/
m_state = STATE.configGet;
- OwnerIQ iq = new OwnerIQ(m_stream.Document);
+ OwnerIQ iq = new OwnerIQ(m_manager.Stream.Document);
iq.Type = IQType.get;
iq.To = m_room;
- m_stream.Tracker.BeginIQ(iq, new IqCB(ConfigForm), null);
+ m_manager.BeginIQ(iq, new IqCB(ConfigForm), null);
}
private void ConfigForm(object sender, IQ iq, object context)
{
// We should always be on the GUI thread.
// XmppStream should invoke before calling OnProtocol in the Tracker.
- Debug.Assert((m_stream.InvokeControl == null) || (!m_stream.InvokeControl.InvokeRequired));
+ Debug.Assert((m_manager.Stream.InvokeControl == null) || (!m_manager.Stream.InvokeControl.InvokeRequired));
IQ resp = OnRoomConfig(this, iq);
if (resp == null)
@@ -819,7 +841,7 @@ private void ConfigForm(object sender, IQ iq, object context)
resp.To = m_room;
resp.Type = IQType.set;
resp.From = null;
- m_stream.Tracker.BeginIQ(resp, new IqCB(Configured), null);
+ m_manager.BeginIQ(resp, new IqCB(Configured), null);
}
private void Configured(object sender, IQ iq, object context)
@@ -858,13 +880,13 @@ private void FinishConfigDefault()
*/
m_state = STATE.configSet;
- OwnerIQ iq = new OwnerIQ(m_stream.Document);
+ OwnerIQ iq = new OwnerIQ(m_manager.Stream.Document);
iq.Type = IQType.set;
iq.To = m_room;
OwnerQuery oq = iq.Instruction;
Data form = oq.Form;
form.Type = XDataType.submit;
- m_stream.Tracker.BeginIQ(iq, new IqCB(Configured), null);
+ m_manager.BeginIQ(iq, new IqCB(Configured), null);
}
///
@@ -873,12 +895,7 @@ private void FinishConfigDefault()
///
public void Join()
{
- if (m_state == STATE.running)
- return;
-
- m_state = STATE.join;
- RoomPresence pres = new RoomPresence(m_stream.Document, m_jid);
- m_stream.Write(pres);
+ Join(null);
}
///
@@ -891,10 +908,11 @@ public void Join(string password)
return;
m_state = STATE.join;
- RoomPresence pres = new RoomPresence(m_stream.Document, m_jid);
- pres.X.Password = password;
+ RoomPresence pres = new RoomPresence(m_manager.Stream.Document, m_jid);
+ if (password != null)
+ pres.X.Password = password;
- m_stream.Write(pres);
+ m_manager.Write(pres);
}
///
@@ -912,12 +930,12 @@ public void Leave(string reason)
gone where the goblins go
*/
- Presence p = new Presence(m_stream.Document);
+ Presence p = new Presence(m_manager.Stream.Document);
p.To = m_jid;
p.Type = PresenceType.unavailable;
if (reason != null)
p.Status = reason;
- m_stream.Write(p);
+ m_manager.Write(p);
// cleanup done when unavailable/110 received.
@@ -940,11 +958,11 @@ public void PublicMessage(string body)
*/
if (body == null)
throw new ArgumentNullException("body");
- Message m = new Message(m_stream.Document);
+ Message m = new Message(m_manager.Stream.Document);
m.To = m_room;
m.Type = MessageType.groupchat;
m.Body = body;
- m_stream.Write(m);
+ m_manager.Write(m);
}
///
@@ -969,11 +987,11 @@ public void PrivateMessage(string nick, string body)
if (body == null)
throw new ArgumentNullException("body");
- Message m = new Message(m_stream.Document);
+ Message m = new Message(m_manager.Stream.Document);
m.To = new JID(m_room.User, m_room.Server, nick);
m.Type = MessageType.chat;
m.Body = body;
- m_stream.Write(m);
+ m_manager.Write(m);
}
///
@@ -1001,12 +1019,12 @@ public void Invite(JID invitee, string reason)
*/
- Message m = new Message(m_stream.Document);
+ Message m = new Message(m_manager.Stream.Document);
m.To = m_room;
- UserX x = new UserX(m_stream.Document);
+ UserX x = new UserX(m_manager.Stream.Document);
x.AddInvite(invitee, reason);
m.AddChild(x);
- m_stream.Write(m);
+ m_manager.Write(m);
}
#region Moderator use cases
@@ -1037,7 +1055,7 @@ public void ChangeRole(string nick, RoomRole role, string reason)
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
iq.Type = IQType.set;
AdminQuery query = iq.Instruction;
@@ -1045,7 +1063,7 @@ public void ChangeRole(string nick, RoomRole role, string reason)
item.Nick = nick;
item.Role = role;
item.Reason = reason;
- m_stream.Tracker.BeginIQ(iq, null, null);
+ m_manager.BeginIQ(iq, null, null);
}
///
@@ -1111,11 +1129,11 @@ public void RetrieveListByRole(RoomRole role, RoomParticipantsEvent callback, ob
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
AdminQuery query = iq.Instruction;
query.AddItem().Role = role;
- m_stream.Tracker.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
+ m_manager.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
}
private void GotList(object sender, IQ iq, object state)
@@ -1144,9 +1162,9 @@ private void GotList(object sender, IQ iq, object state)
ParticipantCollection.Modification mod;
foreach (AdminItem item in query.GetItems())
{
- Presence pres = new Presence(m_stream.Document);
+ Presence pres = new Presence(m_manager.Stream.Document);
pres.From = new JID(m_jid.User, m_jid.Server, item.Nick);
- UserX x = new UserX(m_stream.Document);
+ UserX x = new UserX(m_manager.Stream.Document);
RoomItem xi = x.RoomItem;
xi.Role = item.Role;
xi.Affiliation = item.Affiliation;
@@ -1189,7 +1207,7 @@ public void ModifyRoles(ParticipantCollection parties, string reason, IqCB callb
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
iq.Type = IQType.set;
AdminQuery query = iq.Instruction;
@@ -1207,7 +1225,7 @@ public void ModifyRoles(ParticipantCollection parties, string reason, IqCB callb
}
}
if (count > 0)
- m_stream.Tracker.BeginIQ(iq, callback, state);
+ m_manager.BeginIQ(iq, callback, state);
else
callback(this, null, state);
}
@@ -1242,7 +1260,7 @@ public void ChangeAffiliation(JID jid, RoomAffiliation affiliation, string reaso
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
iq.Type = IQType.set;
AdminQuery query = iq.Instruction;
@@ -1250,7 +1268,7 @@ public void ChangeAffiliation(JID jid, RoomAffiliation affiliation, string reaso
item.JID = jid;
item.Affiliation = affiliation;
item.Reason = reason;
- m_stream.Tracker.BeginIQ(iq, null, null);
+ m_manager.BeginIQ(iq, null, null);
}
///
@@ -1314,11 +1332,11 @@ public void RetrieveListByAffiliation(RoomAffiliation affiliation, RoomParticipa
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
AdminQuery query = iq.Instruction;
query.AddItem().Affiliation = affiliation;
- m_stream.Tracker.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
+ m_manager.BeginIQ(iq, new IqCB(GotList), new RetrieveParticipantsState(callback, state));
}
///
@@ -1346,7 +1364,7 @@ public void ModifyAffiliations(ParticipantCollection parties, string reason, IqC
*/
- RoomAdminIQ iq = new RoomAdminIQ(m_stream.Document);
+ RoomAdminIQ iq = new RoomAdminIQ(m_manager.Stream.Document);
iq.To = m_room;
iq.Type = IQType.set;
AdminQuery query = iq.Instruction;
@@ -1364,7 +1382,7 @@ public void ModifyAffiliations(ParticipantCollection parties, string reason, IqC
}
}
if (count > 0)
- m_stream.Tracker.BeginIQ(iq, callback, state);
+ m_manager.BeginIQ(iq, callback, state);
else
callback(this, null, state);
}
@@ -1374,7 +1392,7 @@ public void ModifyAffiliations(ParticipantCollection parties, string reason, IqC
///
/// A list of all of the current participants.
///
- [SVN(@"$Id: ConferenceManager.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ConferenceManager.cs 731 2008-09-07 23:01:31Z hildjj $")]
public class ParticipantCollection : IEnumerable
{
private Hashtable m_hash = new Hashtable();
@@ -1481,7 +1499,7 @@ public IEnumerator GetEnumerator()
///
/// Someone who is currently in or associated with a room.
///
- [SVN(@"$Id: ConferenceManager.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: ConferenceManager.cs 731 2008-09-07 23:01:31Z hildjj $")]
public class RoomParticipant
{
private Presence m_presence;
diff --git a/jabber/connection/DiscoManager.cs b/jabber/connection/DiscoManager.cs
index b253a58..53bca27 100644
--- a/jabber/connection/DiscoManager.cs
+++ b/jabber/connection/DiscoManager.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -32,7 +32,7 @@ namespace jabber.connection
///
/// Manages a service discovery (disco) identity. See XEP-0030 for more information.
///
- [SVN(@"$Id: DiscoManager.cs 683 2008-06-12 22:28:44Z hildjj $")]
+ [SVN(@"$Id: DiscoManager.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Ident : IComparable
{
private string m_name;
@@ -203,7 +203,7 @@ public override string ToString()
///
/// Manages a JID and Node combination.
///
- [SVN(@"$Id: DiscoManager.cs 683 2008-06-12 22:28:44Z hildjj $")]
+ [SVN(@"$Id: DiscoManager.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class JIDNode
{
private JID m_jid = null;
@@ -315,7 +315,7 @@ public override string ToString()
///
/// NOTE: If you have multiple connections in the same process, they all share the same Disco cache.
///
- [SVN(@"$Id: DiscoManager.cs 683 2008-06-12 22:28:44Z hildjj $")]
+ [SVN(@"$Id: DiscoManager.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class DiscoNode : JIDNode, IEnumerable
{
///
@@ -838,7 +838,7 @@ public IEnumerator GetEnumerator()
// TODO: once etags are finished, make all of this information cached on disk.
// TODO: cache XEP-115 client caps data to disk
// TODO: add negative caching
- [SVN(@"$Id: DiscoManager.cs 683 2008-06-12 22:28:44Z hildjj $")]
+ [SVN(@"$Id: DiscoManager.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class DiscoManager : StreamComponent, IEnumerable
{
///
@@ -982,9 +982,7 @@ private void RequestInfo(DiscoNode node)
jabber.server.JabberService js = m_stream as jabber.server.JabberService;
if (js != null)
iq.From = js.ComponentID;
- m_stream.Tracker.BeginIQ(iq,
- new jabber.connection.IqCB(GotInfo),
- node);
+ BeginIQ(iq, new jabber.connection.IqCB(GotInfo), node);
}
}
}
@@ -999,9 +997,7 @@ private void RequestItems(DiscoNode node)
jabber.server.JabberService js = m_stream as jabber.server.JabberService;
if (js != null)
iq.From = js.ComponentID;
- m_stream.Tracker.BeginIQ(iq,
- new jabber.connection.IqCB(GotItems),
- node);
+ BeginIQ(iq, new jabber.connection.IqCB(GotItems), node);
}
}
}
@@ -1026,7 +1022,7 @@ private void GotInfo(object sender, IQ iq, object onode)
(cond == Error.SERVICE_UNAVAILABLE))
{
IQ aiq = new AgentsIQ(m_stream.Document);
- m_stream.Tracker.BeginIQ(aiq, new jabber.connection.IqCB(GotAgents), m_root);
+ BeginIQ(aiq, new jabber.connection.IqCB(GotAgents), m_root);
return;
}
}
diff --git a/jabber/connection/FileMap.cs b/jabber/connection/FileMap.cs
index 7b85567..48f8842 100644
--- a/jabber/connection/FileMap.cs
+++ b/jabber/connection/FileMap.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -26,7 +26,7 @@ namespace jabber.connection
/// A dictionary backed into a file. Any modification to the dictionary re-writes the file, so
/// writes are somewhat costly. Reads are cached lazily.
///
- [SVN(@"$Id: FileMap.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: FileMap.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class FileMap
where T : Element
{
diff --git a/jabber/connection/HttpStanzaStream.cs b/jabber/connection/HttpStanzaStream.cs
index 83a3e63..ef50f59 100644
--- a/jabber/connection/HttpStanzaStream.cs
+++ b/jabber/connection/HttpStanzaStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
@@ -24,7 +24,7 @@ namespace jabber.connection
///
/// Manages the HTTP Polling XMPP stream.
///
- [SVN(@"$Id: HttpStanzaStream.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: HttpStanzaStream.cs 746 2008-10-28 14:16:19Z hildjj $")]
public abstract class HttpStanzaStream : StanzaStream, ISocketEventListener
{
private AsynchElementStream m_elements = null;
@@ -269,6 +269,8 @@ void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
{
+ Debug.Assert(m_listener != null);
+ Debug.Assert(m_elements != null);
m_listener.BytesRead(buf, offset, length);
m_elements.Push(buf, offset, length);
return true;
diff --git a/jabber/connection/HttpUploader.cs b/jabber/connection/HttpUploader.cs
index cfcf7e3..b55c6c7 100644
--- a/jabber/connection/HttpUploader.cs
+++ b/jabber/connection/HttpUploader.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -26,7 +26,7 @@ namespace jabber.connection
///
/// Manages HTTP Requests via XMPP (XEP-70).
///
- [SVN(@"$Id: HttpUploader.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: HttpUploader.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class HttpUploader
{
///
diff --git a/jabber/connection/IQTracker.cs b/jabber/connection/IQTracker.cs
index 69527ac..d42ad38 100644
--- a/jabber/connection/IQTracker.cs
+++ b/jabber/connection/IQTracker.cs
@@ -8,12 +8,13 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Xml;
@@ -31,7 +32,7 @@ namespace jabber.connection
///
/// Informs the client that an IQ has timed out.
///
- [SVN(@"$Id: IQTracker.cs 652 2008-04-02 15:57:08Z hildjj $")]
+ [SVN(@"$Id: IQTracker.cs 736 2008-09-09 21:16:18Z hildjj $")]
public class IQTimeoutException : Exception
{
///
@@ -47,7 +48,7 @@ public IQTimeoutException(string message)
///
/// Represents the interface for tracking an IQ packet.
///
- [SVN(@"$Id: IQTracker.cs 652 2008-04-02 15:57:08Z hildjj $")]
+ [SVN(@"$Id: IQTracker.cs 736 2008-09-09 21:16:18Z hildjj $")]
public interface IIQTracker
{
///
@@ -70,10 +71,10 @@ public interface IIQTracker
///
/// Tracks outstanding IQ requests.
///
- [SVN(@"$Id: IQTracker.cs 652 2008-04-02 15:57:08Z hildjj $")]
+ [SVN(@"$Id: IQTracker.cs 736 2008-09-09 21:16:18Z hildjj $")]
public class IQTracker: IIQTracker
{
- private Hashtable m_pending = new Hashtable();
+ private Dictionary m_pending = new Dictionary();
private XmppStream m_cli = null;
///
@@ -91,19 +92,21 @@ private void OnIQ(object sender, XmlElement elem)
IQ iq = elem as IQ;
if (iq == null)
return;
+ if ((iq.Type != IQType.result) && (iq.Type != IQType.error))
+ return;
string id = iq.ID;
TrackerData td;
lock (m_pending)
{
- td = (TrackerData) m_pending[id];
+ if (!m_pending.TryGetValue(id, out td))
+ return;
// this wasn't one that was being tracked.
- if (td == null)
- {
+ if (!td.IsMatch(iq))
return;
- }
+
m_pending.Remove(id);
}
@@ -121,7 +124,7 @@ public void BeginIQ(IQ iq, IqCB cb, object cbArg)
// if no callback, ignore response.
if (cb != null)
{
- TrackerData td = new TrackerData(cb, cbArg);
+ TrackerData td = new TrackerData(cb, cbArg, iq.To, iq.ID);
lock (m_pending)
{
m_pending[iq.ID] = td;
@@ -139,7 +142,7 @@ public void BeginIQ(IQ iq, IqCB cb, object cbArg)
public IQ IQ(IQ iqp, int millisecondsTimeout)
{
AutoResetEvent are = new AutoResetEvent(false);
- TrackerData td = new TrackerData(SignalEvent, are);
+ TrackerData td = new TrackerData(SignalEvent, are, iqp.To, iqp.ID);
string id = iqp.ID;
lock (m_pending)
{
@@ -154,7 +157,7 @@ public IQ IQ(IQ iqp, int millisecondsTimeout)
lock (m_pending)
{
- IQ resp = (IQ) m_pending[id];
+ IQ resp = td.Response;
m_pending.Remove(id);
return resp;
}
@@ -162,29 +165,54 @@ public IQ IQ(IQ iqp, int millisecondsTimeout)
private void SignalEvent(object sender, IQ iq, object data)
{
- m_pending[iq.ID] = iq;
((AutoResetEvent)data).Set();
}
///
/// Internal state for a pending tracker request
///
- [SVN(@"$Id: IQTracker.cs 652 2008-04-02 15:57:08Z hildjj $")]
+ [SVN(@"$Id: IQTracker.cs 736 2008-09-09 21:16:18Z hildjj $")]
public class TrackerData
{
private IqCB cb;
private object data;
+ private JID jid;
+ private string id;
+ private IQ response = null;
///
/// Create a tracker data instance.
///
///
///
- public TrackerData(IqCB callback, object state)
+ ///
+ ///
+ public TrackerData(IqCB callback, object state, JID to, string iq_id)
{
Debug.Assert(callback != null);
cb = callback;
data = state;
+ jid = to;
+ id = iq_id;
+ }
+
+ ///
+ /// The response that came in.
+ ///
+ public IQ Response
+ {
+ get { return response; }
+ }
+
+ ///
+ /// Is this IQ the one we're looking for?
+ ///
+ ///
+ ///
+ public bool IsMatch(IQ iq)
+ {
+ JID from = iq.From;
+ return (iq.ID == id) && ((jid == null) || (from == null) || (from == jid));
}
///
@@ -194,6 +222,7 @@ public TrackerData(IqCB callback, object state)
///
public void Call(object sender, IQ iq)
{
+ response = iq;
cb(sender, iq, data);
}
}
diff --git a/jabber/connection/PollingStanzaStream.cs b/jabber/connection/PollingStanzaStream.cs
index b7ecd3b..fba9d46 100644
--- a/jabber/connection/PollingStanzaStream.cs
+++ b/jabber/connection/PollingStanzaStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -26,7 +26,7 @@ namespace jabber.connection
///
/// Manages the HTTP Polling XMPP stream.
///
- [SVN(@"$Id: PollingStanzaStream.cs 664 2008-04-16 14:41:47Z hildjj $")]
+ [SVN(@"$Id: PollingStanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class PollingStanzaStream : HttpStanzaStream
{
///
diff --git a/jabber/connection/PubSubManager.cs b/jabber/connection/PubSubManager.cs
index f139abb..14809ac 100644
--- a/jabber/connection/PubSubManager.cs
+++ b/jabber/connection/PubSubManager.cs
@@ -8,12 +8,13 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
using System.Collections;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml;
@@ -35,14 +36,34 @@ namespace jabber.connection
/// node.AutomatedSubscribe();
///
///
- [SVN(@"$Id: PubSubManager.cs 668 2008-04-22 22:15:03Z hildjj $")]
+ [SVN(@"$Id: PubSubManager.cs 744 2008-10-28 14:11:52Z hildjj $")]
public class PubSubManager : StreamComponent
{
+ private class CBHolder
+ {
+ public string Node = null;
+ public int Max = 10;
+ public event ItemCB OnAdd;
+ public event ItemCB OnRemove;
+
+ public void FireAdd(PubSubNode node, PubSubItem item)
+ {
+ if (OnAdd != null)
+ OnAdd(node, item);
+ }
+ public void FireRemove(PubSubNode node, PubSubItem item)
+ {
+ if (OnRemove != null)
+ OnRemove(node, item);
+ }
+ }
+
///
/// Required designer variable.
///
private IContainer components = null;
- private Hashtable m_nodes = new Hashtable();
+ private Dictionary m_nodes = new Dictionary();
+ private Dictionary m_callbacks = new Dictionary();
///
/// Creates a manager.
@@ -50,17 +71,54 @@ public class PubSubManager : StreamComponent
public PubSubManager()
{
InitializeComponent();
+ this.OnStreamChanged += new bedrock.ObjectHandler(PubSubManager_OnStreamChanged);
}
///
/// Creates a manager in a container.
///
/// Parent container.
- public PubSubManager(IContainer container)
+ public PubSubManager(IContainer container) : this()
{
container.Add(this);
+ }
- InitializeComponent();
+ private void PubSubManager_OnStreamChanged(object sender)
+ {
+ m_stream.OnProtocol += new ProtocolHandler(m_stream_OnProtocol);
+ }
+
+ private void m_stream_OnProtocol(object sender, XmlElement rp)
+ {
+ Message msg = rp as Message;
+ if (msg == null)
+ return;
+ PubSubEvent evt = msg["event", URI.PUBSUB_EVENT] as PubSubEvent;
+ if (evt == null)
+ return;
+
+ EventItems items = evt.GetChildElement();
+ if (items == null)
+ return;
+
+ string node = items.Node;
+ JID from = msg.From.BareJID;
+ JIDNode jn = new JIDNode(from, node);
+ PubSubNode psn = null;
+ if (!m_nodes.TryGetValue(jn, out psn))
+ {
+ CBHolder holder = null;
+ if (!m_callbacks.TryGetValue(node, out holder))
+ {
+ Console.WriteLine("WARNING: notification received for unknown pubsub node");
+ return;
+ }
+ psn = new PubSubNode(m_stream, from, node, holder.Max);
+ psn.OnItemAdd += holder.FireAdd;
+ psn.OnItemRemove += holder.FireRemove;
+ m_nodes[jn] = psn;
+ }
+ psn.FireItems(items);
}
///
@@ -95,6 +153,44 @@ private void InitializeComponent()
///
public event bedrock.ExceptionHandler OnError;
+ ///
+ /// Add a handler for all inbound notifications with the given node name.
+ /// This is handy for PEP implicit subscriptions.
+ ///
+ /// PEP node URI
+ /// Callback when items added
+ /// Callbacks when items removed
+ /// Maximum number of items to store per node in this namespace
+ public void AddNodeHandler(string node, ItemCB addCB, ItemCB removeCB, int maxNumber)
+ {
+ CBHolder holder = null;
+ if (!m_callbacks.TryGetValue(node, out holder))
+ {
+ holder = new CBHolder();
+ holder.Node = node;
+ holder.Max = maxNumber;
+ m_callbacks[node] = holder;
+ }
+ holder.OnAdd += addCB;
+ holder.OnRemove += removeCB;
+ }
+
+ ///
+ /// Remove an existing callback.
+ ///
+ ///
+ ///
+ public void RemoveNodeHandler(string node, ItemCB cb)
+ {
+ CBHolder holder = null;
+ if (m_callbacks.TryGetValue(node, out holder))
+ {
+ // tests indicate removing from a list that doesn't contain this callback is safe.
+ holder.OnAdd -= cb;
+ holder.OnRemove -= cb;
+ }
+ }
+
///
/// Subscribes to a publish-subscribe node.
///
@@ -109,8 +205,8 @@ private void InitializeComponent()
public PubSubNode GetNode(JID service, string node, int maxItems)
{
JIDNode jn = new JIDNode(service, node);
- PubSubNode n = (PubSubNode) m_nodes[jn];
- if (n != null)
+ PubSubNode n = null;
+ if (m_nodes.TryGetValue(jn, out n))
return n;
n = new PubSubNode(Stream, service, node, maxItems);
m_nodes[jn] = n;
@@ -135,10 +231,10 @@ public void RemoveNode(JID service, string node, bedrock.ExceptionHandler errorH
{
JIDNode jn = new JIDNode(service, node);
- PubSubNode psNode = m_nodes[jn] as PubSubNode;
- if (psNode != null)
+ PubSubNode psNode = null;
+ if (m_nodes.TryGetValue(jn, out psNode))
{
- m_nodes[jn] = null;
+ m_nodes.Remove(jn);
}
else
{
@@ -150,6 +246,7 @@ public void RemoveNode(JID service, string node, bedrock.ExceptionHandler errorH
psNode.Delete();
}
+
///
/// Get the default configuration of the node.
///
@@ -162,7 +259,7 @@ public void GetDefaults(JID service, IqCB callback, object state)
OwnerPubSubCommandIQ iq = new OwnerPubSubCommandIQ(m_stream.Document);
iq.To = service;
iq.Type = IQType.get;
- m_stream.Tracker.BeginIQ(iq, OnDefaults, new IQTracker.TrackerData(callback, state));
+ BeginIQ(iq, OnDefaults, new IQTracker.TrackerData(callback, state, null, null));
}
private void OnDefaults(object sender, IQ iq, object data)
@@ -213,7 +310,7 @@ private void OnDefaults(object sender, IQ iq, object data)
/// Manages a list of items with a maximum size. Only one item with a given ID will be in the
/// list at a given time.
///
- [SVN(@"$Id: PubSubManager.cs 668 2008-04-22 22:15:03Z hildjj $")]
+ [SVN(@"$Id: PubSubManager.cs 744 2008-10-28 14:11:52Z hildjj $")]
public class ItemList : ArrayList
{
private Hashtable m_index = new Hashtable();
@@ -376,7 +473,7 @@ public enum Op
///
/// Informs the client that a publish-subscribe error occurred.
///
- [SVN(@"$Id: PubSubManager.cs 668 2008-04-22 22:15:03Z hildjj $")]
+ [SVN(@"$Id: PubSubManager.cs 744 2008-10-28 14:11:52Z hildjj $")]
public class PubSubException : Exception
{
///
@@ -419,7 +516,7 @@ public override string Message
///
/// Manages a node to be subscribed to. Will keep a maximum number of items.
///
- [SVN(@"$Id: PubSubManager.cs 668 2008-04-22 22:15:03Z hildjj $")]
+ [SVN(@"$Id: PubSubManager.cs 744 2008-10-28 14:11:52Z hildjj $")]
public class PubSubNode : StreamComponent, IEnumerable
{
private enum STATE
@@ -471,7 +568,6 @@ internal PubSubNode(XmppStream stream, JID jid, string node, int maxItems)
throw new ArgumentException("must not be empty", "node");
m_stream = stream;
- m_stream.OnProtocol += m_stream_OnProtocol;
m_jid = jid;
m_node = node;
m_items = new ItemList(this, maxItems);
@@ -546,6 +642,27 @@ private void FireError(Op op, string message, XmlElement protocol)
OnError(this, new PubSubException(op, message, protocol));
}
+ internal void FireItems(EventItems items)
+ {
+ // OK, it's for us. Might be a new one or a retraction.
+ // Shrug, even if we're sent a mix, it shouldn't hurt anything.
+
+ /*
+
+
+
+
+
+
+
+ */
+ foreach (string id in items.GetRetractions())
+ m_items.RemoveId(id);
+
+ foreach (PubSubItem item in items.GetItems())
+ m_items.Add(item);
+ }
+
///
/// Adds a handler for the OnItemAdd event, and calls the handler for any existing
/// items. To prevent races, use this rather than .OnItemAdd +=.
@@ -621,7 +738,7 @@ public void Create(jabber.protocol.x.Data config)
iq.To = m_jid;
iq.Type = IQType.set;
iq.Command.CreateConfiguration(config);
- m_stream.Tracker.BeginIQ(iq, GotCreated, null);
+ BeginIQ(iq, GotCreated, null);
}
private void GotCreated(object sender, IQ iq, object state)
@@ -704,7 +821,7 @@ public void Subscribe()
PubSubIQ iq = createCommand(PubSubCommandType.subscribe);
addInfo(iq);
- m_stream.Tracker.BeginIQ(iq, GotSubscribed, null);
+ BeginIQ(iq, GotSubscribed, null);
// don't parallelize getItems, in case sub fails.
}
@@ -794,7 +911,7 @@ public void GetItems()
PubSubIQ piq = new PubSubIQ(m_stream.Document, PubSubCommandType.items, m_node);
piq.To = m_jid;
piq.Type = IQType.get;
- m_stream.Tracker.BeginIQ(piq, GotItems, null);
+ BeginIQ(piq, GotItems, null);
}
private void GotItems(object sender, IQ iq, object state)
@@ -866,46 +983,13 @@ public XmlElement this[string id]
}
}
- private void m_stream_OnProtocol(object sender, XmlElement rp)
- {
- if (rp.Name != "message")
- return;
- PubSubEvent evt = rp["event", URI.PUBSUB_EVENT] as PubSubEvent;
- if (evt == null)
- return;
-
- EventItems items = evt.GetChildElement();
- if (items == null)
- return;
- if (items.Node != m_node)
- return;
-
- // OK, it's for us. Might be a new one or a retraction.
- // Shrug, even if we're sent a mix, it shouldn't hurt anything.
-
- /*
-
-
-
-
-
-
-
- */
- foreach (string id in items.GetRetractions())
- m_items.RemoveId(id);
-
- foreach (PubSubItem item in items.GetItems())
- m_items.Add(item);
- }
-
///
/// Unsubscribes from the node.
///
public void Unsubscribe()
{
PubSubIQ iq = createCommand(PubSubCommandType.unsubscribe);
- m_stream.Tracker.BeginIQ(iq, GotUnsubsribed, null);
+ BeginIQ(iq, GotUnsubsribed, null);
}
private void GotUnsubsribed(object sender, IQ iq, object data)
@@ -922,7 +1006,7 @@ public void Delete()
iq.To = m_jid;
iq.Type = IQType.set;
iq.Command.Node = m_node;
- m_stream.Tracker.BeginIQ(iq, GotDelete, null);
+ BeginIQ(iq, GotDelete, null);
}
private void GotDelete(object sender, IQ iq, object data)
@@ -943,7 +1027,7 @@ public void DeleteItem(string id)
PubSubIQ iq = createCommand(PubSubCommandType.retract);
Retract retract = (Retract)iq.Command;
retract.AddItem(id);
- m_stream.Tracker.BeginIQ(iq, OnDeleteNode, null);
+ BeginIQ(iq, OnDeleteNode, null);
}
private void OnDeleteNode(object sender, IQ iq, object data)
@@ -968,7 +1052,7 @@ public void Purge()
iq.To = m_jid;
iq.Type = IQType.set;
iq.Command.Node = m_node;
- m_stream.Tracker.BeginIQ(iq, GotPurge, null);
+ BeginIQ(iq, GotPurge, null);
}
@@ -995,7 +1079,7 @@ public void PublishItem(string id, XmlElement contents)
item.ID = id;
item.AddChild(contents);
pub.AddChild(item);
- m_stream.Tracker.BeginIQ(iq, new IqCB(OnPublished), item);
+ BeginIQ(iq, new IqCB(OnPublished), item);
}
private void OnPublished(object sender, IQ iq, object data)
@@ -1027,7 +1111,7 @@ public void Configure(IqCB callback, object state)
iq.To = m_jid;
iq.Type = IQType.get;
iq.Command.Node = m_node;
- m_stream.Tracker.BeginIQ(iq, OnConfigure, new IQTracker.TrackerData(callback, state));
+ BeginIQ(iq, OnConfigure, new IQTracker.TrackerData(callback, state, null, null));
}
private void OnConfigure(object sender, IQ iq, object data)
diff --git a/jabber/connection/SocketStanzaStream.cs b/jabber/connection/SocketStanzaStream.cs
index 5e0215d..e1faa01 100644
--- a/jabber/connection/SocketStanzaStream.cs
+++ b/jabber/connection/SocketStanzaStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -25,7 +25,7 @@ namespace jabber.connection
///
/// Contains the types of proxies Jabber-Net supports. This is only for socket connections.
///
- [SVN(@"$Id: SocketStanzaStream.cs 664 2008-04-16 14:41:47Z hildjj $")]
+ [SVN(@"$Id: SocketStanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public enum ProxyType
{
///
@@ -50,7 +50,7 @@ public enum ProxyType
///
/// "Standard" XMPP socket for outbound connections.
///
- [SVN(@"$Id: SocketStanzaStream.cs 664 2008-04-16 14:41:47Z hildjj $")]
+ [SVN(@"$Id: SocketStanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SocketStanzaStream : StanzaStream, ISocketEventListener
{
private AsynchElementStream m_elements = null;
diff --git a/jabber/connection/StanzaStream.cs b/jabber/connection/StanzaStream.cs
index 7b330ae..3ffb3b6 100644
--- a/jabber/connection/StanzaStream.cs
+++ b/jabber/connection/StanzaStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -25,7 +25,7 @@ namespace jabber.connection
///
/// Specifies the connection type, such as socket, polling, and so on.
///
- [SVN(@"$Id: StanzaStream.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: StanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public enum ConnectionType
{
///
@@ -45,7 +45,7 @@ public enum ConnectionType
///
/// Listens for stanza and connection events
///
- [SVN(@"$Id: StanzaStream.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: StanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public interface IStanzaEventListener
{
///
@@ -150,7 +150,7 @@ bool OnInvalidCertificate(BaseSocket sock,
///
/// Manages the base stream for reading and writing full stanzas.
///
- [SVN(@"$Id: StanzaStream.cs 643 2008-03-17 16:24:55Z michael.wegman $")]
+ [SVN(@"$Id: StanzaStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public abstract class StanzaStream
{
///
diff --git a/jabber/connection/States.cs b/jabber/connection/States.cs
index 8082868..e93b198 100644
--- a/jabber/connection/States.cs
+++ b/jabber/connection/States.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -20,7 +20,7 @@ namespace jabber.connection
///
/// Represents the base class for all states.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public abstract class BaseState
{
}
@@ -29,7 +29,7 @@ public abstract class BaseState
/// Specifies the state is up and running. If subclasses change the
/// state transition approach, they should end at the RunningState state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class RunningState : BaseState
{
///
@@ -41,7 +41,7 @@ public class RunningState : BaseState
///
/// Specifies the state is not connected.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ClosedState : BaseState
{
///
@@ -54,7 +54,7 @@ public class ClosedState : BaseState
/// Specifies the state is in the process of connecting such as
/// DNS lookup, socket setup, and so on.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ConnectingState : BaseState
{
///
@@ -66,7 +66,7 @@ public class ConnectingState : BaseState
///
/// Specifies the state is in the "connected socket" state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ConnectedState : BaseState
{
///
@@ -78,7 +78,7 @@ public class ConnectedState : BaseState
///
/// Specifies the state is in the "stream:stream has been received" state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class StreamState : BaseState
{
///
@@ -91,7 +91,7 @@ public class StreamState : BaseState
/// Specifies the state is in a closing state.
/// A close was requested, but hasn't yet finalized.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ClosingState : BaseState
{
///
@@ -103,7 +103,7 @@ public class ClosingState : BaseState
///
/// Specifies the state is in a paused state waiting for reconnect timeout.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ReconnectingState : BaseState
{
///
@@ -115,7 +115,7 @@ public class ReconnectingState : BaseState
///
/// Specifies the state is in the "Accepting incoming socket connections" state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class AcceptingState : BaseState
{
///
@@ -126,7 +126,7 @@ public class AcceptingState : BaseState
///
/// Specifies the state is in Old-style auth, iq:auth or handshake.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class NonSASLAuthState : BaseState
{
///
@@ -137,7 +137,7 @@ public class NonSASLAuthState : BaseState
///
/// Specifies the state is in waiting for the server to send the features element.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ServerFeaturesState : BaseState
{
///
@@ -148,7 +148,7 @@ public class ServerFeaturesState : BaseState
///
/// Specifies the state is in Start-TLS.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class StartTLSState : BaseState
{
///
@@ -159,7 +159,7 @@ public class StartTLSState : BaseState
///
/// Specifies the state is in the compression state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class CompressionState : BaseState
{
///
@@ -170,7 +170,7 @@ public class CompressionState : BaseState
///
/// Specifies the state is in SASL Authentication.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SASLState : BaseState
{
///
@@ -182,7 +182,7 @@ public class SASLState : BaseState
/// Specifies the state is in the SASL Authentication has finished state.
/// Restarting the stream for the last time.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SASLAuthedState : BaseState
{
///
@@ -193,7 +193,7 @@ public class SASLAuthedState : BaseState
///
/// SASL Authentication failed. On some servers you can re-try, or register.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SASLFailedState : BaseState
{
///
@@ -204,7 +204,7 @@ public class SASLFailedState : BaseState
///
/// Specifies the state is in the "Binding session" state.
///
- [SVN(@"$Id: States.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: States.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class BindState : BaseState
{
///
diff --git a/jabber/connection/StreamComponent.cs b/jabber/connection/StreamComponent.cs
index 1eb710c..1156539 100644
--- a/jabber/connection/StreamComponent.cs
+++ b/jabber/connection/StreamComponent.cs
@@ -8,22 +8,24 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
+using System.Xml;
using bedrock.util;
using System.Diagnostics;
+using jabber.protocol.client;
namespace jabber.connection
{
///
/// Manages the XmppStream as a component.
///
- [SVN(@"$Id: StreamComponent.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: StreamComponent.cs 724 2008-08-06 18:09:25Z hildjj $")]
public abstract class StreamComponent : System.ComponentModel.Component
{
///
@@ -70,7 +72,7 @@ public static Component GetComponentFromHost(IDesignerHost host, Type type)
///
/// Informs the client that the XmppStream was changed.
- /// Often at design time, the object will be this StreamControl.
+ /// Often at design time, the object will be this StreamComponent.
///
public event bedrock.ObjectHandler OnStreamChanged;
@@ -102,5 +104,46 @@ public virtual XmppStream Stream
}
}
}
+
+ private JID m_overrideFrom = null;
+
+ ///
+ /// Override the from address that will be stamped on outbound packets.
+ /// Unless your server implemets XEP-193, you shouldn't use this for
+ /// client connections.
+ ///
+ public JID OverrideFrom
+ {
+ get { return m_overrideFrom; }
+ set { m_overrideFrom = value; }
+ }
+
+ ///
+ /// Write the specified stanza to the stream.
+ /// If the from address hasn't been set, and an OverrideFrom has been set,
+ /// the from address will be set to the value of OverrideFrom.
+ ///
+ ///
+ public void Write(XmlElement elem)
+ {
+ if ((m_overrideFrom != null) && (elem.GetAttribute("from") == ""))
+ elem.SetAttribute("from", m_overrideFrom);
+ m_stream.Write(elem);
+ }
+
+ ///
+ /// Does an asynchronous IQ call.
+ /// If the from address hasn't been set, and an OverrideFrom has been set,
+ /// the from address will be set to the value of OverrideFrom.
+ ///
+ ///IQ packet to send.
+ ///Callback to execute when the result comes back.
+ ///Arguments to pass to the callback.
+ public void BeginIQ(IQ iq, IqCB cb, object cbArg)
+ {
+ if ((m_overrideFrom != null) && (iq.From == null))
+ iq.From = m_overrideFrom;
+ m_stream.Tracker.BeginIQ(iq, cb, cbArg);
+ }
}
}
diff --git a/jabber/connection/XmppStream.cs b/jabber/connection/XmppStream.cs
index 2408347..daa4178 100644
--- a/jabber/connection/XmppStream.cs
+++ b/jabber/connection/XmppStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -39,7 +39,7 @@ namespace jabber.connection
///
/// Manages option names. These must be well-formed XML element names.
///
- [SVN(@"$Id: XmppStream.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: XmppStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public abstract class Options
{
///
@@ -208,12 +208,16 @@ public abstract class Options
/// Contains the password for the proxy server.
///
public const string PROXY_PW = "proxy.password";
+ ///
+ /// Override the from address, in a component/service connection.
+ ///
+ public const string OVERRIDE_FROM = "override_from";
}
///
/// Manages the XMPP stream of the connection.
///
- [SVN(@"$Id: XmppStream.cs 681 2008-06-12 20:42:07Z hildjj $")]
+ [SVN(@"$Id: XmppStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
abstract public class XmppStream :
System.ComponentModel.Component,
IStanzaEventListener
@@ -900,8 +904,8 @@ public void WriteStartTag(jabber.protocol.stream.Stream elem)
/// The XML element to send.
public virtual void Write(XmlElement elem)
{
- if (m_stanzas!=null)
- m_stanzas.Write(elem);
+ if (m_stanzas!=null)
+ m_stanzas.Write(elem);
}
///
diff --git a/jabber/connection/sasl/ExternalProcessor.cs b/jabber/connection/sasl/ExternalProcessor.cs
index 4c6f891..3aaf862 100644
--- a/jabber/connection/sasl/ExternalProcessor.cs
+++ b/jabber/connection/sasl/ExternalProcessor.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -24,7 +24,7 @@ namespace jabber.connection.sasl
///
/// SASL Mechanism EXTERNAL as specified in XEP-0178.
///
- [SVN(@"$Id: ExternalProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: ExternalProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ExternalProcessor : SASLProcessor
{
///
diff --git a/jabber/connection/sasl/KerbProcessor.cs b/jabber/connection/sasl/KerbProcessor.cs
index 65f1aa1..f11741a 100644
--- a/jabber/connection/sasl/KerbProcessor.cs
+++ b/jabber/connection/sasl/KerbProcessor.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -26,7 +26,7 @@ namespace jabber.connection.sasl
///
/// Uses Kerberos authentication ot log into XMPP server.
///
- [SVN(@"$Id: KerbProcessor.cs 676 2008-06-12 17:05:11Z hildjj $")]
+ [SVN(@"$Id: KerbProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class KerbProcessor : SASLProcessor
{
///
diff --git a/jabber/connection/sasl/MD5Processor.cs b/jabber/connection/sasl/MD5Processor.cs
index 0343ca1..4e79650 100644
--- a/jabber/connection/sasl/MD5Processor.cs
+++ b/jabber/connection/sasl/MD5Processor.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -28,7 +28,7 @@ namespace jabber.connection.sasl
///
/// RFC2831 DIGEST-MD5 SASL mechanism
///
- [SVN(@"$Id: MD5Processor.cs 676 2008-06-12 17:05:11Z hildjj $")]
+ [SVN(@"$Id: MD5Processor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class MD5Processor : SASLProcessor
{
///
@@ -46,6 +46,10 @@ public class MD5Processor : SASLProcessor
private string m_charset;
private string m_authzid;
+ private readonly MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
+ private readonly Regex CSV = new Regex(@"(?[^= \t\r\n]+)=(?:(?[^,"" \t\r\n]+)|(?:""(?[^""]*)"")),?",
+ RegexOptions.ExplicitCapture);
+
///
/// DIGEST-MD5 Realm
///
@@ -76,10 +80,7 @@ public class MD5Processor : SASLProcessor
///
public static readonly string[] s_requiredDirectives = {USERNAME, PASSWORD};
- private static readonly MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
private static readonly Encoding ENC = System.Text.Encoding.UTF8;
- private static readonly Regex CSV = new Regex(@"(?[^= \t\r\n]+)=(?:(?[^,"" \t\r\n]+)|(?:""(?[^""]*)"")),?",
- RegexOptions.ExplicitCapture | RegexOptions.Compiled);
///
///
diff --git a/jabber/connection/sasl/PlainProcessor.cs b/jabber/connection/sasl/PlainProcessor.cs
index cc716e3..c7c8fd7 100644
--- a/jabber/connection/sasl/PlainProcessor.cs
+++ b/jabber/connection/sasl/PlainProcessor.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -24,7 +24,7 @@ namespace jabber.connection.sasl
///
/// SASL Mechanism PLAIN as specified in RFC 2595.
///
- [SVN(@"$Id: PlainProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: PlainProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class PlainProcessor : SASLProcessor
{
///
diff --git a/jabber/connection/sasl/SASLProcessor.cs b/jabber/connection/sasl/SASLProcessor.cs
index 6863d95..693e518 100644
--- a/jabber/connection/sasl/SASLProcessor.cs
+++ b/jabber/connection/sasl/SASLProcessor.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -29,7 +29,7 @@ namespace jabber.connection.sasl
///
/// Some sort of SASL error
///
- [SVN(@"$Id: SASLProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SASLProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class SASLException : ApplicationException
{
///
@@ -47,7 +47,7 @@ public SASLException() : base(){}
///
/// Authentication failed.
///
- [SVN(@"$Id: SASLProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SASLProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class AuthenticationFailedException : SASLException
{
///
@@ -67,7 +67,7 @@ public AuthenticationFailedException(string message) : base(message)
///
/// A required directive wasn't supplied.
///
- [SVN(@"$Id: SASLProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SASLProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class MissingDirectiveException : SASLException
{
///
@@ -81,7 +81,7 @@ public MissingDirectiveException(string message) : base(message)
///
/// Server sent an invalid challenge
///
- [SVN(@"$Id: SASLProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SASLProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class InvalidServerChallengeException : SASLException
{
///
@@ -94,7 +94,7 @@ public InvalidServerChallengeException(string message) : base(message)
///
/// Summary description for SASLProcessor.
///
- [SVN(@"$Id: SASLProcessor.cs 579 2008-02-13 21:29:33Z hildjj $")]
+ [SVN(@"$Id: SASLProcessor.cs 724 2008-08-06 18:09:25Z hildjj $")]
public abstract class SASLProcessor
{
///
diff --git a/jabber/protocol/AsynchElementStream.cs b/jabber/protocol/AsynchElementStream.cs
index ba8caa0..50f94fd 100644
--- a/jabber/protocol/AsynchElementStream.cs
+++ b/jabber/protocol/AsynchElementStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -27,7 +27,7 @@ namespace jabber.protocol
/// Summary description for AsynchElementStream.
/// TODO: combine with ElementStream, since there's only one impl now.
///
- [SVN(@"$Id: AsynchElementStream.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: AsynchElementStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class AsynchElementStream : ElementStream
{
private static System.Text.Encoding utf = System.Text.Encoding.UTF8;
@@ -327,7 +327,7 @@ private void AddText(string text)
///
/// There was an error parsing XML. What was the context?
///
- [SVN(@"$Id: AsynchElementStream.cs 680 2008-06-12 18:35:08Z hildjj $")]
+ [SVN(@"$Id: AsynchElementStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class XMLParseException : Exception
{
private string m_context = null;
diff --git a/jabber/protocol/Element.cs b/jabber/protocol/Element.cs
index 78babc0..6a0d2e4 100644
--- a/jabber/protocol/Element.cs
+++ b/jabber/protocol/Element.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -27,7 +27,7 @@ namespace jabber.protocol
///
/// An enum that should translate "_" into "-" for use externally.
///
- [SVN(@"$Id: Element.cs 691 2008-06-23 21:30:15Z hildjj $")]
+ [SVN(@"$Id: Element.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class DashAttribute : Attribute
{
///
@@ -42,7 +42,7 @@ public DashAttribute()
/// An XmlElement with type-safe accessors. This class is not much use by itself,
/// but provides a number of utility functions for its descendants.
///
- [SVN(@"$Id: Element.cs 691 2008-06-23 21:30:15Z hildjj $")]
+ [SVN(@"$Id: Element.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class Element : XmlElement
{
///
diff --git a/jabber/protocol/ElementFactory.cs b/jabber/protocol/ElementFactory.cs
index 17ea752..4e30950 100644
--- a/jabber/protocol/ElementFactory.cs
+++ b/jabber/protocol/ElementFactory.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -25,7 +25,7 @@ namespace jabber.protocol
///
/// Qname to type mapping.
///
- [SVN(@"$Id: ElementFactory.cs 663 2008-04-16 14:39:52Z hildjj $")]
+ [SVN(@"$Id: ElementFactory.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class QnameType
{
///
@@ -91,7 +91,7 @@ public override string ToString()
///
/// Interface for packet factories to implement.
///
- [SVN(@"$Id: ElementFactory.cs 663 2008-04-16 14:39:52Z hildjj $")]
+ [SVN(@"$Id: ElementFactory.cs 724 2008-08-06 18:09:25Z hildjj $")]
public interface IPacketTypes
{
///
@@ -104,7 +104,7 @@ public interface IPacketTypes
/// A ElementFactory is a class that knows how to create packet instances of
/// a wide variety of different types.
///
- [SVN(@"$Id: ElementFactory.cs 663 2008-04-16 14:39:52Z hildjj $")]
+ [SVN(@"$Id: ElementFactory.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ElementFactory
{
private Hashtable m_types = new Hashtable();
diff --git a/jabber/protocol/ElementList.cs b/jabber/protocol/ElementList.cs
index ef155b7..2af49f7 100644
--- a/jabber/protocol/ElementList.cs
+++ b/jabber/protocol/ElementList.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -24,7 +24,7 @@ namespace jabber.protocol
/// but removes the big old memory leak in MS's implementation. Also, only returns first-level children,
/// rather than all children below here with the given name. Thanks, MS.
///
- [SVN(@"$Id: ElementList.cs 641 2008-03-13 15:58:22Z hildjj $")]
+ [SVN(@"$Id: ElementList.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ElementList : XmlNodeList
{
private XmlElement m_parent = null;
@@ -185,7 +185,7 @@ public bool MoveNext()
///
/// Parameterized version of ElementList.
///
- [SVN(@"$Id: ElementList.cs 641 2008-03-13 15:58:22Z hildjj $")]
+ [SVN(@"$Id: ElementList.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class TypedElementList : XmlNodeList, System.Collections.Generic.IEnumerable
where T : XmlElement
{
diff --git a/jabber/protocol/ElementStream.cs b/jabber/protocol/ElementStream.cs
index 7a7fc06..d94cbdc 100644
--- a/jabber/protocol/ElementStream.cs
+++ b/jabber/protocol/ElementStream.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -38,7 +38,7 @@ namespace jabber.protocol
///
/// TODO: Combine with AsyncElementStream, since there's only one impl.
///
- [SVN(@"$Id: ElementStream.cs 671 2008-06-03 00:46:38Z hildjj $")]
+ [SVN(@"$Id: ElementStream.cs 724 2008-08-06 18:09:25Z hildjj $")]
public class ElementStream
{
///
diff --git a/jabber/protocol/EnumParser.cs b/jabber/protocol/EnumParser.cs
index 9c6e07c..959a7f6 100644
--- a/jabber/protocol/EnumParser.cs
+++ b/jabber/protocol/EnumParser.cs
@@ -8,7 +8,7 @@
*
* License
*
- * Jabber-Net can be used under either JOSL or the GPL.
+ * Jabber-Net is licensed under the LGPL.
* See LICENSE.txt for details.
* --------------------------------------------------------------------------*/
using System;
@@ -70,66 +70,78 @@ private static bool IsDash(Type t)
private static Dictionary GetValHash(Type t)
{
- Dictionary map = null;
- lock (s_vals) // Needed if more JabberClient instances are used at the same time
- {
- if (!s_vals.TryGetValue(t, out map))
- {
- s_vals[t] = map = new Dictionary();
- bool dash = IsDash(t);
-
- FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
- foreach (FieldInfo fi in fields)
- {
- object[] attrs = fi.GetCustomAttributes(typeof(XMLAttribute), false);
- object val = fi.GetValue(null);
- if (attrs.Length > 0)
- {
- string name = ((XMLAttribute)attrs[0]).Name;
- map[name] = val;
- }
- if (dash)
- map[fi.Name.Replace("_", "-")] = val;
- else
- map[fi.Name] = val;
- }
- }
- }
- return map;
+ Dictionary map;
+ lock (s_vals)
+ {
+ if (s_vals.TryGetValue(t, out map))
+ {
+ return map;
+ }
+ }
+
+ map = new Dictionary();
+ bool dash = IsDash(t);
+
+ FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
+ foreach (FieldInfo fi in fields)
+ {
+ object[] attrs = fi.GetCustomAttributes(typeof(XMLAttribute), false);
+ object val = fi.GetValue(null);
+ if (attrs.Length > 0)
+ {
+ string name = ((XMLAttribute)attrs[0]).Name;
+ map[name] = val;
+ }
+ if (dash)
+ map[fi.Name.Replace("_", "-")] = val;
+ else
+ map[fi.Name] = val;
+ }
+
+ lock (s_vals)
+ {
+ s_vals[t] = map;
+ return map;
+ }
}
private static Dictionary