[Mono-list] assertion g_utf8_validate failed

Mario Fuentes mario@gnome.cl
Thu, 11 Nov 2004 12:03:50 -0300


--=-yVDAvGKcmHGrdpe65qLT
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello, I have a problem with sockets, threads and TextView.  When a
message is received, I add this to a TextView but in some machine it
crash with this error:

Gtk-CRITICAL **.... (gtk_text_buffer_emit_insert): assertion
'g_utf8_validate (text, len, NULL)' failed.

I don't know if is a Decoding problem (from bytes to string) or a GTK
+/System configuration error.

Attached a use case of the problem.

Bye.
-- 
Mario Fuentes
http://primate.gnome.cl/~mario
mailto:mario@gnome.cl

--=-yVDAvGKcmHGrdpe65qLT
Content-Disposition: attachment; filename=Chat.cs
Content-Type: text/x-csharp; name=Chat.cs; charset=UTF-8
Content-Transfer-Encoding: 7bit

// Mario Fuentes <mario@gnome.cl>
// Compile: mcs -pkg:gtk-sharp Chat.cs
namespace Samples {
	using System;
	using System.Text;
	using System.Net;
	using SNS = System.Net.Sockets;
	using System.IO;
	using System.Threading;
	using Gtk;

	public delegate void SuccessHandler (string text);
	
	public class Chat : Window
	{
#region Packet
		internal class Packet {
			internal byte [] buffer;
			internal SNS.Socket socket;
			
			internal Packet (int size, SNS.Socket sock)
			{
				buffer = new byte[size];
				socket = sock;
			}
		}
#endregion

		event SuccessHandler Sended = null;
		event SuccessHandler Recived = null;
		// GUI
		Entry entHost;
		Button btnConnect;
		Button btnCreate;
		ScrolledWindow scrollChat;
		TextView textChat;
		Entry entChat;
		
		// Flags
		bool isConnected = false;
		bool isServer = false;
		bool done = false;
		
		// UserName
		string userName;
		
		// Socket
		SNS.Socket sock = null;
		SNS.Socket srvSock = null;
		
		byte [] buffer = null;
		
		Packet pack = null;
		
		public Chat () : base (WindowType.Toplevel)
		{
			// Setup window properties
			this.Title = "Chat";
			this.BorderWidth = 12;
			this.DeleteEvent += OnDeleteEvent;
			// Add a vertical box
			VBox box = new VBox (false, 6);
			// Pack box on the window
			this.Add (box);
			// Create a table for packing controls
			Table table = new Table (3, 2, false);
			table.RowSpacing = 3;
			table.ColumnSpacing = 6;
			// Pack table on the box
			box.PackStart (table, false, false, 0);
			// Pack a label on the table
			table.Attach (new Label ("Host:"), 0, 1, 0, 1);
			// Create and pack a entre con the table, for get hostname from user
			entHost = new Entry ();
			table.Attach (entHost, 1, 2, 0, 1);
			// A button for try connect to "Host"
			btnConnect = new Button ("Connect");
			btnConnect.Clicked += OnBtnConnectClicked;
			table.Attach (btnConnect, 2, 3, 0, 1);
			// A button for create a server (listen for a user)
			btnCreate = new Button ("Create a server!");
			btnCreate.Clicked += OnBtnCreateClicked;
			table.Attach (btnCreate, 0, 3, 1, 2);
			// A scrolled window container for pack the textview
			scrollChat = new ScrolledWindow ();
			scrollChat.ShadowType = ShadowType.In;
			// Pack on the box
			box.PackStart (scrollChat);
			// TextView for view send/receive text			
			textChat = new TextView ();
			textChat.Editable = false;
			textChat.WrapMode = WrapMode.Word;
			// Pack text into scroll
			scrollChat.Add (textChat);
			// A entry for user text
			entChat = new Entry ();
			entChat.Activated += OnEntChatActivated;
			box.PackStart (entChat, false, false, 0);
			// Show the windows and all widgets/controls contained
			this.ShowAll ();
			// Get username
			userName = System.Environment.UserName;
			Sended += OnSuccess;
			Recived += OnSuccess;
		}
		
		void AppendText (string text)
		{
			textChat.Buffer.Insert (textChat.Buffer.EndIter,
				text + System.Environment.NewLine);
			scrollChat.Vadjustment.Value = scrollChat.Vadjustment.Upper;
		}
		
