private void parseICQ2003aBody(ICQDataStream strmBody) { byte[] baText = strmBody.readBinary(); if (null != baText && baText.Length > 0) { Text = Encoding.Default.GetString(baText); string textUTF8Temp; string textRTFTemp; strmBody.parsePossiblyRemainingRTFandUTF8(out textRTFTemp, out textUTF8Temp); // sometimes, textUTF8Temp is plaintext with spaces in between :-( TextRTF = textRTFTemp; // TextRTF will be null before that operation anyway if (null != textUTF8Temp) Text = textUTF8Temp; } }
private void parseICQ2003bBody(ICQDataStream strmBody) { byte[] baRTFText = strmBody.readBinary(); if (null != baRTFText && baRTFText.Length > 0) TextRTF = Encoding.Default.GetString(baRTFText); byte[] baText = strmBody.readBinary(); if (null != baText && baText.Length > 0) Text = Encoding.Default.GetString(baText); }
private void handleTag(string tagName, ICQDataStream streamContent) { switch(tagName) { case "AnswerFlags": byte[] baAnswerFlags = streamContent.readFixedBinary(5); break; case "SendFlags": case "Status": case "Read": byte[] baSendFlags = streamContent.readFixedBinary(5); // TODO: this is a special Uint format: First 0x69 then four bytes of uint break; case "Body": byte[] baBodyHeader = new byte[0x13]; streamContent.Read(baBodyHeader, 0, 0x3); if (baBodyHeader[1] == 0xEB) // as opposed to 0xEA { streamContent.Read(baBodyHeader, 3, 0x10); //if (isOutgoing != ((baBodyHeader[4] & 0x01) == 0x01)) // throw new InvalidDataException("Outgoing flag is different in packet head and body head"); } byte[] bodyContent = streamContent.readBinary(); if (null != bodyContent) { // bodyContent contains 0x58 as start tag for only ANSI text (ICQ Pro 2003a) or RTF and ANSI (ICQ Pro 2003b) ICQDataStream strmBody = new ICQDataStream(bodyContent); if (0x58 == bodyContent[0]) // maybe bodyContent[0] and bodyContent[1] together are a package type number? { strmBody.Seek(2, SeekOrigin.Begin); UInt32 iICQ2003bIndicator = strmBody.readUInt32(); if (0 != iICQ2003bIndicator) // this means the RTF starts immediately. ICQ Pro 2003b style. { strmBody.Seek(-4, SeekOrigin.Current); parseICQ2003bBody(strmBody); } } else if (0x23 == bodyContent[0]) // this means: ANSI + RTF + UTF-8 strmBody.Seek(2, SeekOrigin.Begin); else if (0x03 == bodyContent[0]) // observed cases are only "The user has added you to his/her Contact list" // + "You added him/her to your Contact List" { MessageType = "Added2ContactList"; return; } else if (0x01 == bodyContent[0]) { MessageType = "AuthorizationRequestAccepted"; return; } else if (0x00 == bodyContent[0]) { MessageType = "Contacts"; return; } else if (0x11 == bodyContent[0]) { MessageType = "BirthdayReminder"; return; } else throw new NotImplementedException("Message start tag " + bodyContent[0].ToString() + " not implemented"); parseICQ2003aBody(strmBody); } break; case "CLSID": byte clsidStartTag = Convert.ToByte(streamContent.ReadByte()); byte[] clsidData = streamContent.readBinary(); break; case "ExtId": byte[] extidContent = streamContent.readFixedBinary(3); break; case "ExtName": byte extName = Convert.ToByte(streamContent.ReadByte()); MessageType = streamContent.readString(); break; case "ExtVers": byte[] extVers = streamContent.readFixedBinary( 5); break; case "Folder": byte[] folder = streamContent.readFixedBinary(3); break; case "MsgUserName": byte startTag = (byte)streamContent.ReadByte(); OtherPartyName = streamContent.readString(); break; case "Time": byte timeStartTag = (byte)streamContent.ReadByte(); if (timeStartTag != 0x69) throw new ArgumentException("Time tag expected to be 0x69, but it was " + timeStartTag.ToString()); TimeOfMessage = streamContent.readUnixTime(); break; default: throw new NotImplementedException("Unknown tag \"" + tagName + "\""); } }