OSDN Git Service

対応プロトコル,UBXパケットタイプを追加・削除出来るよう変更
authorkimikage <kimikage_ceo@hotmail.com>
Fri, 28 Jan 2011 02:28:27 +0000 (11:28 +0900)
committerkimikage <kimikage_ceo@hotmail.com>
Fri, 28 Jan 2011 02:28:27 +0000 (11:28 +0900)
12 files changed:
Yubeshi/Parser.cs
Yubeshi/Ubx/Parser.cs
Yubeshi/UnknownPacket.cs
YubeshiTest/NmeaTest/PacketTest.cs
YubeshiTest/NmeaTest/ParserTest.cs
YubeshiTest/NmeaTest/SamplePackets.cs
YubeshiTest/ParserTest.cs
YubeshiTest/UbxTest/MyPacket.cs [new file with mode: 0755]
YubeshiTest/UbxTest/NavPacketTest.cs
YubeshiTest/UbxTest/ParserTest.cs
YubeshiTest/UbxTest/SamplePackets.cs
YubeshiTest/YubeshiTest.csproj

index be4af0f..07ee34d 100755 (executable)
@@ -15,26 +15,28 @@ namespace Yubeshi
     public class Parser\r
     {\r
         #region type definitions\r
-        protected enum Protocol : int\r
+        public enum Protocol : int\r
         { \r
             Nmea = 0,\r
             Ubx,\r
         }\r
 \r
-        protected delegate bool TrialParser(\r
+        public delegate bool TrialParser(\r
                                 byte[] sentence, out UnknownPacket packet);\r
-        protected delegate int Searcher(byte[] input, int offset);\r
+        public delegate int SyncSearcher(byte[] input, int offset);\r
 \r
-        #endregion\r
-\r
-        #region fields\r
-        private byte[] buffer = new byte[0];\r
-        private List<UnknownPacket> packets = new List<UnknownPacket>();\r
-\r
-        private static readonly Protocol[] protocols;\r
-        private static readonly TrialParser[] parsers;\r
-        private static readonly Searcher[] searchers;\r
+        protected struct ParserFunctions\r
+        {\r
+            public TrialParser TryParse;\r
+            public SyncSearcher SearchSyncFrom;\r
+            public ParserFunctions(TrialParser parser, SyncSearcher searcher)\r
+            {\r
+                TryParse = parser;\r
+                SearchSyncFrom = searcher;\r
+            }\r
+        }\r
 \r
+            \r
         private struct SyncIndex\r
         {\r
             public int Index;\r
@@ -45,21 +47,25 @@ namespace Yubeshi
                 Protocol = protocol;\r
             }\r
         }\r
-        \r
+\r
+        #endregion\r
+\r
+        #region fields\r
+        private byte[] buffer = new byte[0];\r
+        private List<UnknownPacket> packets = new List<UnknownPacket>();\r
+\r
+        private static Dictionary<Protocol, ParserFunctions> functions =\r
+                                new Dictionary<Protocol, ParserFunctions>();\r
+\r
         #endregion\r
 \r
         #region constructors\r
         static Parser()\r
         {\r
-            protocols = Enum.GetValues(typeof(Protocol)) as Protocol[];\r
-\r
-            parsers = new TrialParser[protocols.Length];\r
-            parsers[(int)Protocol.Nmea] = Nmea.Parser.TryParse;\r
-            parsers[(int)Protocol.Ubx] = Ubx.Parser.TryParse;\r
+            Bind(Protocol.Nmea,\r
+                            Nmea.Parser.TryParse, Nmea.Parser.SearchSyncFrom);\r
 \r
-            searchers = new Searcher[protocols.Length];\r
-            searchers[(int)Protocol.Nmea] = Nmea.Parser.SearchSyncFrom;\r
-            searchers[(int)Protocol.Ubx] = Ubx.Parser.SearchSyncFrom;\r
+            Bind(Protocol.Ubx, Ubx.Parser.TryParse, Ubx.Parser.SearchSyncFrom);\r
         }\r
 \r
         public Parser()\r
@@ -72,7 +78,7 @@ namespace Yubeshi
         public void Push(byte[] fragment)\r
         {\r
             Join(fragment);\r
-            ParseBuffer(protocols);\r
+            ParseBuffer(functions);\r
         }\r
 \r
         public UnknownPacket Peek()\r
@@ -88,9 +94,9 @@ namespace Yubeshi
 \r
         public static bool TryParse(byte[] sentence, out UnknownPacket packet)\r
         {\r
-            foreach (Protocol p in protocols)\r
+            foreach (Protocol p in functions.Keys)\r
             {\r
-                if (parsers[(int)p](sentence, out packet))\r
+                if (functions[p].TryParse(sentence, out packet))\r
                 {\r
                     return true;\r
                 }\r
@@ -98,6 +104,17 @@ namespace Yubeshi
             packet = null;\r
             return false;\r
         }\r
+\r
+        public static void Bind(Protocol protocol,\r
+                                    TrialParser parser, SyncSearcher searcher)\r
+        {\r
+            functions[protocol] = new ParserFunctions(parser, searcher);\r
+        }\r
+\r
+        public static void Unbind(Protocol protocol)\r
+        {\r
+            functions.Remove(protocol);\r
+        }\r
         #endregion\r
 \r
         #region protected methods\r
@@ -110,22 +127,30 @@ namespace Yubeshi
             buffer = joined;\r
         }\r
 \r
-        protected void ParseBuffer(Protocol[] protocols)\r
-        { \r
-            List<SyncIndex> foundList = new List<SyncIndex>();\r
-            List<SyncIndex> fullFoundList = new List<SyncIndex>();\r
+        protected void ParseBuffer(\r
+                            Dictionary<Protocol, ParserFunctions> functions)\r
+        {\r
+            Comparison<SyncIndex> sorter = delegate(SyncIndex a, SyncIndex b)\r
+            {\r
+                return a.Index - b.Index;\r
+            };\r
+            List<SyncIndex> found = new List<SyncIndex>();\r
             int offset = 0;\r
             while (offset < buffer.Length)\r
             {\r
-                foreach (Protocol p in protocols)\r
+                foreach (Protocol p in functions.Keys)\r
                 {\r
-                    int index = searchers[(int)p](buffer, offset);\r
+                    int index = functions[p].SearchSyncFrom(buffer, offset);\r
                     if (index >= 0)\r
                     {\r
-                        foundList.Add(new SyncIndex(index, p));\r
+                        SyncIndex s = new SyncIndex(index, p);\r
+                        if (!found.Contains(s))\r
+                        {\r
+                            found.Add(s);\r
+                        }\r
                     }\r
                 }\r
-                if (foundList.Count == 0)\r
+                if (found.Count == 0)\r
                 {\r
                     if (offset == 0)\r
                     {\r
@@ -134,29 +159,23 @@ namespace Yubeshi
                     }\r
                     return;\r
                 }\r
-                foundList.Sort(\r
-                    delegate(SyncIndex a, SyncIndex b)\r
-                    {\r
-                        return a.Index - b.Index;\r
-                    });\r
-                int firstSync = foundList[0].Index;\r
-                byte[] synced = Substring(buffer, firstSync);\r
+                found.Sort(sorter);\r
+                SyncIndex first = found[0];\r
+                byte[] synced = Substring(buffer, first.Index);\r
                 UnknownPacket packet = null;\r
-                if (parsers[(int)foundList[0].Protocol](synced, out packet))\r
+                if (functions[first.Protocol].TryParse(synced, out packet))\r
                 {\r
-                    if (firstSync > 0)\r
+                    if (first.Index > 0)\r
                     {\r
-                        packets.Add(new UnknownPacket(buffer, firstSync));\r
+                        packets.Add(new UnknownPacket(buffer, first.Index));\r
                     }\r
                     packets.Add(packet);\r
                     buffer = Substring(synced, packet.Raw.Length);\r
-                    ParseBuffer(protocols);\r
+                    ParseBuffer(functions);\r
                     return;\r
                 }\r
-                fullFoundList.AddRange(foundList);\r
-                offset = foundList[0].Index + 1;\r
-                foundList.RemoveAt(0);\r
-\r
+                offset = first.Index + 1;\r
+                found.RemoveAt(0);\r
             }\r
         }\r
 \r
index e66770c..4b009c1 100755 (executable)
@@ -17,8 +17,8 @@ namespace Yubeshi.Ubx
         #endregion\r
 \r
         #region fields\r
-        private static readonly Protocol[] protocols =\r
-                                            new Protocol[] { Protocol.Ubx };\r
+        private static readonly \r
+            Dictionary<Protocol, ParserFunctions> functions;\r
         private static Dictionary<Packet.MessageID, TrialParser> parsers;\r
         private static readonly Encoding ascii = Encoding.ASCII;\r
 \r
@@ -27,6 +27,10 @@ namespace Yubeshi.Ubx
         #region constructors\r
         static Parser()\r
         {\r
+            functions = new Dictionary<Protocol, ParserFunctions>();\r
+            functions.Add(Protocol.Ubx, \r
+                                new ParserFunctions(TryParse, SearchSyncFrom));\r
+\r
             parsers = new Dictionary<Packet.MessageID, TrialParser>();\r
             parsers[Packet.MessageID.NavClock] = NavClock.TryParse;\r
             parsers[Packet.MessageID.NavPosEcef] = NavPosEcef.TryParse;\r
@@ -39,10 +43,21 @@ namespace Yubeshi.Ubx
         public new void Push(byte[] fragment)\r
         {\r
             Join(fragment);\r
-            ParseBuffer(protocols);\r
+            ParseBuffer(functions);\r
+        }\r
+\r
+        public static void AddParser(Packet.MessageID id, TrialParser parser)\r
+        {\r
+            parsers[id] = parser;\r
+        }\r
+\r
+        public static void RemoveParser(Packet.MessageID id)\r
+        {\r
+            parsers.Remove(id);\r
         }\r
 \r
-        public new static bool TryParse(byte[] sentence, out UnknownPacket packet)\r
+        public new static bool TryParse(\r
+                                    byte[] sentence, out UnknownPacket packet)\r
         {\r
             packet = null;\r
             if (sentence.Length < 8)\r
index 744bf3a..e86c71c 100755 (executable)
@@ -24,6 +24,7 @@ namespace Yubeshi
             Raw = new byte[length];\r
             Array.Copy(sentence, Raw, Raw.Length);\r
         }\r
+\r
         #endregion\r
 \r
         #region properties\r
@@ -33,6 +34,7 @@ namespace Yubeshi
             get;\r
             protected set;\r
         }\r
+\r
         #endregion\r
     }\r
 }\r