		void SetSensitive (bool b)
		{
			entHost.Sensitive = b;
			btnConnect.Sensitive = b;
			btnCreate.Sensitive = b;
		}
		
		void CreateSocket ()
		{
			IPAddress ipAddress;
			if (isServer)
				ipAddress = IPAddress.Any;
			else
				ipAddress = Dns.Resolve (entHost.Text).AddressList[0];
			
			IPEndPoint ipEndPoint = new IPEndPoint (ipAddress, 9999);
			sock = new SNS.Socket (SNS.AddressFamily.InterNetwork,
			                                  SNS.SocketType.Stream,
			                                  SNS.ProtocolType.Tcp);

			sock.Blocking = false;
			
			if (isServer)
			{
				sock.Bind (ipEndPoint);
				sock.Listen (1);
				sock.BeginAccept (new AsyncCallback (OnConnectCallback), sock);
			}
			else
			{
				sock.BeginConnect (ipEndPoint,
					new AsyncCallback (OnConnectCallback), sock);
			}
		}
		
		void OnConnectCallback (IAsyncResult ar)
		{
			SNS.Socket socket = (SNS.Socket) ar.AsyncState;
			SNS.Socket serverSock = null;
			Console.Write ("OnConnectCallback! ");
			if (isServer)
			{
				serverSock = socket.EndAccept (ar);
				srvSock = serverSock;
				if (serverSock.Connected == false)
					return;
				socket.Close ();
			}
			else
			{
				socket.EndConnect (ar);
				if (socket.Connected == false)
					return;
			}
			Console.WriteLine ("Connected!");
			isConnected = true;
						
			SNS.Socket s = (isServer) ? serverSock : socket;
			WaitForData (s);
		}
		
		void WaitForData (SNS.Socket s)
		{
			pack = new Packet (256, s);
			
			s.BeginReceive (pack.buffer, 0, pack.buffer.Length,
				SNS.SocketFlags.None, new AsyncCallback (OnDataReceive), pack);
		}
		
		void OnDataReceive (IAsyncResult ar)
		{
			Gdk.Threads.Enter ();
			Packet packet = ar.AsyncState as Packet;
			int len = packet.socket.EndReceive (ar);

			if (Recived != null)
			{
				/*
				char [] chars = new char [len + 1];
				System.Text.Encoding.UTF8.GetDecoder ().GetChars (packet.buffer,
					0, len, chars, 0);
				string strRec = new String (chars)
				*/
				string strRec = Encoding.UTF8.GetString (packet.buffer);
				Recived (strRec);
			}
			
			WaitForData (packet.socket);
			
			Gdk.Threads.Leave ();
		}
		
		void OnDataSend (IAsyncResult ar)
		{
			Gdk.Threads.Enter ();
			// ... code		
			
			if (Sended != null)
			{
				string text = ar.AsyncState as String;
				Sended (text);
			}
			
			Gdk.Threads.Leave ();
		}
		
		void Send (string str)
		{
			byte [] buf = Encoding.UTF8.GetBytes (str);
			
			Packet packet = new Packet (0, pack.socket);
			
			packet.socket.BeginSend (buf, 0, buf.Length,
				SNS.SocketFlags.None, new AsyncCallback (OnDataSend), str);
		}
		
		void OnSuccess (string text)
		{
			AppendText (text);
		}
		
#region Callbacks
		void OnDeleteEvent (object o, DeleteEventArgs args)
		{
			// Disconnect
			// TODO
			
			// Stop GTK loop
			args.RetVal = true;
			Application.Quit ();
		}
		
		void OnBtnConnectClicked (object o, EventArgs args)
		{
			CreateSocket ();
			SetSensitive (false);
		}
		
		void OnBtnCreateClicked (object o, EventArgs args)
		{
			isServer = true;
			CreateSocket ();
			SetSensitive (false);
		}
		
		void OnEntChatActivated (object o, EventArgs args)
		{
			if (entChat.Text == String.Empty)
				return;
			
			if (!isConnected)
			{
				Console.WriteLine ("No esta conectado");
				return;
			}
			
			string strSend = userName + "> " + entChat.Text;
			
			Send (strSend);
			
			entChat.Text = String.Empty;
		}
#endregion
	
		public static void Main (string [] args)
		{
			Gdk.Threads.Init ();
			Application.Init ();
			new Chat ();
			Gdk.Threads.Enter ();
			Application.Run ();
			Gdk.Threads.Leave ();
		}
	}
}

--=-yVDAvGKcmHGrdpe65qLT--