4 * This software is distributed under a zlib-style license.
\r
5 * See license.txt for more information.
\r
9 using System.Collections.Generic;
\r
12 namespace Yubeshi.Nmea
\r
14 public abstract class Packet : Yubeshi.UnknownPacket
\r
16 #region type definitions
\r
17 protected delegate Packet PacketBuilder(
\r
18 byte[] sentence, Elements elements);
\r
20 protected class Elements
\r
22 public string[] Values;
\r
23 public int CheckSum;
\r
24 public int PacketLength;
\r
39 #region constructors
\r
45 public Packet(byte[] sentence, int length)
\r
46 : base(sentence, length)
\r
61 #region public method
\r
64 #region protected method
\r
66 protected static bool TryParse(byte[] sentence, out UnknownPacket packet,
\r
67 byte[] header, int elementNum, PacketBuilder builder)
\r
70 if (!Match(sentence, header))
\r
74 Elements elements = GetElements(sentence, elementNum);
\r
75 if (elements == null)
\r
81 packet = builder(sentence, elements);
\r
91 protected static Elements GetElements(byte[] sentence, int elementNum)
\r
93 int elementIndex = 0;
\r
94 int lastCommaPos = 6;
\r
95 if (sentence[1] == 'G' && sentence[2] == 'P')
\r
102 for (int i = lastCommaPos; i < sentence.Length; ++i)
\r
104 if (sentence[i] == ',')
\r
109 if (sentence[i] == '*')
\r
116 if (elementNum < 1)
\r
120 string[] values = new string[elementNum];
\r
121 for (int i = lastCommaPos; i < sentence.Length; ++i)
\r
123 if (sentence[i] == ',' || sentence[i] == '*')
\r
125 if (elementIndex >= elementNum)
\r
129 values[elementIndex++] = Encoding.ASCII.GetString(
\r
130 sentence, lastCommaPos, i - lastCommaPos);
\r
131 lastCommaPos = i + 1;
\r
132 if (sentence[i] == '*')
\r
138 if (elementIndex != elementNum)
\r
143 int length = lastCommaPos + 4; // CC, CC, '\r', '\n'
\r
145 if (sentence.Length < length)
\r
150 if (sentence[lastCommaPos + 2] != (byte)'\r' ||
\r
151 sentence[lastCommaPos + 3] != (byte)'\n')
\r
156 Encoding.ASCII.GetString(sentence, lastCommaPos, 2);
\r
157 Elements elements = new Elements();
\r
158 elements.Values = values;
\r
159 elements.CheckSum = Int32.Parse(
\r
160 csString, System.Globalization.NumberStyles.HexNumber);
\r
161 elements.PacketLength = length;
\r
165 protected static bool Match(byte[] sentence, byte[] header)
\r
167 if (sentence.Length < header.Length)
\r
171 for (int i = 0; i < header.Length; ++i)
\r
173 if (header[i] != sentence[i])
\r
181 protected TimeSpan ParseTime(string time)
\r
183 int h = Int32.Parse(time.Substring(0, 2));
\r
184 int m = Int32.Parse(time.Substring(2, 2));
\r
185 decimal ds = Decimal.Parse(time.Substring(4));
\r
186 int sec = (int)Math.Floor(ds);
\r
187 int msec = (int)((ds - sec) * 1000m);
\r
188 return new TimeSpan(0, h, m, sec, msec);
\r
191 protected static double GetLength(string value, string unit)
\r
195 if (!Double.TryParse(value, out v))
\r
209 protected static int ParseInt(string intString, int defaultValue)
\r
212 if (!Int32.TryParse(intString, out v))
\r
214 return defaultValue;
\r
219 protected static double ParseDouble(string doubleString)
\r
221 return ParseDouble(doubleString, Double.NaN);
\r
224 protected static double ParseDouble(string doubleString,
\r
225 double defaultValue)
\r
228 if (!Double.TryParse(doubleString, out v))
\r
230 return defaultValue;
\r
235 protected static Status ParseStatus(string status)
\r
240 return Status.Invalid;
\r
242 return Status.Valid;
\r
244 return Status.Unknown;
\r