/// <summary> /// Processes the received message /// </summary> private void EndReadHeader(IAsyncResult res) { byte[] odcheader = null; try { odcheader = (byte[])res.AsyncState; socket.EndRead(res); } catch (Exception ex) { Logging.WriteString(String.Format("Exception in DirectIMConnection.EndReadHeader: {0}", ex)); DisconnectFromServer(true); } // Verify that this is an ODC header if (Encoding.ASCII.GetString(odcheader, 0, 4) != "ODC2") { // Huh... return; } ushort datalen = (ushort)((odcheader[4] << 8) | odcheader[5]); if (datalen < 6) { // Oh return; } ByteStream messageheader = ReadPacket(datalen - 6); if (messageheader == null) { // Tum ta tiddily tumpa turr return; } // Extract various members from the message header messageheader.AdvanceToPosition(6); byte[] cookie = messageheader.ReadByteArray(8); messageheader.AdvanceToPosition(22); uint datalength = messageheader.ReadUint(); ushort charset = messageheader.ReadUshort(); ushort subcharset = messageheader.ReadUshort(); DirectIMFlags flags = (DirectIMFlags)messageheader.ReadUint(); messageheader.AdvanceToPosition(38); string screenname = messageheader.ReadString(16, Encoding.ASCII); if ((flags & DirectIMFlags.TypingPacket) != 0) { // Determine the type of typing packet this is if ((flags & DirectIMFlags.UserTyping) != 0) { //_parent.OnTypingNotification(screenname, TypingNotification.TypingStarted); } else if ((flags & DirectIMFlags.UserTyped) != 0) { //_parent.OnTypingNotification(screenname, TypingNotification.TextTyped); } else { // TODO: restore these // _parent.OnTypingNotification(screenname, TypingNotification.TypingFinished); } // Probably no data, but read it in anyway to make sure we're not missing anything ReadPacket((int)datalength); } else if ((flags & DirectIMFlags.ConfirmationPacket) != 0 && datalength == 0) { // Do we really do anything here? I don't think so. } else { // Create a new instant message DirectIM dim = new DirectIM(Other.ScreenName, this); dim.Cookie = csammisrun.OscarLib.Cookie.GetReceivedCookie(cookie); dim.IsAutoResponse = ((flags & DirectIMFlags.AutoResponse) != 0); dim.Encoding = IM.GetEncodingFromCharset(charset, subcharset); // Create a spooler to incrementally read in a DirectIM packet, // then restart the read sequence when it's done DirectIMDataReader reader = new DirectIMDataReader(this, dim); reader.DataReaderComplete += new DataReaderCompleteHandler(delegate { parent.OnDirectIMReceived( reader.Message); reader.Dispose(); ReadHeader(); }); reader.Read(datalength); return; } // Restart the read sequence ReadHeader(); }