index d211f7a..2ed8497 100755 (executable)
@@ -11,9 +11,9 @@ using System.Text;
 using NUnit.Framework;\r
 using Yubeshi;\r
 using Yubeshi.Nmea;\r
-using P = YubeshiTest.Nmea.SamplePackets;\r
+using P = YubeshiTest.NmeaTest.SamplePackets;\r
 \r
-namespace YubeshiTest.Nmea\r
+namespace YubeshiTest.NmeaTest\r
 {\r
 \r
     class PacketTest\r
@@ -23,7 +23,7 @@ namespace YubeshiTest.Nmea
         public void GpDtmTest()\r
         {\r
             UnknownPacket packet;\r
-            Assert.AreEqual(true, GpDtm.TryParse(P.GpDtm, out packet));\r
+            Assert.IsTrue(GpDtm.TryParse(P.GpDtm, out packet));\r
             GpGga p = packet as GpGga;\r
         }\r
 \r
@@ -31,7 +31,7 @@ namespace YubeshiTest.Nmea
         public void GpGgaTest()\r
         {\r
             UnknownPacket packet;\r
-            Assert.AreEqual(true, GpGga.TryParse(P.GpGga, out packet));\r
+            Assert.IsTrue(GpGga.TryParse(P.GpGga, out packet));\r
             GpGga p = packet as GpGga;\r
             Assert.AreEqual(new TimeSpan(0, 9, 27, 25, 0), p.TimeOfFix);\r
             Assert.AreEqual(2837.11399, p.Position.Latitude * 60.0);\r
index 5312f19..ed87d9d 100755 (executable)
@@ -10,9 +10,9 @@ using System.Collections.Generic;
 using System.Text;\r
 using NUnit.Framework;\r
 using Yubeshi.Nmea;\r
-using P = YubeshiTest.Nmea.SamplePackets;\r
+using P = YubeshiTest.NmeaTest.SamplePackets;\r
 \r
-namespace YubeshiTest.Nmea\r
+namespace YubeshiTest.NmeaTest\r
 {\r
 \r
     class ParserTest\r
@@ -22,23 +22,23 @@ namespace YubeshiTest.Nmea
         { \r
             Yubeshi.UnknownPacket p;\r
 \r
-            Assert.AreEqual(false, Parser.TryParse(P.Dummy, out p));\r
-            Assert.AreEqual(null, p);\r
+            Assert.IsFalse(Parser.TryParse(P.Dummy, out p));\r
+            Assert.IsNull(p);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.GpDtm, out p));\r
-            Assert.AreEqual(typeof(GpDtm), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.GpDtm, out p));\r
+            Assert.IsTrue(p is GpDtm);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.GpGga, out p));\r
-            Assert.AreEqual(typeof(GpGga), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.GpGga, out p));\r
+            Assert.IsTrue(p is GpGga);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.GpGll, out p));\r
-            Assert.AreEqual(typeof(GpGll), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.GpGll, out p));\r
+            Assert.IsTrue(p is GpGll);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.GpGrs, out p));\r
-            Assert.AreEqual(typeof(GpGrs), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.GpGrs, out p));\r
+            Assert.IsTrue(p is GpGrs);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.GpGsa, out p));\r
-            Assert.AreEqual(typeof(GpGsa), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.GpGsa, out p));\r
+            Assert.IsTrue(p is GpGsa);\r
         }\r
 \r
         [Test]\r
