OSDN Git Service

初期コミット
[yubeshi/yubeshi.git] / Yubeshi / Nmea / Packet.cs
1 /*\r
2  *      Yubeshi GPS Parser\r
3  *\r
4  *      This software is distributed under a zlib-style license.\r
5  *      See license.txt for more information.\r
6  */\r
7 \r
8 using System;\r
9 using System.Collections.Generic;\r
10 using System.Text;\r
11 \r
12 namespace Yubeshi.Nmea\r
13 {\r
14     public abstract class Packet : Yubeshi.UnknownPacket\r
15     {\r
16         #region type definitions\r
17         protected delegate Packet PacketBuilder(\r
18                                         byte[] sentence, Elements elements);\r
19 \r
20         protected class Elements\r
21         {\r
22             public string[] Values;\r
23             public int CheckSum;\r
24             public int PacketLength;\r
25         }\r
26         #endregion\r
27 \r
28         #region fields\r
29 \r
30         #endregion\r
31 \r
32         #region constructors\r
33 \r
34         public Packet()\r
35         { \r
36         }\r
37 \r
38         public Packet(byte[] sentence)\r
39         {\r
40             Raw = sentence;\r
41         }\r
42 \r
43         #endregion\r
44 \r
45         #region properties\r
46 \r
47         public int CheckSum\r
48         {\r
49             get;\r
50             protected set;\r
51         }\r
52         #endregion\r
53 \r
54         #region public method\r
55 \r
56         #endregion\r
57         #region protected method\r
58 \r
59         protected static bool TryParse(byte[] sentence, out Packet packet, \r
60                                         byte[] header, int elementNum, \r
61                                                         PacketBuilder builder)\r
62         { \r
63             packet = null;\r
64             if (!Match(sentence, header))\r
65             {\r
66                 return false;\r
67             }\r
68             Elements elements = GetElements(sentence, elementNum);\r
69             if (elements == null)\r
70             {\r
71                 return false;\r
72             }\r
73             try\r
74             {\r
75                 packet = builder(sentence, elements);\r
76             }\r
77             catch\r
78             {\r
79                 return false;\r
80             }\r
81             return true;\r
82         }\r
83 \r
84         protected static Elements GetElements(byte[] sentence, int elementNum)\r
85         {\r
86             string[] values = new string[elementNum];\r
87             int elementIndex = 0;\r
88             int lastCommaPos = 7;\r
89             for (int i = lastCommaPos; i < sentence.Length; ++i)\r
90             {\r
91                 if (sentence[i] == ',')\r
92                 {\r
93                     values[elementIndex++] = Encoding.ASCII.GetString(\r
94                                     sentence, lastCommaPos, i - lastCommaPos);\r
95                     lastCommaPos = i + 1;\r
96                     if (elementIndex == elementNum)\r
97                     {\r
98                         break;\r
99                     }\r
100                 }\r
101             }\r
102             if (elementIndex != elementNum)\r
103             {\r
104                 return null;\r
105             }\r
106 \r
107             int length = lastCommaPos + 5;\r
108 \r
109             if (sentence.Length < length)\r
110             {\r
111                 return null;\r
112             }\r
113 \r
114             if (sentence[lastCommaPos] != (byte)'*' || \r
115                 sentence[lastCommaPos+3] != (byte)'\r' ||\r
116                 sentence[lastCommaPos+4] != (byte)'\n')\r
117             {\r
118                 return null;\r
119             }\r
120             int checksum1 = sentence[lastCommaPos+1];\r
121             int checksum2 = sentence[lastCommaPos+2];\r
122             if (checksum1 < '0' || checksum1 > '9')\r
123             {\r
124                 return null;\r
125             }\r
126             if (checksum2 < '0' || checksum1 > '9')\r
127             {\r
128                 return null;\r
129             }\r
130             \r
131             Elements elements = new Elements();\r
132             elements.Values = values;\r
133             elements.CheckSum = (checksum1 - '0') << 4 | (checksum2 - '0');\r
134             elements.PacketLength = length;\r
135             return elements;\r
136         }\r
137 \r
138         protected static bool Match(byte[] sentence, byte[] header)\r
139         {\r
140             if (sentence.Length < header.Length)\r
141             {\r
142                 return false;\r
143             }\r
144             for (int i = 0; i < header.Length; ++i)\r
145             {\r
146                 if (header[i] != sentence[i])\r
147                 {\r
148                     return false;\r
149                 }\r
150             }\r
151             return true;\r
152         }\r
153         #endregion\r
154     }\r
155 }\r