new error tests
authorMarek Safar <marek.safar@gmail.com>
Fri, 8 Apr 2005 10:35:51 +0000 (10:35 -0000)
committerMarek Safar <marek.safar@gmail.com>
Fri, 8 Apr 2005 10:35:51 +0000 (10:35 -0000)
svn path=/trunk/mcs/; revision=42683

155 files changed:
ChangeLog
configure.in
mcs/build/ChangeLog
mcs/build/profiles/basic.make
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/LinkLabel.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs
mcs/class/Mono.Data.Tds/ChangeLog
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ITds.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs [new file with mode: 0644]
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs [new file with mode: 0644]
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.dll.sources
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslCipherSuite.cs
mcs/class/Mono.Security/Test/tools/postecho/ChangeLog
mcs/class/Mono.Security/Test/tools/postecho/Makefile
mcs/class/Mono.Security/Test/tools/postecho/README
mcs/class/Mono.Security/Test/tools/postecho/postmulti.cs [new file with mode: 0644]
mcs/class/Mono.Security/Test/tools/tlstest/ChangeLog
mcs/class/Mono.Security/Test/tools/tlstest/Makefile
mcs/class/Mono.Security/Test/tools/tlstest/tlsmulti.cs [new file with mode: 0644]
mcs/class/System.Configuration.Install/ChangeLog
mcs/class/System.Configuration.Install/Makefile
mcs/class/System.Configuration.Install/System.Configuration.Install/AssemblyInstaller.cs
mcs/class/System.Configuration.Install/System.Configuration.Install/ChangeLog
mcs/class/System.Configuration.Install/System.Configuration.Install/InstallContext.cs
mcs/class/System.Configuration.Install/System.Configuration.Install/Installer.cs
mcs/class/System.Configuration.Install/System.Configuration.Install/TransactedInstaller.cs
mcs/class/System.Data/ChangeLog
mcs/class/System.Data/Makefile
mcs/class/System.Data/System.Data.SqlClient/ChangeLog
mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs [new file with mode: 0644]
mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs
mcs/class/System.Data/System.Data.dll.sources
mcs/class/System.Data/System.Data/ChangeLog
mcs/class/System.Data/System.Data/DataRowCollection.cs
mcs/class/System.Data/TODO
mcs/class/System.DirectoryServices/Test/System.DirectoryServices/ChangeLog
mcs/class/System.DirectoryServices/Test/System.DirectoryServices/DirectoryServicesDirectoryEntryTest.cs
mcs/class/System.Web/ChangeLog
mcs/class/System.Web/System.Web.UI.WebControls/AutoGeneratedField.cs
mcs/class/System.Web/System.Web.UI.WebControls/BoundField.cs
mcs/class/System.Web/System.Web.UI.WebControls/ButtonField.cs
mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog
mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxField.cs
mcs/class/System.Web/System.Web.UI.WebControls/GridView.cs
mcs/class/System.Web/System.Web.UI.WebControls/ImageField.cs
mcs/class/System.Web/System.Web.UI.WebControls/MenuItem.cs
mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSource.cs
mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventArgs.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventHandler.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceView.cs
mcs/class/System.Web/System.Web.UI.WebControls/PagerSettings.cs
mcs/class/System.Web/System.Web.UI.WebControls/TemplateField.cs
mcs/class/System.Web/System.Web.UI.WebControls/TreeNode.cs
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/Page.cs
mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs
mcs/class/System.Web/System.Web.UI/TemplateControl.cs
mcs/class/System.Web/System.Web.dll.sources
mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
mcs/class/System.XML/Mono.Xml.Xsl/XslDecimalFormat.jvm.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.Serialization/ChangeLog
mcs/class/System.XML/System.Xml.Serialization/XmlSerializer.cs
mcs/class/System/System.Net.Sockets/ChangeLog
mcs/class/System/System.Net.Sockets/NetworkStream.cs
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/System.Net/ChangeLog
mcs/class/System/System.Net/ServicePoint.cs
mcs/class/System/System.Net/WebConnectionStream.cs
mcs/class/System/System.Net/WebHeaderCollection.cs
mcs/class/corlib/System.IO/ChangeLog
mcs/class/corlib/System.IO/FileStream.cs
mcs/class/corlib/System.IO/MonoIO.cs
mcs/class/corlib/System.Threading/ChangeLog
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System.Threading/ThreadPool.cs
mcs/class/corlib/Test/System.Reflection/AssemblyTest.cs
mcs/class/corlib/Test/System.Reflection/ChangeLog
mcs/class/corlib/Test/System.Reflection/FieldInfoTest.cs
mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs
mcs/errors/ChangeLog
mcs/errors/cs0422.cs [deleted file]
mcs/errors/cs0442.cs [new file with mode: 0644]
mcs/errors/cs0535-3.cs [new file with mode: 0644]
mcs/errors/cs0655-2.cs [new file with mode: 0644]
mcs/errors/cs0655.cs [new file with mode: 0644]
mcs/errors/cs1636.cs [new file with mode: 0644]
mcs/errors/cs1637.cs [new file with mode: 0644]
mcs/errors/cs1674.cs [new file with mode: 0644]
mcs/errors/gmcs-expect-no-error
mcs/errors/gmcs-expect-wrong-error
mcs/gmcs/AssemblyInfo.cs
mcs/gmcs/ChangeLog
mcs/gmcs/anonymous.cs
mcs/gmcs/attribute.cs
mcs/gmcs/class.cs
mcs/gmcs/const.cs
mcs/gmcs/convert.cs
mcs/gmcs/cs-parser.jay
mcs/gmcs/delegate.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/generic.cs
mcs/gmcs/location.cs
mcs/gmcs/namespace.cs
mcs/gmcs/pending.cs
mcs/gmcs/rootcontext.cs
mcs/gmcs/statement.cs
mcs/gmcs/support.cs
mcs/gmcs/typemanager.cs
mcs/mcs/ChangeLog
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/iterators.cs
mcs/mcs/pending.cs
mcs/mcs/statement.cs
mcs/mcs/typemanager.cs
mcs/tests/ChangeLog
mcs/tests/Makefile
mcs/tests/test-361-2.cs [new file with mode: 0644]
mcs/tests/test-361.cs [new file with mode: 0644]
mcs/tools/mkbundle/ChangeLog
mcs/tools/mkbundle/mkbundle.cs
mcs/tools/mono-service/ChangeLog
mcs/tools/mono-service/mono-service.cs
mono/io-layer/ChangeLog
mono/io-layer/io-private.h
mono/io-layer/io.c
mono/io-layer/sockets.c
mono/io-layer/sockets.h
mono/io-layer/threads.c
mono/io-layer/threads.h
mono/metadata/ChangeLog
mono/metadata/file-io.c
mono/metadata/file-io.h
mono/metadata/icall.c
mono/metadata/socket-io.c
mono/metadata/socket-io.h
mono/metadata/threadpool.c
mono/metadata/threadpool.h
support/ChangeLog
support/errno.c
support/fstab.c

index 617a6a2a833e1dc9c22c2c0260970435ea599c36..7a292c97b369ccdb3779a034257bb7c44b035961 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * configure.in: no more checks for aio_*.
+
 2005-04-05  Zoltan Varga  <vargaz@freemail.hu>
 
        * configure.in: Fix isinf detection on solaris.
index 804e8160f22ea257657e4d1d64713af712946d03..70e9e0f6f51b1fa99857c91078dfe5d27bf3e042 100644 (file)
@@ -1035,41 +1035,6 @@ if test x$platform_win32 = xno; then
                AC_MSG_RESULT(no)
        ]) 
 
-       dnl *********************
-       dnl *** Check for AIO ***
-       dnl *********************
-       AC_MSG_CHECKING([for SIGEV_THREAD definition])
-       dnl Some systems (FreeBSD at least) may have aio_read
-       dnl but don't support/define SIGEV_THREAD.
-       AC_TRY_COMPILE([
-       #include <sys/signal.h>
-       ],[
-       int x = SIGEV_THREAD;
-       ],[
-               ac_cv_c_sigev_thread=yes
-               AC_MSG_RESULT(yes)
-       ],[
-               AC_MSG_RESULT(no)
-       ])
-
-       if test "$ac_cv_c_sigev_thread" = "yes" ; then
-               AC_CHECK_HEADERS(aio.h sys/aio.h)
-               AC_CHECK_LIB(rt, aio_read, [ LIBS="$LIBS -lrt" ],)
-               SIGVAL_PTR="undefined"
-               if test "$ac_cv_header_aio_h" = "yes" -o "$ac_cv_header_sys_aio_h" = "yes" ; then
-                       AC_CHECK_MEMBER(union sigval.sigval_ptr,SIGVAL_PTR="sigval_ptr",, [
-                                       #include <sys/signal.h>
-                                       ])
-                       AC_CHECK_MEMBER(union sigval.sival_ptr,SIGVAL_PTR="sival_ptr",, [
-                                       #include <sys/signal.h>
-                                       ])
-                       if test "$SIGVAL_PTR" = "undefined" ; then
-                               AC_MSG_ERROR([Unable to detect field name in 'union sigval'])
-                       fi
-               fi
-               AC_DEFINE_UNQUOTED(SIGVAL_PTR,$SIGVAL_PTR,[Pointer field name in 'union sigval'])
-       fi
-
        dnl **********************************
        dnl *** Checks for MonoPosixHelper ***
        dnl **********************************
index b3c90303faf5927318ee5feba208526397d0c87a..01b70e0ebd65e1483f5c8dec9b300c4aac2d4567 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * profiles/basic.make (do-profile-check): Handle some possible
+       timestamp problems.  Hopefully fix #74280.
+
 2005-03-30  Zoltan Varga  <vargaz@freemail.hu>
 
        * rules.make (INSTALL_DATA): Pass -c to install.
index d850774733c61e2a9d79ede8e770ae767047f826..0305764307482fd310810297baaf9429a804dbd3 100644 (file)
@@ -33,9 +33,13 @@ do-profile-check:
            echo "*** The compiler '$(EXTERNAL_MCS)' doesn't appear to be usable." 1>&2 ; \
            if test -f $(topdir)/class/lib/monolite/mcs.exe; then \
                echo "*** Falling back to using pre-compiled binaries.  Be warned, this may not work." 1>&2 ; \
+               ( cd $(topdir)/jay && $(MAKE) ); \
+               ( cd $(topdir)/mcs && $(MAKE) PROFILE=basic cs-parser.cs ); \
                ( cd $(topdir)/class/lib/monolite/ && cp *.exe *.dll ../basic ); \
-               ( cd $(topdir)/jay && $(MAKE) ); ( cd $(topdir)/mcs && $(MAKE) PROFILE=basic cs-parser.cs ); \
-               touch $(topdir)/class/lib/basic/*; \
+               case `ls -1t $(topdir)/class/lib/basic/mcs.exe $(topdir)/mcs/cs-parser.cs | sed 1q` in \
+               $(topdir)/class/lib/basic/mcs.exe) : ;; \
+               *) sleep 5; cp $(topdir)/class/lib/monolite/mcs.exe $(topdir)/class/lib/basic ;; \
+               esac; \
            else \
                 echo "*** You need a C# compiler installed to build MCS. (make sure mcs works from the command line)" 1>&2 ; \
                 echo "*** Read INSTALL.txt for information on how to bootstrap a Mono installation." 1>&2 ; \
index 17d067985ee239f7a3cb64e8cea84442fc20de9c..fff5715ac274bcf85b25d615eb5c2951dbbbc23b 100644 (file)
@@ -1,3 +1,9 @@
+2005-04-07  Jordi Mas i Hernandez <jordi@ximian.com>\r
+\r
+       * LinkLabel.cs: move drawing code into the theme\r
+       * ThemeWin32Classic.cs: drawing code and painting background bugfix\r
+       * Theme.cs: define DrawLinkLabel method                                                                         \r
+\r
 2005-04-05  Jackson Harper  <jackson@ximian.com>
 
        * BindingContext.cs: Use weak references so these bad actors don't
index 167a1c7bbec07a183ce3fa4330f0e0de921f87ab..c44eb5f0b42433b72735e3f493ce31fab9fed39a 100644 (file)
@@ -70,11 +70,11 @@ namespace System.Windows.Forms
                private LinkArea link_area;
                private LinkBehavior link_behavior;
                private LinkCollection link_collection;
-               private bool link_visited;
-               private Font link_font;
+               private bool link_visited;              
                private bool link_click;
-               private Piece[] pieces;
-               private int num_pieces;
+               internal Piece[] pieces;
+               internal int num_pieces;\r
+               internal Font link_font;
                private Cursor override_cursor;
                private DialogResult dialog_result;
 
@@ -497,7 +497,7 @@ namespace System.Windows.Forms
                        }
                }
 
-               private Color GetLinkColor (Piece piece, int i)
+               internal Color GetLinkColor (Piece piece, int i)
                {
                        Color color;
 
@@ -519,31 +519,7 @@ namespace System.Windows.Forms
 
                internal new void Draw ()
                {
-                       Color color;
-
-                       //dc.FillRectangle (label_br_back_color, area);
-                       ThemeEngine.Current.CPDrawBorderStyle (DeviceContext, ClientRectangle, BorderStyle);
-
-                       if (Links.Count == 1 && Links[0].Start == 0 &&  Links[0].Length == -1) {
-
-                               color = GetLinkColor (pieces[0], 0);
-                               DeviceContext.DrawString (Text, Font, ThemeEngine.Current.ResPool.GetSolidBrush (color),
-                                       ClientRectangle, string_format);
-                               return;
-                       }
-
-                       for (int i = 0; i < num_pieces; i++)    {
-
-                               color = GetLinkColor (pieces[i], i);
-
-                               if (pieces[i].link == null)
-                                       DeviceContext.DrawString (pieces[i].text, Font, ThemeEngine.Current.ResPool.GetSolidBrush (Color.Black),
-                                               pieces[i].rect.X, pieces[i].rect.Y, string_format);
-                               else
-                                       DeviceContext.DrawString (pieces[i].text, link_font, ThemeEngine.Current.ResPool.GetSolidBrush (color),
-                                               pieces[i].rect.X, pieces[i].rect.Y, string_format);
-                       }
-
+                       ThemeEngine.Current.DrawLinkLabel (DeviceContext, ClientRectangle, this);\r
                        DrawImage (DeviceContext, Image, ClientRectangle, image_align);
                }
 
index 8e3b6699ecc11c49fc4e96c1f53b389c48068e77..2fc3913954dfedc0dcc9c899cacecdf25d06ba99 100644 (file)
@@ -457,6 +457,7 @@ namespace System.Windows.Forms
                #endregion      // Label
 
                #region LinkLabel
+               public abstract void DrawLinkLabel (Graphics dc, Rectangle clip_rectangle, LinkLabel label);
                #endregion      // LinkLabel
                
                #region ListBox
index 79f93a258e378eff0e605a51a4c1aadbbb046815..7e4f9a5a330f3416b71ff6f4e9e3b27fb71c9da0 100644 (file)
@@ -977,7 +977,7 @@ namespace System.Windows.Forms
                {               
                        dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);
                        
-                       CPDrawBorderStyle (dc, clip_rectangle, label.BorderStyle);              
+                       CPDrawBorderStyle (dc, label.ClientRectangle, label.BorderStyle);               
 
                        if (label.Enabled) {
                                dc.DrawString (label.Text, label.Font, ResPool.GetSolidBrush (label.ForeColor), clip_rectangle, label.string_format);
@@ -992,8 +992,38 @@ namespace System.Windows.Forms
                                return new Size (100, 23);
                        }
                }
-               #endregion      // Label
-               
+               #endregion      // Label\r
+\r
+               #region LinkLabel\r
+               public  override void DrawLinkLabel (Graphics dc, Rectangle clip_rectangle, LinkLabel label)\r
+               {\r
+                       Color color;\r
+\r
+                       dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);\r
+                       CPDrawBorderStyle (dc, label.ClientRectangle, label.BorderStyle);\r
+\r
+                       if (label.Links.Count == 1 && label.Links[0].Start == 0 && label.Links[0].Length == -1) {\r
+\r
+                               color = label.GetLinkColor (label.pieces[0], 0);\r
+                               dc.DrawString (label.Text, label.Font, ResPool.GetSolidBrush (color),\r
+                                       label.ClientRectangle, label.string_format);\r
+                               return;\r
+                       }\r
+\r
+                       for (int i = 0; i < label.num_pieces; i++) {\r
+\r
+                               color = label.GetLinkColor (label.pieces[i], i);\r
+\r
+                               if (label.pieces[i].link == null)\r
+                                       dc.DrawString (label.pieces[i].text, label.Font, ResPool.GetSolidBrush (Color.Black),\r
+                                               label.pieces[i].rect.X, label.pieces[i].rect.Y, label.string_format);\r
+                               else\r
+                                       dc.DrawString (label.pieces[i].text, label.link_font, ResPool.GetSolidBrush (color),\r
+                                               label.pieces[i].rect.X, label.pieces[i].rect.Y, label.string_format);\r
+                       }                       \r
+\r
+               }\r
+               #endregion      // LinkLabel\r
                #region ListBox
                
                // Drawing              
index 1702059689455b387e90da7b195704e2695226b3..9a6bc26756e94c6596f9e26d803e180359c93c1c 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-07  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * Mono.Data.Tds.dll.sources: In Mono.Data.Tds.Protocol
+       Added TdsAsyncResult.cs & TdsAsyncState.cs.
+
 2004-08-14 Geoff Norton <gnorton@customerdna.com>
 
         * Mono.Data.Tds.Protocol/TdsComm.cs: 
index 244e5ccbd2798e783cefdf2cb19d2b4365c106f5..a2a385bce09e4c8ab8592cfe8b66152d563b2503 100644 (file)
@@ -1,3 +1,25 @@
+2005-04-07  Sureshkumar T  <tsureshkumar@novell.com>
+           Ankit Jain     <radical@corewars.org>
+
+       * TdsComm.cs: GetPhysicalPacket is devided further into seperate
+       methods GetPhysicalPacketHeader and
+       GetPhysicalPacketData. Implemented asynchronous ReadPacket method.
+
+       * ITds.cs: Added additional methods for asynchronous operations.
+
+       * Tds.cs: Implemented base methods for asynchronous
+       operations. Version specific derivatives should override for
+       specific operations.
+
+       * Tds70.cs: For stored procedure, "exec" is prefixed by
+       default. Implemented asynchronous method for asynchronous command
+       execution.
+
+       * TdsAsyncState.cs: Added. Internal asynchronous state object.
+
+       * TdsAsyncResult.cs: Added. Internal asynchronous result
+       implementation.
+
 2005-04-04  Sureshkumar T  <tsureshkumar@novell.com>
 
        * Tds50.cs: Pass parameters to the server. cut & paste from
index 5e6afaab557c32619763ef0b4acdd6dbe976e67e..885ed5ac6489781cb11fd3b60563de8065baa827 100644 (file)
@@ -104,5 +104,34 @@ namespace Mono.Data.Tds.Protocol {
                event TdsInternalInfoMessageEventHandler TdsInfoMessage;
 
                #endregion // Events
+
+#if NET_2_0
+                #region Asynchronous Methods
+                IAsyncResult BeginExecuteNonQuery (string sql,
+                                                   TdsMetaParameterCollection parameters,
+                                                   AsyncCallback callback,
+                                                   object state);
+                void EndExecuteNonQuery (IAsyncResult ar);
+                IAsyncResult BeginExecuteQuery (string sql,
+                                                   TdsMetaParameterCollection parameters,
+                                                   AsyncCallback callback,
+                                                   object state);
+                void EndExecuteQuery (IAsyncResult ar);
+
+                IAsyncResult BeginExecuteProcedure (string prolog,
+                                                                    string epilog,
+                                                                    string cmdText,
+                                                                    bool IsNonQuery,
+                                                                    TdsMetaParameterCollection parameters,
+                                                                    AsyncCallback callback,
+                                                                    object state);
+                void EndExecuteProcedure (IAsyncResult ar);
+
+                void WaitFor (IAsyncResult ar);
+                void CheckAndThrowException (IAsyncResult ar);
+
+                #endregion //Asynchronous Methods
+#endif // NET_2_0
+
        }
 }
index ecc03232f52fe01003a0a56585d890a3a7135617..63905c42b92d8905a556321dddccee3f7b6e4e74 100644 (file)
@@ -1327,5 +1327,118 @@ namespace Mono.Data.Tds.Protocol {
                }
 
                #endregion // Private Methods
+
+#if NET_2_0
+                #region asynchronous methods
+                protected IAsyncResult BeginExecuteQueryInternal (string sql, bool wantResults, 
+                                                          AsyncCallback callback, object state)
+                {
+                        moreResults = true;
+                       doneProc = false;
+                       messages.Clear ();
+                       outputParameters.Clear ();
+
+                        TdsAsyncResult ar = new TdsAsyncResult (callback, state);
+                        ar.TdsAsyncState.WantResults = wantResults;
+
+                       Comm.StartPacket (TdsPacketType.Query);
+                       Comm.Append (sql);
+                       Comm.SendPacket ();
+
+                        Comm.BeginReadPacket (new AsyncCallback(OnBeginExecuteQueryCallback), 
+                                                                    ar);
+                        return ar;
+                }
+                
+                protected void EndExecuteQueryInternal (IAsyncResult ar)
+                {
+                        if (!ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                        TdsAsyncResult result = (TdsAsyncResult) ar;
+                        if (result.IsCompletedWithException)
+                                throw result.Exception;
+                }
+
+                protected void OnBeginExecuteQueryCallback (IAsyncResult ar)
+                {
+                        TdsAsyncResult result = (TdsAsyncResult) ar.AsyncState;
+                        TdsAsyncState tdsState = (TdsAsyncState) result.TdsAsyncState;
+
+                        try {
+                                Comm.EndReadPacket (ar);
+                                if (!tdsState.WantResults)
+                                        SkipToEnd ();
+                        } catch (Exception e) {
+                                result.MarkComplete (e);
+                                return;
+                        }
+                        result.MarkComplete ();
+                }
+                
+
+                public virtual IAsyncResult BeginExecuteNonQuery (string sql,
+                                                                  TdsMetaParameterCollection parameters,
+                                                                  AsyncCallback callback,
+                                                                  object state)
+                {
+                        // abstract, kept to be backward compatiable.
+                        throw new NotImplementedException ("should not be called!");
+                }
+                
+                public virtual void EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be called!");
+                }
+                
+                public virtual IAsyncResult BeginExecuteQuery (string sql,
+                                                                  TdsMetaParameterCollection parameters,
+                                                                  AsyncCallback callback,
+                                                                  object state)
+                {
+                        // abstract, kept to be backward compatiable.
+                        throw new NotImplementedException ("should not be called!");
+                }
+                
+                public virtual void EndExecuteQuery (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be called!");
+                }
+
+                public virtual IAsyncResult BeginExecuteProcedure (string prolog,
+                                                                    string epilog,
+                                                                    string cmdText,
+                                                                    bool IsNonQuery,
+                                                                    TdsMetaParameterCollection parameters,
+                                                                    AsyncCallback callback,
+                                                                    object state)
+                {
+                        throw new NotImplementedException ("should not be called!");
+                }
+                
+                public virtual void EndExecuteProcedure (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be called!");
+                }
+                
+                public void WaitFor (IAsyncResult ar)
+                {
+                        if (! ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                }
+
+                public void CheckAndThrowException (IAsyncResult ar)
+                {
+                        TdsAsyncResult result = (TdsAsyncResult) ar;
+                        if (result.IsCompleted && result.IsCompletedWithException)
+                                throw result.Exception;
+                }
+
+                #endregion // asynchronous methods
+#endif // NET_2_0
+
+
        }
 }
index f7ba915f90b2726d137376d7754db6ab41ad18a4..d18169b4a92ea5c6f6ed31433a763f50445ac355 100644 (file)
@@ -144,10 +144,10 @@ namespace Mono.Data.Tds.Protocol {
                                        }
                                }
                        }
-                       if (count > 0 || exec.Length > 0)
-                               exec = "exec " + exec;
-
-                       return String.Format ("{0}{1}{2}{3} {4}\n{5}", declare.ToString (), set.ToString (), exec, procedure, BuildParameters (), select.ToString ());  
+                        exec = "exec " + exec;
+                        
+                        string sql = String.Format ("{0}{1}{2}{3} {4}\n{5}", declare.ToString (), set.ToString (), exec, procedure, BuildParameters (), select.ToString ());
+                       return sql;
                }
 
                public override bool Connect (TdsConnectionParameters connectionParameters)
@@ -560,5 +560,75 @@ namespace Mono.Data.Tds.Protocol {
                }
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Asynchronous Methods
+                public override IAsyncResult BeginExecuteNonQuery (string cmdText,
+                                                          TdsMetaParameterCollection parameters,
+                                                          AsyncCallback callback,
+                                                          object state)
+                {
+                        Parameters = parameters;
+                        string sql = cmdText;
+                       if (Parameters != null && Parameters.Count > 0)
+                               sql = BuildExec (cmdText);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, false, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+                public override IAsyncResult BeginExecuteQuery (string cmdText,
+                                                                TdsMetaParameterCollection parameters,
+                                                                AsyncCallback callback,
+                                                                object state)
+                {
+                        Parameters = parameters;
+                        string sql = cmdText;
+                       if (Parameters != null && Parameters.Count > 0)
+                               sql = BuildExec (cmdText);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, true, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteQuery (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+
+                public override IAsyncResult BeginExecuteProcedure (string prolog,
+                                                                    string epilog,
+                                                                    string cmdText,
+                                                                    bool IsNonQuery,
+                                                                    TdsMetaParameterCollection parameters,
+                                                                    AsyncCallback callback,
+                                                                    object state)
+                {
+
+                        
+                        Parameters = parameters;
+                       string pcall = BuildProcedureCall (cmdText);
+                        string sql = String.Format ("{0};{1};{2};", prolog, pcall, epilog);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, !IsNonQuery, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteProcedure (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+
+
+                #endregion // Asynchronous Methods
+#endif // NET_2_0
+
        }
 }
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs
new file mode 100644 (file)
index 0000000..8e6041f
--- /dev/null
@@ -0,0 +1,128 @@
+//
+// Mono.Data.Tds.Protocol.TdsAsyncResult.cs
+//
+// Author:
+//   T Sureshkumar <tsureshkumar@novell.com>
+//   Ankit Jain <radical@corewars.org>
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#if NET_2_0
+using System;
+using System.Threading;
+
+namespace Mono.Data.Tds.Protocol
+{
+        internal class TdsAsyncResult : IAsyncResult
+        {
+                private TdsAsyncState _tdsState;
+                private WaitHandle _waitHandle;
+                private bool _completed = false;
+                private bool _completedSyncly = false;
+                private AsyncCallback _userCallback;
+                private object _retValue;
+                private Exception _exception = null;
+
+                public TdsAsyncResult (AsyncCallback userCallback, TdsAsyncState tdsState)
+                {
+                        _tdsState = tdsState;
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+
+                public TdsAsyncResult (AsyncCallback userCallback, object state)
+                {
+                        _tdsState = new TdsAsyncState (state);
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+                
+
+                public object AsyncState 
+                {
+                        get {   return _tdsState.UserState; }
+                }
+
+                internal TdsAsyncState TdsAsyncState
+                {
+                        get {   return _tdsState; }
+                }
+
+                public WaitHandle AsyncWaitHandle 
+                {
+                        get { return _waitHandle; }
+
+                }
+
+                public bool IsCompleted 
+                {
+                        get {   return _completed; }
+                }
+
+                public bool IsCompletedWithException
+                {
+                        get {   return _exception != null; }
+                }
+
+                public Exception Exception
+                {
+                        get {   return _exception; }
+                }
+
+                public bool CompletedSynchronously 
+                {
+                        get {   return _completedSyncly; }
+                }
+
+                internal object ReturnValue
+                {
+                        get {   return _retValue; }
+                        set {   _retValue = value; }
+                }
+
+                internal void MarkComplete () 
+                {
+                        _completed = true;
+                        _exception = null;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+
+                internal void MarkComplete (Exception e) 
+                {
+                        _completed = true;
+                        _exception = e;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+        }
+}
+
+#endif // NET_2_0
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs
new file mode 100644 (file)
index 0000000..db7b00d
--- /dev/null
@@ -0,0 +1,63 @@
+//
+// Mono.Data.Tds.Protocol.TdsAsyncState.cs
+//
+// Author:
+//   T Sureshkumar <tsureshkumar@novell.com>
+//   Ankit Jain <radical@corewars.org>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Net.Sockets;
+
+
+namespace Mono.Data.Tds.Protocol {
+        internal class TdsAsyncState
+        {
+                object  _userState;
+                bool    _wantResults = false;
+
+                public TdsAsyncState (object userState)
+                {
+                        _userState = userState;
+                }
+
+                public object UserState
+                {
+                        get {return _userState;}
+                        set {_userState = value;}
+                }
+
+                public bool WantResults
+                {
+                        get {return _wantResults;}
+                        set {_wantResults = value;}
+                }
+
+        }
+}
+#endif // NET_2_0
index dd15580154101d9186cf3d23e24b821c474c6ff7..c342b9284b41443bf943c1a662bf8cffe9536604 100644 (file)
@@ -385,8 +385,14 @@ namespace Mono.Data.Tds.Protocol {
 
                private void GetPhysicalPacket ()
                {
-                       int nread = 0;
+                        int dataLength = GetPhysicalPacketHeader ();
+                        GetPhysicalPacketData (dataLength);
+               }
 
+                private int GetPhysicalPacketHeader ()
+                {
+                        int nread = 0;
+                                                
                        // read the header
                        while (nread < 8)
                                nread += stream.Read (tmpBuf, nread, 8 - nread);
@@ -406,19 +412,26 @@ namespace Mono.Data.Tds.Protocol {
                        if (len < 0) {
                                throw new Exception (String.Format ("Confused by a length of {0}", len));
                        }
+                        
+                        return len;
 
-                       // now get the data
-                       nread = 0;
-                       while (nread < len) {
-                               nread += stream.Read (inBuffer, nread, len - nread);
+                }
+                
+                private void GetPhysicalPacketData (int length)
+                {
+                        // now get the data
+                       int nread = 0;
+                       while (nread < length) {
+                               nread += stream.Read (inBuffer, nread, length - nread);
                        }
 
                        packetsReceived++;
 
                        // adjust the bookkeeping info about the incoming buffer
-                       inBufferLength = len;
+                       inBufferLength = length;
                        inBufferIndex = 0;
-               }
+                }
+                
 
                private static int Ntohs (byte[] buf, int offset)
                {
@@ -519,6 +532,59 @@ namespace Mono.Data.Tds.Protocol {
                }
 
                #endregion // Methods
+#if NET_2_0
+                #region Async Methods
+
+                public IAsyncResult BeginReadPacket (AsyncCallback callback, object stateObject)
+               {
+                        TdsAsyncResult ar = new TdsAsyncResult (callback, stateObject);
+
+                        stream.BeginRead (tmpBuf, 0, 8, new AsyncCallback(OnReadPacketCallback), ar);
+                        return ar;
+               }
+                
+                /// <returns>Packet size in bytes</returns>
+                public int EndReadPacket (IAsyncResult ar)
+                {
+                        if (!ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                        return (int) ((TdsAsyncResult) ar).ReturnValue;
+                }
+                
+
+                public void OnReadPacketCallback (IAsyncResult socketAsyncResult)
+                {
+                        TdsAsyncResult ar = (TdsAsyncResult) socketAsyncResult.AsyncState;
+                        int nread = stream.EndRead (socketAsyncResult);
+                        
+                        while (nread < 8)
+                                nread += stream.Read (tmpBuf, nread, 8 - nread);
+
+                       TdsPacketType packetType = (TdsPacketType) tmpBuf[0];
+                       if (packetType != TdsPacketType.Logon && packetType != TdsPacketType.Query && packetType != TdsPacketType.Reply) 
+                       {
+                               throw new Exception (String.Format ("Unknown packet type {0}", tmpBuf[0]));
+                       }
+
+                       // figure out how many bytes are remaining in this packet.
+                       int len = Ntohs (tmpBuf, 2) - 8;
+
+                       if (len >= inBuffer.Length) 
+                               inBuffer = new byte[len];
+
+                       if (len < 0) {
+                               throw new Exception (String.Format ("Confused by a length of {0}", len));
+                       }
+
+                        GetPhysicalPacketData (len);
+                        int value = len + 8;
+                        ar.ReturnValue = ((object)value); // packet size
+                        ar.MarkComplete ();
+                }
+                
+                #endregion // Async Methods
+#endif // NET_2_0
+
        }
 
 }
index fa498da3268b39eca24497377e96c5923845def7..c286e68bccbf388480943f8538ead12523b9cefb 100644 (file)
@@ -31,3 +31,5 @@ Mono.Data.Tds.Protocol/TdsPacketType.cs
 Mono.Data.Tds.Protocol/TdsTimeoutException.cs
 Mono.Data.Tds.Protocol/TdsVersion.cs
 Mono.Data.Tds.Protocol/TODOAttribute.cs
+Mono.Data.Tds.Protocol/TdsAsyncState.cs
+Mono.Data.Tds.Protocol/TdsAsyncResult.cs
index 6add357f8ff4324ef70e4367168cb0fb1a3134e7..52202ba442fed19376271a7ec502c1b564d4b2ac 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-07  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * SslCipherSuite.cs: Fix calculation (sequence number) for the server
+       side stream. Patch by Brian Ritchie.
+
 2005-02-04  Sebastien Pouliot  <sebastien@ximian.com>
 
        * Reverting last changes in SslClientStream and RecordProtocol. This
index e472e501e579a25652489a387857544b90943f55..5819a2838a5dad0c1468adb65bed9a6b503b9f75 100644 (file)
@@ -118,11 +118,11 @@ namespace Mono.Security.Protocol.Tls
                        block.Write(this.pad1);
                        if (this.Context is ClientContext)
                        {
-                               block.Write(this.Context.ReadSequenceNumber);
+                               block.Write(this.Context.WriteSequenceNumber);
                        }
                        else
                        {
-                               block.Write(this.Context.WriteSequenceNumber);
+                               block.Write(this.Context.ReadSequenceNumber);
                        }
                        block.Write((byte)contentType);
                        block.Write((short)fragment.Length);
@@ -298,4 +298,4 @@ namespace Mono.Security.Protocol.Tls
 
                #endregion
        }
-}
\ No newline at end of file
+}
index 505f17f1ce5d1fe096696d85e67d25cf0e7202bd..0cfe661128b7172135ed50dfca8cf80d8c9daab9 100644 (file)
@@ -1,3 +1,9 @@
+2005-04-07  Sebastien Pouliot  <sebastien@ximian.com> 
+
+       * postmulti.cs: New. Async POST tests using HttpWebRequest.
+       * Makefile: Build postmulti tool.
+       * README: updated instructions with the new postmulti tool.
+
 2005-04-06  Sebastien Pouliot  <sebastien@ximian.com> 
  
        * postecho.cs: Added an ICertificatePolicy to ease testing with 
index 386f60257eeaeb5756366f2b67c698d57eac62ed..45465134935156dff42eb326e3a98db3782fe669 100644 (file)
@@ -15,13 +15,16 @@ run-test-local:
 clean-local:
        rm -f *.exe *.mdb *.pdb
 
-sources = postecho.cs
+sources = postecho.cs postmulti.cs
 
 DISTFILES = $(sources)
 
 dist-local: dist-default
 
-all: postecho.exe
+all: postecho.exe postmulti.exe
 
-postecho.exe: $(sources)
-       $(CSCOMPILE) /target:exe /out:$@ $(sources)
+postecho.exe: postecho.cs
+       $(CSCOMPILE) /target:exe /out:$@ $^
+
+postmulti.exe: postmulti.cs
+       $(CSCOMPILE) /target:exe /out:$@ $^
index e88cc25321c1659f72cda9f4599cd92d1a60decf..3f926b4a447a16b03ed986df6da5b1a412b1872e 100644 (file)
@@ -8,6 +8,21 @@ This is almost identical when executed on Mono but very different (execution
 wise not result wise) if you test with the MS runtime.
 
 
+POSTMULTI
+
+To run the postmulti tool your web server(s) must have a script present to 
+return the TEST variable value to the tool.
+
+The tool use async HttpWebRequest|Response to send and receive a fixed (in
+source code, default is 1 megabytes) length buffer from all URLs specified 
+on the command line. 
+
+The WaitHandle class has a limit of 64 handles. Supplying more than 64 URLs
+on the command-line will result in a NotSupportedException exception.
+
+
+NOTES
+
 Available server-side scripts
 
 1.     sendback.asp
diff --git a/mcs/class/Mono.Security/Test/tools/postecho/postmulti.cs b/mcs/class/Mono.Security/Test/tools/postecho/postmulti.cs
new file mode 100644 (file)
index 0000000..1193fcf
--- /dev/null
@@ -0,0 +1,135 @@
+//
+// postmulti.cs: Multi-sessions TLS/SSL Test Program
+//     based on tlstest.cs, tlsmulti.cs and postecho.cs
+//
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
+//
+// Copyright (C) 2004-2005 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+
+using Mono.Security.Protocol.Tls;
+
+public class State {
+
+       static ArrayList handleList = new ArrayList ();
+
+       private int id;
+       private HttpWebRequest request;
+       private ManualResetEvent handle;
+
+       public State (int id, HttpWebRequest req)
+       {
+               this.id = id;
+               request = req;
+               handle = new ManualResetEvent (false);
+               handleList.Add (handle);
+       }
+
+       public int Id {
+               get { return id; }
+       }
+
+       public HttpWebRequest Request {
+               get { return request; }
+       }
+
+       public void Complete ()
+       {
+               handle.Set ();
+       }
+
+       static public void WaitAll ()
+       {
+               if (handleList.Count > 0) {
+                       WaitHandle[] handles = (WaitHandle[]) handleList.ToArray (typeof (WaitHandle));
+                       WaitHandle.WaitAll (handles);
+                       handleList.Clear ();
+               }
+       }
+}
+
+public class MultiTest {
+
+       public const int buffersize = 1024 * 1024;
+
+       static byte[] data = new byte [buffersize];\r
+
+       public static void Main (string[] args) 
+       {
+               ServicePointManager.CertificatePolicy = new TestCertificatePolicy ();
+
+               string postdata = "TEST=";
+               byte[] bytes = Encoding.Default.GetBytes (postdata);
+
+               // prepare test buffer
+               for (int i = 0; i < buffersize; i++)\r
+                       data[i] = 65;
+
+               int id = 1;
+               foreach (string url in args) {
+                       Console.WriteLine ("POST #{0} at {1}", id, url);
+                       HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
+                       req.Method = "POST";
+                       req.ContentType = "application/x-www-form-urlencoded";
+                       req.ContentLength = 5 + data.Length;
+
+                       Stream output = req.GetRequestStream ();
+                       output.Write (bytes, 0, bytes.Length);\r
+                       output.Write (data, 0, data.Length);
+                       output.Close ();
+
+                       State s = new State (id++, req);
+                       req.BeginGetResponse (new AsyncCallback (ResponseCallback), s);
+               }
+
+               State.WaitAll ();
+       }
+
+       private static void ResponseCallback (IAsyncResult result)
+       {
+               State state = ((State) result.AsyncState);
+               HttpWebResponse response = (HttpWebResponse) state.Request.EndGetResponse (result);
+
+               Stream stream = response.GetResponseStream ();
+               StreamReader sr = new StreamReader (stream, Encoding.UTF8);
+               string received = sr.ReadToEnd ();
+
+               if (data.Length != received.Length) {\r
+                       Console.WriteLine ("ECHO #{0} - Invalid length {1}. Expected {2}", state.Id, received.Length, data.Length);\r
+               } else {
+                       bool ok = true;\r
+                       for (int i = 0; i < received.Length; i++) {\r
+                               if (received[i] != 'A') {
+                                       ok = false;\r
+                                       Console.WriteLine ("ECHO #{0} - Error at position #{1} - received '{2}'", state.Id, i, received[i]);\r
+                                       break;\r
+                               }
+                       }
+                       if (ok)\r
+                               Console.WriteLine ("ECHO #{0} - Result OK (length: {1})", state.Id, received.Length);\r
+               }\r
+
+               state.Complete ();
+       }
+
+       public class TestCertificatePolicy : ICertificatePolicy {
+
+               public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
+               {
+                       // whatever the reason we do not stop the SSL connection
+                       return true;
+               }
+       }
+}
index 4287be1d0b4cb6a2663a4bed9f194418b4885cc1..00eb8bac9176823ed586f14bd5bf5366c07c1d23 100755 (executable)
@@ -1,3 +1,8 @@
+2005-04-07  Sebastien Pouliot  <sebastien@ximian.com> 
+
+       * tlsmulti.cs: New. Async GET tests using HttpWebRequest.
+       * Makefile: Build tlsmulti tool.
+
 2004-02-25  Sebastien Pouliot  <sebastien@ximian.com>
 
        * tlstest.cs: Updated to support Basic and Digest authentication. Also
index 323b6ee723962c3589ce0c1681a271cc997b9d0e..be0f47eb43a6a53b78e0ba1c158c0eb0d6a60f32 100755 (executable)
@@ -15,13 +15,16 @@ run-test-local:
 clean-local:
        rm -f *.exe *.pdb
 
-sources = tlstest.cs
+sources = tlstest.cs tlsmulti.cs
 
 DISTFILES = $(sources)
 
 dist-local: dist-default
 
-all: tlstest.exe
+all: tlstest.exe tlsmulti.exe
 
-tlstest.exe: $(sources)
-       $(CSCOMPILE) /target:exe /out:$@ $(sources)
+tlstest.exe: tlstest.cs
+       $(CSCOMPILE) /target:exe /out:$@ $^
+
+tlsmulti.exe: tlsmulti.cs
+       $(CSCOMPILE) /target:exe /out:$@ $^
diff --git a/mcs/class/Mono.Security/Test/tools/tlstest/tlsmulti.cs b/mcs/class/Mono.Security/Test/tools/tlstest/tlsmulti.cs
new file mode 100644 (file)
index 0000000..b0917e1
--- /dev/null
@@ -0,0 +1,106 @@
+//
+// tlsmulti.cs: Multi-sessions TLS/SSL Test Program
+//     based on tlstest.cs
+//
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
+//
+// Copyright (C) 2004-2005 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+
+using Mono.Security.Protocol.Tls;
+
+public class State {
+
+       static ArrayList handleList = new ArrayList ();
+
+       private int id;
+       private HttpWebRequest request;
+       private ManualResetEvent handle;
+
+       public State (int id, HttpWebRequest req)
+       {
+               this.id = id;
+               request = req;
+               handle = new ManualResetEvent (false);
+               handleList.Add (handle);
+       }
+
+       public int Id {
+               get { return id; }
+       }
+
+       public HttpWebRequest Request {
+               get { return request; }
+       }
+
+       public void Complete ()
+       {
+               handle.Set ();
+       }
+
+       static public void WaitAll ()
+       {
+               if (handleList.Count > 0) {
+                       WaitHandle[] handles = (WaitHandle[]) handleList.ToArray (typeof (WaitHandle));
+                       WaitHandle.WaitAll (handles);
+                       handleList.Clear ();
+               }
+       }
+}
+
+public class MultiTest {
+
+       public static void Main (string[] args) 
+       {
+               if (args.Length > 64) {
+                       Console.WriteLine ("WaitHandle has a limit of 64 handles so you cannot process {0} URLs.", args.Length);
+                       return;
+               }
+
+               ServicePointManager.CertificatePolicy = new TestCertificatePolicy ();
+
+               int id = 1;
+               foreach (string url in args) {
+                       Console.WriteLine ("GET #{0} at {1}", id, url);
+                       HttpWebRequest wreq = (HttpWebRequest) WebRequest.Create (url);
+                       State s = new State (id++, wreq);
+                       wreq.BeginGetResponse (new AsyncCallback (ResponseCallback), s);
+               }
+
+               State.WaitAll ();
+       }
+
+       private static void ResponseCallback (IAsyncResult result)
+       {
+               State state = ((State) result.AsyncState);
+               HttpWebResponse response = (HttpWebResponse) state.Request.EndGetResponse (result);
+
+               Stream stream = response.GetResponseStream ();
+               StreamReader sr = new StreamReader (stream, Encoding.UTF8);
+               sr.ReadToEnd ();
+
+               Console.WriteLine ("END #{0}", state.Id);\r
+               state.Complete ();
+       }
+
+       public class TestCertificatePolicy : ICertificatePolicy {
+
+               public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
+               {
+                       // whatever the reason we do not stop the SSL connection
+                       return true;
+               }
+       }
+}
index 4b738c4b94144cf6dd8bd842c27217192a12e060..2e77a14e551b5863e3e7d09739b17f024e56f92a 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (EXTRA_DISTFILES): Add support file
+       Test/.../InstallerAssembly.cs.
+
 2005-03-24  Muthu Kannan  <t.manki@gmail.com>
 
        * Makefile (test-local): Create InstallerAssembly.dll for unit
index a8600155cef5fbbfcecb3a652f7fff252b8cb82d..ae87300e0e6c5558e253dab5e30ec09a90ceb3dd 100644 (file)
@@ -6,7 +6,7 @@ LIBRARY = System.Configuration.Install.dll
 LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:System.Xml.dll /r:System.Runtime.Serialization.Formatters.Soap.dll
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
-EXTRA_DISTFILES = Test/ChangeLog
+EXTRA_DISTFILES = Test/ChangeLog Test/System.Configuration.Install/InstallerAssembly.cs
 
 include ../../build/library.make
 
index f764309e60d188f96f22a62d2ad94afae5b53586..9d3ac73f8fdb515904df1342b8af9c086cffde4c 100644 (file)
@@ -125,7 +125,7 @@ public class AssemblyInstaller : Installer {
                        if (value)
                                Context = new InstallContext (Path + ".InstallLog", null);
                        else
-                               Context = new InstallContext (null, CommandLine);
+                               Context = new InstallContext (Path + ".InstallLog", CommandLine);
                        useNewContext = value;
                }
        }
@@ -149,6 +149,7 @@ public class AssemblyInstaller : Installer {
 
                foreach (Type t in getInstallersFromAssembly (Assembly)) {
                        Installer i = (Installer) Activator.CreateInstance (t);
+                       i.Context = this.Context;
                        Installers.Add (i);
                }
        }
@@ -172,17 +173,32 @@ public class AssemblyInstaller : Installer {
                return ret;
        }
 
+       private bool isInstallable ()
+       {
+               try {
+                       CheckIfInstallable (Path);
+               } catch (Exception e) {
+                       Context.LogMessage ("Assembly " + Path + " does not have any public installers in it.");
+                       return false;
+               }
+               return true;
+       }
+
        public override void Install (IDictionary state)
        {
                // Make sure that the assembly is installable
-               CheckIfInstallable (Path);
+               if (! isInstallable ())
+                       return;
 
                addSubInstallers ();
 
                state = new Hashtable ();
                string stateFile = System.IO.Path.ChangeExtension (this.Path, STATE_FILE_EXT);
                try {
-                       Console.WriteLine ("Starting installation");
+                       string logFilePath = Context.Parameters ["LogFile"];
+                       if (logFilePath != null && logFilePath != "")
+                               Console.WriteLine ("Installation log for assembly " + Path + " is found at " + logFilePath);
+                       Context.LogMessage ("Starting installation of assembly: " + Path);
                        base.Install (state);
                } finally {
                        // Serialise state
@@ -194,11 +210,15 @@ public class AssemblyInstaller : Installer {
                                file.Close ();
                        }
                }
-               Console.WriteLine ("Completed installation");
+               Context.LogMessage ("Installation completed");
        }
 
        public override void Commit (IDictionary state)
        {
+               // Make sure that the assembly is installable
+               if (! isInstallable ())
+                       return;
+
                addSubInstallers ();
                string stateFile = System.IO.Path.ChangeExtension (this.Path, STATE_FILE_EXT);
                // Read serialised state
@@ -210,11 +230,17 @@ public class AssemblyInstaller : Installer {
                        file.Close ();
                }
 
+               Context.LogMessage ("Starting commit of assembly: " + Path);
                base.Commit (state);
+               Context.LogMessage ("Commit completed");
        }
 
        public override void Rollback (IDictionary state)
        {
+               // Make sure that the assembly is installable
+               if (! isInstallable ())
+                       return;
+
                addSubInstallers ();
                string stateFile = System.IO.Path.ChangeExtension (this.Path, STATE_FILE_EXT);
 
@@ -227,13 +253,19 @@ public class AssemblyInstaller : Installer {
                        file.Close ();
                }
 
+               Context.LogMessage ("Starting rollback of assembly: " + Path);
                base.Rollback (state);
 
                File.Delete (stateFile);
+               Context.LogMessage ("Rollback completed");
        }
 
        public override void Uninstall (IDictionary state)
        {
+               // Make sure that the assembly is installable
+               if (! isInstallable ())
+                       return;
+
                addSubInstallers ();
                string stateFile = System.IO.Path.ChangeExtension (this.Path, STATE_FILE_EXT);
 
@@ -247,9 +279,15 @@ public class AssemblyInstaller : Installer {
                        state = null;
                }
 
+               string logFilePath = Context.Parameters ["LogFile"];
+               if (logFilePath != null && logFilePath != "")
+                       Console.WriteLine ("Installation log for assembly " + Path + " is found at " + logFilePath);
+
+               Context.LogMessage ("Starting uninstallation of assembly: " + Path);
                base.Uninstall (state);
 
                File.Delete (stateFile);
+               Context.LogMessage ("Uninstallation completed");
        }
 }
 
index e2c3a7bc488c938a05b5a1446efb966a53f49ff6..0a90e5ecedac843957647eb839bfad9acb3f68f1 100644 (file)
@@ -1,3 +1,13 @@
+2005-04-07  Muthu Kannan  <t.manki@gmail.com>
+
+       * AssemblyInstaller.cs (UseNewContext): Set default path.
+       (Install,Commit,Rollback,Uninstall): Log events.
+       * Installer.cs (Install, Commit, Rollback,Uninstall): 
+       Don't set installer context when invoking subinstallers.
+       * InstallContext.cs (ParseCommandLine): Fix handling of '--'
+       options.
+       * TransactedInstaller.cs (Install): Fix typo.
+
 2005-03-24  Muthu Kannan  <t.manki@gmail.com>
 
        Near-complete implementation of System.Configuration.Install.
index 7b82b650b8e78c1f4e018dad1cae568f05d5f623..fc7e5b0012a651b74ec394d35e2711c758b26bf9 100644 (file)
@@ -116,10 +116,10 @@ public class InstallContext {
                foreach (string a in args) {
                        // Remove leading / or - or --
                        string x = a;   // I am using x instead of a
-                       if (x.StartsWith ("/") || x.StartsWith ("-"))
-                               x = x.Substring (1);
-                       else if (a.StartsWith ("--"))
+                       if (a.StartsWith ("--"))
                                x = x.Substring (2);
+                       else if (x.StartsWith ("/") || x.StartsWith ("-"))
+                               x = x.Substring (1);
 
                        int index;
                        if ((index = x.IndexOf ("=")) == -1) {
index f003d6892fb7ecf3abf132b8b49cb3bd4ee30d86..ba1d3f8e0207c02b6be87a94a9afd6a26e75c6eb 100644 (file)
@@ -141,7 +141,6 @@ public class Installer : Component {
                        for (i = 0; i <= maxi; ++i) {
                                IDictionary ht = new Hashtable ();
                                try {
-                                       Installers [i].Context = this.Context;
                                        Installers [i].Install (ht);
                                } finally {
                                        state.Add (STATE_PREFIX + i.ToString(), ht);
@@ -181,7 +180,6 @@ public class Installer : Component {
 
                for (int i = 0; i <= lastInstaller; ++i) {
                        try {
-                               Installers [i].Context = this.Context;
                                Installers [i].Commit (states [i]);
                        } catch (Exception e) {
                                caught = e;
@@ -222,7 +220,6 @@ public class Installer : Component {
 
                for (int i = 0; i <= lastInstaller; ++i) {
                        try {
-                               Installers [i].Context = this.Context;
                                Installers [i].Rollback (states [i]);
                        } catch (Exception e) {
                                caught = e;
@@ -272,7 +269,6 @@ public class Installer : Component {
 
                for (int i = 0; i <= lastInstaller; ++i) {
                        try {
-                               Installers [i].Context = this.Context;
                                Installers [i].Uninstall (states [i]);
                        } catch (Exception e) {
                                caught = e;
index e744b1fb169d32b56c41e31a124d806861c4b3bd..f219e01a44f3de7c5c2eebcd513b928232dcc648 100644 (file)
@@ -63,7 +63,7 @@ public class TransactedInstaller : Installer {
                }
 
                try {
-                       Context.LogMessage ("Installation phasing completed successfully -- starting commit.");
+                       Context.LogMessage ("Installation phase completed successfully -- starting commit.");
                        Commit (state);
                } catch (Exception e) {
                        Context.LogMessage ("Commit failed.");
index 32ade1d6c67d79dcd4eaae9196c36626336cda72..3a221fd0eea93211a7dd5ebfbb7779e6d358bcdb 100644 (file)
@@ -1,3 +1,12 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (EXTRA_DISTFILES): Add app_test_2.0.config.
+
+2005-04-07  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * System.Data.dll.sources: In System.Data.SqlClient
+       Added SqlAsyncState.cs & SqlAsyncResult.cs
+
 2005-04-04  Sureshkumar T  <tsureshkumar@novell.com>
 
        * System.Data_test.dll.sources: Added
index e66cd1692fef858a2bf25c498a676d352a2fa434..a9cb0b6a7f5e468b82e261d4dc0c762565733c01 100644 (file)
@@ -30,7 +30,8 @@ EXTRA_DISTFILES = \
        Test/System.Xml/region.xml              \
        Test/System.Xml/region.xsd              \
        Test/System.Xml/store.xsd               \
-       Mono.Data.SqlExpressions/Parser.jay
+       Mono.Data.SqlExpressions/Parser.jay     \
+       app_test_2.0.config
 
 BUILT_SOURCES = Mono.Data.SqlExpressions/Parser.cs
 
index bfd627d25ab2af74be7384178eac9ba3cd34a249..11a760426055a592c3578316fe0eb67f67c1e819 100755 (executable)
@@ -1,3 +1,17 @@
+2005-04-07  Sureshkumar T  <tsureshkumar@novell.com>
+           Ankit Jain     <radical@corewars.org>
+
+       * SqlConnection.cs: Implemented additional connection string
+       property "Asynchronous Processing".
+
+       * SqlCommand.cs: Implemented Asynchronous command execution API.
+
+       * SqlAsyncState.cs: A internal state object for asynchronous
+       operations.
+
+       * SqlAsyncResult.cs: Added. Class to hold result for asynchronous
+       queries.
+
 2005-03-28  Sureshkumar T  <tsureshkumar@novell.com>
 
        * SqlCommand.cs: Execute: Add a semicolon at the end of
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs
new file mode 100644 (file)
index 0000000..ff85db2
--- /dev/null
@@ -0,0 +1,139 @@
+//
+// System.Data.SqlClient.SqlAsyncResult.cs
+//
+// Author:
+//   T Sureshkumar <tsureshkumar@novell.com>
+//   Ankit Jain <radical@corewars.org>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#if NET_2_0
+using System;
+using System.Threading;
+
+namespace System.Data.SqlClient
+{
+        internal class SqlAsyncResult : IAsyncResult
+        {
+                private SqlAsyncState   _sqlState;
+                private WaitHandle      _waitHandle;
+                private bool            _completed = false;
+                private bool            _completedSyncly = false;
+                private bool            _ended = false;
+                private AsyncCallback   _userCallback = null;
+                private object          _retValue;
+                private string          _endMethod;
+                private IAsyncResult    _internal;
+
+                public SqlAsyncResult (AsyncCallback userCallback, SqlAsyncState sqlState)
+                {
+                        _sqlState = sqlState;
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+
+                public SqlAsyncResult (AsyncCallback userCallback, object state)
+                {
+                        _sqlState = new SqlAsyncState (state);
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+                
+                public object AsyncState 
+                {
+                        get {   return _sqlState.UserState; }
+                }
+
+                internal SqlAsyncState SqlAsyncState
+                {
+                        get {   return _sqlState; }
+                }
+
+                public WaitHandle AsyncWaitHandle 
+                {
+                        get { return _waitHandle; }
+
+                }
+
+                public bool IsCompleted 
+                {
+                        get {   return _completed; }
+                }
+
+                public bool CompletedSynchronously 
+                {
+                        get {   return _completedSyncly; }
+                }
+
+                internal object ReturnValue
+                {
+                        get {   return _retValue; }
+                        set {   _retValue = value; }
+                }
+
+                public string EndMethod
+                {
+                        get {   return _endMethod; }
+                        set {   _endMethod = value; }
+                }
+
+                public bool Ended
+                {
+                        get {   return _ended; }
+                        set {   _ended = value; }
+                }
+
+
+                internal IAsyncResult InternalResult
+                {
+                        get {   return _internal; }
+                        set {   _internal = value; }
+                }
+
+                public AsyncCallback BubbleCallback
+                {
+                        get { return new AsyncCallback (Bubbleback); }
+                        
+                }
+
+                internal void MarkComplete () 
+                {
+                        _completed = true;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+                
+                public void Bubbleback (IAsyncResult ar)
+                {
+                        this.MarkComplete ();
+                }
+        }
+}
+
+#endif // NET_2_0
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs
new file mode 100644 (file)
index 0000000..7f733d7
--- /dev/null
@@ -0,0 +1,56 @@
+//
+// System.Data.SqlClient.SqlAsyncState.cs
+//
+// Author:
+//   T Sureshkumar <tsureshkumar@novell.com>
+//   Ankit Jain <radical@corewars.org>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Net.Sockets;
+
+
+namespace System.Data.SqlClient
+{
+        internal class SqlAsyncState
+        {
+                object  _userState;
+
+                public SqlAsyncState (object userState)
+                {
+                        _userState = userState;
+                }
+
+                public object UserState
+                {
+                        get {return _userState;}
+                        set {_userState = value;}
+                }
+        }
+}
+#endif // NET_2_0
index 0e632576e4f3fc5465118346dabc261ffb19766f..50bdeb998688b0a6dd11828cadd6a34b5e8128a4 100644 (file)
@@ -542,6 +542,12 @@ namespace System.Data.SqlClient {
                                throw new InvalidOperationException ("There is already an open DataReader associated with this Connection which must be closed first.");
                        if (Connection.XmlReader != null)
                                throw new InvalidOperationException ("There is already an open XmlReader associated with this Connection which must be closed first.");
+#if NET_2_0
+                        if (method.StartsWith ("Begin") && !Connection.AsyncProcessing)
+                                throw new InvalidOperationException ("This Connection object is not " + 
+                                                                     "in Asynchronous mode. Use 'Asynchronous" +
+                                                                     " Processing = true' to set it.");
+#endif // NET_2_0
                }
 
 #if NET_2_0
@@ -579,5 +585,215 @@ namespace System.Data.SqlClient {
 #endif // NET_2_0
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Asynchronous Methods
+
+                internal IAsyncResult BeginExecuteInternal (CommandBehavior behavior, 
+                                                            bool wantResults,
+                                                            AsyncCallback callback, 
+                                                            object state)
+                {
+                        IAsyncResult ar = null;
+                        Connection.Tds.RecordsAffected = 0;
+                       TdsMetaParameterCollection parms = Parameters.MetaParameters;
+                       if (preparedStatement == null) {
+                               bool schemaOnly = ((behavior & CommandBehavior.SchemaOnly) > 0);
+                               bool keyInfo = ((behavior & CommandBehavior.KeyInfo) > 0);
+
+                               StringBuilder sql1 = new StringBuilder ();
+                               StringBuilder sql2 = new StringBuilder ();
+
+                               if (schemaOnly || keyInfo)
+                                       sql1.Append ("SET FMTONLY OFF;");
+                               if (keyInfo) {
+                                       sql1.Append ("SET NO_BROWSETABLE ON;");
+                                       sql2.Append ("SET NO_BROWSETABLE OFF;");
+                               }
+                               if (schemaOnly) {
+                                       sql1.Append ("SET FMTONLY ON;");
+                                       sql2.Append ("SET FMTONLY OFF;");
+                               }
+
+                               switch (CommandType) {
+                               case CommandType.StoredProcedure:
+                                        string prolog = "";
+                                        string epilog = "";
+                                       if (keyInfo || schemaOnly)
+                                               prolog = sql1.ToString ();
+                                        if (keyInfo || schemaOnly)
+                                               epilog = sql2.ToString ();
+                                        Connection.Tds.BeginExecuteProcedure (prolog,
+                                                                              epilog,
+                                                                              CommandText,
+                                                                              !wantResults,
+                                                                              parms,
+                                                                              callback,
+                                                                              state);
+                                                                              
+                                       break;
+                               case CommandType.Text:
+                                       string sql = String.Format ("{0}{1};{2}", sql1.ToString (), CommandText, sql2.ToString ());
+                                        if (wantResults)
+                                                ar = Connection.Tds.BeginExecuteQuery (sql, parms, 
+                                                                                       callback, state);
+                                        else
+                                                ar = Connection.Tds.BeginExecuteNonQuery (sql, parms, callback, state);
+                                       break;
+                               }
+                       }
+                       else 
+                               Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
+
+                        return ar;
+
+                }
+
+                internal void EndExecuteInternal (IAsyncResult ar)
+                {
+                        SqlAsyncResult sqlResult = ( (SqlAsyncResult) ar);
+                        Connection.Tds.WaitFor (sqlResult.InternalResult);
+                        Connection.Tds.CheckAndThrowException (sqlResult.InternalResult);
+                }
+
+                public IAsyncResult BeginExecuteNonQuery ()
+                {
+                        return BeginExecuteNonQuery (null, null);
+                }
+
+                public IAsyncResult BeginExecuteNonQuery (AsyncCallback callback, object state)
+                {
+                        ValidateCommand ("BeginExecuteNonQuery");
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, state);
+                        ar.EndMethod = "EndExecuteNonQuery";
+                        ar.InternalResult = BeginExecuteInternal (CommandBehavior.Default, false, ar.BubbleCallback, ar);
+                        return ar;
+                }
+
+                public int EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteNonQuery");
+                        EndExecuteInternal (ar);
+                        
+                        int ret;
+                        if (commandType == CommandType.StoredProcedure)
+                                ret = -1;
+                        else {
+                                // .NET documentation says that except for INSERT, UPDATE and
+                                // DELETE  where the return value is the number of rows affected
+                                // for the rest of the commands the return value is -1.        
+                                if ((CommandText.ToUpper().IndexOf("UPDATE")!=-1) ||
+                                    (CommandText.ToUpper().IndexOf("INSERT")!=-1) ||   
+                                    (CommandText.ToUpper().IndexOf("DELETE")!=-1))     
+                                        ret = Connection.Tds.RecordsAffected;
+                                else
+                                        ret = -1;
+                        }
+                        GetOutputParameters ();
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return ret;
+                }
+
+                public IAsyncResult BeginExecuteReader ()
+                {
+                        return BeginExecuteReader (null, null, CommandBehavior.Default);
+                }
+
+                public IAsyncResult BeginExecuteReader (CommandBehavior behavior)
+                {
+                        return BeginExecuteReader (null, null, behavior);
+                }
+                
+                public IAsyncResult BeginExecuteReader (AsyncCallback callback, object state)
+                {
+                        return BeginExecuteReader (callback, state, CommandBehavior.Default);
+                }
+
+                public IAsyncResult BeginExecuteReader (AsyncCallback callback, object state, CommandBehavior behavior)
+                {
+                        ValidateCommand ("BeginExecuteReader");
+                        this.behavior = behavior;
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, state);
+                        ar.EndMethod = "EndExecuteReader";
+                        IAsyncResult tdsResult = BeginExecuteInternal (behavior, true, 
+                                                                       ar.BubbleCallback, state);
+                        ar.InternalResult = tdsResult;
+                        return ar;
+                }
+
+                public SqlDataReader EndExecuteReader (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteReader");
+                        EndExecuteInternal (ar);
+                        SqlDataReader reader = null;
+                        try {
+                                reader = new SqlDataReader (this);
+                       }
+                       catch (TdsTimeoutException e) {
+                                // if behavior is closeconnection, even if it throws exception
+                                // the connection has to be closed.
+                                if ((behavior & CommandBehavior.CloseConnection) != 0)
+                                        Connection.Close ();
+                                throw SqlException.FromTdsInternalException ((TdsInternalException) e);
+                       } catch (SqlException) {
+                                // if behavior is closeconnection, even if it throws exception
+                                // the connection has to be closed.
+                                if ((behavior & CommandBehavior.CloseConnection) != 0)
+                                        Connection.Close ();
+
+                                throw;
+                        }
+
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return reader;
+                }
+
+                public IAsyncResult BeginExecuteXmlReader (AsyncCallback callback, object state)
+                {
+                        ValidateCommand ("BeginExecuteXmlReader");
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, state);
+                        ar.EndMethod = "EndExecuteXmlReader";
+                        ar.InternalResult = BeginExecuteInternal (behavior, true, 
+                                                                       ar.BubbleCallback, state);
+                        return ar;
+                }
+
+                public XmlReader EndExecuteXmlReader (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteXmlReader");
+                        EndExecuteInternal (ar);
+                        SqlDataReader reader = new SqlDataReader (this);
+                        SqlXmlTextReader textReader = new SqlXmlTextReader (reader);
+                        XmlReader xmlReader = new XmlTextReader (textReader);
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return xmlReader;
+                }
+
+
+                internal void ValidateAsyncResult (IAsyncResult ar, string endMethod)
+                {
+                        if (ar == null)
+                                throw new ArgumentException ("result passed is null!");
+                        if (! (ar is SqlAsyncResult))
+                                throw new ArgumentException (String.Format ("cannot test validity of types {0}",
+                                                                            ar.GetType ()
+                                                                            ));
+                        SqlAsyncResult result = (SqlAsyncResult) ar;
+                        
+                        if (result.EndMethod != endMethod)
+                                throw new InvalidOperationException (String.Format ("Mismatched {0} called for AsyncResult. " + 
+                                                                                    "Expected call to {1} but {0} is called instead.",
+                                                                                    endMethod,
+                                                                                    result.EndMethod
+                                                                                    ));
+                        if (result.Ended)
+                                throw new InvalidOperationException (String.Format ("The method {0}  cannot be called " + 
+                                                                                    "more than once for the same AsyncResult.",
+                                                                                    endMethod));
+
+                }
+
+                #endregion // Asynchronous Methods
+#endif // NET_2_0
        }
 }
index e8e223d8e4f3b1538c2bd18d62b3fd202c2253f3..e603d6671e4bf28a9554389374ba7510f3d1c33f 100644 (file)
@@ -719,6 +719,11 @@ namespace System.Data.SqlClient {
                                parameters["POOLING"] = "true";
                        if (null == parameters.Get ("WORKSTATION ID") && null == parameters.Get ("WSID"))
                                parameters["WORKSTATION ID"] = Dns.GetHostName();
+#if NET_2_0
+                       if (null == parameters.Get ("ASYNC") &&
+                            null == parameters.Get ("ASYNCHRONOUS PROCESSING"))
+                               parameters ["ASYNCHRONOUS PROCESSING"] = "false";
+#endif
                }
 
                private void SetProperties (NameValueCollection parameters)
@@ -789,6 +794,10 @@ namespace System.Data.SqlClient {
 #if NET_2_0
                                case "MULTIPLEACTIVERESULTSETS":
                                        break;
+                                case "ASYNCHRONOUS PROCESSING" :
+                                case "ASYNC" :
+                                        async = ConvertToBoolean (name, value);
+                                        break;
 #endif
                                        case "NET" :
                                        case "NETWORK" :
@@ -918,5 +927,25 @@ namespace System.Data.SqlClient {
                }
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Fields Net 2
+
+                bool async = false;
+
+                #endregion // Fields  Net 2
+
+                #region Properties Net 2
+
+                [DataSysDescription ("Enable Asynchronous processing, 'Asynchrouse Processing=true/false' in the ConnectionString.")]  
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               internal bool AsyncProcessing  {
+                       get { return async; }
+               }
+
+                #endregion // Properties Net 2
+
+#endif // NET_2_0
+
        }
 }
index 86eebad93925948eb3ee20930ad7f3aa6a7a0ab8..e96856e2a31776bed173140d4811a0d5958f8e72 100755 (executable)
@@ -295,6 +295,8 @@ System.Data.SqlClient/SqlNotificationType.cs
 System.Data.SqlClient/SqlNotificationInfo.cs
 System.Data.SqlClient/SqlNotificationSource.cs
 System.Data.SqlClient/ISqlNotificationReceiver.cs
+System.Data.SqlClient/SqlAsyncState.cs
+System.Data.SqlClient/SqlAsyncResult.cs
 System.Data.SqlClient/SqlClientPermission.cs
 System.Data.SqlClient/SqlClientPermissionAttribute.cs
 System.Data.SqlClient/SqlCommand.cs
index e08772120621893f2019edd4dd984de136c27bc8..adfc97beea8f53baa31c46a719df0e6ba70ae92a 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-07  Lluis Sanchez Gual <lluis@novell.com>
+
+       * DataRowCollection.cs: Fix the signature of the Add method
+       for NET_2_0.
+
 2005-03-16  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataRow.cs : on importing row, it was copying data from incorrect
index c8593545b308a17b67e118bb9445c99a5323ca5e..e42a10ac123672889277871f61e0a5e88550678d 100644 (file)
@@ -109,7 +109,11 @@ namespace System.Data
                /// <summary>
                /// Creates a row using specified values and adds it to the DataRowCollection.
                /// </summary>
+#if NET_2_0
+               public virtual DataRow Add (params object[] values) 
+#else
                public virtual DataRow Add (object[] values) 
+#endif
                {
                        if (values.Length > table.Columns.Count)
                                throw new ArgumentException ("The array is larger than the number of columns in the table.");
index f5058affe21a3377721cc7a7cb017aae5bf230c1..b9f16964980fb7378a4443164fb95b9f56228022 100644 (file)
@@ -155,13 +155,44 @@ available in System.Data.dll.
        DbProviderFactory - done
        DbConnectionFactory
        
-       Add nunit test cases for these.
+       Add nunit test cases for these. - done
        
 * Create Factory classes & methods for Providers.
        Factory methods for SqlClient - done.
        Factory methods for Odbc provider - done.
        Factory methods for OleDb provider
 
-** DbConnectionStringBuilder - done (not added to sources list).
-       This uses Generic.Collections.Dictionary, which has not yet
-   been implemented. Once it is done, this can be added to sources.
+* DbConnectionStringBuilder - done
+
+Asynchronous Command Execution ((target: mono 1.2 PROFILE=net_2_0)
+==================================================================
+
+* Implement the following Asynchronous Execution Commands for SqlClient
+
+   - BeginExecuteNonQuery (2 overrides) - done
+   - BeginExecuteReader   (3 overrides) - done
+   - BegineExecuteXmlReader             - done
+
+   - Implement corresponding asynchronous methods in Tds driver - done
+
+* Pending
+   
+   - Provide Stand Alone test cases
+   - Check whether the result column is xml while doing
+     EndExecuteXmlReader.
+
+
+Test Cases
+==========
+
+* Provide a single consistent test fixture for all data providers
+   available in Test/ProviderTests
+
+* NUnit-ize Provider Tests
+
+* Make these tests to be able to run by command
+   make run-test PROVIDER=mysql   # to run tests marked for mysql & SQL92.
+
+* Provide SQL92 complaint scripts for shema & data, to be loaded
+   irrelevant of data providers.
+
index c7973c7046cb1167be67dedc3b8bc123e41e714d..c7ac9ae4c73e4e3cc790b1c69f7b6310a30586be 100644 (file)
@@ -1,3 +1,12 @@
+2005-04-07  Boris Kirzner  <borisk@mainsoft.com>
+
+       * DirectoryServicesDirectoryEntryTest.cs: 
+               - Rethrow AssertionException so the test will fail if Assert.Fail is called inside try/catch.
+               - Additional test case for Properties.
+               - Additional test case for DeleteTree.
+               - More testing for RefreshCache.
+
+
 2005-03-29  Boris Kirzner  <borisk@mainsoft.com>
 
        * DirectoryServicesDirectoryEntryTest.cs: 
index c0d7846394faff7d5d84702bbf65582d46750c3a..8e1f829914f5a87aa7fced889db347d3f5a5a9b6 100644 (file)
@@ -679,6 +679,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not deleted from server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -723,6 +726,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not moved from old location on the server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -768,6 +774,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not renamed on the server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -822,6 +831,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not deleted from server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -866,6 +878,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not moved from old location on the server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -911,6 +926,9 @@ namespace MonoTests.System.DirectoryServices
                                barakTsabariDE.CommitChanges();\r
                                Assert.Fail("Object " + barakTsabariDN + " was not renamed on the server.");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch (Exception e) {\r
                                // do nothing\r
                        }\r
@@ -1124,7 +1142,7 @@ namespace MonoTests.System.DirectoryServices
 \r
 \r
                [Test]\r
-               public void DirectoryEntry_Properties()\r
+               public void DirectoryEntry_Properties1()\r
                {\r
                        de = new DirectoryEntry(LDAPServerConnectionString);\r
 \r
@@ -1143,6 +1161,89 @@ namespace MonoTests.System.DirectoryServices
                        Assert.AreEqual(((PropertyValueCollection)de.Properties["dc"]).Value,"myhosting");\r
                        Assert.AreEqual(((PropertyValueCollection)de.Properties["description"]).Value,"My wonderful company as much text as you want to place in this line up to 32Kcontinuation data for the line above must have <CR> or <CR><LF> i.e. ENTER works on both Windows and *nix system - new line MUST begin with ONE SPACE");\r
                        Assert.AreEqual(((PropertyValueCollection)de.Properties["o"]).Value,"Example, Inc.");\r
+\r
+                       // ensure that properties are not accessible after removing an entry from the server\r
+                       string barakTsabariDN = LDAPServerRoot + "cn=Barak Tsabari,ou=Human Resources,ou=people,dc=myhosting,dc=example";\r
+                       de = new DirectoryEntry(barakTsabariDN,\r
+                                                                       LDAPServerUsername,\r
+                                                                       LDAPServerPassword,\r
+                                                                       AuthenticationTypes.ServerBind);\r
+                       \r
+                       de.DeleteTree();\r
+                       \r
+                       try {\r
+                               int i = de.Properties.Count;\r
+                               Assert.Fail("Properties should not be accessible after deleting an entry from the server");\r
+                       }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
+                       catch(Exception e) {\r
+                               // supress exception\r
+                       }\r
+\r
+                       try {\r
+                               string s = (string)((PropertyValueCollection)de.Properties["dc"]).Value;\r
+                               Assert.Fail("Properties should not be accessible after deleting an entry from the server");\r
+                       }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
+                       catch(Exception e) {\r
+                               // supress exception\r
+                       }\r
+               }\r
+\r
+               [Test]\r
+               public void DirectoryEntry_Properties2()\r
+               {\r
+                       // delete entry, create a new one (the same) and access properties of the old object\r
+                       string barakTsabariDN = LDAPServerRoot + "cn=Barak Tsabari,ou=Human Resources,ou=people,dc=myhosting,dc=example";\r
+                       de = new DirectoryEntry(barakTsabariDN,\r
+                                                                       LDAPServerUsername,\r
+                                                                       LDAPServerPassword,\r
+                                                                       AuthenticationTypes.ServerBind);\r
+\r
+                       // cause to properties loading\r
+                       Assert.AreEqual(de.Properties.Count,6);\r
+                       Assert.AreEqual(((PropertyValueCollection)de.Properties["sn"]).Value,"Tsabari");\r
+\r
+                       // delete entry\r
+                       de.DeleteTree();\r
+\r
+                       // the local property chache is still accessible\r
+                       Assert.AreEqual(de.Properties.Count,6);\r
+                       Assert.AreEqual(((PropertyValueCollection)de.Properties["sn"]).Value,"Tsabari");\r
+\r
+                       de.CommitChanges();\r
+\r
+                       // the local property chache is still accessible\r
+                       ((PropertyValueCollection)de.Properties["sn"]).Value = "Barbari";\r
+\r
+                       // create the entry back again\r
+                       DirectoryEntry ouHumanResources = new DirectoryEntry(   LDAPServerRoot + "ou=Human Resources,ou=people,dc=myhosting,dc=example",\r
+                                                                                                                                       LDAPServerUsername,\r
+                                                                                                                                       LDAPServerPassword,\r
+                                                                                                                                       AuthenticationTypes.ServerBind);\r
+                       DirectoryEntry cnBarakTsabari = ouHumanResources.Children.Add("cn=Barak Tsabari","Class");\r
+                       ((PropertyValueCollection)cnBarakTsabari.Properties["objectClass"]).Add("person");\r
+                       ((PropertyValueCollection)cnBarakTsabari.Properties["objectClass"]).Add("organizationalPerson");\r
+                       cnBarakTsabari.Properties["cn"].Value = "Barak Tsabari";\r
+                       cnBarakTsabari.Properties["facsimileTelephoneNumber"].Value = "+1 906 777 8853";\r
+                       ((PropertyValueCollection)cnBarakTsabari.Properties["ou"]).Add("Human Resources");\r
+                       ((PropertyValueCollection)cnBarakTsabari.Properties["ou"]).Add("People");\r
+                       cnBarakTsabari.Properties["sn"].Value = "Tsabari";\r
+                       cnBarakTsabari.Properties["telephoneNumber"].Value = "+1 906 777 8854";\r
+                       cnBarakTsabari.CommitChanges();\r
+                       \r
+                       // the local property chache is still accessible\r
+                       Assert.AreEqual(((PropertyValueCollection)de.Properties["sn"]).Value,"Barbari");\r
+\r
+                       // Refresh from server\r
+                       de.RefreshCache();\r
+                       // ensure the properties of an entry are still accessible through the old object\r
+                       Assert.AreEqual(((PropertyValueCollection)de.Properties["sn"]).Value,"Tsabari");\r
+\r
                }\r
 \r
 \r
@@ -1449,6 +1550,45 @@ namespace MonoTests.System.DirectoryServices
                                de.CommitChanges();                                     \r
                                Assert.Fail("Object " + johnSmithDN + " was not deleted from server");\r
                        }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
+                       catch(Exception e) {\r
+                               Console.WriteLine(e.StackTrace);\r
+                               // do nothing\r
+                       }\r
+               }\r
+\r
+               [Test]\r
+               public void DirectoryEntry_DeleteTree2()\r
+               {\r
+                       string johnSmithDN = LDAPServerRoot + "cn=John Smith,ou=Human Resources,ou=people,dc=myhosting,dc=example";\r
+\r
+                       Assert.IsTrue(DirectoryEntry.Exists(johnSmithDN));\r
+                       // two objects refer to the same entry\r
+                       de = new DirectoryEntry(johnSmithDN,\r
+                                                                       LDAPServerUsername,\r
+                                                                       LDAPServerPassword,\r
+                                                                       AuthenticationTypes.ServerBind);\r
+\r
+                       DirectoryEntry johnSmithDE = new DirectoryEntry(johnSmithDN,\r
+                                                                                                                       LDAPServerUsername,\r
+                                                                                                                       LDAPServerPassword,\r
+                                                                                                                       AuthenticationTypes.ServerBind);\r
+\r
+                       johnSmithDE.Properties["telephoneNumber"].Value = "+972 3 9999999";\r
+\r
+                       // check that the second entry is not accessible after the first is deleted\r
+                       de.DeleteTree();\r
+                       de.CommitChanges();\r
+\r
+                       try {\r
+                               johnSmithDE.CommitChanges();                                    \r
+                               Assert.Fail("Object " + johnSmithDN + " should not be accessible");\r
+                       }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
                        catch(Exception e) {\r
                                // do nothing\r
                        }\r
@@ -1557,7 +1697,47 @@ namespace MonoTests.System.DirectoryServices
 \r
                        de.RefreshCache();\r
 \r
-                       Assert.AreEqual(((PropertyValueCollection)de.Properties["description"]).Value,oldValue);                                \r
+                       Assert.AreEqual(((PropertyValueCollection)de.Properties["description"]).Value,oldValue);\r
+                       \r
+                       // call RefeshCache on new entry prior to submitting it to the server shoud fail\r
+                       string newEmployeeDN = LDAPServerRoot + "cn=New Employee,ou=Human Resources,ou=people,dc=myhosting,dc=example";\r
+                       string humanResourcesDN = LDAPServerRoot + "ou=Human Resources,ou=people,dc=myhosting,dc=example";\r
+\r
+                       DirectoryEntry humanResourcesDE = new DirectoryEntry(   humanResourcesDN,\r
+                                                                                                                                       LDAPServerUsername,\r
+                                                                                                                                       LDAPServerPassword,\r
+                                                                                                                                       AuthenticationTypes.ServerBind);\r
+\r
+                       DirectoryEntry newEmployeeDE = humanResourcesDE.Children.Add("cn=New Employee","Class");\r
+                       Assert.AreEqual(newEmployeeDE.Properties["cn"].Value,null);\r
+\r
+                       ((PropertyValueCollection)newEmployeeDE.Properties["objectClass"]).Add("person");\r
+                       ((PropertyValueCollection)newEmployeeDE.Properties["objectClass"]).Add("organizationalPerson");\r
+                       newEmployeeDE.Properties["cn"].Value = "New Employee";\r
+                       newEmployeeDE.Properties["sn"].Value = "Employee";\r
+                       newEmployeeDE.Properties["ou"].Value = "Human Resources";\r
+\r
+                       Assert.AreEqual(newEmployeeDE.Properties["cn"].Value,"New Employee");\r
+\r
+                       try {\r
+                               newEmployeeDE.RefreshCache();\r
+                               Assert.Fail("Call to RefreshCache did not fail");\r
+                       }\r
+                       catch(AssertionException ae) {\r
+                               throw ae;\r
+                       }\r
+                       catch (Exception e) {\r
+                               // supress exception\r
+                       }\r
+\r
+                       Assert.AreEqual(newEmployeeDE.Properties["cn"].Value,"New Employee");\r
+\r
+                       newEmployeeDE.CommitChanges();\r
+\r
+                       // now it should work without any problem\r
+                       newEmployeeDE.RefreshCache();\r
+\r
+                       Assert.AreEqual(newEmployeeDE.Properties["cn"].Value,"New Employee");\r
                }\r
 \r
                [Test]\r
index e7a4374134606ed12c2d8dff5f2eb4d035df53ac..0fe315a28c19f852aa8bc9e254d5f8efd31da9c5 100644 (file)
@@ -1,3 +1,9 @@
+2005-04-07  Lluis Sanchez Gual <lluis@novell.com>
+
+       * System.Web.dll.sources: Added new files:
+               System.Web.UI.WebControls/ObjectDataSourceFilteringEventArgs.cs
+               System.Web.UI.WebControls/ObjectDataSourceFilteringEventHandler.cs
+
 2005-04-01  Lluis Sanchez Gual <lluis@novell.com>
 
        * System.Web.dll.sources: Added new files:
index 98561b0e95e21765f4775e514a0f737a755c4a82..c3c52152d3e977bc31559d7c4b742c646bd8d427 100644 (file)
@@ -52,6 +52,7 @@ namespace System.Web.UI.WebControls {
                internal AutoGeneratedField (AutoGeneratedFieldProperties fieldProperties)
                {
                        DataField = fieldProperties.DataField;
+                       SortExpression = fieldProperties.DataField;
                        DataType = fieldProperties.Type;
                        HeaderText = fieldProperties.Name;
                        ReadOnly = fieldProperties.IsReadOnly;
index c5e46dde148abaea33bfa39c6a7d4f44d3b8bc89..fff91dfa77770b529a0aff17da6dbcab360042b3 100644 (file)
@@ -112,6 +112,7 @@ namespace System.Web.UI.WebControls {
                        }
                        set { 
                                ViewState ["ReadOnly"] = value;
+                               OnFieldChanged ();
                        }
                }
 
@@ -124,6 +125,7 @@ namespace System.Web.UI.WebControls {
                        }
                        set { 
                                ViewState ["HtmlEncode"] = true;
+                               OnFieldChanged ();
                        }
                }
                
@@ -193,19 +195,11 @@ namespace System.Web.UI.WebControls {
                        if (DataField == ThisExpression)
                                return controlContainer.ToString ();
                        else {
-                               IDataItemContainer dic = controlContainer as IDataItemContainer;
+                               IDataItemContainer dic = (IDataItemContainer) controlContainer;
                                if (boundProperty == null) {
-                                       ICustomTypeDescriptor desc = dic.DataItem as ICustomTypeDescriptor;
-                                       if (desc != null) {
-                                               boundProperty = desc.GetProperties () [DataField];
-                                               if (boundProperty != null)
-                                                       return boundProperty.GetValue (dic.DataItem);
-                                       } else {
-                                               PropertyInfo pi = dic.DataItem.GetType ().GetProperty (DataField);
-                                               if (pi != null)
-                                                       return pi.GetValue (dic.DataItem, null);
-                                       }
-                                       throw new InvalidOperationException ("Property '" + DataField + "' not found in data bound item");
+                                       boundProperty = TypeDescriptor.GetProperties (dic.DataItem) [DataField];
+                                       if (boundProperty == null)
+                                               new InvalidOperationException ("Property '" + DataField + "' not found in object of type " + dic.DataItem.GetType());
                                }
                                return boundProperty.GetValue (dic.DataItem);
                        }
@@ -216,7 +210,8 @@ namespace System.Web.UI.WebControls {
                        DataControlFieldCell cell = (DataControlFieldCell) sender;
                        if (cell.Controls.Count > 0) {
                                TextBox box = cell.Controls [0] as TextBox;
-                               box.Text = FormatDataValue (GetValue (cell.BindingContainer), SupportsHtmlEncode && HtmlEncode);
+                               object val = GetValue (cell.BindingContainer);
+                               box.Text = val != null ? val.ToString() : "";
                        }
                        else
                                cell.Text = FormatDataValue (GetValue (cell.BindingContainer), SupportsHtmlEncode && HtmlEncode);
index 9915e628e2e6b88262bf6c6c39b9111c8f85a919..4176ff7d2d763fb482b30c05f6baef3881e23f93 100644 (file)
@@ -60,6 +60,7 @@ namespace System.Web.UI.WebControls {
                
            [WebCategoryAttribute ("Data")]\r
            [DefaultValueAttribute ("")]\r
+               [TypeConverterAttribute ("System.Web.UI.Design.DataSourceViewSchemaConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
                public virtual string DataTextField {
                        get {
                                object ob = ViewState ["DataTextField"];
@@ -155,7 +156,7 @@ namespace System.Web.UI.WebControls {
                                base.InitializeCell (cell, cellType, rowState, rowIndex);
                }
                
-               protected virtual void OnDataBindField (object sender, EventArgs e)
+               void OnDataBindField (object sender, EventArgs e)
                {
                        DataControlFieldCell cell = (DataControlFieldCell) sender;
                        DataControlButton btn = (DataControlButton) cell.Controls [0]; 
@@ -168,17 +169,9 @@ namespace System.Web.UI.WebControls {
                {
                        IDataItemContainer dic = controlContainer as IDataItemContainer;
                        if (boundProperty == null) {
-                               ICustomTypeDescriptor desc = dic.DataItem as ICustomTypeDescriptor;
-                               if (desc != null) {
-                                       boundProperty = desc.GetProperties () [DataTextField];
-                                       if (boundProperty != null)
-                                               return boundProperty.GetValue (dic.DataItem);
-                               } else {
-                                       PropertyInfo pi = dic.DataItem.GetType ().GetProperty (DataTextField);
-                                       if (pi != null)
-                                               return pi.GetValue (dic.DataItem, null);
-                               }
-                               throw new InvalidOperationException ("Property '" + DataTextField + "' not found in data bound item");
+                               boundProperty = TypeDescriptor.GetProperties (dic.DataItem) [DataTextField];
+                               if (boundProperty == null)
+                                       new InvalidOperationException ("Property '" + DataTextField + "' not found in object of type " + dic.DataItem.GetType());
                        }
                        return boundProperty.GetValue (dic.DataItem);
                }
index a1c8bbd6cf7f680161f4d08257dba651f474aac2..8a8910a476e61162333b919cafed0c203e76e587 100644 (file)
@@ -1,3 +1,28 @@
+2005-04-07  Lluis Sanchez Gual <lluis@novell.com>
+
+       * ButtonField.cs: Get data item properties using TypeDescriptor.
+       Made OnDataBindField private.
+       * ObjectDataSourceView.cs: Implemented support for Delete and
+       Insert operations, support for filtering and sorting,
+       conflict detection, etc. It's now complete.
+       * ObjectDataSource.cs: Completed most of functionality. Only
+       caching support is missing.
+       * ObjectDataSourceFilteringEventHandler.cs: New event handler.
+       * TreeNode.cs: Get data item properties using TypeDescriptor.
+       * PagerSettings.cs: Flush.
+       * ObjectDataSourceFilteringEventArgs.cs: New event args.
+       * GridView.cs: Get data item properties using TypeDescriptor
+       and cache them. Properly set descending order in the sort
+       expression. In UpdateRow, make sure we get the old values
+       before the control is bound again.
+       * ImageField.cs: Implemented.
+       * AutoGeneratedField.cs: Initialize the field's sort
+       expression in the constructor.
+       * MenuItem.cs: Get data item properties using TypeDescriptor.
+       * BoundField.cs: Get data item properties using TypeDescriptor.
+       * CheckBoxField.cs: Added missing attributes.
+       * TemplateField.cs: Implemented.
+
 2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * UnitConverter.cs:
index a7480dbff37355da22e04c2a36fe3da6fc44b659..dc6468623e223b07d8f786cee1f9199de81455d6 100644 (file)
@@ -41,21 +41,33 @@ namespace System.Web.UI.WebControls {
        [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class CheckBoxField : BoundField
        {
+           [EditorBrowsableAttribute (EditorBrowsableState.Never)]\r
+           [BrowsableAttribute (false)]\r
+           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
                public override bool ConvertEmptyStringToNull {
                        get { throw GetNotSupportedPropException ("ConvertEmptyStringToNull"); } 
                        set { throw GetNotSupportedPropException ("ConvertEmptyStringToNull"); } 
                }
                
+           [EditorBrowsableAttribute (EditorBrowsableState.Never)]\r
+           [BrowsableAttribute (false)]\r
+           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
                public override string DataFormatString {
                        get { throw GetNotSupportedPropException ("DataFormatString"); } 
                        set { throw GetNotSupportedPropException ("DataFormatString"); } 
                }
                
+           [EditorBrowsableAttribute (EditorBrowsableState.Never)]\r
+           [BrowsableAttribute (false)]\r
+           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
                public override bool HtmlEncode {
                        get { throw GetNotSupportedPropException ("HtmlEncode"); } 
                        set { throw GetNotSupportedPropException ("HtmlEncode"); } 
                }
                
+           [EditorBrowsableAttribute (EditorBrowsableState.Never)]\r
+           [BrowsableAttribute (false)]\r
+           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
                public override string NullDisplayText {
                        get { throw GetNotSupportedPropException ("NullDisplayText"); } 
                        set { throw GetNotSupportedPropException ("NullDisplayText"); } 
index e40f2190ef4e672acf31642288104c44c5320171..91fce8c17e118e641ac0c65cc9c8aef36308f978 100644 (file)
@@ -60,6 +60,8 @@ namespace System.Web.UI.WebControls
                
                ITemplate pagerTemplate;
                ITemplate emptyDataTemplate;
+               
+               PropertyDescriptor[] cachedKeyProperties;
                        
                // View state
                DataControlFieldCollection columns;
@@ -1033,8 +1035,8 @@ namespace System.Web.UI.WebControls
 
                        if (retVal.Count > 0)
                                return (AutoGeneratedFieldProperties[]) retVal.ToArray (typeof(AutoGeneratedFieldProperties));
-                       
-                       throw new HttpException(HttpRuntime.FormatResourceString("DataGrid_NoAutoGenColumns", ID));
+                       else
+                               return new AutoGeneratedFieldProperties [0];
                }
                
                protected virtual GridViewRow CreateRow (int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
@@ -1117,8 +1119,11 @@ namespace System.Web.UI.WebControls
                        DataControlField[] fields = new DataControlField [fieldCollection.Count];
                        fieldCollection.CopyTo (fields, 0);
 
-                       foreach (DataControlField field in fields)
+                       foreach (DataControlField field in fields) {
                                field.Initialize (AllowSorting, this);
+                               if (EnableSortingAndPagingCallbacks)
+                                       field.ValidateSupportsCallback ();
+                       }
 
                        // Main table creation
                        
@@ -1251,15 +1256,20 @@ namespace System.Web.UI.WebControls
                
                IOrderedDictionary CreateRowDataKey (GridViewRow row)
                {
-                       OrderedDictionary dic = new OrderedDictionary ();
-                       ICustomTypeDescriptor desc = row.DataItem as ICustomTypeDescriptor;
-                       if (desc != null && DataKeyNames != null) {
-                               PropertyDescriptorCollection props = desc.GetProperties ();
-                               foreach (string key in DataKeyNames) {
-                                       PropertyDescriptor prop = props [key];
-                                       dic [key] = prop.GetValue (row.DataItem);
+                       if (cachedKeyProperties == null) {
+                               PropertyDescriptorCollection props = TypeDescriptor.GetProperties (row.DataItem);
+                               cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
+                               for (int n=0; n<DataKeyNames.Length; n++) { 
+                                       PropertyDescriptor p = props [DataKeyNames[n]];
+                                       if (p == null)
+                                               new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + row.DataItem.GetType());
+                                       cachedKeyProperties [n] = p;
                                }
                        }
+                       
+                       OrderedDictionary dic = new OrderedDictionary ();
+                       foreach (PropertyDescriptor p in cachedKeyProperties)
+                               dic [p.Name] = p.GetValue (row.DataItem);
                        return dic;
                }
                
@@ -1301,9 +1311,14 @@ namespace System.Web.UI.WebControls
                                        SelectArguments.RetrieveTotalRowCount = true;
                        }
 
-                       if (sortExpression != "")
-                               SelectArguments.SortExpression = sortExpression;
-                               
+                       if (sortExpression != "") {
+                               if (sortDirection == SortDirection.Ascending)
+                                       SelectArguments.SortExpression = sortExpression;
+                               else
+                                       SelectArguments.SortExpression = sortExpression + " DESC";
+                       }
+                       
+                       cachedKeyProperties = null;
                        base.DataBind ();
                }
                
@@ -1377,7 +1392,7 @@ namespace System.Web.UI.WebControls
                                                        if (PageIndex > 0) newIndex = PageIndex - 1;
                                                        break;
                                                default:
-                                                       newIndex = int.Parse (param);
+                                                       newIndex = int.Parse (param) - 1;
                                                        break;
                                        }
                                        ShowPage (newIndex);
@@ -1425,16 +1440,7 @@ namespace System.Web.UI.WebControls
                
                public void Sort (string newSortExpression, SortDirection newSortDirection)
                {
-                       SortDirection newDirection;
-                       if (sortExpression == newSortExpression) {
-                               if (sortDirection == SortDirection.Ascending)
-                                       newDirection = SortDirection.Descending;
-                               else
-                                       newDirection = SortDirection.Ascending;
-                       } else
-                               newDirection = sortDirection;
-                       
-                       GridViewSortEventArgs args = new GridViewSortEventArgs (newSortExpression, newDirection);
+                       GridViewSortEventArgs args = new GridViewSortEventArgs (newSortExpression, newSortDirection);
                        OnSorting (args);
                        if (args.Cancel) return;
                        
@@ -1492,10 +1498,11 @@ namespace System.Web.UI.WebControls
                        
                        if (rowIndex != EditIndex) throw new NotSupportedException ();
                        
+                       currentEditOldValues = oldEditValues.Values;
+
                        GridViewRow row = Rows [rowIndex];
                        currentEditRowKeys = DataKeys [rowIndex].Values;
-                       currentEditNewValues = GetRowValues (row, false, true);
-                       currentEditOldValues = oldEditValues.Values;
+                       currentEditNewValues = GetRowValues (row, false, false);
                        
                        GridViewUpdateEventArgs args = new GridViewUpdateEventArgs (EditIndex, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
                        OnRowUpdating (args);
@@ -1528,6 +1535,7 @@ namespace System.Web.UI.WebControls
                        OnRowDeleting (args);
 
                        if (!args.Cancel) {
+                               RequireBinding ();
                                DataSourceView view = GetData ();
                                if (view != null)
                                        view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
index ad4b86a7fac58b7d254ca3865fe7c4fe5c486ff9..f24df4803d9c4eceebb4ea0997256a54daa774f9 100644 (file)
@@ -2,9 +2,9 @@
 // System.Web.UI.WebControls.ImageField.cs
 //
 // Authors:
-//  Lluis Sanchez Gual (lluis@novell.com)
+//     Lluis Sanchez Gual (lluis@novell.com)
 //
-// (C) 2005 Novell, Inc. (http://www.novell.com)
+// (C) 2005 Novell, Inc (http://www.novell.com)
 //
 
 //
 //
 
 #if NET_2_0
+using System.Collections;
+using System.Collections.Specialized;
 using System.Web.UI;
+using System.ComponentModel;
+using System.Security.Permissions;
+using System.Reflection;
 
-namespace System.Web.UI.WebControls
-{
+namespace System.Web.UI.WebControls {
+
+       [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class ImageField : DataControlField
        {
+               public static readonly string ThisExpression = "!";
+               
+               PropertyDescriptor imageProperty;
+               PropertyDescriptor textProperty;
+               
+               public override bool Initialize (bool sortingEnabled, Control control)
+               {
+                       return base.Initialize (sortingEnabled, control);
+               }
+
+           [DefaultValueAttribute ("")]\r
+           [WebCategoryAttribute ("Appearance")]\r
+           [LocalizableAttribute (true)]\r
+               public virtual string AlternateText {
+                       get {
+                               object ob = ViewState ["AlternateText"];
+                               if (ob != null) return (string) ob;
+                               return string.Empty;
+                       }
+                       set {
+                               ViewState ["AlternateText"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [DefaultValueAttribute (true)]
+               [WebCategoryAttribute ("Behavior")]
+               public virtual bool ConvertEmptyStringToNull {
+                       get {
+                               object ob = ViewState ["ConvertEmptyStringToNull"];
+                               if (ob != null) return (bool) ob;
+                               return true;
+                       }
+                       set {
+                               ViewState ["ConvertEmptyStringToNull"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [TypeConverterAttribute ("System.Web.UI.Design.DataSourceViewSchemaConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+               [WebCategoryAttribute ("Data")]
+               [DefaultValueAttribute ("")]
+               public virtual string DataAlternateTextField {
+                       get {
+                               object ob = ViewState ["DataAlternateTextField"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["DataAlternateTextField"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [WebCategoryAttribute ("Data")]
+               [DefaultValueAttribute ("")]
+               public virtual string DataAlternateTextFormatString {
+                       get {
+                               object ob = ViewState ["DataAlternateTextFormatString"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["DataAlternateTextFormatString"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [TypeConverterAttribute ("System.Web.UI.Design.DataSourceViewSchemaConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+               [WebCategoryAttribute ("Data")]
+               [DefaultValueAttribute ("")]
+               public virtual string DataImageUrlField {
+                       get {
+                               object ob = ViewState ["DataImageUrlField"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["DataImageUrlField"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [WebCategoryAttribute ("Data")]
+               [DefaultValueAttribute ("")]
+               public virtual string DataImageUrlFormatString {
+                       get {
+                               object ob = ViewState ["DataImageUrlFormatString"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["DataImageUrlFormatString"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [DefaultValueAttribute ("")]
+               [WebCategoryAttribute ("Behavior")]
+           [LocalizableAttribute (true)]\r
+               public virtual string NullDisplayText {
+                       get {
+                               object ob = ViewState ["NullDisplayText"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["NullDisplayText"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+           [DefaultValueAttribute ("")]\r
+           [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+           [UrlPropertyAttribute]\r
+           [WebCategoryAttribute ("Behavior")]\r
+               public virtual string NullImageUrl {
+                       get {
+                               object ob = ViewState ["NullImageUrl"];
+                               if (ob != null) return (string) ob;
+                               return "";
+                       }
+                       set {
+                               ViewState ["NullImageUrl"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [WebCategoryAttribute ("Behavior")]
+               [DefaultValueAttribute (false)]
+               public bool ReadOnly {
+                       get {
+                               object val = ViewState ["ReadOnly"];
+                               return val != null ? (bool) val : false;
+                       }
+                       set { 
+                               ViewState ["ReadOnly"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               public override void ExtractValuesFromCell (IOrderedDictionary dictionary,
+                       DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
+               {
+                       if ((ReadOnly && !includeReadOnly) || cell.Controls.Count == 0) return;
+                       
+                       if ((rowState & DataControlRowState.Edit) != 0 && !ReadOnly) {
+                               TextBox box = cell.Controls [0] as TextBox;
+                               dictionary [DataImageUrlField] = box.Text;
+                       } else if (includeReadOnly) {
+                               Image img = cell.Controls [0] as Image;
+                               dictionary [DataImageUrlField] = img.ImageUrl;
+                       }
+               }
+               
+               public override void InitializeCell (DataControlFieldCell cell,
+                       DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
+               {
+                       base.InitializeCell (cell, cellType, rowState, rowIndex);
+                       if (cellType == DataControlCellType.DataCell)
+                               InitializeDataCell (cell, rowState);
+                       cell.DataBinding += new EventHandler (OnDataBindField);
+               }
+               
+               public virtual void InitializeDataCell (DataControlFieldCell cell, DataControlRowState rowState)
+               {
+                       if ((rowState & DataControlRowState.Edit) != 0 && !ReadOnly) {
+                               TextBox box = new TextBox ();
+                               cell.Controls.Add (box);
+                       } else {
+                               Image img = new Image ();
+                               cell.Controls.Add (img);
+                       }
+               }
+               
+               protected virtual string FormatImageUrlValue (object value)
+               {
+                       if (value == null || (value.ToString().Length == 0 && ConvertEmptyStringToNull))
+                               return NullImageUrl;
+                       else if (DataImageUrlFormatString.Length > 0)
+                               return string.Format (DataImageUrlFormatString, value);
+                       else
+                               return value.ToString ();
+               }
+               
+               protected virtual string GetFormattedAlternateText (Control controlContainer)
+               {
+                       if (DataAlternateTextField.Length > 0)
+                       {
+                               if (textProperty == null)
+                                       textProperty = GetProperty (controlContainer, DataAlternateTextField);
+                                       
+                               object value = GetValue (controlContainer, DataAlternateTextField, textProperty);
+                               
+                               if (value == null || (value.ToString().Length == 0 && ConvertEmptyStringToNull))
+                                       return NullDisplayText;
+                               else if (DataAlternateTextFormatString.Length > 0)
+                                       return string.Format (DataAlternateTextFormatString, value);
+                               else
+                                       return value.ToString ();
+                       }
+                       else
+                               return AlternateText;
+               
+               }
+               
+               protected virtual object GetValue (Control controlContainer, string fieldName, PropertyDescriptor cachedDescriptor)
+               {
+                       if (DesignMode)
+                               return GetDesignTimeValue ();
+                       else {
+                               if (fieldName == ThisExpression)
+                                       return controlContainer.ToString ();
+                               else {
+                                       IDataItemContainer dic = (IDataItemContainer) controlContainer;
+                                       if (cachedDescriptor != null) return cachedDescriptor.GetValue (dic.DataItem);
+                                       PropertyDescriptor prop = GetProperty (controlContainer, fieldName);
+                                       return prop.GetValue (dic.DataItem);
+                               }
+                       }
+               }
+               
+               PropertyDescriptor GetProperty (Control controlContainer, string fieldName)
+               {
+                       IDataItemContainer dic = (IDataItemContainer) controlContainer;
+                       PropertyDescriptor prop = TypeDescriptor.GetProperties (dic.DataItem) [fieldName];
+                       if (prop == null)
+                               new InvalidOperationException ("Property '" + fieldName + "' not found in object of type " + dic.DataItem.GetType());
+                       return prop;
+               }
+               
+               protected virtual string GetDesignTimeValue ()
+               {
+                       return "Databound";
+               }
+               
+               protected virtual void OnDataBindField (object sender, EventArgs e)
+               {
+                       DataControlFieldCell cell = (DataControlFieldCell) sender;
+                       
+                       if (imageProperty == null)
+                               imageProperty = GetProperty (cell.BindingContainer, DataImageUrlField);
+                       
+                       Control c = cell.Controls [0];
+                       if (c is TextBox) {
+                               object val = GetValue (cell.BindingContainer, DataImageUrlField, imageProperty);
+                               ((TextBox)c).Text = val != null ? val.ToString() : "";
+                       }
+                       else if (c is Image) {
+                               Image img = (Image)c;
+                               img.ImageUrl = FormatImageUrlValue (GetValue (cell.BindingContainer, DataImageUrlField, imageProperty));
+                               img.AlternateText = GetFormattedAlternateText (cell.BindingContainer);
+                       }
+               }
+               
+               public override void ValidateSupportsCallback ()
+               {
+               }
        }
 }
 #endif
index a9a1f121df9a9188b1a4c22ba0027d25108375e8..b696d394ccc3ca142fd8abf00ebd5fdfe760ebc7 100644 (file)
@@ -492,12 +492,8 @@ namespace System.Web.UI.WebControls
                
                object GetBoundPropertyValue (string name)
                {
-                       if (boundProperties == null) {
-                               ICustomTypeDescriptor desc = hierarchyData as ICustomTypeDescriptor;
-                               if (desc == null)
-                                       throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
-                               boundProperties = desc.GetProperties ();
-                       }
+                       if (boundProperties == null)
+                               boundProperties = TypeDescriptor.GetProperties (hierarchyData);
                        
                        PropertyDescriptor prop = boundProperties.Find (name, true);
                        if (prop == null)
index 21d137978b87fe83827b60e66ab7b46d132fa69b..0385727685e6101b9b614a04b01d504dd7fe7e6d 100644 (file)
@@ -67,6 +67,31 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               public event ObjectDataSourceStatusEventHandler Deleted {
+                       add { DefaultView.Deleted += value; }
+                       remove { DefaultView.Deleted -= value; }
+               }
+               
+               public event ObjectDataSourceMethodEventHandler Deleting {
+                       add { DefaultView.Deleting += value; }
+                       remove { DefaultView.Deleting -= value; }
+               }
+               
+               public event ObjectDataSourceFilteringEventHandler Filtering {
+                       add { DefaultView.Filtering += value; }
+                       remove { DefaultView.Filtering -= value; }
+               }
+               
+               public event ObjectDataSourceStatusEventHandler Inserted {
+                       add { DefaultView.Inserted += value; }
+                       remove { DefaultView.Inserted -= value; }
+               }
+               
+               public event ObjectDataSourceMethodEventHandler Inserting {
+                       add { DefaultView.Inserting += value; }
+                       remove { DefaultView.Inserting -= value; }
+               }
+               
                public event ObjectDataSourceObjectEventHandler ObjectCreated {
                        add { DefaultView.ObjectCreated += value; }
                        remove { DefaultView.ObjectCreated -= value; }
@@ -107,6 +132,36 @@ namespace System.Web.UI.WebControls
                        remove { DefaultView.Updating -= value; }
                }
 
+           [WebCategoryAttribute ("Data")]\r
+           [DefaultValueAttribute (ConflictOptions.OverwriteChanges)]\r
+               public ConflictOptions ConflictDetection {
+                       get { return DefaultView.ConflictDetection; }
+                       set { DefaultView.ConflictDetection = value; }
+               }
+               
+           [WebCategoryAttribute ("Data")]\r
+           [DefaultValueAttribute ("")]\r
+               public string DataObjectTypeName {
+                       get { return DefaultView.DataObjectTypeName; }
+                       set { DefaultView.DataObjectTypeName = value; }
+               }
+               
+           [WebCategoryAttribute ("Data")]\r
+           [DefaultValueAttribute ("")]\r
+               public string DeleteMethod {
+                       get { return DefaultView.DeleteMethod; }
+                       set { DefaultView.DeleteMethod = value; }
+               }
+               
+           [WebCategoryAttribute ("Data")]\r
+           [MergablePropertyAttribute (false)]\r
+           [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+           [DefaultValueAttribute (null)]\r
+           [PersistenceModeAttribute (PersistenceMode.InnerProperty)]\r
+               public ParameterCollection DeleteParameters {
+                       get { return DefaultView.DeleteParameters; }
+               }
+               
            [WebCategoryAttribute ("Paging")]\r
            [DefaultValueAttribute (false)]\r
                public virtual bool EnablePaging {
@@ -114,12 +169,51 @@ namespace System.Web.UI.WebControls
                        set { DefaultView.EnablePaging = value; }
                }
                
+           [WebCategoryAttribute ("Data")]\r
+           [DefaultValueAttribute ("")]\r
+               public string FilterExpression {
+                       get { return DefaultView.FilterExpression; }
+                       set { DefaultView.FilterExpression = value; }
+               }
+               
+           [WebCategoryAttribute ("Data")]\r
+           [MergablePropertyAttribute (false)]\r
+           [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+           [DefaultValueAttribute (null)]\r
+           [PersistenceModeAttribute (PersistenceMode.InnerProperty)]\r
+               public ParameterCollection FilterParameters {
+                       get { return DefaultView.FilterParameters; }
+               }
+               
+           [DefaultValueAttribute ("")]\r
+           [WebCategoryAttribute ("Data")]\r
+               public virtual string InsertMethod {
+                       get { return DefaultView.InsertMethod; }
+                       set { DefaultView.InsertMethod = value; }
+               }
+               
+           [WebCategoryAttribute ("Data")]\r
+           [MergablePropertyAttribute (false)]\r
+           [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+           [DefaultValueAttribute (null)]\r
+           [PersistenceModeAttribute (PersistenceMode.InnerProperty)]\r
+               public ParameterCollection InsertParameters {
+                       get { return DefaultView.InsertParameters; }
+               }
+               
            [WebCategoryAttribute ("Paging")]\r
            [DefaultValueAttribute ("maximumRows")]\r
                public string MaximumRowsParameterName {
                        get { return DefaultView.MaximumRowsParameterName; }
                        set { DefaultView.MaximumRowsParameterName = value; }
                }
+
+           [WebCategoryAttribute ("Data")]\r
+           [DefaultValueAttribute ("original_{0}")]\r
+               public string OldValuesParameterFormatString {
+                       get { return DefaultView.OldValuesParameterFormatString; }
+                       set { DefaultView.OldValuesParameterFormatString = value; }
+               }
                
            [WebCategoryAttribute ("Paging")]\r
            [DefaultValueAttribute ("")]\r
@@ -144,6 +238,13 @@ namespace System.Web.UI.WebControls
                        get { return DefaultView.SelectParameters; }
                }
 
+           [DefaultValueAttribute ("")]\r
+           [WebCategoryAttribute ("Data")]\r
+               public string SortParameterName {
+                       get { return DefaultView.SortParameterName; }
+                       set { DefaultView.SortParameterName = value; }
+               }
+               
            [WebCategoryAttribute ("Paging")]\r
            [DefaultValueAttribute ("startRowIndex")]\r
                public string StartRowIndexParameterName {
@@ -189,6 +290,24 @@ namespace System.Web.UI.WebControls
                        return DefaultView.Select (DataSourceSelectArguments.Empty);
                }
                
+               public int Update ()
+               {
+                       Hashtable empty = new Hashtable ();
+                       return DefaultView.Update (empty, empty, null);
+               }
+
+               public int Delete ()
+               {
+                       Hashtable empty = new Hashtable ();
+                       return DefaultView.Delete (empty, null);
+               }
+               
+               public int Insert ()
+               {
+                       Hashtable empty = new Hashtable ();
+                       return DefaultView.Insert (empty);
+               }
+               
                protected override void LoadViewState (object savedState)
                {
                        if (savedState == null) {
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventArgs.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventArgs.cs
new file mode 100644 (file)
index 0000000..73b62ff
--- /dev/null
@@ -0,0 +1,51 @@
+//
+// System.Web.UI.WebControls.ObjectDataSourceFilteringEventArgs.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace System.Web.UI.WebControls
+{
+       public class ObjectDataSourceFilteringEventArgs : System.ComponentModel.CancelEventArgs
+       {
+               private IOrderedDictionary parameters; 
+               
+               public ObjectDataSourceFilteringEventArgs (IOrderedDictionary parameterValues)
+               {
+                       this.parameters = parameterValues;
+               }
+               
+               public IOrderedDictionary ParameterValues {
+                       get { return parameters; }
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventHandler.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSourceFilteringEventHandler.cs
new file mode 100644 (file)
index 0000000..51295f0
--- /dev/null
@@ -0,0 +1,37 @@
+//
+// System.Web.UI.WebControls.ObjectDataSourceFilteringEventHandler.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#if NET_2_0
+
+namespace System.Web.UI.WebControls
+{
+       public delegate void ObjectDataSourceFilteringEventHandler (object sender, ObjectDataSourceFilteringEventArgs e);
+}
+
+#endif
index aa5396c1ffa5a9d23c7b0a30f3e8af139f49b29c..9800b19d635fdf23f99de078cc8976a25785667d 100644 (file)
@@ -45,11 +45,20 @@ namespace System.Web.UI.WebControls
                ObjectDataSource owner;
                HttpContext context;
                Type objectType;
+               Type dataObjectType;
                
                StateBag viewState = new StateBag ();
                ParameterCollection selectParameters;
                ParameterCollection updateParameters;
-               
+               ParameterCollection deleteParameters;
+               ParameterCollection insertParameters;
+               ParameterCollection filterParameters;
+               
+               private static readonly object DeletedEvent = new object();
+               private static readonly object DeletingEvent = new object();
+               private static readonly object FilteringEvent = new object();
+               private static readonly object InsertedEvent = new object();
+               private static readonly object InsertingEvent = new object();
                private static readonly object ObjectCreatedEvent = new object();
                private static readonly object ObjectCreatingEvent = new object();
                private static readonly object ObjectDisposingEvent = new object();
@@ -65,6 +74,31 @@ namespace System.Web.UI.WebControls
                        this.context = context;
                }
                
+               public event ObjectDataSourceStatusEventHandler Deleted {
+                       add { Events.AddHandler (DeletedEvent, value); }
+                       remove { Events.RemoveHandler (DeletedEvent, value); }
+               }
+               
+               public event ObjectDataSourceMethodEventHandler Deleting {
+                       add { Events.AddHandler (DeletingEvent, value); }
+                       remove { Events.RemoveHandler (DeletingEvent, value); }
+               }
+               
+               public event ObjectDataSourceFilteringEventHandler Filtering {
+                       add { Events.AddHandler (FilteringEvent, value); }
+                       remove { Events.RemoveHandler (FilteringEvent, value); }
+               }
+               
+               public event ObjectDataSourceStatusEventHandler Inserted {
+                       add { Events.AddHandler (InsertedEvent, value); }
+                       remove { Events.RemoveHandler (InsertedEvent, value); }
+               }
+               
+               public event ObjectDataSourceMethodEventHandler Inserting {
+                       add { Events.AddHandler (InsertingEvent, value); }
+                       remove { Events.RemoveHandler (InsertingEvent, value); }
+               }
+               
                public event ObjectDataSourceObjectEventHandler ObjectCreated {
                        add { Events.AddHandler (ObjectCreatedEvent, value); }
                        remove { Events.RemoveHandler (ObjectCreatedEvent, value); }
@@ -105,6 +139,46 @@ namespace System.Web.UI.WebControls
                        remove { Events.RemoveHandler (UpdatingEvent, value); }
                }
                
+               protected virtual void OnDeleted (ObjectDataSourceStatusEventArgs e)
+               {
+                       if (Events != null) {
+                               ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [DeletedEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
+               
+               protected virtual void OnDeleting (ObjectDataSourceMethodEventArgs e)
+               {
+                       if (Events != null) {
+                               ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [DeletingEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
+               
+               protected virtual void OnFiltering (ObjectDataSourceFilteringEventArgs e)
+               {
+                       if (Events != null) {
+                               ObjectDataSourceFilteringEventHandler eh = (ObjectDataSourceFilteringEventHandler) Events [FilteringEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
+               
+               protected virtual void OnInserted (ObjectDataSourceStatusEventArgs e)
+               {
+                       if (Events != null) {
+                               ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [InsertedEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
+               
+               protected virtual void OnInserting (ObjectDataSourceMethodEventArgs e)
+               {
+                       if (Events != null) {
+                               ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [InsertingEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
+               
                protected virtual void OnObjectCreated (ObjectDataSourceEventArgs e)
                {
                        if (Events != null) {
@@ -174,6 +248,14 @@ namespace System.Web.UI.WebControls
                        get { return viewState; }
                }
                
+               public override bool CanDelete {
+                       get { return DeleteMethod.Length > 0; }
+               }
+               
+               public override bool CanInsert {
+                       get { return InsertMethod.Length > 0; }
+               }
+               
                public override bool CanPage {
                        get { return EnablePaging; }
                }
@@ -182,11 +264,66 @@ namespace System.Web.UI.WebControls
                        get { return SelectCountMethod.Length > 0; }
                }
                
+               public override bool CanSort {
+                       get { return true; }
+               }
+               
                public override bool CanUpdate {
                        get { return UpdateMethod.Length > 0; }
                }
                
-               public virtual bool EnablePaging {
+               public ConflictOptions ConflictDetection {
+                       get {
+                               object ret = ViewState ["ConflictDetection"];
+                               return ret != null ? (ConflictOptions)ret : ConflictOptions.OverwriteChanges;
+                       }
+                       set {
+                               ViewState ["ConflictDetection"] = value;
+                       }
+               }
+               
+               public bool ConvertNullToDBNull {
+                       get {
+                               object ret = ViewState ["ConvertNullToDBNull"];
+                               return ret != null ? (bool)ret : false;
+                       }
+                       set {
+                               ViewState ["ConvertNullToDBNull"] = value;
+                       }
+               }
+               
+               public string DataObjectTypeName {
+                       get {
+                               object ret = ViewState ["DataObjectTypeName"];
+                               return ret != null ? (string)ret : string.Empty;
+                       }
+                       set {
+                               ViewState ["DataObjectTypeName"] = value;
+                       }
+               }
+               
+               public string DeleteMethod {
+                       get {
+                               object ret = ViewState ["DeleteMethod"];
+                               return ret != null ? (string)ret : string.Empty;
+                       }
+                       set {
+                               ViewState ["DeleteMethod"] = value;
+                       }
+               }
+               
+               public ParameterCollection DeleteParameters {
+                       get {
+                               if (deleteParameters == null) {
+                                       deleteParameters = new ParameterCollection ();
+                                       if (((IStateManager)this).IsTrackingViewState)
+                                               ((IStateManager)deleteParameters).TrackViewState ();
+                               }
+                               return deleteParameters;
+                       }
+               }
+               
+               public bool EnablePaging {
                        get {
                                object ret = ViewState ["EnablePaging"];
                                return ret != null ? (bool)ret : false;
@@ -196,6 +333,48 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               public string FilterExpression {
+                       get {
+                               object ret = ViewState ["FilterExpression"];
+                               return ret != null ? (string)ret : string.Empty;
+                       }
+                       set {
+                               ViewState ["FilterExpression"] = value;
+                       }
+               }
+               
+               public ParameterCollection FilterParameters {
+                       get {
+                               if (filterParameters == null) {
+                                       filterParameters = new ParameterCollection ();
+                                       if (IsTrackingViewState)
+                                               ((IStateManager)filterParameters).TrackViewState ();
+                               }
+                               return filterParameters;
+                       }
+               }
+               
+               public string InsertMethod {
+                       get {
+                               object ret = ViewState ["InsertMethod"];
+                               return ret != null ? (string)ret : string.Empty;
+                       }
+                       set {
+                               ViewState ["InsertMethod"] = value;
+                       }
+               }
+               
+               public ParameterCollection InsertParameters {
+                       get {
+                               if (insertParameters == null) {
+                                       insertParameters = new ParameterCollection ();
+                                       if (IsTrackingViewState)
+                                               ((IStateManager)insertParameters).TrackViewState ();
+                               }
+                               return insertParameters;
+                       }
+               }
+               
                public string MaximumRowsParameterName {
                        get {
                                object ret = ViewState ["MaximumRowsParameterName"];
@@ -206,7 +385,18 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-               public virtual string SelectCountMethod {
+           [DefaultValueAttribute ("original_{0}")]\r
+               public string OldValuesParameterFormatString {
+                       get {
+                               object ret = ViewState ["OldValuesParameterFormatString"];
+                               return ret != null ? (string)ret : "original_{0}";
+                       }
+                       set {
+                               ViewState ["OldValuesParameterFormatString"] = value;
+                       }
+               }
+                               
+               public string SelectCountMethod {
                        get {
                                object ret = ViewState ["SelectCountMethod"];
                                return ret != null ? (string)ret : string.Empty;
@@ -216,7 +406,7 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-               public virtual string SelectMethod {
+               public string SelectMethod {
                        get {
                                object ret = ViewState ["SelectMethod"];
                                return ret != null ? (string)ret : string.Empty;
@@ -237,6 +427,16 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               public string SortParameterName {
+                       get {
+                               object ret = ViewState ["SortParameterName"];
+                               return ret != null ? (string)ret : string.Empty;
+                       }
+                       set {
+                               ViewState ["SortParameterName"] = value;
+                       }
+               }
+               
                public string StartRowIndexParameterName {
                        get {
                                object ret = ViewState ["StartRowIndexParameterName"];
@@ -247,7 +447,7 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-               public virtual string TypeName {
+               public string TypeName {
                        get {
                                object ret = ViewState ["TypeName"];
                                return ret != null ? (string)ret : string.Empty;
@@ -258,7 +458,7 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-               public virtual string UpdateMethod {
+               public string UpdateMethod {
                        get {
                                object ret = ViewState ["UpdateMethod"];
                                return ret != null ? (string)ret : string.Empty;
@@ -290,27 +490,162 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               Type DataObjectType {
+                       get {
+                               if (dataObjectType == null) {
+                                       dataObjectType = Type.GetType (DataObjectTypeName);
+                                       if (objectType == null)
+                                               throw new InvalidOperationException ("Type not found: " + DataObjectTypeName);
+                               }
+                               return dataObjectType;
+                       }
+               }
+               
                public IEnumerable Select (DataSourceSelectArguments arguments)
                {
                        return ExecuteSelect (arguments);
                }
                
-               protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
+               public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
                {
-                       Hashtable allValues = new Hashtable ();
-                       foreach (DictionaryEntry de in keys)
-                               allValues [de.Key] = de.Value;
-                       foreach (DictionaryEntry de in values)
-                               allValues [de.Key] = de.Value;
+                       return ExecuteUpdate (keys, values, oldValues);
+               }
+               
+               public int Delete (IDictionary keys, IDictionary oldValues)
+               {
+                       return ExecuteDelete (keys, oldValues);
+               }
+               
+               public int Insert (IDictionary values)
+               {
+                       return ExecuteInsert (values);
+               }
+               
+               protected override int ExecuteInsert (IDictionary values)
+               {
+                       if (!CanInsert)
+                               throw new NotSupportedException ("Insert operation not supported.");
+                               
+                       IOrderedDictionary paramValues;
+                       MethodInfo method;
+                       
+                       if (DataObjectTypeName.Length == 0) {
+                               paramValues = MergeParameterValues (InsertParameters, values, null, true);
+                               method = GetObjectMethod (InsertMethod, paramValues);
+                       } else {
+                               method = ResolveDataObjectMethod (InsertMethod, values, null, out paramValues);
+                       }
+                       
+                       ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
+                       OnInserting (args);
+                       if (args.Cancel)
+                               return -1;
+                       
+                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
+                       OnInserted (rargs);
+                       
+                       if (rargs.Exception != null && !rargs.ExceptionHandled)
+                               throw rargs.Exception;
+
+                       return -1;
+               }
 
-                       IOrderedDictionary paramValues = MergeParameterValues (UpdateParameters, allValues);
+               protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
+               {
+                       if (!CanDelete)
+                               throw new NotSupportedException ("Delete operation not supported.");
+                               
+                       if (ConflictDetection == ConflictOptions.CompareAllValues && (oldValues == null || oldValues.Count == 0))
+                               throw new InvalidOperationException ("ConflictDetection is set to CompareAllValues and oldValues collection is null or empty.");
+
+                       IDictionary oldDataValues;
+                       if (ConflictDetection == ConflictOptions.CompareAllValues) {
+                               oldDataValues = new Hashtable ();
+                               foreach (DictionaryEntry de in keys)
+                                       oldDataValues [de.Key] = de.Value;
+                               foreach (DictionaryEntry de in oldValues)
+                                       oldDataValues [de.Key] = de.Value;
+                       } else
+                               oldDataValues = keys;
+                                       
+                       IOrderedDictionary paramValues;
+                       MethodInfo method;
+                       
+                       if (DataObjectTypeName.Length == 0) {
+                               paramValues = MergeParameterValues (DeleteParameters, null, oldDataValues, true);
+                               method = GetObjectMethod (DeleteMethod, paramValues);
+                       } else {
+                               method = ResolveDataObjectMethod (DeleteMethod, oldDataValues, null, out paramValues);
+                       }
                        
+                       ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
+                       OnDeleting (args);
+                       if (args.Cancel)
+                               return -1;
+                       
+                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
+                       
+                       OnDeleted (rargs);
+                       
+                       if (rargs.Exception != null && !rargs.ExceptionHandled)
+                               throw rargs.Exception;
+
+                       return -1;
+               }
+               
+               protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
+               {
+                       IOrderedDictionary paramValues;
+                       MethodInfo method;
+                       
+                       if (DataObjectTypeName.Length == 0)
+                       {
+                               IDictionary dataValues;
+                               IDictionary oldDataValues;
+                               if (ConflictDetection == ConflictOptions.CompareAllValues) {
+                                       oldDataValues = new Hashtable ();
+                                       dataValues = values;
+                                       foreach (DictionaryEntry de in keys)
+                                               oldDataValues [de.Key] = de.Value;
+                                       foreach (DictionaryEntry de in oldValues)
+                                               oldDataValues [de.Key] = de.Value;
+                               } else {
+                                       oldDataValues = keys;
+                                       dataValues = values;
+                               }
+                               paramValues = MergeParameterValues (UpdateParameters, dataValues, oldDataValues, false);
+                               method = GetObjectMethod (UpdateMethod, paramValues);
+                       }
+                       else
+                       {
+                               IDictionary dataValues = new Hashtable ();
+                               IDictionary oldDataValues;
+                               
+                               foreach (DictionaryEntry de in values)
+                                       dataValues [de.Key] = de.Value;
+                                       
+                               if (ConflictDetection == ConflictOptions.CompareAllValues) {
+                                       oldDataValues = new Hashtable ();
+                                       foreach (DictionaryEntry de in keys) {
+                                               oldDataValues [de.Key] = de.Value;
+                                               dataValues [de.Key] = de.Value;
+                                       }
+                                       foreach (DictionaryEntry de in oldValues)
+                                               oldDataValues [de.Key] = de.Value;
+                               } else {
+                                       oldDataValues = null;
+                                       foreach (DictionaryEntry de in keys)
+                                               dataValues [de.Key] = de.Value;
+                               }
+                               method = ResolveDataObjectMethod (UpdateMethod, dataValues, oldDataValues, out paramValues);
+                       }                       
+
                        ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
                        OnUpdating (args);
                        if (args.Cancel)
                                return -1;
                        
-                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (UpdateMethod, paramValues);
+                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
                        OnUpdated (rargs);
                        
                        if (rargs.Exception != null && !rargs.ExceptionHandled)
@@ -323,8 +658,7 @@ namespace System.Web.UI.WebControls
                {
                        arguments.RaiseUnsupportedCapabilitiesError (this);
 
-                       IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null);
-                       
+                       IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null, null, true);
                        ObjectDataSourceSelectingEventArgs args = new ObjectDataSourceSelectingEventArgs (paramValues, arguments, false);
                        OnSelecting (args);
                        if (args.Cancel)
@@ -342,6 +676,9 @@ namespace System.Web.UI.WebControls
                                paramValues [MaximumRowsParameterName] = arguments.MaximumRows;
                        }
                        
+                       if (SortParameterName.Length > 0)
+                               paramValues [SortParameterName] = arguments.SortExpression;
+                       
                        object result = InvokeSelect (SelectMethod, paramValues);
                        
                        if (result is DataSet) {
@@ -353,6 +690,23 @@ namespace System.Web.UI.WebControls
                        
                        if (result is DataTable) {
                                DataView dview = new DataView ((DataTable)result);
+                               if (arguments.SortExpression != null && arguments.SortExpression.Length > 0) {
+                                       dview.Sort = arguments.SortExpression;
+                               }
+                               if (FilterExpression.Length > 0) {
+                                       OrderedDictionary fparams = new OrderedDictionary ();
+                                       foreach (Parameter p in FilterParameters)
+                                               fparams.Add (p.Name, p.GetValue (context, owner));
+                                               
+                                       ObjectDataSourceFilteringEventArgs fargs = new ObjectDataSourceFilteringEventArgs (fparams);
+                                       OnFiltering (fargs);
+                                       if (!fargs.Cancel) {
+                                               object[] formatValues = new object[fargs.ParameterValues.Count];
+                                               for (int n=0; n<formatValues.Length; n++)
+                                                       formatValues [n] = fargs.ParameterValues [n];
+                                               dview.RowFilter = string.Format (FilterExpression, formatValues);
+                                       }
+                               }
                                return dview;
                        }
                        
@@ -375,7 +729,8 @@ namespace System.Web.UI.WebControls
                
                object InvokeSelect (string methodName, IOrderedDictionary paramValues)
                {
-                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (methodName, paramValues);
+                       MethodInfo method = GetObjectMethod (methodName, paramValues);
+                       ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
                        OnSelected (rargs);
                        
                        if (rargs.Exception != null && !rargs.ExceptionHandled)
@@ -384,10 +739,10 @@ namespace System.Web.UI.WebControls
                        return rargs.ReturnValue;
                }
                
-               ObjectDataSourceStatusEventArgs InvokeMethod (string methodName, IOrderedDictionary paramValues)
+               ObjectDataSourceStatusEventArgs InvokeMethod (MethodInfo method, IOrderedDictionary paramValues)
                {
                        object instance = null;
-                       MethodInfo method = GetObjectMethod (methodName, paramValues);
+
                        if (!method.IsStatic)
                                instance = CreateObjectInstance ();
 
@@ -397,7 +752,7 @@ namespace System.Web.UI.WebControls
                        object[] methodArgs = GetParameterArray (pars, paramValues, out outParamInfos); 
                        
                        if (methodArgs == null)
-                               throw CreateMethodException (methodName, paramValues);
+                               throw CreateMethodException (method.Name, paramValues);
                                        
                        object result = null;
                        Hashtable outParams = null;
@@ -441,6 +796,35 @@ namespace System.Web.UI.WebControls
                        throw CreateMethodException (methodName, parameters);
                }
                
+               MethodInfo ResolveDataObjectMethod (string methodName, IDictionary values, IDictionary oldValues, out IOrderedDictionary paramValues)
+               {
+                       MethodInfo method;
+                       if (oldValues != null)
+                               method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType, DataObjectType });
+                       else
+                               method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType });
+                       
+                       if (method == null)
+                               throw new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters of type '" + DataObjectType + "' in '" + ObjectType + "'.");
+                       
+                       paramValues = new OrderedDictionary ();
+                       ParameterInfo[] ps = method.GetParameters ();
+                       
+                       if (oldValues != null) {
+                               if (FormatOldParameter (ps[0].Name) == ps[1].Name) {
+                                       paramValues [ps[0].Name] = CreateDataObject (values);
+                                       paramValues [ps[1].Name] = CreateDataObject (oldValues);
+                               } else if (FormatOldParameter (ps[1].Name) == ps[0].Name) {
+                                       paramValues [ps[0].Name] = CreateDataObject (oldValues);
+                                       paramValues [ps[1].Name] = CreateDataObject (values);
+                               } else
+                                       throw new InvalidOperationException ("Method '" + methodName + "' does not have any parameter that fits the value of OldValuesParameterFormatString.");  
+                       } else {
+                               paramValues [ps[0].Name] = CreateDataObject (values);
+                       }
+                       return method;
+               }
+               
                Exception CreateMethodException (string methodName, IOrderedDictionary parameters)
                {
                        string s = "";
@@ -450,6 +834,17 @@ namespace System.Web.UI.WebControls
                        return new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters " + s + "in type '" + ObjectType + "'.");
                }
                
+               object CreateDataObject (IDictionary values)
+               {
+                       object ob = Activator.CreateInstance (DataObjectType);
+                       foreach (DictionaryEntry de in values) {
+                               PropertyInfo p = DataObjectType.GetProperty ((string)de.Key);
+                               if (p == null) throw new InvalidOperationException ("Property " + de.Key + " not found in type '" +DataObjectType + "'.");
+                               p.SetValue (ob, ConvertParameter (p.PropertyType, de.Value), null);
+                       }
+                       return ob;
+               }
+               
                object CreateObjectInstance ()
                {
                        ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs (null);
@@ -477,17 +872,24 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-               IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values)
+               IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values, IDictionary oldValues, bool allwaysAddNewValues)
                {
                        OrderedDictionary mergedValues = new OrderedDictionary ();
                        foreach (Parameter p in viewParams) {
-                               object val = values != null ? values [p.Name] : null;
-                               if (val != null)
-                                       val = Convert.ChangeType (val, p.Type);
-                               else
-                                       val = p.GetValue (context, owner);
+                               bool oldAdded = false;
+                               if (oldValues != null && oldValues.Contains (p.Name)) {
+                                       object val = Convert.ChangeType (oldValues [p.Name], p.Type);
+                                       mergedValues [FormatOldParameter (p.Name)] = val;
+                                       oldAdded = true;
+                               }
                                
-                               mergedValues [p.Name] = val;
+                               if (values != null && values.Contains (p.Name)) {
+                                       object val = Convert.ChangeType (values [p.Name], p.Type);
+                                       mergedValues [p.Name] = val;
+                               } else if (!oldAdded || allwaysAddNewValues) {
+                                       object val = p.GetValue (context, owner);
+                                       mergedValues [p.Name] = val;
+                               }
                        }
                        
                        if (values != null) {
@@ -496,6 +898,12 @@ namespace System.Web.UI.WebControls
                                                mergedValues [de.Key] = de.Value;
                        }
                        
+                       if (oldValues != null) {
+                               foreach (DictionaryEntry de in oldValues)
+                                       if (!mergedValues.Contains (FormatOldParameter ((string)de.Key)))
+                                               mergedValues [FormatOldParameter ((string)de.Key)] = de.Value;
+                       }
+                       
                        return mergedValues;
                }
                
@@ -521,26 +929,50 @@ namespace System.Web.UI.WebControls
                
                object ConvertParameter (Type targetType, object value)
                {
+                       if (value == null) {
+                               if (targetType.IsPrimitive)
+                                       value = 0;
+                               else if (targetType == typeof(object) && ConvertNullToDBNull)
+                                       return DBNull.Value;
+                       }
                        return Convert.ChangeType (value, targetType);
                }
                
+               string FormatOldParameter (string name)
+               {
+                       string f = OldValuesParameterFormatString;
+                       if (f.Length > 0)
+                               return String.Format (f, name);
+                       else
+                               return name;
+               }
+               
                protected virtual void LoadViewState (object savedState)
                {
-                       object[] state = (savedState == null) ? new object [3] : (object[]) savedState;
+                       object[] state = (savedState == null) ? new object [6] : (object[]) savedState;
                        viewState.LoadViewState (state[0]);
                        ((IStateManager)SelectParameters).LoadViewState (state[1]); 
-                       ((IStateManager)UpdateParameters).LoadViewState (state[1]); 
+                       ((IStateManager)UpdateParameters).LoadViewState (state[2]); 
+                       ((IStateManager)DeleteParameters).LoadViewState (state[3]); 
+                       ((IStateManager)InsertParameters).LoadViewState (state[4]); 
+                       ((IStateManager)FilterParameters).LoadViewState (state[5]); 
                }
 
                protected virtual object SaveViewState()
                {
-                       object[] state = new object [3];
+                       object[] state = new object [6];
                        state [0] = viewState.SaveViewState ();
                        
                        if (selectParameters != null)
                                state [1] = ((IStateManager)selectParameters).SaveViewState ();
                        if (updateParameters != null)
                                state [2] = ((IStateManager)updateParameters).SaveViewState ();
+                       if (deleteParameters != null)
+                               state [3] = ((IStateManager)deleteParameters).SaveViewState ();
+                       if (insertParameters != null)
+                               state [4] = ((IStateManager)insertParameters).SaveViewState ();
+                       if (filterParameters != null)
+                               state [5] = ((IStateManager)filterParameters).SaveViewState ();
                        
                        foreach (object ob in state)
                                if (ob != null) return state;
@@ -553,13 +985,22 @@ namespace System.Web.UI.WebControls
                        viewState.TrackViewState ();
                        if (selectParameters != null) ((IStateManager)selectParameters).TrackViewState ();
                        if (updateParameters != null) ((IStateManager)updateParameters).TrackViewState ();
+                       if (deleteParameters != null) ((IStateManager)deleteParameters).TrackViewState ();
+                       if (insertParameters != null) ((IStateManager)insertParameters).TrackViewState ();
+                       if (filterParameters != null) ((IStateManager)filterParameters).TrackViewState ();
                }
                
-               bool IStateManager.IsTrackingViewState
+               protected virtual bool IsTrackingViewState
                {
                        get { return viewState.IsTrackingViewState; }
                }
                
+               
+               bool IStateManager.IsTrackingViewState
+               {
+                       get { return IsTrackingViewState; }
+               }
+               
                void IStateManager.TrackViewState()
                {
                        TrackViewState ();
index bd0b2a8a5f3b04c7c81aad37cce150d57f2d193d..2913fcf63cf0e101d311aaea0cceb2fe1d6ada4f 100644 (file)
@@ -275,7 +275,7 @@ namespace System.Web.UI.WebControls
                        {\r
                                int first = currentPage / PageButtonCount;\r
                                int last = first + PageButtonCount;\r
-                               if (last >= pageCount) last = pageCount - 1;\r
+                               if (last >= pageCount) last = pageCount;\r
                                \r
                                if (first > 0) {\r
                                        if (Mode == PagerButtons.NumericFirstLast)\r
@@ -284,7 +284,7 @@ namespace System.Web.UI.WebControls
                                }\r
                                \r
                                for (int n = first; n < last; n++)\r
-                                       row.Cells.Add (CreateCell (n.ToString(), string.Empty, (n != currentPage) ? "Page" : "", n.ToString()));\r
+                                       row.Cells.Add (CreateCell ((n+1).ToString(), string.Empty, (n != currentPage) ? "Page" : "", (n+1).ToString()));\r
                                \r
                                if (last < pageCount - 1) {\r
                                        row.Cells.Add (CreateCell (NextPageText, NextPageImageUrl, "Page", "Next"));\r
index 784a06d5c3ff2254cad9dcc1cb878b8906ccbcbd..73a54d1e0f7d8c24fd1e9866f5cbd4a6ee3cfc00 100644 (file)
 //
 
 #if NET_2_0
+using System.Collections.Specialized;
 using System.Web.UI;
+using System.Security.Permissions;
+using System.ComponentModel;
 
 namespace System.Web.UI.WebControls
 {
+       [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class TemplateField : DataControlField
        {
+               ITemplate alternatingItemTemplate;
+               ITemplate editItemTemplate;
+               ITemplate footerTemplate;
+               ITemplate headerTemplate;
+               ITemplate insertItemTemplate;
+               ITemplate itemTemplate;
+               
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.TwoWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate AlternatingItemTemplate {
+                       get { return alternatingItemTemplate; }
+                       set { alternatingItemTemplate = value; OnFieldChanged (); }
+               }
+               
+               [DefaultValueAttribute (true)]
+               [WebCategoryAttribute ("Behavior")]
+               public virtual bool ConvertEmptyStringToNull {
+                       get {
+                               object ob = ViewState ["ConvertEmptyStringToNull"];
+                               if (ob != null) return (bool) ob;
+                               return true;
+                       }
+                       set {
+                               ViewState ["ConvertEmptyStringToNull"] = value;
+                               OnFieldChanged ();
+                       }
+               }
+
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.TwoWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate EditItemTemplate {
+                       get { return editItemTemplate; }
+                       set { editItemTemplate = value; OnFieldChanged (); }
+               }
+
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.OneWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate FooterTemplate {
+                       get { return footerTemplate; }
+                       set { footerTemplate = value; OnFieldChanged (); }
+               }
+
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.OneWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate HeaderTemplate {
+                       get { return headerTemplate; }
+                       set { headerTemplate = value; OnFieldChanged (); }
+               }
+
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.TwoWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate InsertItemTemplate {
+                       get { return insertItemTemplate; }
+                       set { insertItemTemplate = value; OnFieldChanged (); }
+               }
+
+               [DefaultValue (null)]
+               [TemplateContainer (typeof(IDataItemContainer), BindingDirection.TwoWay)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
+               public ITemplate ItemTemplate {
+                       get { return itemTemplate; }
+                       set { itemTemplate = value; OnFieldChanged (); }
+               }
+               
+               public override void InitializeCell (DataControlFieldCell cell,
+                       DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
+               {
+                       if (cellType == DataControlCellType.Header) {
+                               if (headerTemplate != null && ShowHeader) {
+                                       headerTemplate.InstantiateIn (cell);
+                                       return;
+                               }
+                       } else if (cellType == DataControlCellType.Footer) {
+                               if (footerTemplate != null) {
+                                       footerTemplate.InstantiateIn (cell);
+                                       return;
+                               }
+                       } else {
+                               if ((rowState & DataControlRowState.Insert) != 0) {
+                                       if (headerTemplate != null) {
+                                               insertItemTemplate.InstantiateIn (cell);
+                                               return;
+                                       }
+                               }
+                               else if ((rowState & DataControlRowState.Edit) != 0) {
+                                       if (editItemTemplate != null) {
+                                               editItemTemplate.InstantiateIn (cell);
+                                               return;
+                                       }
+                               }
+                               else if ((rowState & DataControlRowState.Alternate) != 0 && alternatingItemTemplate != null) {
+                                       alternatingItemTemplate.InstantiateIn (cell);
+                                       return;
+                               }
+                               else if (itemTemplate != null) {
+                                       itemTemplate.InstantiateIn (cell);
+                                       return;
+                               }
+                       }
+                       
+                       base.InitializeCell (cell, cellType, rowState, rowIndex);
+               }
+               
+               [MonoTODO]
+               public override void ExtractValuesFromCell (IOrderedDictionary dictionary,
+                       DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
+               {
+               }
+               
+               public override void ValidateSupportsCallback ()
+               {
+                       throw new NotSupportedException ("Callback not supported on TemplateField. Turn disable callbacks on '" + Control.ID + "'.");
+               }
+
        }
 }
 #endif
index e0ac7b119f4f7e4c534cb79a1f60eeda786a61ec..e5b5f5579779d571f1cba237edfc29bde3b8eadf 100644 (file)
@@ -653,12 +653,8 @@ namespace System.Web.UI.WebControls
                
                object GetBoundPropertyValue (string name)
                {
-                       if (boundProperties == null) {
-                               ICustomTypeDescriptor desc = hierarchyData as ICustomTypeDescriptor;
-                               if (desc == null)
-                                       throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
-                               boundProperties = desc.GetProperties ();
-                       }
+                       if (boundProperties == null)
+                               boundProperties = TypeDescriptor.GetProperties (hierarchyData);
                        
                        PropertyDescriptor prop = boundProperties.Find (name, true);
                        if (prop == null)
index 97c73fed0adce5d7b09d479a77ae39419e1167cf..6cf559f1a768ca8c4873e908a21a2bb916f09b31 100644 (file)
@@ -1,3 +1,10 @@
+2005-04-07  Lluis Sanchez Gual <lluis@novell.com>
+
+       * TemplateControl.cs:
+       * Page.cs: Moved Eval and XPath from Page
+       to TemplateControl.
+       * StateManagedCollection.cs: Avoid saving null state.
+
 2005-04-01  Lluis Sanchez Gual <lluis@novell.com>
 
        * DataSourceView.cs: Rethrow exceptions not handled by operation
index efbd0a9b4dd49fe2dfb9367a3f1abe29cca11b65..792496586346fe7735176a27daee24f050f50956 100755 (executable)
@@ -1277,58 +1277,6 @@ public class Page : TemplateControl, IHttpHandler
                _form = form;
        }
        
-       Stack dataItemCtx;
-       
-       internal void PushDataItemContext (object o)
-       {
-               if (dataItemCtx == null)
-                       dataItemCtx = new Stack ();
-               
-               dataItemCtx.Push (o);
-       }
-       
-       internal void PopDataItemContext ()
-       {
-               if (dataItemCtx == null)
-                       throw new InvalidOperationException ();
-               
-               dataItemCtx.Pop ();
-       }
-       
-       internal object CurrentDataItem {
-               get {
-                       if (dataItemCtx == null)
-                               throw new InvalidOperationException ("No data item");
-                       
-                       return dataItemCtx.Peek ();
-               }
-       }
-       
-       protected object Eval (string expression)
-       {
-               return DataBinder.Eval (CurrentDataItem, expression);
-       }
-       
-       protected object Eval (string expression, string format)
-       {
-               return DataBinder.Eval (CurrentDataItem, expression, format);
-       }
-       
-       protected object XPath (string xpathexpression)
-       {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression);
-       }
-       
-       protected object XPath (string xpathexpression, string format)
-       {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
-       }
-       
-       protected IEnumerable XPathSelect (string xpathexpression)
-       {
-               return XPathBinder.Select (CurrentDataItem, xpathexpression);
-       }
-       
     [BrowsableAttribute (false)]
     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        public Page PreviousPage {
index ac3e868c837d7ce1325690aa20edc72d90176aa1..4c3d1a39998c62152aa487ffe0b59d0192d834ab 100644 (file)
@@ -78,6 +78,8 @@ namespace System.Web.UI {
                #region IStateManager
                void IStateManager.LoadViewState (object savedState)
                {
+                       if (savedState == null) return;
+
                        int pos = -1;
                        foreach (Pair p in (ArrayList)savedState) {
                                pos ++;
@@ -108,6 +110,7 @@ namespace System.Web.UI {
                {
                        ArrayList saved = new ArrayList ();
                        Type [] knownTypes = GetKnownTypes ();
+                       bool allNull = true;
                        
                        foreach (IStateManager itm in items) {
                                object state = itm.SaveViewState ();
@@ -130,9 +133,11 @@ namespace System.Web.UI {
                                        p.Second = t;
                                
                                saved.Add (p);
+                               allNull = false;
                        }
                        
-                       return saved;
+                       if (allNull) return null;
+                       else return saved;
                }
                
                void IStateManager.TrackViewState ()
index 1014c3792f96f4d7a0780ff7e9782405866a421d..dea7aba2d1bb0a25a8895c0c55bfa481abeef5db 100755 (executable)
@@ -260,5 +260,60 @@ namespace System.Web.UI {
                        }
                }
 
+#if NET_2_0
+
+       Stack dataItemCtx;
+       
+       internal void PushDataItemContext (object o)
+       {
+               if (dataItemCtx == null)
+                       dataItemCtx = new Stack ();
+               
+               dataItemCtx.Push (o);
+       }
+       
+       internal void PopDataItemContext ()
+       {
+               if (dataItemCtx == null)
+                       throw new InvalidOperationException ();
+               
+               dataItemCtx.Pop ();
+       }
+       
+       internal object CurrentDataItem {
+               get {
+                       if (dataItemCtx == null)
+                               throw new InvalidOperationException ("No data item");
+                       
+                       return dataItemCtx.Peek ();
+               }
+       }
+       
+       protected object Eval (string expression)
+       {
+               return DataBinder.Eval (CurrentDataItem, expression);
+       }
+       
+       protected object Eval (string expression, string format)
+       {
+               return DataBinder.Eval (CurrentDataItem, expression, format);
+       }
+       
+       protected object XPath (string xpathexpression)
+       {
+               return XPathBinder.Eval (CurrentDataItem, xpathexpression);
+       }
+       
+       protected object XPath (string xpathexpression, string format)
+       {
+               return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
+       }
+       
+       protected IEnumerable XPathSelect (string xpathexpression)
+       {
+               return XPathBinder.Select (CurrentDataItem, xpathexpression);
+       }
+#endif
+
        }
 }
index 820cb6da031a6ef68ca2af600d11a34f35602d3d..266979895b91ba3873f5c11a9f5c5fb58581ffd1 100755 (executable)
@@ -468,6 +468,8 @@ System.Web.UI.WebControls/ObjectDataSourceDisposingEventArgs.cs
 System.Web.UI.WebControls/ObjectDataSourceDisposingEventHandler.cs
 System.Web.UI.WebControls/ObjectDataSourceEventArgs.cs
 System.Web.UI.WebControls/ObjectDataSourceEventHandler.cs
+System.Web.UI.WebControls/ObjectDataSourceFilteringEventArgs.cs
+System.Web.UI.WebControls/ObjectDataSourceFilteringEventHandler.cs
 System.Web.UI.WebControls/ObjectDataSourceMethodEventArgs.cs
 System.Web.UI.WebControls/ObjectDataSourceMethodEventHandler.cs
 System.Web.UI.WebControls/ObjectDataSourceSelectingEventArgs.cs
index 2a471f391461a4d837c7c7bacfc38d15fa9e46e4..e613a6aa11e7f67f37e366679d59a30eac917fd3 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-07  Andrew Skiba  <andrews@mainsoft.com>
+
+       * XslDecimalFormat.jvm.cs : added
 2005-03-31  Atsushi Enomoto  <atsushi@ximian.com>
 
        * MSXslScriptManager.cs : added TARGET_JVM switch (that does not
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XslDecimalFormat.jvm.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XslDecimalFormat.jvm.cs
new file mode 100644 (file)
index 0000000..5266bb3
--- /dev/null
@@ -0,0 +1,149 @@
+//
+// XslDecimalFormat.jvm.cs
+//
+// Authors:
+//     Andrew Skiba <andrews@mainsoft.com>
+//     
+// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+using QName = System.Xml.XmlQualifiedName;
+
+namespace Mono.Xml.Xsl {
+       internal class XslDecimalFormat {
+               
+               java.text.DecimalFormatSymbols javaFormat;
+               string baseUri;
+               int lineNumber;
+               int linePosition;
+
+               public static readonly XslDecimalFormat Default = new XslDecimalFormat ();
+               
+               XslDecimalFormat ()
+               {
+                       javaFormat = new java.text.DecimalFormatSymbols ();
+               }
+
+               public XslDecimalFormat (Compiler c)
+                       :this ()
+               {
+                       Initialize(c); 
+               }
+
+               private void Initialize(Compiler c)
+               {
+                       XPathNavigator n = c.Input;
+
+                       IXmlLineInfo li = n as IXmlLineInfo;
+                       if (li != null) {
+                               lineNumber = li.LineNumber;
+                               linePosition = li.LinePosition;
+                       }
+                       baseUri = n.BaseURI;
+
+                       if (n.MoveToFirstAttribute ()) {
+                               do {
+                                       if (n.NamespaceURI != String.Empty)
+                                               continue;
+                                       
+                                       switch (n.LocalName) {
+                                       case "name": break; // already handled
+                                       case "decimal-separator":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT decimal-separator value must be exact one character.", null, n);
+                                               javaFormat.setDecimalSeparator (n.Value[0]);
+                                               break;
+                                               
+                                       case "grouping-separator":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT grouping-separator value must be exact one character.", null, n);
+                                               javaFormat.setGroupingSeparator (n.Value[0]);
+                                               break;
+                                               
+                                       case "infinity":
+                                               javaFormat.setInfinity (n.Value);
+                                               break;
+                                       case "minus-sign":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT minus-sign value must be exact one character.", null, n);
+                                               javaFormat.setMinusSign (n.Value[0]);
+                                               break;
+                                       case "NaN":
+                                               javaFormat.setNaN (n.Value);
+                                               break;
+                                       case "percent":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT percent value must be exact one character.", null, n);
+                                               javaFormat.setPercent (n.Value[0]);
+                                               break;
+                                       case "per-mille":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT per-mille value must be exact one character.", null, n);
+                                               javaFormat.setPerMill (n.Value[0]);
+                                               break;
+                                       case "digit":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT digit value must be exact one character.", null, n);
+                                               javaFormat.setDigit (n.Value[0]);
+                                               break;
+                                       case "zero-digit":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT zero-digit value must be exact one character.", null, n);
+                                               javaFormat.setZeroDigit (n.Value [0]);
+                                               break;
+                                       case "pattern-separator":
+                                               if (n.Value.Length != 1)
+                                                       throw new XsltCompileException ("XSLT pattern-separator value must be exact one character.", null, n);
+                                               javaFormat.setPatternSeparator (n.Value [0]);
+                                               break;
+                                       }
+                               } while (n.MoveToNextAttribute ());
+                               n.MoveToParent ();
+                       }
+               }
+
+               public void CheckSameAs (XslDecimalFormat other)
+               {
+                       if (! this.javaFormat.equals (other.javaFormat))
+                               throw new XsltCompileException (null, other.baseUri, other.lineNumber, other.linePosition);
+               }
+
+               public string FormatNumber (double number, string pattern)
+               {
+                       java.text.DecimalFormat frm = new java.text.DecimalFormat("", javaFormat);
+
+                       frm.applyLocalizedPattern (pattern);
+                       java.lang.StringBuffer buffer= new java.lang.StringBuffer ();
+                       java.text.FieldPosition fld = new java.text.FieldPosition (0);
+
+                       frm.format (number, buffer, fld);
+                       return buffer.ToString();
+               }
+       }
+}
index 2ce8c966ea2e24bb58d554a2d83ff0ed3166b060..61af2b30d00ecd9a1fe4e7fa2394540464e86332 100755 (executable)
@@ -1,3 +1,8 @@
+2004-04-03  Andrew Skiba  <andrews@mainsoft.com>
+
+       * XmlSerializer.cs: added TARGET_JVM that does not support on-the-fly
+       code generation.
+
 2005-03-30  Lluis Sanchez Gual  <lluis@novell.com>
 
        * SerializationCodeGenerator.cs: 
index 91ad4498489410488210e83004d046112d57afd5..e9d3e1418cc8a81bc38220da964e1cfb3809956a 100644 (file)
@@ -37,9 +37,11 @@ using System.Reflection;
 using System.Xml;
 using System.Xml.Schema;
 using System.Text;
+#if !TARGET_JVM
 using System.CodeDom;
 using System.CodeDom.Compiler;
 using Microsoft.CSharp;
+#endif
 using System.Configuration;
 using System.Security.Policy;
 
@@ -99,18 +101,14 @@ namespace System.Xml.Serialization
                
                static XmlSerializer ()
                {
-                       string db = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_DEBUG");
-                       deleteTempFiles = (db == null || db == "no");
-                       
-                       IDictionary table = (IDictionary) ConfigurationSettings.GetConfig("system.diagnostics");
-                       if (table != null) {
-                               table = (IDictionary) table["switches"];
-                               if (table != null) {
-                                       string val = (string) table ["XmlSerialization.Compilation"];
-                                       if (val == "1") deleteTempFiles = false;
-                               }
-                       }
                        
+#if !TARGET_JVM
+                       string db = null;
+                       string th = null;
+                       generationThreshold = -1;
+                       backgroundGeneration = false;
+#else
+                       string db = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_DEBUG");
                        string th = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_THS");
                        
                        if (th == null) {
@@ -124,6 +122,19 @@ namespace System.Xml.Serialization
                                backgroundGeneration = (generationThreshold != 0);
                                if (generationThreshold < 1) generationThreshold = 1;
                        }
+#endif
+                       deleteTempFiles = (db == null || db == "no");
+                       
+                       IDictionary table = (IDictionary) ConfigurationSettings.GetConfig("system.diagnostics");
+                       if (table != null) 
+                       {
+                               table = (IDictionary) table["switches"];
+                               if (table != null) 
+                               {
+                                       string val = (string) table ["XmlSerialization.Compilation"];
+                                       if (val == "1") deleteTempFiles = false;
+                               }
+                       }
                }
 
 #region Constructors
@@ -561,6 +572,20 @@ namespace System.Xml.Serialization
                        return new XmlSerializationReaderInterpreter (typeMapping);
                }
                
+#if TARGET_JVM
+               void CheckGeneratedTypes (XmlMapping typeMapping)
+               {
+                       throw new NotImplementedException();
+               }
+               void GenerateSerializersAsync (GenerationBatch batch)
+               {
+                       throw new NotImplementedException();
+               }
+               void RunSerializerGeneration (object obj)
+               {
+                       throw new NotImplementedException();
+               }
+#else
                void CheckGeneratedTypes (XmlMapping typeMapping)
                {
                        lock (this)
@@ -715,6 +740,7 @@ namespace System.Xml.Serialization
                                
                        return res.CompiledAssembly;
                }
+#endif
                
 #if NET_2_0
                GenerationBatch LoadFromSatelliteAssembly (GenerationBatch batch)
index 94b721c005e73930c6210b3927ee1f582ab96c89..49f4f2f21fdbf268b28437958d243193d272ec6d 100644 (file)
@@ -1,3 +1,13 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Socket.cs: added SocketOperation enum and 2 new fields to
+       SocketAsyncResult that are used by the runtime. Asynchronous read/write
+       are serialized so that only 1 of each kind is really 'active'.
+       Handle non-blocking connects in BeginConnect instead of doing 2 Poll()
+       in the threadpool.
+
+       * NetworkStream.cs: better message for the exception.
+
 2005-04-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * Socket.cs: remove unused async IO code.
index 178589f3cca0f383e25d35f68bd7f70ac0544331..0d02bc89f983e9563efe96c93d218d29595cb472 100644 (file)
@@ -64,7 +64,7 @@ namespace System.Net.Sockets
                        if (socket.SocketType != SocketType.Stream)
                                throw new ArgumentException ("Socket is not of type Stream", "socket");
                        if (!socket.Blocking)
-                               throw new IOException ();
+                               throw new IOException ("Operation not allowed on a non-blocking socket.");
                        
                        this.socket = socket;
                        this.owns_socket = owns_socket;
index 433716848c7a1beb489c1f580dbf9964da318164..79b451c5914fe38eb74b5cdb6f55a39a97307e6a 100644 (file)
@@ -44,6 +44,15 @@ namespace System.Net.Sockets
 {
        public class Socket : IDisposable 
        {
+               enum SocketOperation {
+                       Accept,
+                       Connect,
+                       Receive,
+                       ReceiveFrom,
+                       Send,
+                       SendTo
+               }
+
                [StructLayout (LayoutKind.Sequential)]
                private sealed class SocketAsyncResult: IAsyncResult 
                {
@@ -70,28 +79,19 @@ namespace System.Net.Sockets
                        bool completed;
                        AsyncCallback real_callback;
                        int error;
+                       SocketOperation operation;
+                       object ares;
 
-                       public SocketAsyncResult (Socket sock, object state, AsyncCallback callback)
+                       public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
                        {
                                this.Sock = sock;
                                this.handle = sock.socket;
                                this.state = state;
                                this.real_callback = callback;
+                               this.operation = operation;
                                SockFlags = SocketFlags.None;
                        }
 
-                       public void CreateAsyncDelegate ()
-                       {
-                               if (real_callback != null)
-                                       this.callback = new AsyncCallback (FakeCB);
-                       }
-
-                       static void FakeCB (IAsyncResult result)
-                       {
-                               SocketAsyncResult ares = (SocketAsyncResult) result;
-                               ares.real_callback.BeginInvoke (ares, null, null);
-                       }
-
                        public void CheckIfThrowDelayedException ()
                        {
                                if (delayedException != null)
@@ -106,6 +106,52 @@ namespace System.Net.Sockets
                                IsCompleted = true;
                                if (real_callback != null)
                                        real_callback (this);
+
+                               Queue queue = null;
+                               if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
+                                       queue = Sock.readQ;
+                               } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
+                                       queue = Sock.writeQ;
+                               }
+
+                               if (queue == null)
+                                       return;
+
+                               SocketAsyncCall sac = null;
+                               SocketAsyncResult req = null;
+                               lock (queue) {
+                                       queue.Dequeue (); // remove ourselves
+                                       if (queue.Count > 0) {
+                                               req = (SocketAsyncResult) queue.Peek ();
+                                               Worker worker = new Worker (req);
+                                               sac = GetDelegate (worker, req.operation);
+                                       }
+                               }
+
+                               if (sac != null)
+                                       sac.BeginInvoke (null, req);
+                       }
+
+                       SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
+                       {
+                               switch (op) {
+                               case SocketOperation.Receive:
+                                       return new SocketAsyncCall (worker.Receive);
+                               case SocketOperation.ReceiveFrom:
+                                       return new SocketAsyncCall (worker.ReceiveFrom);
+                               case SocketOperation.Send:
+                                       return new SocketAsyncCall (worker.Send);
+                               case SocketOperation.SendTo:
+                                       return new SocketAsyncCall (worker.SendTo);
+                               default:
+                                       return null; // never happens
+                               }
+                       }
+
+                       public void Complete (bool synch)
+                       {
+                               completed_sync = synch;
+                               Complete ();
                        }
 
                        public void Complete (int total)
@@ -113,7 +159,14 @@ namespace System.Net.Sockets
                                this.total = total;
                                Complete ();
                        }
-                       
+
+                       public void Complete (Exception e, bool synch)
+                       {
+                               completed_sync = synch;
+                               delayedException = e;
+                               Complete ();
+                       }
+
                        public void Complete (Exception e)
                        {
                                delayedException = e;
@@ -193,9 +246,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        Socket acc_socket = null;
                                        try {
-                                               if (!result.Sock.blocking)
-                                                       result.Sock.Poll (-1, SelectMode.SelectRead);
-
                                                acc_socket = result.Sock.Accept ();
                                        } catch (Exception e) {
                                                result.Complete (e);
@@ -211,19 +261,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        try {
                                                result.Sock.Connect (result.EndPoint);
-                                       } catch (SocketException se) {
-                                               if (result.Sock.blocking || se.ErrorCode != 10036) {
-                                                       result.Complete (se);
-                                                       return;
-                                               }
-                                               
-                                               try {
-                                                       result.Sock.Poll (-1, SelectMode.SelectWrite);
-                                                       result.Sock.Connect (result.EndPoint);
-                                               } catch (Exception k) {
-                                                       result.Complete (k);
-                                                       return;
-                                               }
                                        } catch (Exception e) {
                                                result.Complete (e);
                                                return;
@@ -238,9 +275,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        int total = 0;
                                        try {
-                                               if (!result.Sock.blocking)
-                                                       result.Sock.Poll (-1, SelectMode.SelectRead);
-
                                                total = result.Sock.Receive_nochecks (result.Buffer,
                                                                             result.Offset,
                                                                             result.Size,
@@ -259,9 +293,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        int total = 0;
                                        try {
-                                               if (!result.Sock.blocking)
-                                                       result.Sock.Poll (-1, SelectMode.SelectRead);
-
                                                total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
                                                                                 result.Offset,
                                                                                 result.Size,
@@ -281,9 +312,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        int total = 0;
                                        try {
-                                               if (!result.Sock.blocking)
-                                                       result.Sock.Poll (-1, SelectMode.SelectWrite);
-
                                                total = result.Sock.Send_nochecks (result.Buffer,
                                                                          result.Offset,
                                                                          result.Size,
@@ -301,9 +329,6 @@ namespace System.Net.Sockets
                                lock (result) {
                                        int total = 0;
                                        try {
-                                               if (!result.Sock.blocking)
-                                                       result.Sock.Poll (-1, SelectMode.SelectWrite);
-
                                                total = result.Sock.SendTo_nochecks (result.Buffer,
                                                                            result.Offset,
                                                                            result.Size,
@@ -327,6 +352,8 @@ namespace System.Net.Sockets
                internal bool blocking=true;
                private int pendingEnds;
                private int closeDelayed;
+               private Queue readQ = new Queue (2);
+               private Queue writeQ = new Queue (2);
 
                delegate void SocketAsyncCall ();
                /*
@@ -752,10 +779,10 @@ namespace System.Net.Sockets
                                throw new ObjectDisposedException (GetType ().ToString ());
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
+                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
                        Worker worker = new Worker (req);
                        SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
-                       sac.BeginInvoke (null, null);
+                       sac.BeginInvoke (null, req);
                        return(req);
                }
 
@@ -770,11 +797,28 @@ namespace System.Net.Sockets
                                throw new ArgumentNullException ("end_point");
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
+                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
                        req.EndPoint = end_point;
-                       Worker worker = new Worker (req);
-                       SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
-                       sac.BeginInvoke (null, null);
+                       int error = 0;
+                       if (!blocking) {
+                               SocketAddress serial = end_point.Serialize ();
+                               Connect_internal (socket, serial, out error);
+                               if (error == 0) {
+                                       // succeeded synch
+                                       req.Complete (true);
+                               } else if (error != 10036 && error != 10035) {
+                                       // error synch
+                                       req.Complete (new SocketException (error), true);
+                               }
+                       }
+
+                       if (blocking || error == 10036 || error == 10035) {
+                               // continue asynch
+                               Worker worker = new Worker (req);
+                               SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
+                               sac.BeginInvoke (null, req);
+                       }
+
                        return(req);
                }
 
@@ -797,14 +841,20 @@ namespace System.Net.Sockets
                                throw new ArgumentOutOfRangeException ("size");
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
-                       req.Buffer = buffer;
-                       req.Offset = offset;
-                       req.Size = size;
-                       req.SockFlags = socket_flags;
-                       Worker worker = new Worker (req);
-                       SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
-                       sac.BeginInvoke (null, null);
+                       SocketAsyncResult req;
+                       lock (readQ) {
+                               req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
+                               req.Buffer = buffer;
+                               req.Offset = offset;
+                               req.Size = size;
+                               req.SockFlags = socket_flags;
+                               readQ.Enqueue (req);
+                               if (readQ.Count == 1) {
+                                       Worker worker = new Worker (req);
+                                       SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
+                                       sac.BeginInvoke (null, req);
+                               }
+                       }
 
                        return req;
                }
@@ -831,15 +881,21 @@ namespace System.Net.Sockets
                                throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
-                       req.Buffer = buffer;
-                       req.Offset = offset;
-                       req.Size = size;
-                       req.SockFlags = socket_flags;
-                       req.EndPoint = remote_end;
-                       Worker worker = new Worker (req);
-                       SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
-                       sac.BeginInvoke (null, null);
+                       SocketAsyncResult req;
+                       lock (readQ) {
+                               req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
+                               req.Buffer = buffer;
+                               req.Offset = offset;
+                               req.Size = size;
+                               req.SockFlags = socket_flags;
+                               req.EndPoint = remote_end;
+                               readQ.Enqueue (req);
+                               if (readQ.Count == 1) {
+                                       Worker worker = new Worker (req);
+                                       SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
+                                       sac.BeginInvoke (null, req);
+                               }
+                       }
                        return req;
                }
 
@@ -862,14 +918,20 @@ namespace System.Net.Sockets
                                throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
-                       req.Buffer = buffer;
-                       req.Offset = offset;
-                       req.Size = size;
-                       req.SockFlags = socket_flags;
-                       Worker worker = new Worker (req);
-                       SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
-                       sac.BeginInvoke (null, null);
+                       SocketAsyncResult req;
+                       lock (writeQ) {
+                               req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
+                               req.Buffer = buffer;
+                               req.Offset = offset;
+                               req.Size = size;
+                               req.SockFlags = socket_flags;
+                               writeQ.Enqueue (req);
+                               if (writeQ.Count == 1) {
+                                       Worker worker = new Worker (req);
+                                       SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
+                                       sac.BeginInvoke (null, req);
+                               }
+                       }
                        return req;
                }
 
@@ -895,15 +957,21 @@ namespace System.Net.Sockets
                                throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
 
                        Interlocked.Increment (ref pendingEnds);
-                       SocketAsyncResult req = new SocketAsyncResult (this, state, callback);
-                       req.Buffer = buffer;
-                       req.Offset = offset;
-                       req.Size = size;
-                       req.SockFlags = socket_flags;
-                       req.EndPoint = remote_end;
-                       Worker worker = new Worker(req);
-                       SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
-                       sac.BeginInvoke (null, null);
+                       SocketAsyncResult req;
+                       lock (writeQ) {
+                               req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
+                               req.Buffer = buffer;
+                               req.Offset = offset;
+                               req.Size = size;
+                               req.SockFlags = socket_flags;
+                               req.EndPoint = remote_end;
+                               writeQ.Enqueue (req);
+                               if (writeQ.Count == 1) {
+                                       Worker worker = new Worker (req);
+                                       SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
+                                       sac.BeginInvoke (null, req);
+                               }
+                       }
                        return req;
                }
 
@@ -958,8 +1026,9 @@ namespace System.Net.Sockets
                        
                        SocketAddress serial = remote_end.Serialize ();
                        Connect_internal(socket, serial, out error);
-                       if (error != 0)
+                       if (error != 0) {
                                throw new SocketException (error);
+                       }
                        
                        connected=true;
                }
@@ -1291,7 +1360,7 @@ namespace System.Net.Sockets
 
                                throw new SocketException (error);
                        }
-                       
+
                        connected = true;
 
                        return ret;
index c35f36adf0d5c83ab0a3cd4562daacef78d860aa..8869ad1ccb0a8231ec573cd94f4a1d2a69cdf22e 100644 (file)
@@ -1,3 +1,15 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * WebHeaderCollection.cs: added if-modified-since to the list of
+       restricted headers.
+
+       * ServicePoint.cs: use a field object when locking.
+
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * WebConnectionStream.cs: ForceCompletion actually calls NextRead. No
+       need to wait for a Close/ReadAll when we have no content.
+
 2005-04-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * NtlmClient.cs: fix typo in assembly name.
index 09a1f61d609651f631e8098aed23d72348f52825..9ffbf85d99ad303fba2bbc5025b48227304c233d 100644 (file)
@@ -53,6 +53,7 @@ namespace System.Net
                Hashtable groups;
                bool sendContinue = true;
                bool useConnect;
+               object locker = new object ();
 #if NET_1_1
                bool useNagle;
 #endif
@@ -98,7 +99,7 @@ namespace System.Net
 
                public int CurrentConnections {
                        get {
-                               lock (this) {
+                               lock (locker) {
                                        return currentConnections;
                                }
                        }
@@ -106,7 +107,7 @@ namespace System.Net
 
                public DateTime IdleSince {
                        get {
-                               lock (this) {
+                               lock (locker) {
                                        return idleSince;
                                }
                        }
@@ -241,7 +242,7 @@ namespace System.Net
                {
                        WebConnection cnc;
                        
-                       lock (this) {
+                       lock (locker) {
                                WebConnectionGroup cncGroup = GetConnectionGroup (groupName);
                                cnc = cncGroup.GetConnection ();
                        }
@@ -251,7 +252,7 @@ namespace System.Net
 
                internal void IncrementConnection ()
                {
-                       lock (this) {
+                       lock (locker) {
                                currentConnections++;
                                idleSince = DateTime.Now.AddMilliseconds (1000000);
                        }
@@ -259,7 +260,7 @@ namespace System.Net
 
                internal void DecrementConnection ()
                {
-                       lock (this) {
+                       lock (locker) {
                                currentConnections--;
                                if (currentConnections == 0)
                                        idleSince = DateTime.Now;
index 4d42e8c00b4256fb6d802806d6a0ddb37f58104b..295fd543c647015c37ff8eee633d4d32f9e819b3 100644 (file)
@@ -57,7 +57,6 @@ namespace System.Net
                byte [] headers;
                bool disposed;
                bool headersSent;
-               bool forceCompletion;
 
                public WebConnectionStream (WebConnection cnc)
                {
@@ -116,13 +115,14 @@ namespace System.Net
 
                internal void ForceCompletion ()
                {
-                       forceCompletion = true;
+                       nextReadCalled = true;
+                       cnc.NextRead ();
                }
                
                internal void CheckComplete ()
                {
                        bool nrc = nextReadCalled;
-                       if (forceCompletion || (!nrc && readBufferSize - readBufferOffset == contentLength)) {
+                       if (!nrc && readBufferSize - readBufferOffset == contentLength) {
                                nextReadCalled = true;
                                cnc.NextRead ();
                        }
index 62e78571f1ac919b214f223489d2acd71809069c..31679545c565af61139585c3052b8dad9fa55901 100644 (file)
@@ -64,6 +64,7 @@ namespace System.Net
                        restricted.Add ("date", true);\r
                        restricted.Add ("expect", true);\r
                        restricted.Add ("host", true);\r
+                       restricted.Add ("if-modified-since", true);\r
                        restricted.Add ("range", true);\r
                        restricted.Add ("referer", true);\r
                        restricted.Add ("transfer-encoding", true);\r
@@ -139,7 +140,7 @@ namespace System.Net
                        if (name == null)\r
                                throw new ArgumentNullException ("name");\r
                        if (internallyCreated && IsRestricted (name))\r
-                               throw new ArgumentException ("restricted header");\r
+                               throw new ArgumentException ("This header must be modified with the appropiate property.");
                        this.AddWithoutValidate (name, value);\r
                }\r
 \r
index 1c82c258d1f4549b6fcff933074e31c4539a0f20..1a836952c11cac238d395cb36219fef38dfe4e6e 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * FileStream.cs:
+       * MonoIO.cs: remove dead code related to async IO.
+
 2005-03-24  Sebastien Pouliot  <sebastien@ximian.com>
 
        * Directory.cs: Added a Demand for Read/Write when creating a new 
index c78102a913379af5ee6f6e31bfea428823fcb247..bc92a004b35ac2afee8f17cafd9eaa35b6b6b022 100644 (file)
@@ -82,6 +82,8 @@ namespace System.IO
                                this.canseek = true;
                        } else {
                                this.canseek = false;
+                               noBuffering = true;
+                               bufferSize = 0;
                        }
 
                        this.handle = handle;
@@ -90,9 +92,6 @@ namespace System.IO
                        this.async = isAsync;
                        this.anonymous = false;
 
-                       if (isAsync && MonoIO.SupportsAsync)
-                               ThreadPool.BindHandle (handle);
-
                        InitBuffer (bufferSize, noBuffering);
 
                        /* Can't set append mode */
@@ -198,8 +197,7 @@ namespace System.IO
 
                        MonoIOError error;
 
-                       bool openAsync = (isAsync && MonoIO.SupportsAsync);
-                       this.handle = MonoIO.Open (name, mode, access, share, openAsync, out error);
+                       this.handle = MonoIO.Open (name, mode, access, share, false, out error);
                        if (handle == MonoIO.InvalidHandle) {
                                // don't leak the path information for isolated storage
                                string fname = (anonymous) ? Path.GetFileName (name) : name;
@@ -215,8 +213,6 @@ namespace System.IO
                        if (MonoIO.GetFileType (handle, out error) == MonoFileType.Disk) {
                                this.canseek = true;
                                this.async = isAsync;
-                               if (openAsync)
-                                       ThreadPool.BindHandle (handle);
                        } else {
                                this.canseek = false;
                                this.async = false;
@@ -280,7 +276,7 @@ namespace System.IO
                                if (handle == MonoIO.InvalidHandle)
                                        throw new ObjectDisposedException ("Stream has been closed");
 
-                               if (!canseek)
+                               if (!CanSeek)
                                        throw new NotSupportedException ("The stream does not support seeking");
 
                                // Buffered data might change the length of the stream
@@ -480,28 +476,8 @@ namespace System.IO
                        if (!async)
                                return base.BeginRead (buffer, offset, count, cback, state);
 
-                       if (!MonoIO.SupportsAsync) {
-                               ReadDelegate r = new ReadDelegate (ReadInternal);
-                               return r.BeginInvoke (buffer, offset, count, cback, state);                     
-                       }
-
-                       FileStreamAsyncResult result = new FileStreamAsyncResult (cback, state);
-                       result.Count = count;
-                       result.OriginalCount = count;
-                       int buffered = ReadSegment (buffer, offset, count);
-                       if (buffered >= count) {
-                               result.SetComplete (null, buffered, true);
-                               return result;
-                       }
-                       
-                       result.Buffer = buffer;
-                       result.Offset = offset + buffered;
-                       result.Count -= buffered;
-                       
-                       KeepReference (result);
-                       MonoIO.BeginRead (handle, result);
-
-                       return result;
+                       ReadDelegate r = new ReadDelegate (ReadInternal);
+                       return r.BeginInvoke (buffer, offset, count, cback, state);                     
                }
                
                public override int EndRead (IAsyncResult async_result)
@@ -512,35 +488,15 @@ namespace System.IO
                        if (!async)
                                return base.EndRead (async_result);
 
-                       if (!MonoIO.SupportsAsync) {
-                               AsyncResult ares = async_result as AsyncResult;
-                               if (ares == null)
-                                       throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
-                               ReadDelegate r = ares.AsyncDelegate as ReadDelegate;
-                               if (r == null)
-                                       throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
-                               return r.EndInvoke (async_result);
-                       }
-
-                       FileStreamAsyncResult result = async_result as FileStreamAsyncResult;
-                       if (result == null || result.BytesRead == -1)
+                       AsyncResult ares = async_result as AsyncResult;
+                       if (ares == null)
                                throw new ArgumentException ("Invalid IAsyncResult", "async_result");
 
-                       RemoveReference (result);
-                       if (result.Done)
-                               throw new InvalidOperationException ("EndRead already called.");
-
-                       result.Done = true;
-                       if (!result.IsCompleted)
-                               result.AsyncWaitHandle.WaitOne ();
-
-                       if (result.Exception != null)
-                               throw result.Exception;
+                       ReadDelegate r = ares.AsyncDelegate as ReadDelegate;
+                       if (r == null)
+                               throw new ArgumentException ("Invalid IAsyncResult", "async_result");
 
-                       buf_start += result.BytesRead;
-                       return result.OriginalCount - result.Count + result.BytesRead;
+                       return r.EndInvoke (async_result);
                }
 
                public override void Write (byte[] src, int src_offset, int count)
@@ -648,24 +604,8 @@ namespace System.IO
                                bytes = buffer;
                        }
 
-                       if (!MonoIO.SupportsAsync) {
-                               WriteDelegate w = new WriteDelegate (WriteInternal);
-                               return w.BeginInvoke (buffer, offset, count, cback, state);                     
-                       }
-
-                       if (buffered >= count) {
-                               result.SetComplete (null, buffered, true);
-                               return result;
-                       }
-                       
-                       result.Buffer = buffer;
-                       result.Offset = offset;
-                       result.Count = count;
-                       
-                       KeepReference (result);
-                       MonoIO.BeginWrite (handle, result);
-
-                       return result;
+                       WriteDelegate w = new WriteDelegate (WriteInternal);
+                       return w.BeginInvoke (buffer, offset, count, cback, state);                     
                }
                
                public override void EndWrite (IAsyncResult async_result)
@@ -678,36 +618,16 @@ namespace System.IO
                                return;
                        }
 
-                       if (!MonoIO.SupportsAsync) {
-                               AsyncResult ares = async_result as AsyncResult;
-                               if (ares == null)
-                                       throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
-                               WriteDelegate w = ares.AsyncDelegate as WriteDelegate;
-                               if (w == null)
-                                       throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
-                               w.EndInvoke (async_result);
-                               return;
-                       }
-
-                       FileStreamAsyncResult result = async_result as FileStreamAsyncResult;
-                       if (result == null || result.BytesRead != -1)
+                       AsyncResult ares = async_result as AsyncResult;
+                       if (ares == null)
                                throw new ArgumentException ("Invalid IAsyncResult", "async_result");
 
-                       RemoveReference (result);
-                       if (result.Done)
-                               throw new InvalidOperationException ("EndWrite already called.");
-
-                       result.Done = true;
-                       if (!result.IsCompleted)
-                               result.AsyncWaitHandle.WaitOne ();
-
-                       if (result.Exception != null)
-                               throw result.Exception;
+                       WriteDelegate w = ares.AsyncDelegate as WriteDelegate;
+                       if (w == null)
+                               throw new ArgumentException ("Invalid IAsyncResult", "async_result");
 
-                       buf_start += result.Count;
-                       buf_offset = buf_length = 0;
+                       w.EndInvoke (async_result);
+                       return;
                }
 
                public override long Seek (long offset, SeekOrigin origin)
@@ -1061,30 +981,9 @@ namespace System.IO
                        buf_dirty = false;
                }
 
-               static void KeepReference (object o)
-               {
-                       lock (typeof (FileStream)) {
-                               if (asyncObjects == null)
-                                       asyncObjects = new Hashtable ();
-
-                               asyncObjects [o] = o;
-                       }
-               }
-               
-               static void RemoveReference (object o)
-               {
-                       lock (typeof (FileStream)) {
-                               if (asyncObjects == null)
-                                       return;
-
-                               asyncObjects.Remove (o);
-                       }
-               }
-
                // fields
 
                internal const int DefaultBufferSize = 8192;
-               private static Hashtable asyncObjects;
 
                private FileAccess access;
                private bool owner;
index 5f7994e9ce2f2db07749d495987443b24fdabaed..8c1b6e701b5d752d5d863d62563272ac991e3ebe 100644 (file)
@@ -1,4 +1,3 @@
-//
 // System.IO.MonoIO.cs: static interface to native filesystem.
 //
 // Author:
@@ -45,10 +44,7 @@ namespace System.IO
                public static readonly IntPtr
                        InvalidHandle = (IntPtr)(-1L);
 
-               public static readonly bool SupportsAsync = GetSupportsAsync ();
-
                // error methods
-
                public static Exception GetException (MonoIOError error)
                {
                        return GetException (String.Empty, error);
@@ -155,10 +151,6 @@ namespace System.IO
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static MonoFileType GetFileType (IntPtr handle, out MonoIOError error);
 
-               // aio_* methods
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern static bool GetSupportsAsync ();
-
                public static bool Exists (string path, out MonoIOError error)
                {
                        FileAttributes attrs = GetFileAttributes (path,
@@ -392,13 +384,6 @@ namespace System.IO
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static int GetTempPath(out string path);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static void BeginWrite (IntPtr handle,FileStreamAsyncResult ares);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static void BeginRead (IntPtr handle, FileStreamAsyncResult ares);
-
        }
 }
 
index 09f7b851a86fe7b32dbfd6b357b898b943eefa19..073c445d2f5a5075f494d7b309456ca64583aabc 100644 (file)
@@ -1,3 +1,12 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * ThreadPool.cs: BindHandle does nothing now.
+
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Thread.cs: clear the Unstarted bit before calling Start_internal.
+       Fixes bug #72738.
+
 2005-04-04  Ben Maurer  <bmaurer@ximian.com>
 
        * Thread.cs: Do argument checking for Current[UI]Culture to make
index cecf2cc31c2b6601dbb946b7650346d024032cc9..ae9998055688fcb3105924d08bd0d38dd66af783 100755 (executable)
@@ -658,14 +658,14 @@ namespace System.Threading
                                        throw new SystemException ("Thread creation failed");
                                }
 
-                               // Launch this thread
-                               Start_internal(system_thread_handle);
-
                                // Mark the thread state as Running
                                // (which is all bits
                                // cleared). Therefore just remove the
                                // Unstarted bit
                                clr_state(ThreadState.Unstarted);
+
+                               // Launch this thread
+                               Start_internal(system_thread_handle);
                        }
                }
 
index adb823f02c6855412b394d7d5c424bd8788f95cc..c0c8ad58738323040f2b7addaead479782cf6bc6 100755 (executable)
@@ -43,13 +43,9 @@ namespace System.Threading {
                        /* nothing to do */
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern bool BindHandleInternal (IntPtr osHandle);
-
-               [SecurityPermission (SecurityAction.Demand, UnmanagedCode=true)]
                public static bool BindHandle (IntPtr osHandle)
                {
-                       return BindHandleInternal (osHandle);
+                       return true;
                }
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
index b65612b51c086b2abd346f289381901a9911f6b6..b6b4b7e89872ad8c8952b30622b3a00f1346c917 100644 (file)
@@ -188,6 +188,36 @@ namespace MonoTests.System.Reflection
                        Assembly corlib2 = Assembly.LoadWithPartialName ("corlib_plattest");
                        Assert.IsTrue (corlib != null || corlib2 != null);
                }
+
+#if NET_2_0
+               [Test]
+               public void ReflectionOnlyLoad ()
+               {
+                       Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (AssemblyTest).Assembly.FullName);
+                       
+                       Assert.IsNotNull (assembly);
+                       Assert.IsTrue (assembly.ReflectionOnly);
+               }
+
+               [Test]
+               public void ReflectionOnlyLoadFrom ()
+               {
+                       string loc = typeof (AssemblyTest).Assembly.Location;
+                       string filename = Path.GetFileName (loc);
+                       Assembly assembly = Assembly.ReflectionOnlyLoadFrom (filename);
+
+                       Assert.IsNotNull (assembly);
+                       Assert.IsTrue (assembly.ReflectionOnly);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void CreateInstanceOnRefOnly ()
+               {
+                       Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (AssemblyTest).Assembly.FullName);
+                       assembly.CreateInstance ("MonoTests.System.Reflection.AssemblyTest");
+               }
+#endif
        }
 }
 
index 6c132e15758e5b3cbae60c1e738bb6fc30df82b8..309e6a0fed1c31c5f98492a8f723bdf42e7b28ee 100644 (file)
@@ -1,3 +1,14 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * FieldInfoTest.cs (RefOnlyFieldClass): Rename from RefOnlyClass.
+       * MethodInfoTest.cs (RefOnlyMethodClass): Rename from RefOnlyClass.
+
+2005-04-08  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * AssemblyTest.cs: Added tests for ReflectionOnly support.
+       * MethodInfoTest.cs: Added test for Reflection Only support.
+       * FieldInfoTest.cs: Added tests for ReflectionOnly support.
+       
 2005-04-04  Sebastien Pouliot  <sebastien@ximian.com>
 
        * AssemblyNameTest.cs: Added tests for Clone and serialization without
index 9ecb7f21afcd8e31051f451376845d9eff5882ff..1cb7a0201e9356e0818043bbb0f963056a646b7d 100644 (file)
@@ -95,6 +95,37 @@ public class FieldInfoTest : Assertion
                AssertEquals (typeof (Marshal1), Type.GetType (attr.MarshalType));
                */
        }
+
+       [Test]
+       [ExpectedException (typeof (InvalidOperationException))]
+       public void GetValueOnRefOnlyAssembly ()
+       {
+               Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (FieldInfoTest).Assembly.FullName);
+               Type t = assembly.GetType (typeof (RefOnlyFieldClass).FullName);
+               FieldInfo f = t.GetField ("RefOnlyField", BindingFlags.Static | BindingFlags.NonPublic);
+
+               f.GetValue (null);
+       }
+       
+       [Test]
+       [ExpectedException (typeof (InvalidOperationException))]
+       public void SetValueOnRefOnlyAssembly ()
+       {
+               Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (FieldInfoTest).Assembly.FullName);
+               Type t = assembly.GetType (typeof (RefOnlyFieldClass).FullName);
+               FieldInfo f = t.GetField ("RefOnlyField", BindingFlags.Static | BindingFlags.NonPublic);
+
+               f.SetValue (null, 8);
+       }
+       
 #endif
 }              
+#if NET_2_0
+// Helper class
+class RefOnlyFieldClass 
+{
+       // Helper property
+       static int RefOnlyField;
+}
+#endif
 }
index c6277f9b97373e405638a3bba9e7cd4399f15f41..4959abd8147bbdfb760b96f92d53da54c5673651 100644 (file)
@@ -153,7 +153,30 @@ namespace MonoTests.System.Reflection
                        else
                                AssertEquals (false, locals [1].IsPinned);
                }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void InvokeOnRefOnlyAssembly ()
+               {
+                       Assembly a = Assembly.ReflectionOnlyLoad (typeof (MethodInfoTest).Assembly.FullName);
+                       Type t = a.GetType (typeof (RefOnlyMethodClass).FullName);
+                       MethodInfo m = t.GetMethod ("RefOnlyMethod", BindingFlags.Static | BindingFlags.NonPublic);
+                       
+                       m.Invoke (null, new object [0]);
+               }
+
 #endif
        }
+       
+#if NET_2_0
+       // Helper class
+       class RefOnlyMethodClass 
+       {
+               // Helper static method
+               static void RefOnlyMethod ()
+               {
+               }
+       }
+#endif
 }
 
index f3b71c595a12777263b908190a961acc40a97524..96e60ee4ca4ffdebfe0ce80b62edbe3ef05ce589 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * cs0535-3.cs: New test from #58413.
+
 2005-04-05  Raja R Harinath  <rharinath@novell.com>
 
        * cs0208-5.cs, cs0208-6.cs: New tests from #62232.
diff --git a/mcs/errors/cs0422.cs b/mcs/errors/cs0422.cs
deleted file mode 100644 (file)
index 1c8fe1a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// cs0422.cs: 'C.Prop.get': abstract properties cannot have private accessors
-// Line: 7
-
-abstract class C {
-    protected abstract int Prop
-    {
-       private get;
-       set;
-    }
-}
-
diff --git a/mcs/errors/cs0442.cs b/mcs/errors/cs0442.cs
new file mode 100644 (file)
index 0000000..e6b10fd
--- /dev/null
@@ -0,0 +1,11 @@
+// cs0442.cs: 'C.Prop.get': abstract properties cannot have private accessors
+// Line: 7
+
+abstract class C {
+    protected abstract int Prop
+    {
+       private get;
+       set;
+    }
+}
+
diff --git a/mcs/errors/cs0535-3.cs b/mcs/errors/cs0535-3.cs
new file mode 100644 (file)
index 0000000..6b50e0b
--- /dev/null
@@ -0,0 +1,18 @@
+// cs0535.cs: 'Test' does not implement interface member 'X.Hola(ref string)'
+// Line: 9
+
+using System;
+interface X {
+       void Hola (ref string name);
+}
+
+class Test : X {
+       static void Main ()
+       {
+       }
+
+       public void Hola (out string name)
+       {
+               name = null;
+       }
+}
diff --git a/mcs/errors/cs0655-2.cs b/mcs/errors/cs0655-2.cs
new file mode 100644 (file)
index 0000000..10e4441
--- /dev/null
@@ -0,0 +1,14 @@
+// cs0655.cs: 'd' is not a valid named attribute argument because its type is not valid attribute type
+// Line: 11
+
+using System;
+
+class TestAttribute : Attribute
+{
+   public int[][] a;
+}
+
+[Test (a = null)]
+class C
+{
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0655.cs b/mcs/errors/cs0655.cs
new file mode 100644 (file)
index 0000000..49cd84e
--- /dev/null
@@ -0,0 +1,14 @@
+// cs0655.cs: 'd' is not a valid named attribute argument because its type is not valid attribute type
+// Line: 11
+
+using System;
+
+class TestAttribute : Attribute
+{
+   public decimal d;
+}
+
+[Test (d = 44444)]
+class C
+{
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1636.cs b/mcs/errors/cs1636.cs
new file mode 100644 (file)
index 0000000..853a31b
--- /dev/null
@@ -0,0 +1,11 @@
+// CS1636: __arglist is not allowed in parameter list of iterators
+// Line: 6
+
+class C
+{
+    public System.Collections.IEnumerator GetEnumerator (__arglist)
+    {
+        yield return 1;
+    }
+    
+}
diff --git a/mcs/errors/cs1637.cs b/mcs/errors/cs1637.cs
new file mode 100644 (file)
index 0000000..7e6237f
--- /dev/null
@@ -0,0 +1,12 @@
+// CS1637: Iterators cannot have unsafe parameters or yield types
+// Line: 6
+// Compiler options: /unsafe
+
+unsafe class C
+{
+    public System.Collections.IEnumerator GetEnumerator (int* p)
+    {
+        yield return 1;
+    }
+    
+}
diff --git a/mcs/errors/cs1674.cs b/mcs/errors/cs1674.cs
new file mode 100644 (file)
index 0000000..657397e
--- /dev/null
@@ -0,0 +1,12 @@
+// cs1674.cs: 'int': type used in a using statement must be implicitly convertible to 'System.IDisposable'
+// Line: 8
+
+class C
+{
+    void Method (int arg)
+    {
+       using (arg)
+       {
+       }
+    }
+}
\ No newline at end of file
index 1f6d8775c7abb8cda809004e083d3549e8f9c377..a9a4c0035f8fbb54413b9440ec28e6b119ef6de9 100644 (file)
@@ -28,6 +28,7 @@ cs0249.cs
 cs0266-2.cs
 cs0534-3.cs
 cs0534-4.cs
+cs0535-3.cs
 cs0576.cs
 cs0611-2.cs
 cs0611.cs
index 5c83b149352e7e6a5c9d2596d8cfc2642ab0c1e0..33260c9e0f91b9fb3cce990d5625b7ffe62727c9 100644 (file)
@@ -39,7 +39,7 @@ cs0269.cs
 cs0271.cs
 cs0272.cs
 cs0407.cs
-cs0422.cs
+cs0442.cs
 cs0428.cs
 cs0525-2.cs
 cs0525.cs
@@ -71,6 +71,8 @@ cs0647-13.cs
 cs0647-15.cs
 cs0650.cs
 cs0654.cs
+cs0655.cs
+cs0655-2.cs
 cs0681.cs
 cs0683.cs
 cs0686.cs
@@ -112,6 +114,8 @@ cs1629-2.cs
 cs1629.cs
 cs1633.cs
 cs1634.cs
+cs1636.cs
+cs1637.cs
 cs1638.cs
 cs1641.cs
 cs1642.cs
@@ -126,6 +130,7 @@ cs1666.cs
 cs1670.cs
 cs1671-2.cs
 cs1671.cs
+cs1674.cs
 cs1677-2.cs
 cs1677.cs
 cs1708.cs
index 8275cebbcb161304528011dad83b1966fcb29227..92c4dc0e1f2cbf61c9204dd1b9050f564cf4de32 100644 (file)
@@ -1,7 +1,7 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-[assembly: AssemblyVersion("1.1.3")]
+[assembly: AssemblyVersion("1.1.4")]
 [assembly: AssemblyTitle ("Mono C# Compiler")]
 [assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
 [assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
index e5cf73f5cea69b07b5584f6566722e5410ccb35c..a5500550b3b1ae022ef0d6ad53cc8c00daf340d0 100644 (file)
@@ -1,3 +1,154 @@
+2005-02-09  Raja R Harinath  <rharinath@novell.com>
+
+       Combine two near-redundant caches.
+       * typemanager.cs (method_params): Rename from method_internal_params.
+       (TypeManager.GetParameterData): New.  Replace
+       Invocation.GetParameterData.
+       (TypeManager.LookupParametersByBuilder): Remove.
+       * expression.cs (Invocation.method_parameter_cache): Remove.
+       (Invocation.GetParameterData): Remove.
+       Update to changes.
+       * anonymous.cs, attribute.cs, convert.cs, delegate.cs:
+       Update to changes.
+
+2005-02-08  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #72015.
+       * delegate.cs (Delegate.DefineType): When bootstrapping corlib, if
+       TypeManager.multicast_delegate_type is null, resolve it by looking
+       up "System.MulticastDelegate".
+       * rootcontext.cs (RootContext.ResolveCore): Simplify.
+
+2005-02-07  Abin Thomas (NOSIP)  <projectmonokochi@rediffmail.com>
+           Anoob V.E (NOSIP)  <projectmonokochi@rediffmail.com>
+           Harilal P.R (NOSIP)  <projectmonokochi@rediffmail.com>
+
+       Fix cs0164.cs.
+       * statement.cs (LabeledStatement.Resolve): Don't set 'referenced'.
+       (LabeledStatement.AddReference): New.  Set 'referenced'.
+       (Goto.Resolve): Use it.
+
+2005-02-05  John Luke  <john.luke@gmail.com>
+
+       * driver.cs: remove duplicate -doc line in Usage ()
+
+2005-02-04  Raja R Harinath  <rharinath@novell.com>
+
+       * location.cs (Location.AddFile): Fix CS2002 error report.
+
+2005-02-02  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs (Delegate.DefineType): Report an internal error if
+       TypeManager.multicast_delegate_type is null.  See bug #72015 for
+       details.        
+
+2005-02-02  Raja R Harinath  <rharinath@novell.com>
+
+       Fix a crasher in a variant of #31984.
+       * const.cs (Constant.CheckBase): New override that defers the
+       new-or-override check in case the base type hasn't been populated
+       yet.
+       (Constant.Define): Ensure the new-or-override check is performed.
+
+2005-02-01  Duncan Mak  <duncan@ximian.com>
+
+       * const.cs (LookupConstantValue): Check that `ce' is not null
+       before calling GetValue ().
+
+2005-02-01  Raja R Harinath  <rharinath@novell.com>
+
+       Fix test-334.cs (#69519).
+       * cs-parser.jay (using_alias_directive): Pass in an expression to
+       NamespaceEntry.UsingAlias.
+       (using_namespace_directive): Pass in an expression to
+       NamespaceEntry.Using.
+       (namespace_name): Don't flatten to a string.
+       * namespace.cs (NamespaceEntry.AliasEntry): Store an expression.
+       (NamespaceEntry.AliasEntry.Resolve): Lookup using
+       ResolveAsTypeStep.
+       (NamespaceEntry.UsingEntry): Likewise.
+       (NamespaceEntry.Using,NamespaceEntry.UsingAlias): Update to
+       changes.
+       (NamespaceEntry.LookupForUsing): Remove.
+       (NamespaceEntry.LookupNamespaceOrType): Add support for dotted
+       names.
+       (NamespaceEntry.Lookup): Remove support for dotted names.
+
+2005-02-01  Raja R Harinath  <rharinath@novell.com>
+
+       * namespace.cs (NamespaceEntry.NamespaceEntry): Simplify, and
+       split into two.
+       (NamespaceEntry.ImplicitParent): Compute on demand.
+       (NamespaceEntry.Doppelganger): New implicit namespace-entry that
+       parallels the current.
+       (NamespaceEntry.LookupForUsing): Use it.
+       (NamespaceEntry.Lookup): If the current namespace-entry is
+       implicit, don't search aliases and using tables.
+
+2005-02-01  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #31984.
+       * class.cs (TypeContainer.DoDefineMembers): Don't initialize
+       BaseCache here.
+       (TypeContainer.BaseCache): Compute on demand.
+       (TypeContainer.FindMembers): Define constants and types if they're
+       not already created.
+       (FieldMember.Define): Move resetting of ec.InUnsafe before error
+       check.
+       * const.cs (Constant.Define): Make idempotent.
+
+2005-01-29  Miguel de Icaza  <miguel@novell.com>
+
+       * pending.cs: Produce better code (no nops produced by using Ldarg
+       + value).
+       
+       * pending.cs (PendingImplementation.DefineProxy): It was not `arg
+       i - 1' it should be arg + 1.
+
+       Fixes bug #71819.
+
+2005-01-28  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType): Make private
+       non-virtual.
+       (Attribute.ResolveType): Make virtual.
+       (GlobalAttribute.ResolveType,GlobalAttribute.Resolve): Simplify
+       handling of RootContext.Tree.Types.
+
+2005-01-27  Raja R Harinath  <rharinath@novell.com>
+
+       Update attribute-handling to use the SimpleName/MemberAccess
+       mechanisms.
+       * cs-parser.jay (attribute): Pass in an expression to the
+       constructors of Attribute and GlobalAttribute.
+       * attribute.cs (Attribute): Take an expression for the name.
+       (Attribute.ResolvePossibleAttributeTypes): New.  Resolves the
+       passed in attribute name expression.
+       (Attribute.CheckAttributeType): Use it.
+       * ecore.cs (FullNamedExpression.ResolveAsTypeStep): New.
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Move body to ...
+       (MemberAccess.ResolveNamespaceOrType): ... here.  Add 'silent'
+       argument to prevent error messages if the lookup fails.
+
+2005-01-27  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Indirection): Implemented IVariable interface
+       to support indirection in AddressOf operator.
+       (PointerArithmetic.Emit): Add optimalization for case where
+       result can be precomputed.
+
+2005-01-26  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.AttributeTargets): Return the correct
+       AttributeTargets depending on our `Kind' instead of throwing an
+       exception; fixes #71632.
+
+2005-01-26  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix #71257
+       * expression.cs (MemberAccess.ResolveMemberAccess): Add CS0176 test for
+       constant members.
+
 2005-03-17  Martin Baulig  <martin@ximian.com>
 
        * anonymous.cs (AnonymousMethod.method_modifiers): Change default
index 2d2790f1096bda542a5c1cfe1b5f2e05e313ab60..d77e6d1b7926b2514570b863eb4933a4de4dad9e 100644 (file)
@@ -165,7 +165,7 @@ namespace Mono.CSharp {
 
                        MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (ec, delegate_type, loc);
                        invoke_mb = (MethodInfo) invoke_mg.Methods [0];
-                       ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
+                       ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
 
                        //
                        // If implicit parameters are set, then we must check for out in the parameters
index 30d6a61dcced525a185d747c6f7662f4d3588d41..3613cd4afaaf8fb6a6180476bdb097094109e423 100644 (file)
@@ -72,6 +72,9 @@ namespace Mono.CSharp {
                public AttributeTargets Target;
 
                public readonly string    Name;
+               public readonly Expression LeftExpr;
+               public readonly string Identifier;
+
                public readonly ArrayList Arguments;
 
                public readonly Location Location;
@@ -102,9 +105,11 @@ namespace Mono.CSharp {
 
                static PtrHashtable usage_attr_cache = new PtrHashtable ();
                
-               public Attribute (string target, string name, ArrayList args, Location loc)
+               public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
                {
-                       Name = name;
+                       LeftExpr = left_expr;
+                       Identifier = identifier;
+                       Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
                        Arguments = args;
                        Location = loc;
                        ExplicitTarget = target;
@@ -114,7 +119,7 @@ namespace Mono.CSharp {
                {
                        Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
                                      "fields which are not readonly, static or const;  or read-write instance properties.",
-                                     Name);
+                                     name);
                }
 
                static void Error_AttributeArgumentNotValid (string extra, Location loc)
@@ -155,26 +160,49 @@ namespace Mono.CSharp {
                                       "Could not find a constructor for this argument list.");
                }
 
+               void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2)
+               {
+                       t1 = null;
+                       t2 = null;
+
+                       FullNamedExpression n1 = null;
+                       FullNamedExpression n2 = null;
+                       string IdentifierAttribute = Identifier + "Attribute";
+                       if (LeftExpr == null) {
+                               n1 = new SimpleName (Identifier, Location).ResolveAsTypeStep (ec);
+
+                               // FIXME: Shouldn't do this for quoted attributes: [@A]
+                               n2 = new SimpleName (IdentifierAttribute, Location).ResolveAsTypeStep (ec);
+                       } else {
+                               FullNamedExpression l = LeftExpr.ResolveAsTypeStep (ec);
+                               if (l == null) {
+                                       Report.Error (246, Location, "Couldn't find namespace or type '{0}'", LeftExpr);
+                                       return;
+                               }
+                               n1 = new MemberAccess (l, Identifier, Location).ResolveNamespaceOrType (ec, true);
+
+                               // FIXME: Shouldn't do this for quoted attributes: [X.@A]
+                               n2 = new MemberAccess (l, IdentifierAttribute, Location).ResolveNamespaceOrType (ec, true);
+                       }
+
+                       TypeExpr te1 = n1 == null ? null : n1 as TypeExpr;
+                       TypeExpr te2 = n2 == null ? null : n2 as TypeExpr;                      
+
+                       if (te1 != null)
+                               t1 = te1.ResolveType (ec);
+                       if (te2 != null)
+                               t2 = te2.ResolveType (ec);
+               }
+
                /// <summary>
                 ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                 /// </summary>
-               protected virtual Type CheckAttributeType (EmitContext ec)
+               Type CheckAttributeType (EmitContext ec)
                {
-                       string NameAttribute = Name + "Attribute";
-                       FullNamedExpression n1 = ec.ResolvingTypeTree
-                               ? ec.DeclSpace.FindType (Location, Name)
-                               : ec.DeclSpace.LookupType (Name, true, Location);
+                       Type t1, t2;
+                       ResolvePossibleAttributeTypes (ec, out t1, out t2);
 
-                       // FIXME: Shouldn't do this for quoted attributes: [@A]
-                       FullNamedExpression n2 = ec.ResolvingTypeTree
-                               ? ec.DeclSpace.FindType (Location, NameAttribute)
-                               : ec.DeclSpace.LookupType (NameAttribute, true, Location);
-
-                       TypeExpr e1 = n1 == null ? null : n1 as TypeExpr;
-                       TypeExpr e2 = n2 == null ? null : n2 as TypeExpr;                       
-
-                       Type t1 = e1 == null ? null : e1.ResolveType (ec);
-                       Type t2 = e2 == null ? null : e2.ResolveType (ec);
+                       string NameAttribute = Name + "Attribute";
 
                        String err0616 = null;
                        if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
@@ -210,7 +238,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public Type ResolveType (EmitContext ec)
+               public virtual Type ResolveType (EmitContext ec)
                {
                        if (Type == null)
                                Type = CheckAttributeType (ec);
@@ -522,7 +550,7 @@ namespace Mono.CSharp {
                        // of type object
                        //
 
-                       ParameterData pd = Invocation.GetParameterData (constructor);
+                       ParameterData pd = TypeManager.GetParameterData (constructor);
 
                        int last_real_param = pd.Count;
                        if (pd.HasParams) {
@@ -1191,52 +1219,46 @@ namespace Mono.CSharp {
        {
                public readonly NamespaceEntry ns;
 
-               public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):
-                       base (target, name, args, loc)
+               public GlobalAttribute (TypeContainer container, string target, 
+                                       Expression left_expr, string identifier, ArrayList args, Location loc):
+                       base (target, left_expr, identifier, args, loc)
                {
                        ns = container.NamespaceEntry;
                }
 
-               protected override Type CheckAttributeType (EmitContext ec)
+               void Enter ()
                {
                        // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
                        // each time a new file is parsed.  However, we need to use the NamespaceEntry
                        // in effect where the attribute was used.  Since code elsewhere cannot assume
                        // that the NamespaceEntry is right, just overwrite it.
                        //
-                       // Precondition: RootContext.Tree.Types == null || RootContext.Tree.Types == ns.
-                       //               The second case happens when we are recursively invoked from inside Emit.
-
-                       NamespaceEntry old = null;
-                       if (ec.DeclSpace == RootContext.Tree.Types) {
-                               old = ec.DeclSpace.NamespaceEntry;
-                               ec.DeclSpace.NamespaceEntry = ns;
-                               if (old != null && old != ns)
-                                       throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
-                       }
+                       // Precondition: RootContext.Tree.Types == null
 
-                       Type retval = base.CheckAttributeType (ec);
+                       if (RootContext.Tree.Types.NamespaceEntry != null)
+                               throw new InternalErrorException (Location + " non-null NamespaceEntry");
 
-                       if (ec.DeclSpace == RootContext.Tree.Types)
-                               ec.DeclSpace.NamespaceEntry = old;
+                       RootContext.Tree.Types.NamespaceEntry = ns;
+               }
 
+               void Leave ()
+               {
+                       RootContext.Tree.Types.NamespaceEntry = null;
+               }
+
+               public override Type ResolveType (EmitContext ec)
+               {
+                       Enter ();
+                       Type retval = base.ResolveType (ec);
+                       Leave ();
                        return retval;
                }
 
                public override CustomAttributeBuilder Resolve (EmitContext ec)
                {
-                       if (ec.DeclSpace == RootContext.Tree.Types) {
-                               NamespaceEntry old = ec.DeclSpace.NamespaceEntry;
-                               ec.DeclSpace.NamespaceEntry = ns;
-                               if (old != null)
-                                       throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
-                       }
-
+                       Enter ();
                        CustomAttributeBuilder retval = base.Resolve (ec);
-
-                       if (ec.DeclSpace == RootContext.Tree.Types)
-                               ec.DeclSpace.NamespaceEntry = null;
-
+                       Leave ();
                        return retval;
                }
        }
index c1add900dd8c2dbce7cba2276307f702e2407c6d..62b39abcef232960177d329712a9c8c93d7a547f 100644 (file)
@@ -1470,15 +1470,6 @@ namespace Mono.CSharp {
 
                protected virtual bool DoDefineMembers ()
                {
-                       //
-                       // We need to be able to use the member cache while we are checking/defining
-                       //
-                       if (TypeBuilder.BaseType != null)
-                               base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
-
-                       if (TypeBuilder.IsInterface)
-                               base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
-
                        if (IsTopLevel) {
                                if ((ModFlags & Modifiers.NEW) != 0)
                                        Error_KeywordNotAllowed (Location);
@@ -1799,6 +1790,10 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                FieldBuilder fb = con.FieldBuilder;
+                                               if (fb == null) {
+                                                       if (con.Define ())
+                                                               fb = con.FieldBuilder;
+                                               }
                                                if (fb != null && filter (fb, criteria) == true) {
                                                        if (members == null)
                                                                members = new ArrayList ();
@@ -1986,6 +1981,9 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                TypeBuilder tb = t.TypeBuilder;
+                                               if (tb == null)
+                                                       tb = t.DefineType ();
+
                                                if (tb != null && (filter (tb, criteria) == true)) {
                                                        if (members == null)
                                                                members = new ArrayList ();
@@ -2588,6 +2586,12 @@ namespace Mono.CSharp {
 
                public virtual MemberCache BaseCache {
                        get {
+                               if (base_cache != null)
+                                       return base_cache;
+                               if (TypeBuilder.BaseType != null)
+                                       base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
+                               if (TypeBuilder.IsInterface)
+                                       base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
                                return base_cache;
                        }
                }
@@ -3554,7 +3558,7 @@ namespace Mono.CSharp {
 
                protected override bool CheckGenericOverride (MethodInfo method, string name)
                {
-                       ParameterData pd = Invocation.GetParameterData (method);
+                       ParameterData pd = TypeManager.GetParameterData (method);
 
                        for (int i = 0; i < ParameterTypes.Length; i++) {
                                GenericConstraints ogc = pd.GenericConstraints (i);
@@ -5661,9 +5665,9 @@ namespace Mono.CSharp {
                        }
 
                        if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
-                               Report.SymbolRelatedToPreviousError (conflict_symbol);
-                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
-                       }
+                               Report.SymbolRelatedToPreviousError (conflict_symbol);
+                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+                       }
 
                        return true;
                }
@@ -5762,13 +5766,13 @@ namespace Mono.CSharp {
                        
                        MemberType = texpr.Type;
 
+                       ec.InUnsafe = old_unsafe;
+
                        if (MemberType == TypeManager.void_type) {
                                Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
                                return false;
                        }
 
-                       ec.InUnsafe = old_unsafe;
-
                        if (!CheckBase ())
                                return false;
                        
index 1c15f85ecaa87a95376b2a3753923b132a7a94c5..956ed4fb9da83369ad8be260c165ebcd3ab10bf0 100644 (file)
@@ -62,11 +62,25 @@ namespace Mono.CSharp {
                }
 #endif
 
+               protected override bool CheckBase ()
+               {
+                       // Constant.Define can be called when the parent type hasn't yet been populated
+                       // and it's base types need not have been populated.  So, we defer this check
+                       // to the second time Define () is called on this member.
+                       if (Parent.BaseCache == null)
+                               return true;
+                       return base.CheckBase ();
+               }
+
                /// <summary>
                ///   Defines the constant in the @parent
                /// </summary>
                public override bool Define ()
                {
+                       // Make Define () idempotent, but ensure that the error check happens.
+                       if (FieldBuilder != null)
+                               return base.CheckBase ();
+
                        if (!base.Define ())
                                return false;
 
@@ -248,7 +262,9 @@ namespace Mono.CSharp {
                                }
                                Expr = ce;
                        }
-                       ConstantValue = ce.GetValue ();
+
+                       if (ce != null)
+                               ConstantValue = ce.GetValue ();
 
                        if (MemberType.IsEnum){
                                //
index ed60169616d0826541ec12ee9212e07605a8f188..0e6c2ef098b04e9ee2873ab8342b0f2391a5570e 100644 (file)
@@ -896,7 +896,7 @@ namespace Mono.CSharp {
                        //
                        Type source_type = source.Type;
                        foreach (MethodBase mb in me.Methods){
-                               ParameterData pd = Invocation.GetParameterData (mb);
+                               ParameterData pd = TypeManager.GetParameterData (mb);
                                Type param_type = pd.ParameterType (0);
 
                                if (param_type == source_type)
@@ -1158,7 +1158,7 @@ namespace Mono.CSharp {
 
                        
                        foreach (MethodBase mb in union.Methods){
-                               ParameterData pd = Invocation.GetParameterData (mb);
+                               ParameterData pd = TypeManager.GetParameterData (mb);
                                MethodInfo mi = (MethodInfo) mb;
                                
                                if (pd.ParameterType (0) == most_specific_source &&
index 99aad5441001bd25e6e6374e4339e1bb151453ce..811ba6f3486fe314f0d403569bce459e578d1f64 100644 (file)
@@ -338,7 +338,8 @@ using_alias_directive
        : USING IDENTIFIER ASSIGN 
          namespace_or_type_name SEMICOLON
          {
-               current_namespace.UsingAlias ((string) $2, (MemberName) $4, lexer.Location);
+               MemberName name = (MemberName) $4;
+               current_namespace.UsingAlias ((string) $2, name.GetTypeExpression (lexer.Location), lexer.Location);
          }
        | USING error {
                CheckIdentifierToken (yyToken);
@@ -348,7 +349,8 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2, lexer.Location);
+               MemberName ns_name = (MemberName) $2;
+               current_namespace.Using (ns_name.GetTypeExpression (lexer.Location), lexer.Location);
           }
        ;
 
@@ -401,7 +403,7 @@ namespace_name
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "namespace name expected");
 
-               $$ = name.GetName ();
+               $$ = name;
          }
        ;
 
@@ -622,19 +624,23 @@ attribute
          }
          opt_attribute_arguments
          {
+               Location loc = (Location) $2;
                MemberName mname = (MemberName) $1;
                if (mname.IsGeneric) {
                        Report.Error (404, lexer.Location,
                                      "'<' unexpected: attributes cannot be generic");
                }
 
-               string name = mname.GetName ();
+               MemberName left = mname.Left;
+               string identifier = mname.Name;
+
+               Expression left_expr = left == null ? null : left.GetTypeExpression (loc);
+
                if (current_attr_target == "assembly" || current_attr_target == "module")
                        $$ = new GlobalAttribute (current_container, current_attr_target,
-                                                 name, (ArrayList) $3, (Location) $2);
+                                                 left_expr, identifier, (ArrayList) $3, loc);
                else
-                       $$ = new Attribute (current_attr_target, name, (ArrayList) $3,
-                                           (Location) $2);
+                       $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc);
          }
        ;
 
index 70ea16b6a353c01903d4fdc3102d7e1c3e1d68db..533cd3d3f06939d16b8507461c70ce54a81e2bf3 100644 (file)
@@ -90,6 +90,11 @@ namespace Mono.CSharp {
                        TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel) |
                                TypeAttributes.Class | TypeAttributes.Sealed;
 
+                       if (TypeManager.multicast_delegate_type == null && !RootContext.StdLib) {
+                               TypeExpr expr = new TypeLookupExpression ("System.MulticastDelegate");
+                               TypeManager.multicast_delegate_type = expr.ResolveType (ec);
+                       }
+
                        if (TypeManager.multicast_delegate_type == null)
                                Report.Error (-100, Location, "Internal error: delegate used before " +
                                              "System.MulticastDelegate is resolved.  This can only " +
@@ -154,13 +159,15 @@ namespace Mono.CSharp {
                {
                        MethodAttributes mattr;
                        int i;
-                       ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
 
                        if (IsGeneric) {
                                foreach (TypeParameter type_param in TypeParameters)
                                        type_param.DefineType (ec);
                        }
 
+                       if (ec == null)
+                               throw new InternalErrorException ("Define called before DefineType?");
+
                        // FIXME: POSSIBLY make this static, as it is always constant
                        //
                        Type [] const_arg_types = new Type [2];
@@ -464,19 +471,18 @@ namespace Mono.CSharp {
                                return null;
 
                        MethodBase invoke_mb = mg.Methods [0];
-                       ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
+                       ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
 
                        if (!mg.HasTypeArguments &&
                            !TypeManager.InferTypeArguments (ec, invoke_pd, ref mb))
                                return null;
 
-                       ParameterData pd = Invocation.GetParameterData (mb);
-                       int pd_count = pd.Count;
+                       ParameterData pd = TypeManager.GetParameterData (mb);
 
-                       if (invoke_pd.Count != pd_count)
+                       if (invoke_pd.Count != pd.Count)
                                return null;
 
-                       for (int i = pd_count; i > 0; ) {
+                       for (int i = pd.Count; i > 0; ) {
                                i--;
 
                                Type invoke_pd_type = invoke_pd.ParameterType (i);
@@ -538,7 +544,7 @@ namespace Mono.CSharp {
                        }
                        
                        MethodBase mb = ((MethodGroupExpr) ml).Methods [0];
-                       ParameterData pd = Invocation.GetParameterData (mb);
+                       ParameterData pd = TypeManager.GetParameterData (mb);
 
                        int pd_count = pd.Count;
 
@@ -594,7 +600,7 @@ namespace Mono.CSharp {
                        }
                        
                        MethodBase mb = ((MethodGroupExpr) ml).Methods [0];
-                       ParameterData pd = Invocation.GetParameterData (mb);
+                       ParameterData pd = TypeManager.GetParameterData (mb);
 
                        Expression probe_ml = Expression.MemberLookup (
                                ec, delegate_type, "Invoke", loc);
@@ -605,7 +611,7 @@ namespace Mono.CSharp {
                        }
                        
                        MethodBase probe_mb = ((MethodGroupExpr) probe_ml).Methods [0];
-                       ParameterData probe_pd = Invocation.GetParameterData (probe_mb);
+                       ParameterData probe_pd = TypeManager.GetParameterData (probe_mb);
                        
                        if (((MethodInfo) mb).ReturnType != ((MethodInfo) probe_mb).ReturnType)
                                return false;
@@ -757,7 +763,7 @@ namespace Mono.CSharp {
                                ec, type, "Invoke", MemberTypes.Method,
                                Expression.AllBindingFlags, loc);
                        MethodBase method = ((MethodGroupExpr) invoke_method).Methods [0];
-                       ParameterData param = Invocation.GetParameterData (method);
+                       ParameterData param = TypeManager.GetParameterData (method);
                        string delegate_desc = Delegate.FullDelegateDesc (type, method, param);
 
                        if (!mg.HasTypeArguments &&
@@ -803,33 +809,32 @@ namespace Mono.CSharp {
 
                protected Expression ResolveMethodGroupExpr (EmitContext ec, MethodGroupExpr mg)
                {
-                               foreach (MethodInfo mi in mg.Methods){
-                                       delegate_method = Delegate.VerifyMethod (
-                                               ec, type, mi, loc);
-
-                                       if (delegate_method != null)
-                                               break;
-                               }
-                                       
-                               if (delegate_method == null) {
-                                       Error_NoMatchingMethodForDelegate (ec, mg, type, loc);
-                                       return null;
-                               }
-
-                               //
-                               // Check safe/unsafe of the delegate
-                               //
-                               if (!ec.InUnsafe){
-                                       ParameterData param = Invocation.GetParameterData (delegate_method);
-                                       int count = param.Count;
-                                       
-                                       for (int i = 0; i < count; i++){
-                                               if (param.ParameterType (i).IsPointer){
-                                                       Expression.UnsafeError (loc);
-                                                       return null;
-                                               }
+                       foreach (MethodInfo mi in mg.Methods){
+                               delegate_method  = Delegate.VerifyMethod (ec, type, mi, loc);
+                               
+                               if (delegate_method != null)
+                                       break;
+                       }
+                       
+                       if (delegate_method == null) {
+                               Error_NoMatchingMethodForDelegate (ec, mg, type, loc);
+                               return null;
+                       }
+                       
+                       //
+                       // Check safe/unsafe of the delegate
+                       //
+                       if (!ec.InUnsafe){
+                               ParameterData param = TypeManager.GetParameterData (delegate_method);
+                               int count = param.Count;
+                               
+                               for (int i = 0; i < count; i++){
+                                       if (param.ParameterType (i).IsPointer){
+                                               Expression.UnsafeError (loc);
+                                               return null;
                                        }
                                }
+                       }
                                                
                        //TODO: implement caching when performance will be low
                        IMethodData md = TypeManager.GetMethod (delegate_method);
index 02f218d5e5e946da36bdda9137915c0708689059..e2c77737a4b6de18ce96a0bbe053ed0e872a4afa 100644 (file)
@@ -221,7 +221,6 @@ namespace Mono.CSharp
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
                                "   -out:FNAME         Specifies output file\n" +
-                               "   -doc:XMLFILE         Generates xml documentation into specified file\n" +
                                "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
                                "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
index b89198d4ec66b6463a36fb2593b78228a0cdb4bf..31f0ecbb4c7a8c7854d02ceedde4eca4211a6fc8 100644 (file)
@@ -944,7 +944,7 @@ namespace Mono.CSharp {
                                sb.Append (valid [i]);
                        }
 
-                       Error (119, "Expression denotes a `" + ExprClassName () + "' where " +
+                       Report.Error (119, loc, "Expression denotes a `" + ExprClassName () + "' where " +
                               "a `" + sb.ToString () + "' was expected");
                }
                
@@ -2278,6 +2278,11 @@ namespace Mono.CSharp {
        ///   section 10.8.1 (Fully Qualified Names).
        /// </summary>
        public abstract class FullNamedExpression : Expression {
+               public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
+               {
+                       return this;
+               }
+
                public abstract string FullName {
                        get;
                }
index 9fbf4d75702060f84f30c418a85e153984de9624..be01ef78f7d92aaaf554260f49605259b4ec8d5e 100644 (file)
@@ -431,13 +431,15 @@ namespace Mono.CSharp {
                                }
 
                                IVariable variable = Expr as IVariable;
-                               if (!ec.InFixedInitializer && ((variable == null) || !variable.VerifyFixed (false))) {
+                               bool is_fixed = variable != null && variable.VerifyFixed (false);
+
+                               if (!ec.InFixedInitializer && !is_fixed) {
                                        Error (212, "You can only take the address of an unfixed expression inside " +
                                               "of a fixed statement initializer");
                                        return null;
                                }
 
-                               if (ec.InFixedInitializer && ((variable != null) && variable.VerifyFixed (false))) {
+                               if (ec.InFixedInitializer && is_fixed) {
                                        Error (213, "You can not fix an already fixed expression");
                                        return null;
                                }
@@ -661,7 +663,7 @@ namespace Mono.CSharp {
        // after semantic analysis (this is so we can take the address
        // of an indirection).
        //
-       public class Indirection : Expression, IMemoryLocation, IAssignMethod {
+       public class Indirection : Expression, IMemoryLocation, IAssignMethod, IVariable {
                Expression expr;
                LocalTemporary temporary;
                bool prepared;
@@ -735,6 +737,21 @@ namespace Mono.CSharp {
                {
                        return "*(" + expr + ")";
                }
+
+               #region IVariable Members
+
+               public VariableInfo VariableInfo {
+                       get {
+                               return null;
+                       }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       return true;
+               }
+
+               #endregion
        }
        
        /// <summary>
@@ -3458,17 +3475,26 @@ namespace Mono.CSharp {
                                //
                                left.Emit (ec);
                                ig.Emit (OpCodes.Conv_I);
-                               right.Emit (ec);
-                               if (size != 1){
-                                       if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, element);
-                                       else 
-                                               IntLiteral.EmitInt (ig, size);
-                                       if (rtype == TypeManager.int64_type)
-                                               ig.Emit (OpCodes.Conv_I8);
-                                       else if (rtype == TypeManager.uint64_type)
-                                               ig.Emit (OpCodes.Conv_U8);
-                                       ig.Emit (OpCodes.Mul);
+
+                               Constant right_const = right as Constant;
+                               if (right_const != null && size != 0) {
+                                       Expression ex = ConstantFold.BinaryFold (ec, Binary.Operator.Multiply, new IntConstant (size), right_const, loc);
+                                       if (ex == null)
+                                               return;
+                                       ex.Emit (ec);
+                               } else {
+                                       right.Emit (ec);
+                                       if (size != 1){
+                                               if (size == 0)
+                                                       ig.Emit (OpCodes.Sizeof, element);
+                                               else 
+                                                       IntLiteral.EmitInt (ig, size);
+                                               if (rtype == TypeManager.int64_type)
+                                                       ig.Emit (OpCodes.Conv_I8);
+                                               else if (rtype == TypeManager.uint64_type)
+                                                       ig.Emit (OpCodes.Conv_U8);
+                                               ig.Emit (OpCodes.Mul);
+                                       }
                                }
                                
                                if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
@@ -4290,13 +4316,6 @@ namespace Mono.CSharp {
                Expression expr;
                MethodBase method = null;
                
-               static Hashtable method_parameter_cache;
-
-               static Invocation ()
-               {
-                       method_parameter_cache = new PtrHashtable ();
-               }
-                       
                //
                // arguments is an ArrayList, but we do not want to typecast,
                // as it might be null.
@@ -4317,31 +4336,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               /// <summary>
-               ///   Returns the Parameters (a ParameterData interface) for the
-               ///   Method `mb'
-               /// </summary>
-               public static ParameterData GetParameterData (MethodBase mb)
-               {
-                       object pd = method_parameter_cache [mb];
-                       object ip;
-                       
-                       if (pd != null)
-                               return (ParameterData) pd;
-
-                       ip = TypeManager.LookupParametersByBuilder (mb);
-                       if (ip != null){
-                               method_parameter_cache [mb] = ip;
-
-                               return (ParameterData) ip;
-                       } else {
-                               ReflectionParameters rp = new ReflectionParameters (mb);
-                               method_parameter_cache [mb] = rp;
-
-                               return (ParameterData) rp;
-                       }
-               }
-
                /// <summary>
                ///   Determines "better conversion" as specified in 7.4.2.3
                ///
@@ -4457,8 +4451,8 @@ namespace Mono.CSharp {
                                           MethodBase candidate, bool candidate_params,
                                           MethodBase best, bool best_params, Location loc)
                {
-                       ParameterData candidate_pd = GetParameterData (candidate);
-                       ParameterData best_pd = GetParameterData (best);
+                       ParameterData candidate_pd = TypeManager.GetParameterData (candidate);
+                       ParameterData best_pd = TypeManager.GetParameterData (best);
                
                        int cand_count = candidate_pd.Count;
 
@@ -4563,7 +4557,7 @@ namespace Mono.CSharp {
                        sb.Append (".");
                        sb.Append (mb.Name);
                        
-                       ParameterData pd = GetParameterData (mb);
+                       ParameterData pd = TypeManager.GetParameterData (mb);
 
                        int count = pd.Count;
                        sb.Append (" (");
@@ -4657,7 +4651,7 @@ namespace Mono.CSharp {
                                                      int arg_count, MethodBase candidate,
                                                      bool do_varargs)
                {
-                       ParameterData pd = GetParameterData (candidate);
+                       ParameterData pd = TypeManager.GetParameterData (candidate);
                        
                        int pd_count = pd.Count;
 
@@ -4755,7 +4749,7 @@ namespace Mono.CSharp {
                static bool IsApplicable (EmitContext ec, ArrayList arguments, int arg_count,
                                          MethodBase candidate)
                {
-                       ParameterData pd = GetParameterData (candidate);
+                       ParameterData pd = TypeManager.GetParameterData (candidate);
 
                        if (arg_count != pd.Count)
                                return false;
@@ -4905,7 +4899,7 @@ namespace Mono.CSharp {
                                //
                                for (int i = 0; i < methods.Length; ++i) {
                                        MethodBase c = (MethodBase) methods [i];
-                                       ParameterData pd = GetParameterData (c);
+                                       ParameterData pd = TypeManager.GetParameterData (c);
 
                                        if (pd.Count != arg_count)
                                                continue;
@@ -4925,7 +4919,7 @@ namespace Mono.CSharp {
                                         
                                        for (int i = 0; i < methods.Length; ++i) {
                                                MethodBase c = methods [i];
-                                               ParameterData pd = GetParameterData (c);
+                                               ParameterData pd = TypeManager.GetParameterData (c);
 
                                                if (pd.Count != arg_count)
                                                        continue;
@@ -5093,7 +5087,7 @@ namespace Mono.CSharp {
                                                          Type delegate_type, bool may_fail,
                                                          Location loc)
                {
-                       ParameterData pd = GetParameterData (method);
+                       ParameterData pd = TypeManager.GetParameterData (method);
                        int pd_count = pd.Count;
                        
                        for (int j = 0; j < arg_count; j++) {
@@ -5336,7 +5330,7 @@ namespace Mono.CSharp {
                {
                        ParameterData pd;
                        if (mb != null)
-                               pd = GetParameterData (mb);
+                               pd = TypeManager.GetParameterData (mb);
                        else
                                pd = null;
                        
@@ -5406,7 +5400,7 @@ namespace Mono.CSharp {
                static Type[] GetVarargsTypes (EmitContext ec, MethodBase mb,
                                               ArrayList arguments)
                {
-                       ParameterData pd = GetParameterData (mb);
+                       ParameterData pd = TypeManager.GetParameterData (mb);
 
                        if (arguments == null)
                                return new Type [0];
@@ -7283,7 +7277,15 @@ namespace Mono.CSharp {
 
                                                object real_value = ((Constant) c.Expr).GetValue ();
 
-                                               return Constantify (real_value, t);
+                                               Expression exp = Constantify (real_value, t);
+
+                                               if (left_is_explicit && !left_is_type && !IdenticalNameAndTypeName (ec, left_original, left, loc)) {
+                                                       Report.SymbolRelatedToPreviousError (c);
+                                                       error176 (loc, c.GetSignatureForError ());
+                                                       return null;
+                                               }
+                                       
+                                               return exp;
                                        }
                                }
 
@@ -7606,6 +7608,11 @@ namespace Mono.CSharp {
                }
 
                public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
+               {
+                       return ResolveNamespaceOrType (ec, false);
+               }
+
+               public FullNamedExpression ResolveNamespaceOrType (EmitContext ec, bool silent)
                {
                        FullNamedExpression new_expr = expr.ResolveAsTypeStep (ec);
 
@@ -7619,7 +7626,7 @@ namespace Mono.CSharp {
                                FullNamedExpression retval = ns.Lookup (ec.DeclSpace, lookup_id, loc);
                                if ((retval != null) && (args != null))
                                        retval = new ConstructedType (retval, args, loc).ResolveAsTypeStep (ec);
-                               if (retval == null)
+                               if (!silent && retval == null)
                                        Report.Error (234, loc, "The type or namespace name `{0}' could not be found in namespace `{1}'", Identifier, ns.FullName);
                                return retval;
                        }
@@ -7638,7 +7645,7 @@ namespace Mono.CSharp {
 
                        Expression member_lookup;
                        member_lookup = MemberLookupFinal (ec, expr_type, expr_type, lookup_id, loc);
-                       if (member_lookup == null) {
+                       if (!silent && member_lookup == null) {
                                Report.Error (234, loc, "The type name `{0}' could not be found in type `{1}'", 
                                              Identifier, new_expr.FullName);
                                return null;
index 42507a17664386de6062a044a5e5b1ee1fd94a30..22e2d0ed925420c51652e83e946a4d9ff14ae9f5 100644 (file)
@@ -598,7 +598,7 @@ namespace Mono.CSharp {
                                        mb = mb.GetGenericMethodDefinition ();
 
                                int pos = type.GenericParameterPosition;
-                               ParameterData pd = Invocation.GetParameterData (mb);
+                               ParameterData pd = TypeManager.GetParameterData (mb);
                                GenericConstraints temp_gc = pd.GenericConstraints (pos);
                                Type mparam = mb.GetGenericArguments () [pos];
 
@@ -2118,7 +2118,7 @@ namespace Mono.CSharp {
                        else
                                arg_count = arguments.Count;
                        
-                       ParameterData pd = Invocation.GetParameterData (method);
+                       ParameterData pd = TypeManager.GetParameterData (method);
 
                        int pd_count = pd.Count;
 
@@ -2207,7 +2207,7 @@ namespace Mono.CSharp {
                        else
                                arg_count = 0;
 
-                       ParameterData pd = Invocation.GetParameterData (method);
+                       ParameterData pd = TypeManager.GetParameterData (method);
                        if (arg_count != pd.Count)
                                return false;
 
@@ -2251,7 +2251,7 @@ namespace Mono.CSharp {
                        if (!TypeManager.IsGenericMethod (method))
                                return true;
 
-                       ParameterData pd = Invocation.GetParameterData (method);
+                       ParameterData pd = TypeManager.GetParameterData (method);
                        if (apd.Count != pd.Count)
                                return false;
 
index 3b81e8e68327edd1a41a6b0be0047823658285ff..d580aee2b105f7b7f50d27c5b4ebca7fea60d39f 100644 (file)
@@ -57,7 +57,7 @@ namespace Mono.CSharp {
        ///   in 8 bits (and say, map anything after char 255 to be `255+').
        /// </remarks>
        public struct Location {
-               public int token; 
+               int token; 
 
                static ArrayList source_list;
                static Hashtable source_files;
@@ -84,7 +84,12 @@ namespace Mono.CSharp {
                        string path = Path.GetFullPath (name);
 
                        if (source_files.Contains (path)){
-                               Report.Warning (2002, name, "Source file '{0}' specified multiple times", path);
+                               int id = (int) source_files [path];
+                               string other_name = ((SourceFile) source_list [id - 1]).Name;
+                               if (name.Equals (other_name))
+                                       Report.Warning (2002, "Source file '{0}' specified multiple times", name);
+                               else
+                                       Report.Warning (2002, "Source filenames '{0}' and '{1}' both refer to the same file: {2}", name, other_name, path);
                                return;
                        }
 
index ec0a8347be7f965ea04df864df213b262a8c2377..d803b3906b47382eb28f9dfe058a2440ac37e14c 100644 (file)
@@ -229,37 +229,40 @@ namespace Mono.CSharp {
                // exist.
                //
                public class UsingEntry {
-                       public readonly string Name;
+                       public Expression Name;
                        public readonly NamespaceEntry NamespaceEntry;
                        public readonly Location Location;
                        
-                       public UsingEntry (NamespaceEntry entry, string name, Location loc)
+                       public UsingEntry (NamespaceEntry entry, Expression name, Location loc)
                        {
                                Name = name;
                                NamespaceEntry = entry;
                                Location = loc;
                        }
 
-                       Namespace resolved_ns;
+                       internal FullNamedExpression resolved;
 
                        public Namespace Resolve ()
                        {
-                               if (resolved_ns != null)
-                                       return resolved_ns;
+                               if (resolved != null)
+                                       return resolved as Namespace;
+
+                               DeclSpace root = RootContext.Tree.Types;
+                               root.NamespaceEntry = NamespaceEntry;
+                               resolved = Name.ResolveAsTypeStep (root.EmitContext);
+                               root.NamespaceEntry = null;
 
-                               FullNamedExpression resolved = NamespaceEntry.LookupForUsing (Name, Location);
-                               resolved_ns = resolved as Namespace;
-                               return resolved_ns;
+                               return resolved as Namespace;
                        }
                }
 
                public class AliasEntry {
                        public readonly string Name;
-                       public readonly MemberName Alias;
+                       public readonly Expression Alias;
                        public readonly NamespaceEntry NamespaceEntry;
                        public readonly Location Location;
                        
-                       public AliasEntry (NamespaceEntry entry, string name, MemberName alias, Location loc)
+                       public AliasEntry (NamespaceEntry entry, string name, Expression alias, Location loc)
                        {
                                Name = name;
                                Alias = alias;
@@ -274,55 +277,62 @@ namespace Mono.CSharp {
                                if (resolved != null)
                                        return resolved;
 
-                               //
-                               // GENERICS: Cope with the expression and not with the string
-                               // this will fail with `using A = Stack<int>'
-                               //
-                               
-                               string alias = Alias.GetTypeName ();
-
-                               resolved = NamespaceEntry.LookupForUsing (alias, Location);
-                               if (resolved == null)
-                                       return null;
-
-                               if (Alias.TypeArguments == null)
-                                       return resolved;
-
-                               EmitContext ec = RootContext.Tree.Types.EmitContext;
-                               resolved = new TypeAliasExpression (resolved, Alias.TypeArguments, Location);
-                               resolved = resolved.ResolveAsTypeStep (ec);
+                               DeclSpace root = RootContext.Tree.Types;
+                               root.NamespaceEntry = NamespaceEntry;
+                               resolved = Alias.ResolveAsTypeStep (root.EmitContext);
+                               root.NamespaceEntry = null;
 
                                return resolved;
                        }
                }
 
                public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, Location loc)
-                       : this (parent, file, name, false, loc)
-               { }
-
-               protected NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, bool is_implicit, Location loc)
                {
                        this.parent = parent;
                        this.file = file;
-                       this.IsImplicit = is_implicit;
+                       this.IsImplicit = false;
                        this.ID = ++next_id;
 
-                       if (!is_implicit && (parent != null))
+                       if (parent != null)
                                ns = parent.NS.GetNamespace (name, true);
                        else if (name != null)
                                ns = Namespace.LookupNamespace (name, true);
                        else
                                ns = Namespace.Root;
                        ns.AddNamespaceEntry (this);
+                       this.FullName = ns.Name;
+               }
 
-                       if ((parent != null) && (parent.NS != ns.Parent))
-                               implicit_parent = new NamespaceEntry (parent, file, ns.Parent.Name, true, loc);
-                       else
-                               implicit_parent = parent;
 
+               private NamespaceEntry (NamespaceEntry parent, SourceFile file, Namespace ns)
+               {
+                       this.parent = parent;
+                       this.file = file;
+                       this.IsImplicit = true;
+                       this.ID = ++next_id;
+                       this.ns = ns;
                        this.FullName = ns.Name;
                }
 
+               //
+               // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is
+               // resolved as if the immediately containing namespace body has no using-directives.
+               //
+               // Section 16.3.2 says that the same rule is applied when resolving the namespace-name
+               // in the using-namespace-directive.
+               //
+               // To implement these rules, the expressions in the using directives are resolved using 
+               // the "doppelganger" (ghostly bodiless duplicate).
+               //
+               NamespaceEntry doppelganger;
+               NamespaceEntry Doppelganger {
+                       get {
+                               if (!IsImplicit && doppelganger == null)
+                                       doppelganger = new NamespaceEntry (ImplicitParent, file, ns);
+                               return doppelganger;
+                       }
+               }
+
                static int next_id = 0;
                public readonly string FullName;
                public readonly int ID;
@@ -342,6 +352,13 @@ namespace Mono.CSharp {
 
                public NamespaceEntry ImplicitParent {
                        get {
+                               if (parent == null)
+                                       return null;
+                               if (implicit_parent == null) {
+                                       implicit_parent = (parent.NS == ns.Parent)
+                                               ? parent
+                                               : new NamespaceEntry (parent, file, ns.Parent);
+                               }
                                return implicit_parent;
                        }
                }
@@ -354,32 +371,34 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Records a new namespace for resolving name references
                /// </summary>
-               public void Using (string ns, Location loc)
+               public void Using (Expression ns, Location loc)
                {
+                       string name = ns.ToString ();
                        if (DeclarationFound){
                                Report.Error (1529, loc, "A using clause must precede all other namespace elements");
                                return;
                        }
 
-                       if (ns == FullName)
+                       if (name == FullName)
                                return;
                        
                        if (using_clauses == null)
                                using_clauses = new ArrayList ();
 
                        foreach (UsingEntry old_entry in using_clauses) {
-                               if (old_entry.Name == ns) {
+                               if (old_entry.Name.ToString () == name) {
                                        if (RootContext.WarningLevel >= 3)
-                                               Report.Warning (105, loc, "The using directive for '{0}' appeared previously in this namespace", ns);
+                                               Report.Warning (105, loc, "The using directive for '{0}' appeared previously in this namespace", name);
                                                return;
                                        }
                                }
-                       
-                       UsingEntry ue = new UsingEntry (this, ns, loc);
+
+
+                       UsingEntry ue = new UsingEntry (Doppelganger, ns, loc);
                        using_clauses.Add (ue);
                }
 
-               public void UsingAlias (string name, MemberName alias, Location loc)
+               public void UsingAlias (string name, Expression alias, Location loc)
                {
                        if (DeclarationFound){
                                Report.Error (1529, loc, "A using clause must precede all other namespace elements");
@@ -395,7 +414,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       aliases [name] = new AliasEntry (this, name, alias, loc);
+                       aliases [name] = new AliasEntry (Doppelganger, name, alias, loc);
                }
 
                public FullNamedExpression LookupAlias (string alias)
@@ -407,93 +426,51 @@ namespace Mono.CSharp {
                        return entry == null ? null : entry.Resolve ();
                }
 
-               //
-               // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is 
-               // resolved as if the immediately containing namespace body has no using-directives.
-               //
-               // Section 16.3.2 says that the same rule is applied when resolving the namespace-name
-               // in the using-namespace-directive.
-               //
-               public FullNamedExpression LookupForUsing (string dotted_name, Location loc)
+               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc)
                {
-                       int pos = dotted_name.IndexOf ('.');
-                       string simple_name = dotted_name;
+                       FullNamedExpression resolved = null;
                        string rest = null;
+
+                       // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
+                       int pos = name.IndexOf ('.');
                        if (pos >= 0) {
-                               simple_name = dotted_name.Substring (0, pos);
-                               rest = dotted_name.Substring (pos + 1);
+                               rest = name.Substring (pos + 1);
+                               name = name.Substring (0, pos);
                        }
 
-                       FullNamedExpression o = NS.Lookup (null, simple_name, loc);
-                       if (o == null && ImplicitParent != null)
-                               o = ImplicitParent.LookupNamespaceOrType (null, simple_name, loc);
+                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
+                               if ((resolved = curr_ns.Lookup (ds, name, loc)) != null)
+                                       break;
+                       }
 
-                       if (o == null || rest == null)
-                               return o;
+                       if (resolved == null || rest == null)
+                               return resolved;
 
-                       Namespace ns = o as Namespace;
+                       Namespace ns = resolved as Namespace;
                        if (ns != null)
-                               return ns.Lookup (null, rest, loc);
-                       
-                       Type nested = TypeManager.LookupType (o.FullName + "." + rest);
-                       if (nested == null)
+                               return ns.Lookup (ds, rest, loc);
+
+                       Type nested = TypeManager.LookupType (resolved.FullName + "." + rest);
+                       if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested)))
                                return null;
 
                        return new TypeExpression (nested, Location.Null);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc)
-               {
-                       FullNamedExpression resolved = null;
-                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
-                               if ((resolved = curr_ns.Lookup (ds, name, loc)) != null)
-                                       break;
-                       }
-                       return resolved;
-               }
-
                private FullNamedExpression Lookup (DeclSpace ds, string name, Location loc)
                {
-                       FullNamedExpression o;
-                       Namespace ns;
-
-                       //
-                       // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
-                       //
-                       // FIXME: Remove this block.  Only simple names should come here.
-                       //        The bug: The loop in LookupNamespaceOrType continues if 
-                       //        the lookup for N succeeds but the nested lookup for I fails.
-                       //        This is one part of #52697.
-                       //
-                       int pos = name.IndexOf ('.');
-                       if (pos >= 0) {
-                               string first = name.Substring (0, pos);
-                               string last = name.Substring (pos + 1);
-
-                               o = Lookup (ds, first, loc);
-                               if (o == null)
-                                       return null;
-
-                               ns = o as Namespace;
-                               if (ns != null) {
-                                       o = ns.Lookup (ds, last, loc);
-                                       return o;
-                               }
-
-                               Type nested = TypeManager.LookupType (o.FullName + "." + last);
-                               if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested)))
-                                       return null;
-
-                               return new TypeExpression (nested, Location.Null);
-                       }
+                       // Precondition: Only simple names (no dots) will be looked up with this function.
 
                        //
                        // Check whether it's in the namespace.
                        //
-                       o = NS.Lookup (ds, name, loc);
+                       FullNamedExpression o = NS.Lookup (ds, name, loc);
                        if (o != null)
                                return o;
 
+                       if (IsImplicit)
+                               return null;
+
                        //
                        // Check aliases.
                        //
@@ -501,9 +478,6 @@ namespace Mono.CSharp {
                        if (o != null)
                                return o;
 
-                       if (name.IndexOf ('.') > 0)
-                               return null;
-
                        //
                        // Check using entries.
                        //
@@ -561,7 +535,7 @@ namespace Mono.CSharp {
                        if (using_clauses != null) {
                                using_list = new string [using_clauses.Count];
                                for (int i = 0; i < using_clauses.Count; i++)
-                                       using_list [i] = ((UsingEntry) using_clauses [i]).Name;
+                                       using_list [i] = ((UsingEntry) using_clauses [i]).Name.ToString ();
                        } else {
                                using_list = new string [0];
                        }
@@ -629,8 +603,8 @@ namespace Mono.CSharp {
                                        if (ue.Resolve () != null)
                                                continue;
 
-                                       if (LookupForUsing (ue.Name, ue.Location) == null)
-                                               error246 (ue.Location, ue.Name);
+                                       if (ue.resolved == null)
+                                               error246 (ue.Location, ue.Name.ToString ());
                                        else
                                                Report.Error (138, ue.Location, "The using keyword only lets you specify a namespace, " +
                                                              "`" + ue.Name + "' is a class not a namespace.");
@@ -645,7 +619,7 @@ namespace Mono.CSharp {
                                        if (alias.Resolve () != null)
                                                continue;
 
-                                       error246 (alias.Location, alias.Alias.GetTypeName ());
+                                       error246 (alias.Location, alias.Alias.ToString ());
                                }
                        }
                }
index 5663f612e9e4cc6db6a9de24aacde4ef14751b40..01824a36f1846c715683a87650a61b6f5cc90053 100644 (file)
@@ -467,7 +467,7 @@ namespace Mono.CSharp {
                                CallingConventions.Standard | CallingConventions.HasThis,
                                base_method.ReturnType, args);
 
-                       ParameterData pd = Invocation.GetParameterData (iface_method);
+                       ParameterData pd = TypeManager.GetParameterData (iface_method);
                        proxy.DefineParameter (0, ParameterAttributes.None, "");
                        for (int i = 0; i < pd.Count; i++) {
                                string name = pd.ParameterName (i);
index edd6e7941b93e1992f99686476365cc693943154..4fbc27ec19df55f6539cba1e14189fc6338badd1 100644 (file)
@@ -364,6 +364,9 @@ namespace Mono.CSharp {
                        // These are classes that depends on the core interfaces
                        //
                        string [] classes_second_stage = {
+                               "System.Enum",
+                               "System.String",
+                               "System.Array",
                                "System.Reflection.MemberInfo",
                                "System.Type",
                                "System.Exception",
@@ -400,19 +403,18 @@ namespace Mono.CSharp {
                                "System.Security.CodeAccessPermission"
                        };
 
-                       // We must store them here before calling BootstrapCorlib_ResolveDelegate.
-                       TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String");
-                       TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum");
-                       TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array");
-                       TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
-                       TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
-                       
                        foreach (string cname in classes_second_stage)
                                BootstrapCorlib_ResolveClass (root, cname);
 
                        BootstrapCorlib_ResolveStruct (root, "System.Nullable`1");
 
                        BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback");
+
+                       // These will be defined indirectly during the previous ResolveDelegate.
+                       // However make sure the rest of the checks happen.
+                       string [] delegate_types = { "System.Delegate", "System.MulticastDelegate" };
+                       foreach (string cname in delegate_types)
+                               BootstrapCorlib_ResolveClass (root, cname);
                }
                        
                // <summary>
index f18304a36e0b1668db18d1e042d6fc159c3b0da5..5b30e0e57e7c8c6eebae9c625a51a1b0bdbe1aa1 100644 (file)
@@ -646,6 +646,7 @@ namespace Mono.CSharp {
                                label.AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
 
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       label.AddReference ();
 
                        return true;
                }
@@ -718,8 +719,6 @@ namespace Mono.CSharp {
                {
                        ec.CurrentBranching.Label (vectors);
 
-                       referenced = true;
-
                        return true;
                }
 
@@ -732,6 +731,11 @@ namespace Mono.CSharp {
                        LabelTarget (ec);
                        ec.ig.MarkLabel (label);
                }
+
+               public void AddReference ()
+               {
+                       referenced = true;
+               }
        }
        
 
index 8fd2e343b52db746e450b82e12f5614879afb2f9..4da27e196eb2da2a4eb08f1f260a63dae67d5a86 100644 (file)
@@ -50,7 +50,7 @@ namespace Mono.CSharp {
 
                        if (mb.Mono_IsInflatedMethod) {
                                MethodInfo generic = mb.GetGenericMethodDefinition ();
-                               gpd = Invocation.GetParameterData (generic);
+                               gpd = TypeManager.GetParameterData (generic);
 
                                last_arg_is_params = gpd.HasParams;
                                return;
index 2acf526722e78ef5140479788daf2b226b1d2317..db7b639a837264fe363c880a168d303f2d860c24 100644 (file)
@@ -242,10 +242,9 @@ public partial class TypeManager {
        static Hashtable indexer_arguments;
 
        // <remarks>
-       //   Maybe `method_arguments' should be replaced and only
-       //   method_internal_params should be kept?
+       //   Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
        // <remarks>
-       static Hashtable method_internal_params;
+       static Hashtable method_params;
 
        // <remarks>
        //  Keeps track of methods
@@ -277,7 +276,7 @@ public partial class TypeManager {
                builder_to_ifaces = null;
                method_arguments = null;
                indexer_arguments = null;
-               method_internal_params = null;
+               method_params = null;
                builder_to_method = null;
                
                fields = null;
@@ -377,7 +376,7 @@ public partial class TypeManager {
                builder_to_member_cache = new PtrHashtable ();
                builder_to_method = new PtrHashtable ();
                method_arguments = new PtrHashtable ();
-               method_internal_params = new PtrHashtable ();
+               method_params = new PtrHashtable ();
                indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
                
@@ -937,7 +936,7 @@ public partial class TypeManager {
 
                MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
                string signature = GetFullNameSignature (mb);
-               string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+               string arg = GetParameterData (mb).ParameterDesc (0);
                return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
        }
 
@@ -948,15 +947,8 @@ public partial class TypeManager {
         {
                StringBuilder sig = new StringBuilder ("(");
 
-               //
-               // FIXME: We should really have a single function to do
-               // everything instead of the following 5 line pattern
-               //
-                ParameterData iparams = LookupParametersByBuilder (mb);
+               ParameterData iparams = GetParameterData (mb);
 
-               if (iparams == null)
-                       iparams = new ReflectionParameters (mb);
-               
                // Is property
                if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
                        return GetFullNameSignature (mb);
@@ -1863,18 +1855,20 @@ public partial class TypeManager {
                        args = NoTypes;
                                
                method_arguments.Add (mb, args);
-               method_internal_params.Add (mb, ip);
+               method_params.Add (mb, ip);
        }
        
-       static public InternalParameters LookupParametersByBuilder (MethodBase mb)
+       static public ParameterData GetParameterData (MethodBase mb)
        {
-               if (! (mb is ConstructorBuilder || mb is MethodBuilder))
-                       return null;
-               
-               if (method_internal_params.Contains (mb))
-                       return (InternalParameters) method_internal_params [mb];
-               else
-                       throw new Exception ("Argument for Method not registered" + mb);
+               object pd = method_params [mb];
+               if (pd == null) {
+                       if (mb is MethodBuilder || mb is ConstructorBuilder)
+                               throw new InternalErrorException ("Argument for Method not registered" + mb);
+
+                       method_params [mb] = pd = new ReflectionParameters (mb);
+               }
+
+               return (ParameterData) pd;
        }
 
        /// <summary>
index 4039c60624863b4c6ba23e3f18968d720abc6ae8..1bdd931fa03a432affec2e0e2ed50ed878c4e602 100644 (file)
@@ -1,3 +1,53 @@
+2005-04-08  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute.IsValidArgumentType): Test valid named
+       argument types.
+       (Attribute.Resolve): Add named argument type checking.
+       
+       * class.cs (FixedField.Define): Use IsPrimitiveType
+       
+       * expression.cs (Binary.ResolveOperator): Reflect IsCLRType renaming.
+       
+       * iterators.cs (Iterator.DefineIterator): Add check for arglist and
+       unsafe parameter types.
+       
+       * statement.cs (Using.ResolveExpression): Add better error description.
+       
+       * typemanager.cs (IsCLRType): Renamed to IsPrimitiveType.
+       
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #74484.
+       * attribute.cs (Attribute.GetAttributeUsage): Resolve
+       AttributeUsageAttribute in the emitcontext of the attribute class,
+       not in the emitcontext of the attributable entity it was attached to.
+       * cs-parser.jay: Use 'current_class', not 'current_container',
+       when creating a GlobalAttribute.
+
+2005-04-08  Alp Toker  <alp@atoker.com>
+
+       * pending.cs: The fix to #58413 failed to compile methods implementing
+       interfaces with/without params modifiers and vice versa, even though
+       params modifiers aren't part of the signature. Make the modifier check
+       less strict as in csc.
+
+2005-04-07  Abin Thomas  <projectmonokochi@rediffmail.com>
+           Anoob V E  <projectmonokochi@rediffmail.com>
+           Harilal P R  <projectmonokochi@rediffmail.com>
+
+       Fix #58413.
+       * pending.cs (TypeAndMethods.mods): New.  Store the parameter
+       modifiers of pending methods.
+       (PendingImplementation.PendingImplementation): Initialize it.
+       Add Parameter.Modifier [][] mods and initialize it with ParameterData.
+       (PendingImplementation.InterFaceMethod): Repalce Type[] argument
+       with ParameterData.  Add check for modifiers.
+       * class.cs (MethodData.Define): Update to changes.
+
+2005-04-07  Raja R Harinath  <rharinath@novell.com>
+
+       * ecore.cs (Expression.IsAccessorAccessible): Clarify code somewhat.
+
 2005-04-07  Marek Safar  <marek.safar@seznam.cz>
 
        * class.cs (PropertyMethod.Define): Check private accessor in abstract
index b112cbebdd49f4a6f39259cb3b42e9b58e7a27dd..b83fc9a85af242062881a9bf1cb343bb789f6ccc 100644 (file)
@@ -113,6 +113,11 @@ namespace Mono.CSharp {
                                      name);
                }
 
+               void Error_InvalidNamedAgrumentType (string name)
+               {
+                       Report.Error (655, Location, "'{0}' is not a valid named attribute argument because its type is not valid attribute type", name);
+               }
+
                static void Error_AttributeArgumentNotValid (string extra, Location loc)
                {
                        Report.Error (182, loc,
@@ -279,7 +284,17 @@ namespace Mono.CSharp {
                        Error_AttributeArgumentNotValid (loc);
                        return false;
                }
-               
+
+               bool IsValidArgumentType (Type t)
+               {
+                       return TypeManager.IsPrimitiveType (t) ||
+                               (t.IsArray && TypeManager.IsPrimitiveType (t.GetElementType ())) ||
+                               TypeManager.IsEnumType (t) ||
+                               t == TypeManager.string_type ||
+                               t == TypeManager.object_type ||
+                               t == TypeManager.type_type;
+               }
+
                // Cache for parameter-less attributes
                static PtrHashtable att_cache = new PtrHashtable ();
 
@@ -427,6 +442,12 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
+                                       if (!IsValidArgumentType (pi.PropertyType)) {
+                                               Report.SymbolRelatedToPreviousError (pi);
+                                               Error_InvalidNamedAgrumentType (member_name);
+                                               return null;
+                                       }
+
                                        object value;
                                        if (!GetAttributeArgumentExpression (e, Location, pi.PropertyType, out value))
                                                return null;
@@ -443,6 +464,12 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
+                                       if (!IsValidArgumentType (fi.FieldType)) {
+                                               Report.SymbolRelatedToPreviousError (fi);
+                                               Error_InvalidNamedAgrumentType (member_name);
+                                               return null;
+                                       }
+
                                        object value;
                                        if (!GetAttributeArgumentExpression (e, Location, fi.FieldType, out value))
                                                return null;
@@ -498,7 +525,7 @@ namespace Mono.CSharp {
                                }
 
                                object value = pos_values [j];
-                               if (value != null && a.Type != value.GetType () && a.Type.IsPrimitive) {
+                               if (value != null && a.Type != value.GetType () && TypeManager.IsPrimitiveType (a.Type)) {
                                        bool fail;
                                        pos_values [j] = TypeManager.ChangeType (value, a.Type, out fail);
                                        if (fail) {
@@ -640,18 +667,14 @@ namespace Mono.CSharp {
                                return ua;
                        }
 
-                       if (attr_class.OptAttributes == null) {
-                               usage_attr_cache.Add (Type, DefaultUsageAttribute);
-                               return DefaultUsageAttribute;
-                       }
+                       Attribute a = attr_class.OptAttributes == null
+                               ? null
+                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, attr_class.EmitContext);
 
-                       Attribute a = attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, ec);
-                       if (a == null) {
-                               usage_attr_cache.Add (Type, DefaultUsageAttribute);
-                               return DefaultUsageAttribute;
-                       }
+                       ua = a == null
+                               ? DefaultUsageAttribute 
+                               : a.GetAttributeUsageAttribute (attr_class.EmitContext);
 
-                       ua = a.GetAttributeUsageAttribute (ec);
                        usage_attr_cache.Add (Type, ua);
                        return ua;
                }
index 92c9d0e5fbe8b54c9ca69b1fca08a73ffb089a1d..81bea2a2c8badfc040676606d58f0fc79d7ca6d5 100644 (file)
@@ -4573,10 +4573,10 @@ namespace Mono.CSharp {
                        if (container.Pending != null){
                                if (member is Indexer) // TODO: test it, but it should work without this IF
                                        implementing = container.Pending.IsInterfaceIndexer (
-                                               member.InterfaceType, method.ReturnType, ParameterTypes);
+                                               member.InterfaceType, method.ReturnType, ParameterInfo);
                                else
                                        implementing = container.Pending.IsInterfaceMethod (
-                                               member.InterfaceType, name, method.ReturnType, ParameterTypes);
+                                               member.InterfaceType, name, method.ReturnType, ParameterInfo);
 
                                if (member.InterfaceType != null){
                                        if (implementing == null){
@@ -4691,11 +4691,11 @@ namespace Mono.CSharp {
                                if (member is Indexer) {
                                        container.Pending.ImplementIndexer (
                                                member.InterfaceType, builder, method.ReturnType,
-                                               ParameterTypes, member.IsExplicitImpl);
+                                               ParameterInfo, member.IsExplicitImpl);
                                } else
                                        container.Pending.ImplementMethod (
                                                member.InterfaceType, name, method.ReturnType,
-                                               ParameterTypes, member.IsExplicitImpl);
+                                               ParameterInfo, member.IsExplicitImpl);
 
                                if (member.IsExplicitImpl)
                                        container.TypeBuilder.DefineMethodOverride (
@@ -5471,7 +5471,7 @@ namespace Mono.CSharp {
                        if (!base.Define ())
                                return false;
 
-                       if (!MemberType.IsPrimitive) {
+                       if (!TypeManager.IsPrimitiveType (MemberType)) {
                                Report.Error (1663, Location, "Fixed sized buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double");
                                return false;
                        }
@@ -6069,7 +6069,7 @@ namespace Mono.CSharp {
                                        flags = method.flags;
                                } else {
                                        if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
-                                               Report.Error (422, Location, "{0}': abstract properties cannot have private accessors", GetSignatureForError (container));
+                                               Report.Error (442, Location, "{0}': abstract properties cannot have private accessors", GetSignatureForError (container));
                                        }
 
                                        CheckModifiers (container, ModFlags);
index 761371a25e5cf0d31dc2b0bf5bac543aacfdfb99..b4748fa1d68c58e02c6dff4d623d44af38b5c1df 100644 (file)
@@ -598,7 +598,7 @@ attribute
                Expression left_expr = left == null ? null : left.GetTypeExpression (loc);
 
                if (current_attr_target == "assembly" || current_attr_target == "module")
-                       $$ = new GlobalAttribute (current_container, current_attr_target,
+                       $$ = new GlobalAttribute (current_class, current_attr_target,
                                                  left_expr, identifier, (ArrayList) $3, loc);
                else
                        $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc);
@@ -4833,7 +4833,7 @@ public void parse ()
                else
                        yyparse (lexer);
                Tokenizer tokenizer = lexer as Tokenizer;
-               tokenizer.cleanup ();           
+               tokenizer.cleanup ();
        } catch (Exception e){
                // 
                // Removed for production use, use parser verbose to get the output.
@@ -4843,6 +4843,8 @@ public void parse ()
                if (yacc_verbose_flag > 0)
                        Console.WriteLine (e);
        }
+
+       RootContext.Tree.Types.NamespaceEntry = null;
 }
 
 void CheckToken (int error, int yyToken, string msg)
index 48f1f173dc652650ea2d5f003bce4fe78a65e24a..b98bc9dad312d36ea5f6d34fb285de5d171c64ba 100644 (file)
@@ -185,34 +185,23 @@ namespace Mono.CSharp {
                        //
                        // If only accessible to the current class or children
                        //
-                       if (ma == MethodAttributes.Private) {
-                               Type declaring_type = mi.DeclaringType;
+                       if (ma == MethodAttributes.Private)
+                               return invocation_type == mi.DeclaringType ||
+                                       TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
 
-                               if (invocation_type != declaring_type)
-                                       return TypeManager.IsNestedChildOf (invocation_type, declaring_type);
-
-                               return true;
-                       }
-                       //
-                       // FamAndAssem requires that we not only derivate, but we are on the
-                       // same assembly.  
-                       //
-                       if (ma == MethodAttributes.FamANDAssem){
-                               return (mi.DeclaringType.Assembly != invocation_type.Assembly);
-                       }
-
-                       // Assembly and FamORAssem succeed if we're in the same assembly.
-                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
-                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+                       if (mi.DeclaringType.Assembly == invocation_type.Assembly) {
+                               if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
                                        return true;
+                       } else {
+                               if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem)
+                                       return false;
                        }
 
-                       // We already know that we aren't in the same assembly.
-                       if (ma == MethodAttributes.Assembly)
-                               return false;
-
                        // Family and FamANDAssem require that we derive.
-                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+                       // FamORAssem requires that we derive if in different assemblies.
+                       if (ma == MethodAttributes.Family ||
+                           ma == MethodAttributes.FamANDAssem ||
+                           ma == MethodAttributes.FamORAssem) {
                                if (!TypeManager.IsNestedFamilyAccessible (invocation_type, mi.DeclaringType))
                                        return false;
 
@@ -3641,8 +3630,8 @@ namespace Mono.CSharp {
                        }
 
                        bool must_do_cs1540_check;
-                       if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check)
-                                   && IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
+                       if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check) &&
+                             IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
                                
                                Report.Error (122, loc, "'{0}' is inaccessible due to its protection level",
                                                DeclaringType.Name + "." + EventInfo.Name);
index 984ef60180d5c8fe62e467cc759246ead0411484..3ce28b8f3a8e530c64f50e10d02d48d86ea11352 100644 (file)
@@ -2276,7 +2276,7 @@ namespace Mono.CSharp {
                        // Do not perform operator overload resolution when both sides are
                        // built-in types
                        //
-                       if (!(TypeManager.IsCLRType (l) && TypeManager.IsCLRType (r))){
+                       if (!(TypeManager.IsPrimitiveType (l) && TypeManager.IsPrimitiveType (r))){
                                //
                                // Step 1: Perform Operator Overload location
                                //
index 61d9caebed652b94355f07fd497290e22cfe88ab..a81ea1e57d5525c86039c1046bc4680837224531 100644 (file)
@@ -390,6 +390,16 @@ namespace Mono.CSharp {
                                                "Iterators cannot have ref or out parameters");
                                        return false;
                                }
+
+                               if ((mod & Parameter.Modifier.ARGLIST) != 0) {
+                                       Report.Error (1636, Location, "__arglist is not allowed in parameter list of iterators");
+                                       return false;
+                               }
+
+                               if (parameters.ParameterType (i).IsPointer) {
+                                       Report.Error (1637, Location, "Iterators cannot have unsafe parameters or yield types");
+                                       return false;
+                               }
                        }
 
                        ArrayList list = new ArrayList ();
index 98a4e9993eec4b4a0b9fb137bf6a577f7784202a..133da0d7dad38b701689ac6b225d2c3d7a51b69f 100644 (file)
@@ -35,6 +35,9 @@ namespace Mono.CSharp {
                // of methods above.
                public Type [][]     args;
 
+               //This is used to store the modifiers of arguments
+               public Parameter.Modifier [][] mods;
+               
                //
                // This flag on the method says `We found a match, but
                // because it was private, we could not use the match
@@ -166,6 +169,7 @@ namespace Mono.CSharp {
                                pending_implementations [i].optional = missing.Optional;
                                pending_implementations [i].methods = mi;
                                pending_implementations [i].args = new Type [count][];
+                               pending_implementations [i].mods = new Parameter.Modifier [count][];
                                pending_implementations [i].found = new bool [count];
                                pending_implementations [i].need_proxy = new MethodInfo [count];
                                string indexer_name = TypeManager.IndexerPropertyName (t);
@@ -175,15 +179,24 @@ namespace Mono.CSharp {
                                
                                int j = 0;
                                foreach (MethodInfo m in mi){
-                                       Type [] types;
-                                       
+                                       pending_implementations [i].args [j] = TypeManager.NoTypes;
+                                       pending_implementations [i].mods [j] = null;
+
                                        // If there is a previous error, just ignore
                                        if (m == null)
-                                               types = TypeManager.NoTypes;
-                                       else
-                                               types = TypeManager.GetArgumentTypes (m);
-                                       
-                                       pending_implementations [i].args [j] = types;
+                                               continue;
+
+                                       pending_implementations [i].args [j] = TypeManager.GetArgumentTypes (m);
+
+                                       ParameterData pd = TypeManager.GetParameterData (m);
+                                       
+                                       if (pd.Count > 0){
+                                               Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
+                                               for (int k = 0; k < pd.Count; k++)
+                                                       pm [k] = pd.ParameterModifier (k);
+                                               pending_implementations [i].mods [j] = pm;
+                                       }
+                       
                                        j++;
                                }
                                i++;
@@ -197,6 +210,7 @@ namespace Mono.CSharp {
                                abstract_methods.CopyTo (pending_implementations [i].methods, 0);
                                pending_implementations [i].found = new bool [count];
                                pending_implementations [i].args = new Type [count][];
+                               pending_implementations [i].mods = new Parameter.Modifier [count][];
                                pending_implementations [i].type = type_builder;
 
                                string indexer_name = TypeManager.IndexerPropertyName (type_builder);
@@ -208,8 +222,17 @@ namespace Mono.CSharp {
                                        MethodInfo mi = (MethodInfo) m;
                                        
                                        Type [] types = TypeManager.GetArgumentTypes (mi);
+                                       ParameterData pd = TypeManager.GetParameterData (mi);
                                        
                                        pending_implementations [i].args [j] = types;
+                                       pending_implementations [i].mods [j] = null;
+                                       if (pd.Count > 0){
+                                               Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
+                                               for (int k = 0; k < pd.Count; k++)
+                                                       pm [k] = pd.ParameterModifier (k);
+                                               pending_implementations [i].mods [j] = pm;
+                                       }
+                                               
                                        j++;
                                }
                        }
@@ -318,23 +341,23 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Whether the specified method is an interface method implementation
                /// </summary>
-               public MethodInfo IsInterfaceMethod (Type t, string name, Type ret_type, Type [] args)
+               public MethodInfo IsInterfaceMethod (Type t, string name, Type ret_type, ParameterData args)
                {
                        return InterfaceMethod (t, name, ret_type, args, Operation.Lookup, null);
                }
 
-               public MethodInfo IsInterfaceIndexer (Type t, Type ret_type, Type [] args)
+               public MethodInfo IsInterfaceIndexer (Type t, Type ret_type, ParameterData args)
                {
                        return InterfaceMethod (t, null, ret_type, args, Operation.Lookup, null);
                }
 
-               public void ImplementMethod (Type t, string name, Type ret_type, Type [] args, bool clear_one) 
+               public void ImplementMethod (Type t, string name, Type ret_type, ParameterData args, bool clear_one) 
                {
                        InterfaceMethod (t, name, ret_type, args,
                                         clear_one ? Operation.ClearOne : Operation.ClearAll, null);
                }
 
-               public void ImplementIndexer (Type t, MethodInfo mi, Type ret_type, Type [] args, bool clear_one) 
+               public void ImplementIndexer (Type t, MethodInfo mi, Type ret_type, ParameterData args, bool clear_one) 
                {
                        InterfaceMethod (t, null, ret_type, args,
                                         clear_one ? Operation.ClearOne : Operation.ClearAll, mi);
@@ -357,10 +380,10 @@ namespace Mono.CSharp {
                ///   that was used in the interface, then we always need to create a proxy for it.
                ///
                /// </remarks>
-               public MethodInfo InterfaceMethod (Type t, string name, Type ret_type, Type [] args,
+               public MethodInfo InterfaceMethod (Type t, string name, Type ret_type, ParameterData args,
                                                   Operation op, MethodInfo need_proxy)
                {
-                       int arg_len = args.Length;
+                       int arg_len = args.Count;
 
                        if (pending_implementations == null)
                                return null;
@@ -403,16 +426,16 @@ namespace Mono.CSharp {
                                        if (tm.args [i].Length != arg_len)
                                                continue;
 
-                                       int j, top = args.Length;
-                                       bool fail = false;
-                                       
-                                       for (j = 0; j < top; j++){
-                                               if (tm.args [i][j] != args[j]){
-                                                       fail = true;
+                                       int j, top = args.Count;
+
+                                       for (j = 0; j < top; j++)
+                                               if (tm.args [i][j] != args.ParameterType (j) ||
+                                                               (tm.mods [i][j] != args.ParameterModifier (j) &&
+                                                                tm.mods [i][j] != Parameter.Modifier.PARAMS &&
+                                                                args.ParameterModifier (j) != Parameter.Modifier.PARAMS)
+                                                        )
                                                        break;
-                                               }
-                                       }
-                                       if (fail)
+                                       if (j != top)
                                                continue;
 
                                        if (op != Operation.Lookup){
index b5d33eba61e04f3f528b6971a4f8480a81f62d33..cf159fe6cd6cf77d1402d65eb0996e31e0e33f8c 100644 (file)
@@ -3857,11 +3857,11 @@ namespace Mono.CSharp {
                bool ResolveExpression (EmitContext ec)
                {
                        if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)){
-                               conv = Convert.ImplicitConversionRequired (
-                                       ec, expr, TypeManager.idisposable_type, loc);
-
-                               if (conv == null)
+                               if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
+                                       Report.Error (1674, loc, "'{0}': type used in a using statement must be implicitly convertible to 'System.IDisposable'",
+                                               TypeManager.CSharpName (expr_type));
                                        return false;
+                               }
                        }
 
                        return true;
index 1132913b02054c15367012a8a9ec129ba23d03d2..f4c5bbe447b4a5b6b2a53ec111cef6eb922bf25d 100644 (file)
@@ -1481,15 +1481,12 @@ public class TypeManager {
        // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
        // the pieces in the code where we use IsBuiltinType and special case decimal_type.
        // 
-       public static bool IsCLRType (Type t)
+       public static bool IsPrimitiveType (Type t)
        {
-               if (t == object_type || t == int32_type || t == uint32_type ||
+               return (t == int32_type || t == uint32_type ||
                    t == int64_type || t == uint64_type || t == float_type || t == double_type ||
                    t == char_type || t == short_type || t == bool_type ||
-                   t == sbyte_type || t == byte_type || t == ushort_type)
-                       return true;
-               else
-                       return false;
+                   t == sbyte_type || t == byte_type || t == ushort_type);
        }
 
        public static bool IsDelegateType (Type t)
index 6b0f16c08f3cb1eae3f9881bf941156773320cd7..e3c47ff5f86c839fe05d4573bfbb65d0c7a708d2 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-08  Raja R Harinath  <rharinath@novell.com>
+
+       * test-361.cs, test-361-2.cs: New test from #74484.
+
 2005-04-05  Raja R Harinath  <rharinath@novell.com>
 
        * mtest-8-dll.cs, mtest-8-exe.cs: New test from #73820.
index 895786185e93033f2f132bd47c0bc8a766428725..50df1078a440e7d31c069ae21bc61f3f6cc0de9c 100644 (file)
@@ -8,7 +8,7 @@ SUBDIRS =
 include ../build/rules.make
 
 DISTFILES = README.tests harness.mk $(wildcard *.cs) $(wildcard *.il) $(wildcard *.xml) $(wildcard *.inc) \
-       test-353-2.cs
+       test-353-2.cs test-361-2.cs
 
 with_mono_path = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH"
 
@@ -31,7 +31,7 @@ USE_MCS_FLAGS :=
 NEW_TEST_SOURCES_common = xml-033 xml-034 xml-035 xml-036 test-329 2test-16 test-330 a-parameter5 test-331 test-332 \
                          test-333 test-311 test-335 test-336 test-337 test-287 test-338 test-339 test-341 test-334 test-342 \
                          test-344 test-345 test-346 test-347 test-348 test-349 test-350 test-351 test-352 test-353 test-354 test-355 \
-                         test-356 test-357 test-358 test-359 test-360 \
+                         test-356 test-357 test-358 test-359 test-360 test-361 \
        mtest-7-dll mtest-7-exe \
        mtest-8-dll mtest-8-exe
 
@@ -152,7 +152,7 @@ TEST_ORDERING = \
 # Some tests may require additional files to be available in the current directory.
 # To promote interoperability, we prefer that those files not be referred to with ../ or ..\\
 # To that end, we will copy those files to the test-harness directory, so that we can refer to simple filenames.
-TEST_HARNESS_EXTRAS = $(wildcard *.inc) test-74.cs test-353-2.cs
+TEST_HARNESS_EXTRAS = $(wildcard *.inc) test-74.cs test-353-2.cs test-361-2.cs
 
 all-local install-local uninstall-local:
 
diff --git a/mcs/tests/test-361-2.cs b/mcs/tests/test-361-2.cs
new file mode 100644 (file)
index 0000000..99ea411
--- /dev/null
@@ -0,0 +1,5 @@
+// Subordinate test file for test-361.cs
+
+using System;
+[AttributeUsage (AttributeTargets.Class)]
+class X : Attribute { }
diff --git a/mcs/tests/test-361.cs b/mcs/tests/test-361.cs
new file mode 100644 (file)
index 0000000..0809ee0
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: test-361-2.cs
+
+[X]
+class Test {
+       static void Main () { }
+}
index 124e84c2d6ebc00028ba98d4a5a7899b6fe30318..48e22bf83f01ab9992c925b6f632d43987cce3e8 100644 (file)
@@ -1,3 +1,6 @@
+2004-04-08  James Willcox  <james@ximian.com>
+
+       * mkbundle.cs: add a --static flag for statically linking to libmono
 
 Wed Mar 16 18:11:47 CET 2005 Paolo Molaro <lupus@ximian.com>
 
index a804901bdf0015469020968adb92efc4cb0d451f..4b446b92bad088e4ee25bf514cb97a1ea1e59f73 100644 (file)
@@ -23,6 +23,7 @@ class MakeBundle {
        static bool autodeps = false;
        static bool keeptemp = false;
        static bool compile_only = false;
+       static bool static_link = false;
        
        static int Main (string [] args)
        {
@@ -75,7 +76,9 @@ class MakeBundle {
                        case "--keeptemp":
                                keeptemp = true;
                                break;
-                               
+                       case "--static":
+                               static_link = true;
+                               break;
                        default:
                                sources.Add (args [i]);
                                break;
@@ -208,9 +211,19 @@ class MakeBundle {
 
                        if (compile_only)
                                return;
-                       
-                       cmd = String.Format ("cc -o {2} -Wall {0} `pkg-config --cflags --libs mono` {1}",
-                                            temp_c, temp_o, output);
+
+                       if (static_link)
+                               cmd = String.Format ("cc -o {2} -Wall `pkg-config --cflags mono` {0} " +
+                                                    "`pkg-config --libs-only-L mono` -Wl,-Bstatic " +
+                                                    "`pkg-config --libs-only-l mono | sed -e \"s/\\-lm //\" | " +
+                                                    "sed -e \"s/\\-ldl //\" | sed -e \"s/\\-lpthread //\"` " +
+                                                    "-Wl,-Bdynamic -ldl -lm -lrt {1}",
+                                                    temp_c, temp_o, output);
+                       else
+                               cmd = String.Format ("cc -o {2} -Wall {0} `pkg-config --cflags --libs mono` {1}",
+                                                    temp_c, temp_o, output);
+
+                            
                        Console.WriteLine (cmd);
                        ret = system (cmd);
                        if (ret != 0){
@@ -328,7 +341,8 @@ class MakeBundle {
                                   "    -L path     Adds `path' to the search path for assemblies\n" +
                                   "    --nodeps    Turns off automatic dependency embedding (default)\n" +
                                   "    --deps      Turns on automatic dependency embedding\n" +
-                                  "    --keeptemp  Keeps the temporary files\n");
+                                  "    --keeptemp  Keeps the temporary files\n" +
+                                  "    --static    Statically link to mono libs\n");
        }
 
        [DllImport ("libc")]
index a0b8bca196da8fcfa00f66784d10af4e14a76d45..15aae4a49e199176ae8be24f8f72efce2f2515fd 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-07  Zoltan Varga  <vargaz@freemail.hu>
+
+       * mono-service.cs: Fix compilation with csc.
+
 2004-04-06  Joerg Rosenkranz  <joergr@voelcker.com>
 
        * mono-service.cs: 
index 05a9529f34f636894544e901b7bf5ad0bbddc3c5..59b2f571bef6063081e3ee042228e1d988f41841 100644 (file)
@@ -124,7 +124,7 @@ class MonoServiceRunner {
                
                try {
                        a = Assembly.LoadFrom (assembly);
-               } catch (FileNotFoundException fnf) {
+               } catch (FileNotFoundException) {
                        error ("Could not find assembly {0}", assembly);
                        return 1;
                } catch (BadImageFormatException){
@@ -169,13 +169,13 @@ class MonoServiceRunner {
                signal_event.Reset ();
 
                // Hook up 
-               signal (UnixConvert.FromSignum (Signum.SIGTERM), my_handler);
-               signal (UnixConvert.FromSignum (Signum.SIGUSR1), my_handler);
-               signal (UnixConvert.FromSignum (Signum.SIGUSR2), my_handler);
+               signal (UnixConvert.FromSignum (Signum.SIGTERM), new sighandler_t (my_handler));
+               signal (UnixConvert.FromSignum (Signum.SIGUSR1), new sighandler_t (my_handler));
+               signal (UnixConvert.FromSignum (Signum.SIGUSR2), new sighandler_t (my_handler));
 
                // Start up the service.
 
-               ServiceBase service;
+               ServiceBase service = null;
                
                if (name != null){
                        foreach (ServiceBase svc in services){
index ee58ea4bfab221cdd29ca9214fce4d4870d22fd8..31f34abc7bb88898a2322de9cdea088dc9f20c1e 100644 (file)
@@ -1,3 +1,12 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * io-private.h:
+       * threads.c:
+       * threads.h:
+       * io.c:
+       * sockets.c:
+       * sockets.h: removed dead code that deals with async IO.
+
 2005-03-30  Zoltan Varga  <vargaz@freemail.hu>
 
        * atomic.c (InterlockedIncrement): Fix fallback implementation of
index 0fd2b4a7d4bec586e697c34a555b0913571306b9..1ff3ea9a144dddb32aee7d0a6754996db83e621d 100644 (file)
@@ -37,8 +37,6 @@ struct _WapiHandle_file
 struct _WapiHandlePrivate_file
 {
        WapiFDMapped fd_mapped;
-       gboolean async;
-       WapiOverlappedCB callback;
 };
 
 struct _WapiHandle_find
@@ -56,9 +54,6 @@ struct _WapiHandlePrivate_find
 
 G_BEGIN_DECLS
 int _wapi_file_handle_to_fd (gpointer handle);
-gboolean _wapi_io_add_callback (gpointer handle,
-                               WapiOverlappedCB callback,
-                               guint64 flags);
 G_END_DECLS
 
 #endif /* _WAPI_IO_PRIVATE_H_ */
index 86bad7f756cefbcde416bd76b8f3d71b5d3dcb9a..443eb41eb4b1f5917319b147bf606c9568d2ee21 100644 (file)
 #include <stdio.h>
 #include <utime.h>
 
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_AIO_H
-#include <aio.h>
-#define USE_AIO        1
-#elif defined(HAVE_SYS_AIO_H)
-#include <sys/aio.h>
-#define USE_AIO 1
-#else
-#undef USE_AIO
-#endif
-#endif
-
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/handles-private.h>
@@ -286,38 +274,6 @@ static WapiFileType file_getfiletype(void)
        return(FILE_TYPE_DISK);
 }
 
-#ifdef USE_AIO
-typedef struct {
-       struct aiocb *aio;
-       WapiOverlapped *overlapped;
-       WapiOverlappedCB callback;
-} notifier_data_t;
-
-#define SIGPTR(a) a.SIGVAL_PTR
-
-static void
-async_notifier (union sigval sig)
-{
-       notifier_data_t *ndata = SIGPTR (sig);
-       guint32 error;
-       guint32 numbytes;
-
-       error = aio_return (ndata->aio);
-       if (error < 0) {
-               error = _wapi_get_win32_file_error (error);
-               numbytes = 0;
-       } else {
-               numbytes = error;
-               error = 0;
-       }
-
-       ndata->callback (error, numbytes, ndata->overlapped);
-       g_free (ndata->aio);
-       g_free (ndata);
-}
-
-#endif /* USE_AIO */
-
 static gboolean file_read(gpointer handle, gpointer buffer,
                          guint32 numbytes, guint32 *bytesread,
                          WapiOverlapped *overlapped)
@@ -356,90 +312,30 @@ static gboolean file_read(gpointer handle, gpointer buffer,
                return(FALSE);
        }
 
-       if (file_private_handle->async == FALSE) {
-               do {
-                       ret=read(file_private_handle->fd_mapped.fd, buffer,
-                                numbytes);
-               }
-               while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
-                       
-               if(ret==-1) {
-                       gint err = errno;
-
-#ifdef DEBUG
-                       g_message(G_GNUC_PRETTY_FUNCTION
-                                 ": read of handle %p fd %d error: %s", handle,
-                                 file_private_handle->fd_mapped.fd,
-                                 strerror(err));
-#endif
-                       SetLastError (_wapi_get_win32_file_error (err));
-                       return(FALSE);
-               }
-               
-               if(bytesread!=NULL) {
-                       *bytesread=ret;
-               }
-               
-               return(TRUE);
-       }
-
-#ifndef USE_AIO
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return FALSE;
-#else
-       if (overlapped == NULL || file_private_handle->callback == NULL) {
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return FALSE;
-       }
-
-       {
-       int fd = file_private_handle->fd_mapped.fd;
-       struct aiocb *aio;
-       int result;
-       notifier_data_t *ndata;
-
-       ndata = g_new0 (notifier_data_t, 1);
-       aio = g_new0 (struct aiocb, 1);
-       ndata->overlapped = overlapped;
-       ndata->aio = aio;
-       ndata->callback = file_private_handle->callback;
-
-       aio->aio_fildes = fd;
-       aio->aio_lio_opcode = LIO_READ;
-       aio->aio_nbytes = numbytes;
-       aio->aio_offset = overlapped->Offset + (((gint64) overlapped->OffsetHigh) << 32);
-       aio->aio_buf = buffer;
-       aio->aio_sigevent.sigev_notify = SIGEV_THREAD;
-       aio->aio_sigevent.sigev_notify_function = async_notifier;
-       SIGPTR (aio->aio_sigevent.sigev_value) = ndata;
-
-       result = aio_read (aio);
-       if (result == -1) {
-               _wapi_set_last_error_from_errno ();
-               return FALSE;
+       do {
+               ret=read(file_private_handle->fd_mapped.fd, buffer,
+                        numbytes);
        }
+       while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+               
+       if(ret==-1) {
+               gint err = errno;
 
-       result = aio_error (aio);
-#ifdef DEBUG
-       g_print ("aio_error (read) returned %d for %d\n", result, fd);
-#endif
-       if (result == 0) {
-               numbytes = aio_return (aio);
 #ifdef DEBUG
-               g_print ("numbytes %d for %d\n", numbytes, fd);
+               g_message(G_GNUC_PRETTY_FUNCTION
+                         ": read of handle %p fd %d error: %s", handle,
+                         file_private_handle->fd_mapped.fd,
+                         strerror(err));
 #endif
-       } else {
-               errno = result;
-               _wapi_set_last_error_from_errno ();
-               return FALSE;
+               SetLastError (_wapi_get_win32_file_error (err));
+               return(FALSE);
        }
-
-       if (bytesread)
-               *bytesread = numbytes;
-
-       return TRUE;
+       
+       if(bytesread!=NULL) {
+               *bytesread=ret;
        }
-#endif
+       
+       return(TRUE);
 }
 
 static gboolean file_write(gpointer handle, gconstpointer buffer,
@@ -450,6 +346,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
        struct _WapiHandlePrivate_file *file_private_handle;
        gboolean ok;
        int ret;
+       off_t current_pos;
        
        ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
                                (gpointer *)&file_handle,
@@ -480,116 +377,54 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
                return(FALSE);
        }
        
-       if (file_private_handle->async == FALSE) {
-               off_t current_pos;
-               
-               /* Need to lock the region we're about to write to,
-                * because we only do advisory locking on POSIX
-                * systems
-                */
-               current_pos = lseek (file_private_handle->fd_mapped.fd,
-                                    (off_t)0, SEEK_CUR);
-               if (current_pos == -1) {
-#ifdef DEBUG
-                       g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d lseek failed: %s", handle, file_private_handle->fd_mapped.fd, strerror (errno));
-#endif
-                       _wapi_set_last_error_from_errno ();
-                       return(FALSE);
-               }
-               
-               if (_wapi_lock_file_region (file_private_handle->fd_mapped.fd,
-                                           current_pos, numbytes) == FALSE) {
-                       /* The error has already been set */
-                       return(FALSE);
-               }
-               
-               do {
-                       ret=write(file_private_handle->fd_mapped.fd, buffer,
-                                 numbytes);
-               }
-               while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
-
-               _wapi_unlock_file_region (file_private_handle->fd_mapped.fd,
-                                         current_pos, numbytes);
-
-               if (ret == -1) {
-                       if (errno == EINTR) {
-                               ret = 0;
-                       } else {
-                               _wapi_set_last_error_from_errno ();
+       /* Need to lock the region we're about to write to,
+        * because we only do advisory locking on POSIX
+        * systems
+        */
+       current_pos = lseek (file_private_handle->fd_mapped.fd,
+                            (off_t)0, SEEK_CUR);
+       if (current_pos == -1) {
 #ifdef DEBUG
-                       g_message(G_GNUC_PRETTY_FUNCTION
-                                 ": write of handle %p fd %d error: %s", handle,
-                                 file_private_handle->fd_mapped.fd,
-                                 strerror(errno));
+               g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d lseek failed: %s", handle, file_private_handle->fd_mapped.fd, strerror (errno));
 #endif
-
-                               return(FALSE);
-                       }
-               }
-               if(byteswritten!=NULL) {
-                       *byteswritten=ret;
-               }
-               return(TRUE);
+               _wapi_set_last_error_from_errno ();
+               return(FALSE);
        }
-
-#ifndef USE_AIO
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return FALSE;
-#else
-       if (overlapped == NULL || file_private_handle->callback == NULL) {
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return FALSE;
+       
+       if (_wapi_lock_file_region (file_private_handle->fd_mapped.fd,
+                                   current_pos, numbytes) == FALSE) {
+               /* The error has already been set */
+               return(FALSE);
        }
-
-       {
-       int fd = file_private_handle->fd_mapped.fd;
-       struct aiocb *aio;
-       int result;
-       notifier_data_t *ndata;
-
-       ndata = g_new0 (notifier_data_t, 1);
-       aio = g_new0 (struct aiocb, 1);
-       ndata->overlapped = overlapped;
-       ndata->aio = aio;
-       ndata->callback = file_private_handle->callback;
-
-       aio->aio_fildes = fd;
-       aio->aio_lio_opcode = LIO_WRITE;
-       aio->aio_nbytes = numbytes;
-       aio->aio_offset = overlapped->Offset + (((gint64) overlapped->OffsetHigh) << 32);
-       aio->aio_buf = (gpointer) buffer;
-       aio->aio_sigevent.sigev_notify = SIGEV_THREAD;
-       aio->aio_sigevent.sigev_notify_function = async_notifier;
-       SIGPTR (aio->aio_sigevent.sigev_value) = ndata;
-
-       result = aio_write (aio);
-       if (result == -1) {
-               _wapi_set_last_error_from_errno ();
-               return FALSE;
+       
+       do {
+               ret=write(file_private_handle->fd_mapped.fd, buffer,
+                         numbytes);
        }
+       while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
 
-       result = aio_error (aio);
-#ifdef DEBUG
-       g_print ("aio_error (write) returned %d for %d\n", result, fd);
-#endif
-       if (result == 0) {
-               numbytes = aio_return (aio);
+       _wapi_unlock_file_region (file_private_handle->fd_mapped.fd,
+                                 current_pos, numbytes);
+
+       if (ret == -1) {
+               if (errno == EINTR) {
+                       ret = 0;
+               } else {
+                       _wapi_set_last_error_from_errno ();
 #ifdef DEBUG
-       g_print ("numbytes %d for %d\n", numbytes, fd);
+               g_message(G_GNUC_PRETTY_FUNCTION
+                         ": write of handle %p fd %d error: %s", handle,
+                         file_private_handle->fd_mapped.fd,
+                         strerror(errno));
 #endif
-       } else {
-               errno = result;
-               _wapi_set_last_error_from_errno ();
-               return FALSE;
-       }
 
-       if (byteswritten)
-               *byteswritten = numbytes;
-
-       return TRUE;
+                       return(FALSE);
+               }
        }
-#endif
+       if(byteswritten!=NULL) {
+               *byteswritten=ret;
+       }
+       return(TRUE);
 }
 
 static gboolean file_flush(gpointer handle)
@@ -1873,7 +1708,6 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
 
        file_private_handle->fd_mapped.fd=fd;
        file_private_handle->fd_mapped.assigned=TRUE;
-       file_private_handle->async = ((attrs & FILE_FLAG_OVERLAPPED) != 0);
        file_handle->filename=_wapi_handle_scratch_store (filename,
                                                          strlen (filename));
        if(security!=NULL) {
@@ -4019,60 +3853,6 @@ guint32 GetTempPath (guint32 len, gunichar2 *buf)
        return(ret);
 }
 
-gboolean
-_wapi_io_add_callback (gpointer fd_handle,
-                      WapiOverlappedCB callback,
-                      guint64 flags G_GNUC_UNUSED)
-{
-       struct _WapiHandle_file *file_handle;
-       struct _WapiHandlePrivate_file *file_private_handle;
-       gboolean ok;
-       int thr_ret;
-       gboolean ret = FALSE;
-       gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
-       
-       if (handle == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(FALSE);
-       }
-       
-       ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
-                                 (gpointer *) &file_handle,
-                                 (gpointer *) &file_private_handle);
-
-       if (ok == FALSE) {
-               ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
-                                         (gpointer *) &file_handle,
-                                         (gpointer *) &file_private_handle);
-
-       }
-
-       if (ok == FALSE || file_private_handle->async == FALSE) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
-                             handle);
-       thr_ret = _wapi_handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-       
-       if (file_private_handle->callback != NULL) {
-               SetLastError (ERROR_INVALID_PARAMETER);
-               goto cleanup;
-       }
-       ret = TRUE;
-       
-       file_private_handle->callback = callback;
-
-cleanup:
-       thr_ret = _wapi_handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
-
-       return(ret);
-}
-
 gint32
 GetLogicalDriveStrings (guint32 len, gunichar2 *buf)
 {
index 9954ef14a9e01a7a17a10dd93260e9d86815f15d..25a92970e8c3cab01efd06413755040ef8b2b83e 100644 (file)
 #include <signal.h>
 #endif
 
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_AIO_H
-#include <aio.h>
-#define USE_AIO        1
-#elif defined(HAVE_SYS_AIO_H)
-#include <sys/aio.h>
-#define USE_AIO 1
-#else
-#undef USE_AIO
-#endif
-#endif
-
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/socket-private.h>
@@ -1063,110 +1051,3 @@ void _wapi_FD_SET(guint32 fd, fd_set *set)
        FD_SET(fd, set);
 }
 
-#ifdef USE_AIO
-
-typedef struct {
-       struct aiocb *aio;
-       gpointer ares;
-       SocketAsyncCB callback;
-} notifier_data_t;
-
-#define SIGPTR(a) a.SIGVAL_PTR
-
-static void
-async_notifier (union sigval sig)
-{
-       notifier_data_t *ndata = SIGPTR (sig);
-       guint32 error;
-       guint32 numbytes;
-
-       error = aio_return (ndata->aio);
-       if (error < 0) {
-               error = _wapi_get_win32_file_error (error);
-               numbytes = 0;
-       } else {
-               numbytes = error;
-               error = 0;
-       }
-
-       ndata->callback (error, numbytes, ndata->ares);
-       g_free (ndata->aio);
-       g_free (ndata);
-}
-
-static gboolean
-do_aio_call (gboolean is_read, gpointer fd_handle, gpointer buffer,
-               guint32 numbytes, guint32 *out_bytes,
-               gpointer ares,
-               SocketAsyncCB callback)
-{
-       gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
-       int fd = GPOINTER_TO_UINT (fd_handle);
-       struct aiocb *aio;
-       int result;
-       notifier_data_t *ndata;
-       
-       if (handle == NULL ||
-           _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
-               WSASetLastError (WSAENOTSOCK);
-               return FALSE;
-       }
-
-       ndata = g_new0 (notifier_data_t, 1);
-       aio = g_new0 (struct aiocb, 1);
-       ndata->ares = ares;
-       ndata->aio = aio;
-       ndata->callback = callback;
-
-       aio->aio_fildes = fd;
-       aio->aio_lio_opcode = (is_read) ? LIO_READ : LIO_WRITE;
-       aio->aio_nbytes = numbytes;
-       aio->aio_offset = 0;
-       aio->aio_buf = buffer;
-       aio->aio_sigevent.sigev_notify = SIGEV_THREAD;
-       aio->aio_sigevent.sigev_notify_function = async_notifier;
-       SIGPTR (aio->aio_sigevent.sigev_value) = ndata;
-
-       if (is_read) {
-               result = aio_read (aio);
-       } else {
-               result = aio_write (aio);
-       }
-
-       if (result == -1) {
-               WSASetLastError (errno_to_WSA (errno, "do_aio_call"));
-               return FALSE;
-       }
-
-       result = aio_error (aio);
-       if (result == 0) {
-               numbytes = aio_return (aio);
-       } else {
-               WSASetLastError (errno_to_WSA (result, "do_aio_call"));
-               return FALSE;
-       }
-
-       if (out_bytes)
-               *out_bytes = numbytes;
-
-       return TRUE;
-}
-
-gboolean _wapi_socket_async_read (gpointer handle, gpointer buffer,
-                                 guint32 numbytes,
-                                 guint32 *bytesread, gpointer ares,
-                                 SocketAsyncCB callback)
-{
-       return do_aio_call (TRUE, handle, buffer, numbytes, bytesread, ares, callback);
-}
-
-gboolean _wapi_socket_async_write (gpointer handle, gpointer buffer,
-                                 guint32 numbytes,
-                                 guint32 *byteswritten, gpointer ares,
-                                 SocketAsyncCB callback)
-{
-       return do_aio_call (FALSE, handle, buffer, numbytes, byteswritten, ares, callback);
-}
-
-#endif /* USE_AIO */
-
index 19268c9b68b8f831c46bcc2beb3372859260a9da..371c63e50d1980830134f152a55fe929679fb969 100644 (file)
@@ -49,18 +49,4 @@ extern int WSAIoctl (guint32 handle, gint32 command,
                     gchar *output, gint o_len, glong *written,
                     void *unused1, void *unused2);
 
-#ifndef PLATFORM_WIN32
-typedef void (*SocketAsyncCB) (guint32 error, guint32 numbytes, gpointer ares);
-
-gboolean _wapi_socket_async_read (gpointer handle, gpointer buffer,
-                                 guint32 numbytes,
-                                 guint32 *bytesread, gpointer ares,
-                                 SocketAsyncCB callback);
-
-gboolean _wapi_socket_async_write (gpointer handle, gpointer buffer,
-                                 guint32 numbytes,
-                                 guint32 *bytesread, gpointer ares,
-                                 SocketAsyncCB callback);
-#endif
-
 #endif /* _WAPI_SOCKETS_H_ */
index 3ebda7c2a59507b19129e0682eae09e782528944..08868769da1b64fcc69302f55e36e5ac6d49ce32 100644 (file)
@@ -933,21 +933,6 @@ void Sleep(guint32 ms)
        SleepEx(ms, FALSE);
 }
 
-gboolean
-BindIoCompletionCallback (gpointer handle,
-                         WapiOverlappedCB callback,
-                         guint64 flags)
-{
-       WapiHandleType type;
-       
-       type = _wapi_handle_type (handle);
-       if (type == WAPI_HANDLE_FILE || type == WAPI_HANDLE_PIPE)
-               return _wapi_io_add_callback (handle, callback, flags);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return FALSE;
-}
-
 guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, 
                                        gpointer param)
 {
index b9602c8373ce0ed584ee6888fe901b291b1d94f9..996788b9d487ed822ca876c0a728663a291fdd5b 100644 (file)
@@ -55,10 +55,6 @@ extern gpointer TlsGetValue(guint32 idx);
 extern gboolean TlsSetValue(guint32 idx, gpointer value);
 extern void Sleep(guint32 ms);
 extern guint32 SleepEx(guint32 ms, gboolean alertable);
-extern gboolean BindIoCompletionCallback (gpointer handle,
-                                         WapiOverlappedCB callback,
-                                         guint64 flags);
-
 extern guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer thread_handle, 
                                        gpointer param);
 
index 465b1171dd2d318142ae222e9aa0d8f705646722..a561f41290efe6220d338d049ef067d25e571fd2 100644 (file)
@@ -1,3 +1,25 @@
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * file-io.c:
+       * file-io.h:
+       * threadpool.c:
+       * threadpool.h:
+       * icall.c:
+       * socket-io.c: removed dead code for async IO.
+
+2005-04-07 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * socket-io.h: 2 more fields in MonoSocketAsyncResult.
+
+       * threadpool.c: intercept socket async. calls and pass them to a thread
+       that is polling and dispatching the job items to the threadpool as
+       socket become ready. Fixes bugs #71217, #71933.
+
+       * icall.c: Removed AsyncReceive and AsyncSend. Speed up for copies
+       between char and short/ushort arrays.
+
+       * socket-io.c: remove dead code.
+
 2005-04-06  Atsushi Enomoto  <atsushi@ximian.com>
 
        * locales.c,
index b9283b677705807ec1f584e48f02bb0d3752bece..ebd97d9de87be40a9485400a07e71bbfcc6986fb 100644 (file)
 #include <signal.h>
 #include <unistd.h>
 
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_AIO_H
-#include <aio.h>
-#define USE_AIO        1
-#elif defined(HAVE_SYS_AIO_H)
-#include <sys/aio.h>
-#define USE_AIO 1
-#else
-#undef USE_AIO
-#endif
-#endif
-
 #include <mono/metadata/object.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/file-io.h>
@@ -918,73 +906,6 @@ ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name)
        return(ret);
 }
 
-/*
- * Asynchronous IO
- */
-MonoBoolean
-ves_icall_System_IO_MonoIO_GetSupportsAsync (void)
-{
-       MONO_ARCH_SAVE_REGS;
-
-#ifdef PLATFORM_WIN32
-       /* Seems like BindIoCompletionCallback is not found when compiling...
-        * Disabling AIO support on win. Any one wants to fix this?
-        */
-       return FALSE;   
-       /* return (g_getenv ("MONO_DISABLE_AIO") == NULL && WINVER >= 0x500); */
-#elif defined(USE_AIO)
-       return FALSE;
-       /* Disabled. See bug 73718. We can enable this again if we have
-        * a thread that handles socket/file IO
-        *
-       if (aio_cancel (-1, NULL) == -1 && errno == ENOSYS)
-               return FALSE;
-
-       return (g_getenv ("MONO_DISABLE_AIO") == NULL);
-       */
-#else
-       return FALSE;
-#endif
-}
-
-static WapiOverlapped *
-get_overlapped_from_fsa (MonoFSAsyncResult *ares)
-{
-       WapiOverlapped *ovl;
-
-       ovl = g_new0 (WapiOverlapped, 1);
-       ovl->Offset = ares->offset;
-       ovl->hEvent = ares->wait_handle;
-
-       return ovl;
-}
-
-MonoBoolean
-ves_icall_System_IO_MonoIO_BeginRead (HANDLE handle, MonoFSAsyncResult *ares)
-{
-       guint32 bytesread;
-       WapiOverlapped *ovl;
-
-       MONO_ARCH_SAVE_REGS;
-
-       ovl = get_overlapped_from_fsa (ares);
-       ovl->handle1 = ares;
-       return ReadFile (handle, mono_array_addr (ares->buffer, gchar, ares->offset), ares->count, &bytesread, ovl);
-}
-
-MonoBoolean
-ves_icall_System_IO_MonoIO_BeginWrite (HANDLE handle, MonoFSAsyncResult *ares)
-{
-       guint32 byteswritten;
-       WapiOverlapped *ovl;
-
-       MONO_ARCH_SAVE_REGS;
-
-       ovl = get_overlapped_from_fsa (ares);
-       ovl->handle1 = ares;
-       return WriteFile (handle, mono_array_addr (ares->buffer, gchar, ares->offset), ares->count, &byteswritten, ovl);
-}
-
 void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                      gint64 length, gint32 *error)
 {
index 55ce838308783e6f9844e1c2967ed5b4671c58ca..b3f8b9f48f5455a159edebc29a148525ce1f1224 100644 (file)
@@ -95,21 +95,6 @@ typedef struct _MonoFSAsyncResult {
        MonoDelegate *real_cb;
 } MonoFSAsyncResult;
 
-#ifdef PLATFORM_WIN32
-typedef struct _WapiOverlapped WapiOverlapped;
-
-struct _WapiOverlapped
-{
-       guint32 Internal;
-       guint32 InternalHigh;
-       guint32 Offset;
-       guint32 OffsetHigh;
-       gpointer hEvent;
-       gpointer handle1;
-       gpointer handle2;
-};
-#endif
-
 /* System.IO.MonoIO */
 
 extern MonoBoolean
@@ -229,15 +214,6 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars (void);
 extern gint32
 ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name);
 
-extern MonoBoolean
-ves_icall_System_IO_MonoIO_GetSupportsAsync (void);
-
-extern MonoBoolean
-ves_icall_System_IO_MonoIO_BeginRead (HANDLE handle, MonoFSAsyncResult *ares);
-
-extern MonoBoolean
-ves_icall_System_IO_MonoIO_BeginWrite (HANDLE handle, MonoFSAsyncResult *ares);
-
 extern void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                             gint64 length, gint32 *error);
 extern void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
index 5596c6c3ca4319b54c7d7ee4a9c03ad0baffd802..0e5c04801207970086721810a03c9a6f354b0e74 100644 (file)
@@ -562,6 +562,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
        MonoClass *src_class;
        MonoClass *dest_class;
        int i;
+       gboolean char_int16;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -606,7 +607,13 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
                return TRUE;
        }
 
-       if (src_class != dest_class) {
+       /* Check if we're copying a char[] <==> (u)short[] */
+       char_int16 = (src_class == mono_defaults.int16_class || src_class == mono_defaults.uint16_class ||
+                               src_class == mono_defaults.char_class);
+       char_int16 = (char_int16 && (dest_class == mono_defaults.int16_class || dest_class == mono_defaults.uint16_class ||
+                               dest_class == mono_defaults.char_class));
+
+       if (!char_int16 && src_class != dest_class) {
                if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
                        return FALSE;
 
@@ -6053,8 +6060,6 @@ static const IcallEntry path_icalls [] = {
 };
 
 static const IcallEntry monoio_icalls [] = {
-       {"BeginRead", ves_icall_System_IO_MonoIO_BeginRead },
-       {"BeginWrite", ves_icall_System_IO_MonoIO_BeginWrite },
        {"Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close},
        {"CopyFile(string,string,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CopyFile},
        {"CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CreateDirectory},
@@ -6069,7 +6074,6 @@ static const IcallEntry monoio_icalls [] = {
        {"GetFileStat(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileStat},
        {"GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType},
        {"GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength},
-       {"GetSupportsAsync", ves_icall_System_IO_MonoIO_GetSupportsAsync},
        {"GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath},
        {"Lock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Lock},
        {"MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile},
@@ -6296,8 +6300,6 @@ static const IcallEntry dns_icalls [] = {
 
 static const IcallEntry socket_icalls [] = {
        {"Accept_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Accept_internal},
-       {"AsyncReceiveInternal", ves_icall_System_Net_Sockets_Socket_AsyncReceive},
-       {"AsyncSendInternal", ves_icall_System_Net_Sockets_Socket_AsyncSend},
        {"Available_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Available_internal},
        {"Bind_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Bind_internal},
        {"Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal},
@@ -6305,7 +6307,6 @@ static const IcallEntry socket_icalls [] = {
        {"Connect_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Connect_internal},
        {"GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal},
        {"GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal},
-       {"GetSupportsAsync", ves_icall_System_IO_MonoIO_GetSupportsAsync},
        {"Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal},
        {"LocalEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal},
        {"Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal},
@@ -6598,7 +6599,6 @@ static const IcallEntry thread_icalls [] = {
 };
 
 static const IcallEntry threadpool_icalls [] = {
-       {"BindHandleInternal", ves_icall_System_Threading_ThreadPool_BindHandle},
        {"GetAvailableThreads", ves_icall_System_Threading_ThreadPool_GetAvailableThreads},
        {"GetMaxThreads", ves_icall_System_Threading_ThreadPool_GetMaxThreads},
        {"GetMinThreads", ves_icall_System_Threading_ThreadPool_GetMinThreads},
index 264a7dacb8cae09ae3a15d4a2b7f0f754b646324..5aeca9b713cb3016364cde7d10ce6c641d52dccb 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_AIO_H
-#include <aio.h>
-#define USE_AIO        1
-#elif defined(HAVE_SYS_AIO_H)
-#include <sys/aio.h>
-#define USE_AIO 1
-#else
-#undef USE_AIO
-#endif
-#endif
-
 #include <mono/metadata/object.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/socket-io.h>
@@ -2362,92 +2350,6 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostName_internal(MonoString **h_
        return(TRUE);
 }
 
-
-/* Async interface */
-#ifndef USE_AIO
-void
-ves_icall_System_Net_Sockets_Socket_AsyncReceive (MonoSocketAsyncResult *ares, gint *error)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       *error = ERROR_NOT_SUPPORTED;
-}
-
-void
-ves_icall_System_Net_Sockets_Socket_AsyncSend (MonoSocketAsyncResult *ares, gint *error)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       *error = ERROR_NOT_SUPPORTED;
-}
-#else
-static void
-wsa_overlapped_callback (guint32 error, guint32 numbytes, gpointer result)
-{
-       MonoSocketAsyncResult *ares = (MonoSocketAsyncResult *) result;
-       MonoThread *thread;
-       ares->completed = TRUE;
-       ares->error = error;
-       ares->total = numbytes;
-
-       if (ares->callback != NULL) {
-               gpointer p [1];
-
-               *p = ares;
-               thread = mono_thread_attach (mono_object_domain (ares));
-               mono_runtime_invoke (ares->callback->method_info->method, NULL, p, NULL);
-
-               mono_thread_detach (thread);
-       }
-
-       if (ares->wait_handle != NULL)
-               SetEvent (ares->wait_handle->handle);
-}
-
-void
-ves_icall_System_Net_Sockets_Socket_AsyncReceive (MonoSocketAsyncResult *ares, gint *error)
-{
-       gint32 bytesread;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (_wapi_socket_async_read (ares->handle,
-                                       mono_array_addr (ares->buffer, gchar, ares->offset),
-                                       ares->size,
-                                       &bytesread,
-                                       ares,
-                                       wsa_overlapped_callback) == FALSE) {
-               *error = WSAGetLastError ();
-       } else {
-               *error = 0;
-               ares->completed_synch = TRUE;
-               wsa_overlapped_callback (0, bytesread, ares);
-       }
-}
-
-void
-ves_icall_System_Net_Sockets_Socket_AsyncSend (MonoSocketAsyncResult *ares, gint *error)
-{
-       gint32 byteswritten;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (_wapi_socket_async_write (ares->handle,
-                                       mono_array_addr (ares->buffer, gchar, ares->offset),
-                                       ares->size,
-                                       &byteswritten,
-                                       ares,
-                                       wsa_overlapped_callback) == FALSE) {
-               *error = WSAGetLastError ();
-       } else {
-               *error = 0;
-               ares->completed_synch = TRUE;
-               wsa_overlapped_callback (0, byteswritten, ares);
-       }
-}
-#endif /* USE_AIO */
-
 void mono_network_init(void)
 {
        WSADATA wsadata;
index 5c2ee72181aba0cd18958c915d250ca7c07b77c0..521b2ffa6ad56576011468cc46ff7fa88e41468f 100644 (file)
@@ -157,6 +157,8 @@ typedef struct _MonoSocketAsyncResult {
        MonoBoolean completed;
        MonoDelegate *real_callback;
        gint error;
+       gint operation;
+       MonoAsyncResult *ares;
 } MonoSocketAsyncResult;
 
 typedef struct
@@ -193,9 +195,6 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *a
 extern MonoBoolean ves_icall_System_Net_Dns_GetHostName_internal(MonoString **h_name);
 extern MonoBoolean ves_icall_System_Net_Sockets_Socket_Poll_internal (SOCKET sock, gint mode, gint timeout, gint32 *error);
 
-extern void ves_icall_System_Net_Sockets_Socket_AsyncReceive (MonoSocketAsyncResult *ares, gint *error);
-extern void ves_icall_System_Net_Sockets_Socket_AsyncSend (MonoSocketAsyncResult *ares, gint *error);
-
 extern void mono_network_init(void);
 extern void mono_network_cleanup(void);
 
index c4a764e02ea9e5d95274677f58aedacb1a03de6f..cc64df75fc281effa2698f0f247cda572ca4de69 100644 (file)
@@ -6,7 +6,7 @@
  *   Gonzalo Paniagua Javier (gonzalo@ximian.com)
  *
  * (C) 2001-2003 Ximian, Inc.
- * (c) 2004 Novell, Inc. (http://www.novell.com)
+ * (c) 2004,2005 Novell, Inc. (http://www.novell.com)
  */
 
 #include <config.h>
 #include <mono/metadata/file-io.h>
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/socket-io.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/os/gc_wrapper.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <mono/utils/mono-poll.h>
 
 #include "threadpool.h"
 
@@ -51,6 +60,18 @@ static MonoGHashTable *ares_htable = NULL;
 
 static CRITICAL_SECTION ares_lock;
 
+typedef struct {
+       CRITICAL_SECTION io_lock; /* access to sock_to_state */
+       int inited;
+       int pipe [2];
+       GHashTable *sock_to_state;
+
+       HANDLE new_sem; /* access to newpfd and write side of the pipe */
+       mono_pollfd *newpfd;
+} SocketIOData;
+
+static SocketIOData socket_io_data;
+
 /* we append a job */
 static HANDLE job_added;
 
@@ -66,9 +87,344 @@ typedef struct {
 
 static void async_invoke_thread (gpointer data);
 static void append_job (MonoAsyncResult *ar);
+static void start_thread_or_queue (MonoAsyncResult *ares);
 
 static GList *async_call_queue = NULL;
 
+static MonoClass *socket_async_call_klass;
+
+#define INIT_POLLFD(a, b, c) {(a)->fd = b; (a)->events = c; (a)->revents = 0;}
+enum {
+       AIO_FIRST,
+       AIO_ACCEPT = 0,
+       AIO_CONNECT,
+       AIO_RECEIVE,
+       AIO_RECEIVEFROM,
+       AIO_SEND,
+       AIO_SENDTO,
+       AIO_LAST
+};
+
+static void
+socket_io_cleanup (SocketIOData *data)
+{
+       if (data->inited == 0)
+               return;
+
+       EnterCriticalSection (&data->io_lock);
+       data->inited = 0;
+       close (data->pipe [0]);
+       data->pipe [0] = -1;
+       close (data->pipe [1]);
+       data->pipe [1] = -1;
+       CloseHandle (data->new_sem);
+       data->new_sem = NULL;
+       g_hash_table_destroy (data->sock_to_state);
+       data->sock_to_state = NULL;
+       LeaveCriticalSection (&data->io_lock);
+}
+
+static int
+get_event_from_state (MonoSocketAsyncResult *state)
+{
+       switch (state->operation) {
+       case AIO_ACCEPT:
+       case AIO_RECEIVE:
+       case AIO_RECEIVEFROM:
+               return MONO_POLLIN;
+       case AIO_SEND:
+       case AIO_SENDTO:
+       case AIO_CONNECT:
+               return MONO_POLLOUT;
+       default: /* Should never happen */
+               g_print ("socket_io_add: unknown value in switch!!!\n");
+               return 0;
+       }
+}
+
+static int
+get_events_from_list (GSList *list)
+{
+       MonoSocketAsyncResult *state;
+       int events = 0;
+
+       while (list && list->data) {
+               state = (MonoSocketAsyncResult *) list->data;
+               events |= get_event_from_state (state);
+               list = list->next;
+       }
+
+       return events;
+}
+
+static GSList *
+process_io_event (GSList *list, int event)
+{
+       MonoSocketAsyncResult *state;
+       GSList *oldlist;
+
+       oldlist = list;
+       state = NULL;
+       while (list) {
+               state = (MonoSocketAsyncResult *) list->data;
+               if (get_event_from_state (state) == event)
+                       break;
+               list = list->next;
+       }
+
+       if (list != NULL) {
+               oldlist = g_slist_remove_link (oldlist, list);
+               g_slist_free_1 (list);
+               start_thread_or_queue (state->ares);
+       }
+
+       return oldlist;
+}
+
+static int
+mark_bad_fds (mono_pollfd *pfds, int nfds)
+{
+       int i, ret;
+       mono_pollfd *pfd;
+       int count = 0;
+
+       for (i = 0; i < nfds; i++) {
+               pfd = &pfds [i];
+               if (pfd->fd == -1)
+                       continue;
+
+               ret = mono_poll (pfds, 1, 0);
+               if (ret == -1 && errno == EBADF) {
+                       pfd->revents |= MONO_POLLNVAL;
+                       count++;
+               } else if (ret == 1) {
+                       count++;
+               }
+       }
+
+       return count;
+}
+
+static void
+socket_io_main (gpointer p)
+{
+#define INITIAL_POLLFD_SIZE    1024
+#define POLL_ERRORS (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)
+       SocketIOData *data = p;
+       mono_pollfd *pfds;
+       gint maxfd = 1;
+       gint allocated;
+       gint i;
+       MonoThread *thread;
+
+       thread = mono_thread_current ();
+       thread->threadpool_thread = TRUE;
+       thread->state |= ThreadState_Background;
+
+       allocated = INITIAL_POLLFD_SIZE;
+       pfds = g_new0 (mono_pollfd, allocated);
+       INIT_POLLFD (pfds, data->pipe [0], MONO_POLLIN);
+       for (i = 1; i < allocated; i++)
+               INIT_POLLFD (&pfds [i], -1, 0);
+
+       while (1) {
+               int nsock = 0;
+               mono_pollfd *pfd;
+               char one [1];
+               GSList *list;
+
+               do {
+                       if (nsock == -1) {
+                               if ((thread->state & ThreadState_StopRequested) != 0)
+                                       mono_thread_interruption_checkpoint ();
+                       }
+
+                       nsock = mono_poll (pfds, maxfd, -1);
+               } while (nsock == -1 && errno == EINTR);
+
+               /* 
+                * Apart from EINTR, we only check EBADF, for the rest:
+                *  EINVAL: mono_poll() 'protects' us from descriptor
+                *      numbers above the limit if using select() by marking
+                *      then as MONO_POLLERR.  If a system poll() is being
+                *      used, the number of descriptor we're passing will not
+                *      be over sysconf(_SC_OPEN_MAX), as the error would have
+                *      happened when opening.
+                *
+                *  EFAULT: we own the memory pointed by pfds.
+                *  ENOMEM: we're doomed anyway
+                *
+                */
+
+               if (nsock == -1 && errno == EBADF) {
+                       pfds->revents = 0; /* Just in case... */
+                       nsock = mark_bad_fds (pfds, maxfd);
+               }
+
+               if ((pfds->revents & POLL_ERRORS) != 0) {
+                       /* We're supposed to die now, as the pipe has been closed */
+                       g_free (pfds);
+                       socket_io_cleanup (data);
+                       return;
+               }
+
+               /* Got a new socket */
+               if ((pfds->revents & MONO_POLLIN) != 0) {
+                       for (i = 1; i < allocated; i++) {
+                               pfd = &pfds [i];
+                               if (pfd->fd == -1 || pfd->fd == data->newpfd->fd)
+                                       break;
+                       }
+
+                       if (i == allocated) {
+                               mono_pollfd *oldfd;
+
+                               oldfd = pfds;
+                               i = allocated;
+                               allocated = allocated * 2;
+                               pfds = g_renew (mono_pollfd, oldfd, allocated);
+                               g_free (oldfd);
+                               for (; i < allocated; i++)
+                                       INIT_POLLFD (&pfds [i], -1, 0);
+                       }
+
+                       read (data->pipe [0], one, 1);
+                       INIT_POLLFD (&pfds [i], data->newpfd->fd, data->newpfd->events);
+                       ReleaseSemaphore (data->new_sem, 1, NULL);
+                       if (i >= maxfd)
+                               maxfd = i + 1;
+                       nsock--;
+               }
+
+               if (nsock == 0)
+                       continue;
+
+               EnterCriticalSection (&data->io_lock);
+               if (data->inited == 0) {
+                       g_free (pfds);
+                       return; /* cleanup called */
+               }
+
+               for (i = 1; i < maxfd && nsock > 0; i++) {
+                       pfd = &pfds [i];
+                       if (pfd->fd == -1 || pfd->revents == 0)
+                               continue;
+
+                       nsock--;
+                       list = g_hash_table_lookup (data->sock_to_state, GINT_TO_POINTER (pfd->fd));
+                       if (list != NULL && (pfd->revents & (MONO_POLLIN | POLL_ERRORS)) != 0) {
+                               list = process_io_event (list, MONO_POLLIN);
+                       }
+
+                       if (list != NULL && (pfd->revents & (MONO_POLLOUT | POLL_ERRORS)) != 0) {
+                               list = process_io_event (list, MONO_POLLOUT);
+                       }
+
+                       if (list != NULL) {
+                               g_hash_table_replace (data->sock_to_state, GINT_TO_POINTER (pfd->fd), list);
+                               pfd->events = get_events_from_list (list);
+                       } else {
+                               g_hash_table_remove (data->sock_to_state, GINT_TO_POINTER (pfd->fd));
+                               pfd->fd = -1;
+                               if (i == maxfd - 1)
+                                       maxfd--;
+                       }
+               }
+               LeaveCriticalSection (&data->io_lock);
+       }
+}
+
+static void
+socket_io_init (SocketIOData *data)
+{
+       if (pipe (data->pipe) != 0) {
+               int err = errno;
+               perror ("mono");
+               g_assert (err);
+       }
+
+       data->sock_to_state = g_hash_table_new (g_direct_hash, g_direct_equal);
+       data->new_sem = CreateSemaphore (NULL, 1, 1, NULL);
+       mono_thread_create (mono_get_root_domain (), socket_io_main, data);
+}
+
+static void
+socket_io_add (MonoAsyncResult *ares, MonoSocketAsyncResult *state)
+{
+       int events;
+       char msg [1];
+       GSList *list;
+       SocketIOData *data = &socket_io_data;
+
+       state->ares = ares;
+       if (InterlockedCompareExchange (&data->inited, -1, -1) == 0) {
+               EnterCriticalSection (&data->io_lock);
+               if (0 == data->inited) {
+                       socket_io_init (data);
+                       data->inited = 1;
+               }
+               LeaveCriticalSection (&data->io_lock);
+       }
+
+       WaitForSingleObject (data->new_sem, INFINITE);
+       if (data->newpfd == NULL)
+               data->newpfd = g_new0 (mono_pollfd, 1);
+
+       EnterCriticalSection (&data->io_lock);
+       list = g_hash_table_lookup (data->sock_to_state, GINT_TO_POINTER (state->handle));
+       if (list == NULL) {
+               list = g_slist_alloc ();
+               list->data = state;
+       } else {
+               list = g_slist_append (list, state);
+       }
+
+       events = get_events_from_list (list);
+       INIT_POLLFD (data->newpfd, GPOINTER_TO_INT (state->handle), events);
+       g_hash_table_replace (data->sock_to_state, GINT_TO_POINTER (state->handle), list);
+       LeaveCriticalSection (&data->io_lock);
+       *msg = (char) state->operation;
+       write (data->pipe [1], msg, 1);
+}
+
+static gboolean
+socket_io_filter (MonoObject *target, MonoObject *state)
+{
+       gint op;
+       MonoSocketAsyncResult *sock_res = (MonoSocketAsyncResult *) state;
+       MonoClass *klass;
+
+       if (target == NULL || state == NULL)
+               return FALSE;
+
+       klass = InterlockedCompareExchangePointer ((gpointer *) &socket_async_call_klass, NULL, NULL);
+       if (klass == NULL) {
+               MonoImage *system_assembly = mono_image_loaded ("System");
+
+               if (system_assembly == NULL)
+                       return FALSE;
+
+               klass = mono_class_from_name (system_assembly, "System.Net.Sockets", "Socket/SocketAsyncCall");
+               if (klass == NULL) {
+                       /* Should never happen... */
+                       g_print ("socket_io_filter: SocketAsyncCall class not found.\n");
+                       return FALSE;
+               }
+
+               InterlockedCompareExchangePointer ((gpointer *) &socket_async_call_klass, klass, NULL);
+       }
+
+       if (target->vtable->klass != klass)
+               return FALSE;
+
+       op = sock_res->operation;
+       if (op < AIO_FIRST || op >= AIO_LAST)
+               return FALSE;
+
+       return TRUE;
+}
+
 static void
 mono_async_invoke (MonoAsyncResult *ares)
 {
@@ -91,7 +447,6 @@ mono_async_invoke (MonoAsyncResult *ares)
 
        /* notify listeners */
        mono_monitor_enter ((MonoObject *) ares);
-       
        if (ares->handle != NULL) {
                ac->wait_event = ((MonoWaitHandle *) ares->handle)->handle;
                SetEvent (ac->wait_event);
@@ -113,6 +468,7 @@ mono_thread_pool_init ()
                return;
 
        MONO_GC_REGISTER_ROOT (ares_htable);
+       InitializeCriticalSection (&socket_io_data.io_lock);
        InitializeCriticalSection (&ares_lock);
        ares_htable = mono_g_hash_table_new (NULL, NULL);
        job_added = CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
@@ -133,7 +489,6 @@ mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate *
        MonoDomain *domain = mono_domain_get ();
        MonoAsyncResult *ares;
        ASyncCall *ac;
-       int busy, worker;
 
 #ifdef HAVE_BOEHM_GC
        ac = GC_MALLOC (sizeof (ASyncCall));
@@ -156,20 +511,34 @@ mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate *
        EnterCriticalSection (&ares_lock);
        mono_g_hash_table_insert (ares_htable, ares, ares);
        LeaveCriticalSection (&ares_lock);
-       
+
+       if (socket_io_filter (target, state)) {
+               socket_io_add (ares, (MonoSocketAsyncResult *) state);
+               return ares;
+       }
+
+       start_thread_or_queue (ares);
+       return ares;
+}
+
+static void
+start_thread_or_queue (MonoAsyncResult *ares)
+{
+       int busy, worker;
+       MonoDomain *domain;
+
        busy = (int) InterlockedCompareExchange (&busy_worker_threads, 0, -1);
        worker = (int) InterlockedCompareExchange (&mono_worker_threads, 0, -1); 
        if (worker <= ++busy &&
            worker < mono_max_worker_threads) {
                InterlockedIncrement (&mono_worker_threads);
                InterlockedIncrement (&busy_worker_threads);
+               domain = ((MonoObject *) ares)->vtable->domain;
                mono_thread_create (domain, async_invoke_thread, ares);
        } else {
                append_job (ares);
                ReleaseSemaphore (job_added, 1, NULL);
        }
-
-       return ares;
 }
 
 MonoObject *
@@ -225,6 +594,8 @@ mono_thread_pool_cleanup (void)
        LeaveCriticalSection (&mono_delegate_section);
        if (job_added)
                ReleaseSemaphore (job_added, release, NULL);
+
+       socket_io_cleanup (&socket_io_data);
 }
 
 static void
@@ -417,33 +788,3 @@ overlapped_callback (guint32 error, guint32 numbytes, WapiOverlapped *overlapped
        g_free (overlapped);
 }
 
-MonoBoolean
-ves_icall_System_Threading_ThreadPool_BindHandle (gpointer handle)
-{
-       MONO_ARCH_SAVE_REGS;
-
-#ifdef PLATFORM_WIN32
-       return FALSE;
-#else
-       if (!BindIoCompletionCallback (handle, overlapped_callback, 0)) {
-               gint error = GetLastError ();
-               MonoException *exc;
-               gchar *msg;
-
-               if (error == ERROR_INVALID_PARAMETER) {
-                       exc = mono_get_exception_argument (NULL, "Invalid parameter.");
-               } else {
-                       msg = g_strdup_printf ("Win32 error %d.", error);
-                       exc = mono_exception_from_name_msg (mono_defaults.corlib,
-                                                           "System",
-                                                           "ApplicationException", msg);
-                       g_free (msg);
-               }
-
-               mono_raise_exception (exc);
-       }
-
-       return TRUE;
-#endif
-}
-
index c92f070bbb1140521db68a4be864097b4fcb6f6f..b83af59a18e0a2c6d70547fe0559c90bbd4565e8 100644 (file)
@@ -35,7 +35,4 @@ MonoBoolean
 ves_icall_System_Threading_ThreadPool_SetMinThreads (gint workerThreads, 
                                                                gint completionPortThreads);
 
-MonoBoolean
-ves_icall_System_Threading_ThreadPool_BindHandle (gpointer handle);
-
 #endif
index 84ae4c23899742f32bdd3e60c5ed2257c5caa965..ee4196b63a2350945b2d2e1a981108e8aaafaeed 100644 (file)
@@ -1,3 +1,11 @@
+2005-04-07  Zoltan Varga  <vargaz@freemail.hu>
+
+       * errno.c: Use the GNU version of strerror_r if _GNU_SOURCE is defined
+         (otherwise assume existence of XPG variant).  This allows proper
+         compilation under Red Hat 9.
+       * fstab.c: protect against users calling setfsent(), setfsent(), ...  
+         endfsent(), which would otherwise leak a FILE handle.
+
 2005-04-05  Zoltan Varga  <vargaz@freemail.hu>
 
        * mph.h: Apply patch from the freebsd ports collection.
index a5d215513bb856426b62e00a6bf36058d7091dce..a28425e03b84ab8a34617a148ba96577d4e3d939 100644 (file)
@@ -2,11 +2,6 @@
  * <errno.h> wrapper functions.
  */
 
-/* to get XPG's strerror_r declaration */
-#undef _GNU_SOURCE
-#undef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-
 #include <errno.h>
 #include <string.h>
 #include "mph.h"
@@ -28,12 +23,102 @@ Mono_Posix_Stdlib_SetLastError (int error_number)
 }
 
 #ifdef HAVE_STRERROR_R
+
+/* 
+ * There are two versions of strerror_r: 
+ *  - the GNU version:  char *strerror_r (int errnum, char *buf, size_t n);
+ *  - the XPG version:    int strerror_r (int errnum, char *buf, size_t n);
+ *
+ * Ideally I could stick with the XPG version, but we need to support 
+ * Red Hat 9, which only supports the GNU version.
+ *
+ * Furthermore, I do NOT want to export the GNU version in Mono.Posix.dll, 
+ * as that's supposed to contain *standard* function definitions (give or 
+ * take a few GNU extensions).  Portability trumps all.
+ *
+ * Consequently, we export the functionality of the XPG version.  
+ * Internally, we se the GNU version if _GNU_SOURCE is defined, otherwise 
+ * we assume that the XPG version is present.
+ */
+
+#ifdef _GNU_SOURCE
+#define mph_min(x,y) ((x) <= (y) ? (x) : (y))
+
+/* If you pass an invalid errno value to glibc 2.3.2's strerror_r, you get
+ * back the string "Unknown error" with the error value appended. */
+static const char mph_unknown[] = "Unknown error ";
+
+/*
+ * Translate the GNU semantics to the XPG semantics.
+ *
+ * From reading the (RH9-using) GLibc 2.3.2 sysdeps/generic/_strerror.c, 
+ * we can say the following:
+ *   - If errnum is a valid error number, a pointer to a constant string is
+ *     returned.  Thus, the prototype *lies* (it's not really a char*).
+ *     `buf' is unchanged (WTF?).
+ *   - If errnum is an *invalid* error number, an error message is copied
+ *     into `buf' and `buf' is returned.  The error message returned is
+ *     "Unknown error %i", where %i is the input errnum.
+ *
+ * Meanwhile, XPG always modifies `buf' if there's enough space, and either
+ * returns 0 (success) or -1 (error) with errno = EINVAL (bad errnum) or
+ * ERANGE (`buf' isn't big enough).  Also, GLibc 2.3.3 (which has the XPG
+ * version) first checks the validity of errnum first, then does the copy.
+ *
+ * Assuming that the GNU implementation doesn't change much (ha!), we can
+ * check for EINVAL by comparing the strerror_r return to `buf', OR by
+ * comparing the return value to "Uknown error".  (This assumes that 
+ * strerror_r will always only return the input buffer for errors.)
+ *
+ * Check for ERANGE by comparing the string length returned by strerror_r to
+ * `n'.
+ *
+ * Then pray that this actually works...
+ */
+gint32
+Mono_Posix_Syscall_strerror_r (int errnum, char *buf, mph_size_t n)
+{
+       char *r;
+       char ebuf [sizeof(mph_unknown)];
+       size_t len;
+       size_t blen;
+
+       mph_return_if_size_t_overflow (n);
+
+       /* first, check for valid errnum */
+       r = strerror_r (errnum, ebuf, sizeof(ebuf));
+       len = strlen (r);
+
+       if (r == ebuf ||
+                       strncmp (r, mph_unknown, mph_min (len, sizeof(mph_unknown))) == 0) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       /* valid errnum (we hope); is buffer big enough? */
+       blen = (size_t) n;
+       if ((len+1) > blen) {
+               errno = ERANGE;
+               return -1;
+       }
+
+       strncpy (buf, r, len);
+       buf[len] = '\0';
+
+       return 0;
+}
+
+#else /* !def _GNU_SOURCE */
+
 gint32
 Mono_Posix_Syscall_strerror_r (int errnum, char *buf, mph_size_t n)
 {
        mph_return_if_size_t_overflow (n);
        return strerror_r (errnum, buf, (size_t) n);
 }
+
+#endif /* def _GNU_SOURCE */
+
 #endif /* def HAVE_STRERROR_R */
 
 G_END_DECLS
index c9ff50547a84f6dae119375892199b9fc249110e..2fb79be2671092f6a128e009d687012529ab2fdc 100644 (file)
@@ -174,6 +174,9 @@ etc_fstab;
 static int
 setfsent (void)
 {
+       /* protect from bad users calling setfsent(), setfsent(), ... endfsent() */
+       if (etc_fstab != NULL)
+               fclose (etc_fstab);
        etc_fstab = fopen ("/etc/vfstab", "r");
        if (etc_fstab != NULL)
                return 1;