index 4452539..e0ffe45 100755 (executable)
@@ -9,7 +9,7 @@ using System;
 using System.Collections.Generic;\r
 using System.Text;\r
 \r
-namespace YubeshiTest.Nmea\r
+namespace YubeshiTest.NmeaTest\r
 {\r
     public class SamplePackets\r
     {\r
index 42a4f24..e4ed3cb 100755 (executable)
@@ -24,8 +24,8 @@ namespace YubeshiTest
             {\r
                 noise[i] = (byte)(i & 0x7F | 0x80);\r
             }\r
-            noise[52, -1] = Nmea.SamplePackets.Dummy;\r
-            noise[79, -1] = Ubx.SamplePackets.Dummy;\r
+            noise[52, -1] = NmeaTest.SamplePackets.Dummy;\r
+            noise[79, -1] = UbxTest.SamplePackets.Dummy;\r
         }\r
 \r
         [Test]\r
@@ -47,8 +47,8 @@ namespace YubeshiTest
             UnknownPacket p;\r
 \r
             OctetString data = noise;\r
-            data += Nmea.SamplePackets.GpDtm;\r
-            data += Ubx.SamplePackets.NavClock;\r
+            data += NmeaTest.SamplePackets.GpDtm;\r
+            data += UbxTest.SamplePackets.NavClock;\r
             data += noise;\r
 \r
             parser.Push(data);\r
diff --git a/YubeshiTest/UbxTest/MyPacket.cs b/YubeshiTest/UbxTest/MyPacket.cs
new file mode 100755 (executable)
index 0000000..14a459f
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ *     Yubeshi GPS Parser\r
+ *\r
+ *     This software is distributed under a zlib-style license.\r
+ *     See license.txt for more information.\r
+ */\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using Yubeshi;\r
+using Yubeshi.Ubx;\r
+\r
+namespace YubeshiTest.UbxTest\r
+{\r
+    class MyPacket : Unknown\r
+    {\r
+        #region constructors\r
+\r
+        public MyPacket(byte[] sentence, int length)\r
+            : base(sentence, length)\r
+        {\r
+            ID = (MessageID)0xFFFF;\r
+            \r
+            Content =BitConverter.ToUInt32(sentence, 6 + 0);\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region properties\r
+        public uint Content\r
+        {\r
+            get;\r
+            set;\r
+        }\r
+        #endregion\r
+\r
+        #region public methods\r
+        public static bool TryParse(byte[] sentence, out UnknownPacket packet)\r
+        {\r
+            return TryParse(sentence, out packet, (MessageID)0xFFFF, 4, Build);\r
+        }\r
+        #endregion\r
+\r
+        #region private methods\r
+\r
+        private static Packet Build(byte[] sentence, int length)\r
+        {\r
+            return new MyPacket(sentence, length);\r
+        }\r
+        #endregion\r
+    }\r
+}\r
index e913209..4b66701 100755 (executable)
@@ -11,9 +11,9 @@ using System.Text;
 using NUnit.Framework;\r
 using Yubeshi;\r
 using Yubeshi.Ubx;\r
-using P = YubeshiTest.Ubx.SamplePackets;\r
+using P = YubeshiTest.UbxTest.SamplePackets;\r
 \r
-namespace YubeshiTest.Ubx\r
+namespace YubeshiTest.UbxTest\r
 {\r
 \r
     class NavPacketTest\r
@@ -22,7 +22,7 @@ namespace YubeshiTest.Ubx
         public void NavClockTest()\r
         {\r
             UnknownPacket packet;\r
-            Assert.AreEqual(true, NavClock.TryParse(P.NavClock, out packet));\r
+            Assert.IsTrue(NavClock.TryParse(P.NavClock, out packet));\r
             NavClock p = packet as NavClock;\r
         }\r
 \r
@@ -30,14 +30,14 @@ namespace YubeshiTest.Ubx
         public void NavPosEcefTest()\r
         {\r
             UnknownPacket p;\r
-            Assert.AreEqual(true, NavPosEcef.TryParse(P.NavPosEcef, out p));\r
+            Assert.IsTrue(NavPosEcef.TryParse(P.NavPosEcef, out p));\r
         }\r
 \r
         [Test]\r
         public void NavSolTest()\r
         {\r
             UnknownPacket packet;\r
-            Assert.AreEqual(true, NavSol.TryParse(P.NavSol, out packet));\r
+            Assert.IsTrue(NavSol.TryParse(P.NavSol, out packet));\r
             NavSol p = packet as NavSol;\r
             Assert.AreEqual(-3961181.33, p.Position.X);\r
             Assert.AreEqual(3346187.67, p.Position.Y);\r
index 73e0e69..86a544a 100755 (executable)
@@ -10,9 +10,9 @@ using System.Collections.Generic;
 using System.Text;\r
 using NUnit.Framework;\r
 using Yubeshi.Ubx;\r
-using P = YubeshiTest.Ubx.SamplePackets;\r
+using P = YubeshiTest.UbxTest.SamplePackets;\r
 \r
-namespace YubeshiTest.Ubx\r
+namespace YubeshiTest.UbxTest\r
 {\r
 \r
     class ParserTest\r
@@ -22,18 +22,38 @@ namespace YubeshiTest.Ubx
         {\r
             Yubeshi.UnknownPacket p;\r
 \r
-            Assert.AreEqual(false, Parser.TryParse(P.Dummy, out p));\r
-            Assert.AreEqual(null, p);\r
+            Assert.IsFalse(Parser.TryParse(P.Dummy, out p));\r
+            Assert.IsNull(p);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.NavClock, out p));\r
-            Assert.AreEqual(typeof(NavClock), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.NavClock, out p));\r
+            Assert.IsTrue(p is NavClock);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.NavPosEcef, out p));\r
-            Assert.AreEqual(typeof(NavPosEcef), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.NavPosEcef, out p));\r
+            Assert.IsTrue(p is NavPosEcef);\r
 \r
