⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.cs

📁 Windows Mobile用户签名程序
💻 CS
字号:
/*
	SignatureData class
	--
	Stores the signature information. The width and height specify the size of
	the signature canvas. The lines property stores a list of line segments. 
	Each line segment contains an array of points (x and y coordinates).
	
	The class can flatten itself into a stream of bytes and unflatten, or
	reconstruct itself, from a stream of bytes. These are used when it needs
	to be sent over a TCP socket.
	
	
	Network class
	--
	Contains helper methods that read / write data to byte streams and help
	with the TCP socket message terminator.
*/

using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing;

namespace Common
{
	/// <summary>
	/// Class that contains the signature data. The class knows how 
	/// to flatten itself to a stream of bytes and reconstruct 
	/// itself from a stream of bytes.
	/// </summary>
	public class SignatureData
	{
		// this identifies this class, used when sent over socket
		// so receiving application can validate the data stream
		static public string SignatureId = "signature";
		
		int _width;				// width of signature canvas
		int _height;			// height of signature canvas
		ArrayList _lines;		// list of line segments
		
		//
		// Properties
		//
		
		public ArrayList Lines
		{
			get { return _lines; }
		}
		
		public int Width 
		{
			get { return _width; }
		}
		
		public int Height
		{
			get { return _height; }
		}
		
		// construct an object from stream of bytes
		public SignatureData(byte[] bits)
		{
			// index into data stream
			int bitsIndex = 0;
			
			// get signature id
			if (!IsValidStream(bits, ref bitsIndex))
			{
				// this is not what we are expecting
				throw (new Exception("Invalid data stream."));
			}
			
			// width and height
			_width = Network.GetInt32(bits, ref bitsIndex);
			_height = Network.GetInt32(bits, ref bitsIndex);

			// number of line segments
			Int32 linesCount = Network.GetInt32(bits, ref bitsIndex);
			_lines = new ArrayList(linesCount);
			
			// loop through each line segment and get points
			for (int line=0; line < linesCount; line++)
			{
				// number of points in this segment
				Int32 pointsCount = Network.GetInt32(bits, ref bitsIndex);
				Point[] points = new Point[pointsCount];
				
				// get all points in this segment
				for (int point=0; point < pointsCount; point++)
				{
					points[point].X = Network.GetInt32(bits, ref bitsIndex);
					points[point].Y = Network.GetInt32(bits, ref bitsIndex);
				}
				
				// add line segment to list
				_lines.Add(points);
			}
		}
		
		/// <summary>
		/// Flatten object to a stream of bytes.
		/// </summary>
		static public byte[] GetBytes(int width, int height, ArrayList lines)
		{
			// hold byte stream
			MemoryStream stream = new MemoryStream();

			// signature id
			Network.WriteString(stream, SignatureData.SignatureId);
			
			// width and height
			Network.WriteInt32(stream, width);
			Network.WriteInt32(stream, height);
			
			// number of segments
			Network.WriteInt32(stream, lines.Count);
			
			// each segment
			foreach (Point[] points in lines)
			{
				// points in the segment
				Network.WriteInt32(stream, points.Length);
				foreach (Point pt in points)
				{
					Network.WriteInt32(stream, pt.X);
					Network.WriteInt32(stream, pt.Y);
				}
			}

			return stream.ToArray();
		}

		/// <summary>
		/// Return true if byte array is a valid SignatureData class,
		/// otherwise return false.
		/// </summary>
		private bool IsValidStream(byte[] bits, ref int bitsIndex)
		{
			bool valid = false;
			
			// see if first value is length of signature id
			Int32 idLength = Network.GetInt32(bits, ref bitsIndex);
			if (idLength == SignatureData.SignatureId.Length)
			{
				// get the signature id mark
				byte[] id = Network.GetBytes(bits, ref bitsIndex, idLength);
			
				// see if this is the stream we expect
				if (ASCIIEncoding.ASCII.GetString(id, 0, idLength) == SignatureData.SignatureId)
					valid = true;
			}
			
			return valid;
		}
	}


	/// <summary>
	/// Network helper functions.
	/// </summary>
	public class Network
	{
		/// <summary>
		/// socket message terminator 
		/// </summary>
		static public string Terminator
		{
			get { return "<data_end>"; }
		}
		
		/// <summary>
		/// socket message terminator as bytes 
		/// </summary>
		static public byte[] TerminatorBytes
		{
			get 
			{
				return ASCIIEncoding.ASCII.GetBytes(Terminator);
			}
		}

		// all static methods
		private Network()
		{
		}

		/// <summary>
		/// Return true if the terminator is located at the
		/// end of the byte array, otherwise return false.
		/// </summary>
		static public bool CheckForTerminator(byte[] data)
		{
			// return right away if not even long enough to contain terminator
			if (data == null || data.Length < Terminator.Length)
				return false;
		
			// see if message terminator is at end of stream
			string endBuf = Encoding.ASCII.GetString(data,
				(int)(data.Length - Terminator.Length), (int)Terminator.Length);
		
			return Network.Terminator.Equals(endBuf);
		}

		/// <summary>
		/// Write int bytes to byte stream.
		/// </summary>
		static public void WriteInt32(MemoryStream stream, Int32 data)
		{
			stream.Write(BitConverter.GetBytes(data), 0, Marshal.SizeOf(data));
		}		

		/// <summary>
		/// Write string to byte stream. First write length, followed
		/// by string content.
		/// </summary>
		static public void WriteString(MemoryStream stream, string data)
		{
			// write length of string followed by the string bytes
			WriteInt32(stream, data.Length);
			stream.Write(ASCIIEncoding.ASCII.GetBytes(data), 0, data.Length);
		}		

		/// <summary>
		/// Return int from byte stream.
		/// </summary>
		static public Int32 GetInt32(byte[] bits, ref int bitsIndex)
		{
			Int32 data = BitConverter.ToInt32(bits, bitsIndex);
			bitsIndex += Marshal.SizeOf(data);
			return data;
		}

		/// <summary>
		/// Return specified bytes from byte stream.
		/// </summary>
		static public byte[] GetBytes(byte[] bits, ref int bitsIndex, int length)
		{
			byte[] data = new byte[length];
			Buffer.BlockCopy(bits, bitsIndex, data, 0, length);
			bitsIndex += length;
			return data;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -