1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Text;
7 using System.Data.SqlTypes;
8 using System.IO;
9 
10 using Microsoft.SqlServer.Server;
11 
12 [Serializable]
13 [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, MaxByteSize = 20)]
14 public class Line : INullable, IBinarySerialize
15 {
16     private Point start = new Point();
17     private Point end = new Point();
18 
19     private bool fIsNull = false;
20 
21     public static Line Null { get { return new Line(true); } }
22 
23     public const int MaxByteSize = 20;
24     public const bool IsFixedLength = true;
25     public const bool IsByteOrdered = false;
26 
Line()27     public Line()
28     {
29         start.X = start.Y = end.X = end.Y = 0;
30     }
31 
Line(bool fNull)32     public Line(bool fNull)
33     {
34         fIsNull = true;
35     }
36 
Line(Point ix, Point iy)37     public Line(Point ix, Point iy)
38     {
39         start.X = ix.X;
40         start.Y = ix.Y;
41         end.X = iy.X;
42         end.Y = iy.Y;
43     }
44 
45     public bool IsNull
46     {
47         get
48         {
49             return fIsNull;
50         }
51     }
52 
Read(BinaryReader r)53     public void Read(BinaryReader r)
54     {
55         start = new Point();
56         start.Read(r);
57         end = new Point();
58         end.Read(r);
59         fIsNull = BitConverter.ToBoolean(r.ReadBytes(1), 0);
60     }
61 
Write(BinaryWriter w)62     public void Write(BinaryWriter w)
63     {
64         start.Write(w);
65         end.Write(w);
66         w.Write(fIsNull);
67     }
68 
FillFromBytes(SqlBytes data)69     public void FillFromBytes(SqlBytes data)
70     {
71         if (data.IsNull)
72         {
73             fIsNull = true;
74             return;
75         }
76 
77         if (data.Length != 16)
78             throw new ArgumentException();
79         byte[] value = data.Value;
80 
81         //read x1,y1,x2,y2
82         start.X = BitConverter.ToInt32(value, 0);
83         start.Y = BitConverter.ToInt32(value, 4);
84         end.X = BitConverter.ToInt32(value, 8);
85         end.Y = BitConverter.ToInt32(value, 12);
86     }
87 
FillBytes(SqlBytes data)88     public void FillBytes(SqlBytes data)
89     {
90         if (fIsNull)
91         {
92             if (data.IsNull)
93                 return;
94             else
95             {
96                 data.SetNull();
97                 return;
98             }
99         }
100 
101         byte[] bigbytes = new byte[16];
102         byte[] bytes = BitConverter.GetBytes(start.X);
103         bytes.CopyTo(bigbytes, 0);
104         bytes = BitConverter.GetBytes(start.Y);
105         bytes.CopyTo(bigbytes, 4);
106 
107         bytes = BitConverter.GetBytes(end.X);
108         bytes.CopyTo(bigbytes, 8);
109         bytes = BitConverter.GetBytes(end.Y);
110         bytes.CopyTo(bigbytes, 12);
111 
112         int i;
113         for (i = 0; i < bigbytes.Length; i++)
114             data[i] = bigbytes[i];
115         data.SetLength(i);
116     }
117 
118     //it should be x1,y1,x2,y2
Parse(SqlString data)119     public static Line Parse(SqlString data)
120     {
121         string[] array = data.Value.Split(new char[] { ',' });
122 
123         if (array.Length != 4)
124             throw new ArgumentException();
125         Line line = new Line();
126         line.start.X = int.Parse(array[0]);
127         line.start.Y = int.Parse(array[1]);
128         line.end.X = int.Parse(array[2]);
129         line.end.Y = int.Parse(array[3]);
130 
131         return line;
132     }
133 
ToString()134     public override string ToString()
135     {
136         StringBuilder builder = new StringBuilder();
137         builder.Append(start.ToString());
138         builder.Append(",");
139         builder.Append(end.ToString());
140 
141         return builder.ToString();
142     }
143 
Length()144     public double Length()
145     {
146         return end.DistanceFrom(start);
147     }
148 
149     public Point Start
150     {
151         get
152         {
153             return start;
154         }
155     }
156 
157     public Point End
158     {
159         get
160         {
161             return end;
162         }
163     }
164 }