-            Assert.AreEqual(true, Parser.TryParse(P.NavSol, out p));\r
-            Assert.AreEqual(typeof(NavSol), p.GetType());\r
+            Assert.IsTrue(Parser.TryParse(P.NavSol, out p));\r
+            Assert.IsTrue(p is NavSol);\r
 \r
         }\r
+\r
+        [Test]\r
+        public void AddParser()\r
+        {\r
+            Yubeshi.UnknownPacket p;\r
+\r
+            Assert.IsFalse(Parser.TryParse(P.UserDefined, out p));\r
+            Assert.IsNull(p);\r
+\r
+            Parser.AddParser((Packet.MessageID)0xFFFF, MyPacket.TryParse);\r
+\r
+            Assert.IsTrue(Parser.TryParse(P.UserDefined, out p));\r
+            Assert.IsTrue(p is MyPacket);\r
+            Assert.AreEqual(0x04030201, (p as MyPacket).Content);\r
+\r
+            Parser.RemoveParser((Packet.MessageID)0xFFFF);\r
+\r
+            Assert.IsFalse(Parser.TryParse(P.UserDefined, out p));\r
+            Assert.IsNull(p);\r
+        }\r
     }\r
 }\r
index ac9c7c8..9740fe8 100755 (executable)
@@ -9,11 +9,13 @@ using System;
 using System.Collections.Generic;\r
 using System.Text;\r
 \r
-namespace YubeshiTest.Ubx\r
+namespace YubeshiTest.UbxTest\r
 {\r
     public class SamplePackets\r
     {\r
         public static readonly byte[] Dummy;\r
+        public static readonly byte[] UserDefined;\r
+\r
         public static readonly byte[] NavClock;\r
         public static readonly byte[] NavPosEcef;\r
         public static readonly byte[] NavSol;\r
@@ -29,6 +31,12 @@ namespace YubeshiTest.Ubx
                 0xFF, 0xFF\r
             };\r
 \r
+            UserDefined = new byte[] {\r
+                0xB5, 0x62, 0xFF, 0xFF, 0x04, 0x00,\r
+                0x01, 0x02, 0x03, 0x04, \r
+                0xFF, 0xFF\r
+            };\r
+\r
             NavClock = new byte[]{\r
                 0xB5, 0x62, 0x01, 0x22, 0x14, 0x00, \r
                 0x70, 0xAA, 0xB4, 0x12, \r
index 4d07a35..a2c86f9 100755 (executable)
@@ -51,6 +51,7 @@
     <Compile Include="NmeaTest\SamplePackets.cs" />\r
     <Compile Include="ParserTest.cs" />\r
     <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="UbxTest\MyPacket.cs" />\r
     <Compile Include="UbxTest\NavPacketTest.cs" />\r
     <Compile Include="UbxTest\ParserTest.cs" />\r
     <Compile Include="UbxTest\SamplePackets.cs" />\r