diff --git a/src/NmeaParser/BluetoothDevice.Android.cs b/src/NmeaParser/BluetoothDevice.Android.cs
index 0f1d56a..12c893a 100644
--- a/src/NmeaParser/BluetoothDevice.Android.cs
+++ b/src/NmeaParser/BluetoothDevice.Android.cs
@@ -22,11 +22,11 @@ using Android.Bluetooth;
namespace NmeaParser
{
- ///
- /// A Bluetooth NMEA device
- ///
- public class BluetoothDevice : NmeaDevice
- {
+ ///
+ /// A Bluetooth NMEA device
+ ///
+ public class BluetoothDevice : NmeaDevice
+ {
private static Java.Util.UUID SERIAL_UUID = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
private Android.Bluetooth.BluetoothDevice m_device;
private BluetoothSocket? m_socket;
@@ -45,14 +45,14 @@ namespace NmeaParser
}
}
- ///
- /// Initializes a new instance of the class.
- ///
- /// The Android Bluetooth Device.
- public BluetoothDevice(Android.Bluetooth.BluetoothDevice device)
- {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Android Bluetooth Device.
+ public BluetoothDevice(Android.Bluetooth.BluetoothDevice device)
+ {
m_device = device ?? throw new ArgumentNullException(nameof(device));
- }
+ }
///
/// Creates the stream the NmeaDevice is working on top off.
@@ -66,24 +66,24 @@ namespace NmeaParser
var d = adapter.GetRemoteDevice(m_device.Address);
var socket = d.CreateRfcommSocketToServiceRecord(SERIAL_UUID);
socket.Connect();
- m_socket = socket;
+ m_socket = socket;
return Task.FromResult(socket.InputStream);
- }
+ }
- ///
- /// Closes the stream the NmeaDevice is working on top off.
- ///
- /// The stream.
- ///
- protected override Task CloseStreamAsync(System.IO.Stream stream)
- {
- if (stream == null)
- throw new ArgumentNullException("stream");
- stream.Dispose();
- m_socket?.Dispose();
- m_socket = null;
- return Task.FromResult(true);
- }
+ ///
+ /// Closes the stream the NmeaDevice is working on top off.
+ ///
+ /// The stream.
+ ///
+ protected override Task CloseStreamAsync(System.IO.Stream stream)
+ {
+ if (stream == null)
+ throw new ArgumentNullException("stream");
+ stream.Dispose();
+ m_socket?.Dispose();
+ m_socket = null;
+ return Task.FromResult(true);
+ }
///
public override bool CanWrite => true;
@@ -95,6 +95,6 @@ namespace NmeaParser
throw new InvalidOperationException("Device not open");
return m_socket.OutputStream.WriteAsync(buffer, offset, length);
}
- }
+ }
}
#endif
\ No newline at end of file
diff --git a/src/NmeaParser/BluetoothDevice.UWP.cs b/src/NmeaParser/BluetoothDevice.UWP.cs
index f4d6bff..e752eea 100644
--- a/src/NmeaParser/BluetoothDevice.UWP.cs
+++ b/src/NmeaParser/BluetoothDevice.UWP.cs
@@ -28,12 +28,12 @@ using Windows.Networking.Proximity;
namespace NmeaParser
{
- ///
- /// A Bluetooth NMEA device
- ///
- public class BluetoothDevice : NmeaDevice
- {
- private Windows.Devices.Bluetooth.Rfcomm.RfcommDeviceService? m_deviceService;
+ ///
+ /// A Bluetooth NMEA device
+ ///
+ public class BluetoothDevice : NmeaDevice
+ {
+ private Windows.Devices.Bluetooth.Rfcomm.RfcommDeviceService? m_deviceService;
private Windows.Networking.Proximity.PeerInformation? m_devicePeer;
private StreamSocket? m_socket;
private bool m_disposeService;
@@ -59,8 +59,8 @@ namespace NmeaParser
/// The RF Comm Device service.
/// Whether this devicee should also dispose the RfcommDeviceService provided when this device disposes.
public BluetoothDevice(RfcommDeviceService service, bool disposeService = false)
- {
- m_deviceService = service ?? throw new ArgumentNullException(nameof(service));
+ {
+ m_deviceService = service ?? throw new ArgumentNullException(nameof(service));
m_disposeService = disposeService;
}
@@ -88,8 +88,8 @@ namespace NmeaParser
///
///
protected override async Task OpenStreamAsync()
- {
- var socket = new Windows.Networking.Sockets.StreamSocket();
+ {
+ var socket = new Windows.Networking.Sockets.StreamSocket();
socket.Control.KeepAlive = true;
if (m_devicePeer != null)
{
@@ -101,10 +101,10 @@ namespace NmeaParser
}
else
throw new InvalidOperationException();
- m_socket = socket;
+ m_socket = socket;
return new DummyStream(); //We're going to use WinRT buffers instead and will handle read/write, so no reason to return a real stream. This is mainly done to avoid locking issues reading and writing at the same time
- }
+ }
private class DummyStream : Stream
{
@@ -126,13 +126,13 @@ namespace NmeaParser
/// The stream.
///
protected override Task CloseStreamAsync(System.IO.Stream stream)
- {
+ {
if(m_socket == null)
throw new InvalidOperationException("No connection to close");
- m_socket.Dispose();
- m_socket = null;
- return Task.FromResult(true);
- }
+ m_socket.Dispose();
+ m_socket = null;
+ return Task.FromResult(true);
+ }
///
@@ -174,6 +174,6 @@ namespace NmeaParser
m_semaphoreSlim.Release();
}
}
- }
+ }
}
#endif
\ No newline at end of file
diff --git a/src/NmeaParser/BufferedStreamDevice.cs b/src/NmeaParser/BufferedStreamDevice.cs
index 3cd218a..09decc0 100644
--- a/src/NmeaParser/BufferedStreamDevice.cs
+++ b/src/NmeaParser/BufferedStreamDevice.cs
@@ -21,241 +21,241 @@ using System.Threading.Tasks;
namespace NmeaParser
{
- ///
- /// An abstract generic NMEA device that reads a stream at a decreased pace,
- /// mostly used to emulate NMEA input from files and strings.
- ///
- public abstract class BufferedStreamDevice : NmeaDevice
- {
- private BufferedStream? m_stream;
- private readonly int m_readSpeed;
+ ///
+ /// An abstract generic NMEA device that reads a stream at a decreased pace,
+ /// mostly used to emulate NMEA input from files and strings.
+ ///
+ public abstract class BufferedStreamDevice : NmeaDevice
+ {
+ private BufferedStream? m_stream;
+ private readonly int m_readSpeed;
- ///
- /// Initializes a new instance of the class.
- ///
- protected BufferedStreamDevice() : this(1000)
- {
- }
- ///
- /// Initializes a new instance of the class.
- ///
- /// The time to wait between each group of lines being read in milliseconds
- protected BufferedStreamDevice(int readSpeed)
- {
- m_readSpeed = readSpeed;
- }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected BufferedStreamDevice() : this(1000)
+ {
+ }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The time to wait between each group of lines being read in milliseconds
+ protected BufferedStreamDevice(int readSpeed)
+ {
+ m_readSpeed = readSpeed;
+ }
- ///
- /// Gets the stream to perform buffer reads on.
- ///
- ///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- protected abstract Task GetStreamAsync();
+ ///
+ /// Gets the stream to perform buffer reads on.
+ ///
+ ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ protected abstract Task GetStreamAsync();
- ///
- /// Opens the stream asynchronous.
- ///
- ///
- protected sealed async override Task OpenStreamAsync()
- {
- var stream = await GetStreamAsync();
- StreamReader sr = new StreamReader(stream);
- m_stream = new BufferedStream(sr, m_readSpeed);
- return m_stream;
- }
+ ///
+ /// Opens the stream asynchronous.
+ ///
+ ///
+ protected sealed async override Task OpenStreamAsync()
+ {
+ var stream = await GetStreamAsync();
+ StreamReader sr = new StreamReader(stream);
+ m_stream = new BufferedStream(sr, m_readSpeed);
+ return m_stream;
+ }
- ///
- /// Closes the stream asynchronous.
- ///
- /// The stream.
- ///
- protected override Task CloseStreamAsync(System.IO.Stream stream)
- {
- m_stream?.Dispose();
- return Task.FromResult(true);
- }
+ ///
+ /// Closes the stream asynchronous.
+ ///
+ /// The stream.
+ ///
+ protected override Task CloseStreamAsync(System.IO.Stream stream)
+ {
+ m_stream?.Dispose();
+ return Task.FromResult(true);
+ }
- // stream that slowly populates a buffer from a StreamReader to simulate nmea messages coming
- // in lastLineRead by lastLineRead at a steady stream
- private class BufferedStream : Stream
- {
- private readonly StreamReader m_sr;
- private byte[] m_buffer = new byte[0];
- private readonly System.Threading.Timer m_timer;
- private readonly object lockObj = new object();
- private string? groupToken = null;
- private string? lastLineRead = null;
- ///
- /// Initializes a new instance of the class.
- ///
- /// The stream.
- /// The read speed in milliseconds.
- public BufferedStream(StreamReader stream, int readSpeed)
- {
- m_sr = stream;
- m_timer = new System.Threading.Timer(OnRead, null, 0, readSpeed); //read a group of lines every 'readSpeed' milliseconds
- }
- private void OnRead(object state)
- {
- if (lastLineRead != null)
- AppendToBuffer(lastLineRead);
- //Get the group token if we don't have one
- while (groupToken == null && (lastLineRead == null || !lastLineRead.StartsWith("$", StringComparison.Ordinal)))
- {
- lastLineRead = ReadLine(); //seek forward to first nmea token
- AppendToBuffer(lastLineRead);
- }
- if(groupToken == null && lastLineRead != null)
- {
- var values = lastLineRead.Trim().Split(new char[] { ',' });
- if (values.Length > 0)
- groupToken = values[0];
- }
- lastLineRead = ReadLine();
- while (!lastLineRead.StartsWith(groupToken, StringComparison.Ordinal)) //keep reading until messages start repeating again
- {
- AppendToBuffer(lastLineRead);
- lastLineRead = ReadLine();
- }
- }
- private void AppendToBuffer(string line)
- {
- var bytes = Encoding.UTF8.GetBytes(line);
- lock (lockObj)
- {
- byte[] newBuffer = new byte[m_buffer.Length + bytes.Length];
- m_buffer.CopyTo(newBuffer, 0);
- bytes.CopyTo(newBuffer, m_buffer.Length);
- m_buffer = newBuffer;
- }
- }
- private string ReadLine()
- {
- if (m_sr.EndOfStream)
- m_sr.BaseStream.Seek(0, SeekOrigin.Begin); //start over
- return m_sr.ReadLine() + '\n';
- }
- ///
- /// Gets a value indicating whether this instance can read.
- ///
- ///
- /// true if this instance can read; otherwise, false.
- ///
- public override bool CanRead { get { return true; } }
- ///
- /// Gets a value indicating whether this instance can seek.
- ///
- ///
- /// true if this instance can seek; otherwise, false.
- ///
- public override bool CanSeek { get { return false; } }
- ///
- /// Gets a value indicating whether this instance can write.
- ///
- ///
- /// true if this instance can write; otherwise, false.
- ///
- public override bool CanWrite { get { return false; } }
- ///
- /// Flushes this instance.
- ///
- public override void Flush() { }
- ///
- /// Gets the length.
- ///
- ///
- /// The length.
- ///
- public override long Length { get { return m_sr.BaseStream.Length; } }
+ // stream that slowly populates a buffer from a StreamReader to simulate nmea messages coming
+ // in lastLineRead by lastLineRead at a steady stream
+ private class BufferedStream : Stream
+ {
+ private readonly StreamReader m_sr;
+ private byte[] m_buffer = new byte[0];
+ private readonly System.Threading.Timer m_timer;
+ private readonly object lockObj = new object();
+ private string? groupToken = null;
+ private string? lastLineRead = null;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream.
+ /// The read speed in milliseconds.
+ public BufferedStream(StreamReader stream, int readSpeed)
+ {
+ m_sr = stream;
+ m_timer = new System.Threading.Timer(OnRead, null, 0, readSpeed); //read a group of lines every 'readSpeed' milliseconds
+ }
+ private void OnRead(object state)
+ {
+ if (lastLineRead != null)
+ AppendToBuffer(lastLineRead);
+ //Get the group token if we don't have one
+ while (groupToken == null && (lastLineRead == null || !lastLineRead.StartsWith("$", StringComparison.Ordinal)))
+ {
+ lastLineRead = ReadLine(); //seek forward to first nmea token
+ AppendToBuffer(lastLineRead);
+ }
+ if(groupToken == null && lastLineRead != null)
+ {
+ var values = lastLineRead.Trim().Split(new char[] { ',' });
+ if (values.Length > 0)
+ groupToken = values[0];
+ }
+ lastLineRead = ReadLine();
+ while (!lastLineRead.StartsWith(groupToken, StringComparison.Ordinal)) //keep reading until messages start repeating again
+ {
+ AppendToBuffer(lastLineRead);
+ lastLineRead = ReadLine();
+ }
+ }
+ private void AppendToBuffer(string line)
+ {
+ var bytes = Encoding.UTF8.GetBytes(line);
+ lock (lockObj)
+ {
+ byte[] newBuffer = new byte[m_buffer.Length + bytes.Length];
+ m_buffer.CopyTo(newBuffer, 0);
+ bytes.CopyTo(newBuffer, m_buffer.Length);
+ m_buffer = newBuffer;
+ }
+ }
+ private string ReadLine()
+ {
+ if (m_sr.EndOfStream)
+ m_sr.BaseStream.Seek(0, SeekOrigin.Begin); //start over
+ return m_sr.ReadLine() + '\n';
+ }
+ ///
+ /// Gets a value indicating whether this instance can read.
+ ///
+ ///
+ /// true if this instance can read; otherwise, false.
+ ///
+ public override bool CanRead { get { return true; } }
+ ///
+ /// Gets a value indicating whether this instance can seek.
+ ///
+ ///
+ /// true if this instance can seek; otherwise, false.
+ ///
+ public override bool CanSeek { get { return false; } }
+ ///
+ /// Gets a value indicating whether this instance can write.
+ ///
+ ///
+ /// true if this instance can write; otherwise, false.
+ ///
+ public override bool CanWrite { get { return false; } }
+ ///
+ /// Flushes this instance.
+ ///
+ public override void Flush() { }
+ ///
+ /// Gets the length.
+ ///
+ ///
+ /// The length.
+ ///
+ public override long Length { get { return m_sr.BaseStream.Length; } }
- ///
- /// Gets or sets the position.
- ///
- ///
- /// The position.
- ///
- ///
- public override long Position
- {
- get { return m_sr.BaseStream.Position; }
- set
- {
- throw new NotSupportedException();
- }
- }
- ///
- /// Reads the specified buffer.
- ///
- /// The buffer.
- /// The offset.
- /// The count.
- ///
- public override int Read(byte[] buffer, int offset, int count)
- {
- lock (lockObj)
- {
- if (this.m_buffer.Length <= count)
- {
- int length = this.m_buffer.Length;
- this.m_buffer.CopyTo(buffer, 0);
- this.m_buffer = new byte[0];
- return length;
- }
- else
- {
- Array.Copy(this.m_buffer, buffer, count);
- byte[] newBuffer = new byte[this.m_buffer.Length - count];
- Array.Copy(this.m_buffer, count, newBuffer, 0, newBuffer.Length);
- this.m_buffer = newBuffer;
- return count;
- }
- }
- }
+ ///
+ /// Gets or sets the position.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ public override long Position
+ {
+ get { return m_sr.BaseStream.Position; }
+ set
+ {
+ throw new NotSupportedException();
+ }
+ }
+ ///
+ /// Reads the specified buffer.
+ ///
+ /// The buffer.
+ /// The offset.
+ /// The count.
+ ///
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ lock (lockObj)
+ {
+ if (this.m_buffer.Length <= count)
+ {
+ int length = this.m_buffer.Length;
+ this.m_buffer.CopyTo(buffer, 0);
+ this.m_buffer = new byte[0];
+ return length;
+ }
+ else
+ {
+ Array.Copy(this.m_buffer, buffer, count);
+ byte[] newBuffer = new byte[this.m_buffer.Length - count];
+ Array.Copy(this.m_buffer, count, newBuffer, 0, newBuffer.Length);
+ this.m_buffer = newBuffer;
+ return count;
+ }
+ }
+ }
- ///
- /// Seeks the specified offset.
- ///
- /// The offset.
- /// The origin.
- ///
- ///
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
+ ///
+ /// Seeks the specified offset.
+ ///
+ /// The offset.
+ /// The origin.
+ ///
+ ///
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException();
+ }
- ///
- /// Sets the length.
- ///
- /// The value.
- ///
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
+ ///
+ /// Sets the length.
+ ///
+ /// The value.
+ ///
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
- ///
- /// Writes the specified buffer to the device.
- ///
- /// The buffer.
- /// The offset.
- /// The count.
- ///
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException();
- }
+ ///
+ /// Writes the specified buffer to the device.
+ ///
+ /// The buffer.
+ /// The offset.
+ /// The count.
+ ///
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new NotSupportedException();
+ }
- ///
- /// Releases unmanaged and - optionally - managed resources.
- ///
- /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- m_sr.Dispose();
- m_timer.Dispose();
- }
- }
- }
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ m_sr.Dispose();
+ m_timer.Dispose();
+ }
+ }
+ }
}
diff --git a/src/NmeaParser/IMultiSentenceMessage.cs b/src/NmeaParser/IMultiSentenceMessage.cs
index 6948d04..4e31a19 100644
--- a/src/NmeaParser/IMultiSentenceMessage.cs
+++ b/src/NmeaParser/IMultiSentenceMessage.cs
@@ -18,25 +18,25 @@ using System.Text;
namespace NmeaParser
{
- ///
- /// Interface used for NMEA messages that span multiple sentences
- ///
- public interface IMultiSentenceMessage
- {
- ///
- /// Attempts to append one message to an existing one
- ///
- ///
- /// This method should return false if the message being appended isn't the next message in line, and various indicators show this is a different message than the previous one. It should also return false if you append to a message that didn't start with the first message.
- ///
- ///
- ///
- /// True is the message was successfully appended, False is the message couldn't be appended.
- bool TryAppend(string messageType, string[] values);
+ ///
+ /// Interface used for NMEA messages that span multiple sentences
+ ///
+ public interface IMultiSentenceMessage
+ {
+ ///
+ /// Attempts to append one message to an existing one
+ ///
+ ///
+ /// This method should return false if the message being appended isn't the next message in line, and various indicators show this is a different message than the previous one. It should also return false if you append to a message that didn't start with the first message.
+ ///
+ ///
+ ///
+ /// True is the message was successfully appended, False is the message couldn't be appended.
+ bool TryAppend(string messageType, string[] values);
- ///
- /// Gets a value indicating whether this message is fully loaded from all its sentences
- ///
- bool IsComplete { get; }
- }
+ ///
+ /// Gets a value indicating whether this message is fully loaded from all its sentences
+ ///
+ bool IsComplete { get; }
+ }
}
diff --git a/src/NmeaParser/Nmea/Garmin/PGRME.cs b/src/NmeaParser/Nmea/Garmin/PGRME.cs
index 5be2e18..99cc1bd 100644
--- a/src/NmeaParser/Nmea/Garmin/PGRME.cs
+++ b/src/NmeaParser/Nmea/Garmin/PGRME.cs
@@ -20,9 +20,9 @@ namespace NmeaParser.Nmea.Garmin
/// Recommended Minimum
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pgrme")]
- [NmeaMessageType("PGRME")]
- public class Pgrme : NmeaMessage
- {
+ [NmeaMessageType("PGRME")]
+ public class Pgrme : NmeaMessage
+ {
///
/// Initializes a new instance of the class.
///
@@ -31,47 +31,47 @@ namespace NmeaParser.Nmea.Garmin
public Pgrme(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 6)
- throw new ArgumentException("Invalid PGRME", "message");
-
- HorizontalError = NmeaMessage.StringToDouble(message[0]);
- HorizontalErrorUnits = message[1];
- VerticalError = NmeaMessage.StringToDouble(message[2]);
- VerticalErrorUnits = message[3];
- SphericalError = NmeaMessage.StringToDouble(message[4]);
- SphericalErrorUnits = message[5];
- }
+ throw new ArgumentException("Invalid PGRME", "message");
+
+ HorizontalError = NmeaMessage.StringToDouble(message[0]);
+ HorizontalErrorUnits = message[1];
+ VerticalError = NmeaMessage.StringToDouble(message[2]);
+ VerticalErrorUnits = message[3];
+ SphericalError = NmeaMessage.StringToDouble(message[4]);
+ SphericalErrorUnits = message[5];
+ }
- ///
- /// Estimated horizontal position error in meters (HPE)
- ///
- /// Range: 0.0 to 999.9 meters
- public double HorizontalError{ get; }
+ ///
+ /// Estimated horizontal position error in meters (HPE)
+ ///
+ /// Range: 0.0 to 999.9 meters
+ public double HorizontalError{ get; }
- ///
- /// Horizontal Error unit ('M' for Meters)
- ///
- public string HorizontalErrorUnits{ get; }
+ ///
+ /// Horizontal Error unit ('M' for Meters)
+ ///
+ public string HorizontalErrorUnits{ get; }
- ///
- /// Estimated vertical position error in meters (VPE)
- ///
- /// Range: 0.0 to 999.9 meters
- public double VerticalError{ get; }
+ ///
+ /// Estimated vertical position error in meters (VPE)
+ ///
+ /// Range: 0.0 to 999.9 meters
+ public double VerticalError{ get; }
- ///
- /// Vertical Error unit ('M' for Meters)
- ///
- public string VerticalErrorUnits{ get; }
+ ///
+ /// Vertical Error unit ('M' for Meters)
+ ///
+ public string VerticalErrorUnits{ get; }
- ///
- /// Overall spherical equivalent position error (EPE)
- ///
- /// Range: 0.0 to 999.9 meters
- public double SphericalError{ get; }
+ ///
+ /// Overall spherical equivalent position error (EPE)
+ ///
+ /// Range: 0.0 to 999.9 meters
+ public double SphericalError{ get; }
- ///
- /// Spherical Error unit ('M' for Meters)
- ///
- public string SphericalErrorUnits{ get; }
- }
+ ///
+ /// Spherical Error unit ('M' for Meters)
+ ///
+ public string SphericalErrorUnits{ get; }
+ }
}
diff --git a/src/NmeaParser/Nmea/Gga.cs b/src/NmeaParser/Nmea/Gga.cs
index bdda051..1a1e441 100644
--- a/src/NmeaParser/Nmea/Gga.cs
+++ b/src/NmeaParser/Nmea/Gga.cs
@@ -23,97 +23,97 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgga")]
[NmeaMessageType("--GGA")]
public class Gga : NmeaMessage
- {
+ {
///
/// Initializes a new instance of the class.
///
/// The message type
/// The NMEA message values.
public Gga(string type, string[] message) : base(type, message)
- {
- if (message == null || message.Length < 14)
- throw new ArgumentException("Invalid GPGGA", "message");
- FixTime = StringToTimeSpan(message[0]);
- Latitude = NmeaMessage.StringToLatitude(message[1], message[2]);
- Longitude = NmeaMessage.StringToLongitude(message[3], message[4]);
- Quality = (Gga.FixQuality)int.Parse(message[5], CultureInfo.InvariantCulture);
- NumberOfSatellites = int.Parse(message[6], CultureInfo.InvariantCulture);
- Hdop = NmeaMessage.StringToDouble(message[7]);
- Altitude = NmeaMessage.StringToDouble(message[8]);
- AltitudeUnits = message[9];
- HeightOfGeoid = NmeaMessage.StringToDouble(message[10]);
- HeightOfGeoidUnits = message[11];
- var timeInSeconds = StringToDouble(message[12]);
- if (!double.IsNaN(timeInSeconds))
- TimeSinceLastDgpsUpdate = TimeSpan.FromSeconds(timeInSeconds);
- else
- TimeSinceLastDgpsUpdate = TimeSpan.MaxValue;
- if (message[13].Length > 0)
- DgpsStationId = int.Parse(message[13], CultureInfo.InvariantCulture);
- else
- DgpsStationId = -1;
- }
+ {
+ if (message == null || message.Length < 14)
+ throw new ArgumentException("Invalid GPGGA", "message");
+ FixTime = StringToTimeSpan(message[0]);
+ Latitude = NmeaMessage.StringToLatitude(message[1], message[2]);
+ Longitude = NmeaMessage.StringToLongitude(message[3], message[4]);
+ Quality = (Gga.FixQuality)int.Parse(message[5], CultureInfo.InvariantCulture);
+ NumberOfSatellites = int.Parse(message[6], CultureInfo.InvariantCulture);
+ Hdop = NmeaMessage.StringToDouble(message[7]);
+ Altitude = NmeaMessage.StringToDouble(message[8]);
+ AltitudeUnits = message[9];
+ HeightOfGeoid = NmeaMessage.StringToDouble(message[10]);
+ HeightOfGeoidUnits = message[11];
+ var timeInSeconds = StringToDouble(message[12]);
+ if (!double.IsNaN(timeInSeconds))
+ TimeSinceLastDgpsUpdate = TimeSpan.FromSeconds(timeInSeconds);
+ else
+ TimeSinceLastDgpsUpdate = TimeSpan.MaxValue;
+ if (message[13].Length > 0)
+ DgpsStationId = int.Parse(message[13], CultureInfo.InvariantCulture);
+ else
+ DgpsStationId = -1;
+ }
- ///
- /// Time of day fix was taken
- ///
- public TimeSpan FixTime { get; }
-
- ///
- /// Latitude
- ///
- public double Latitude { get; }
+ ///
+ /// Time of day fix was taken
+ ///
+ public TimeSpan FixTime { get; }
+
+ ///
+ /// Latitude
+ ///
+ public double Latitude { get; }
- ///
- /// Longitude
- ///
- public double Longitude { get; }
+ ///
+ /// Longitude
+ ///
+ public double Longitude { get; }
- ///
- /// Fix Quality
- ///
- public Gga.FixQuality Quality { get; }
+ ///
+ /// Fix Quality
+ ///
+ public Gga.FixQuality Quality { get; }
- ///
- /// Number of satellites being tracked
- ///
- public int NumberOfSatellites { get; }
+ ///
+ /// Number of satellites being tracked
+ ///
+ public int NumberOfSatellites { get; }
- ///
- /// Horizontal Dilution of Precision
- ///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hdop")]
- public double Hdop { get; }
+ ///
+ /// Horizontal Dilution of Precision
+ ///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hdop")]
+ public double Hdop { get; }
- ///
- /// Altitude
- ///
- public double Altitude { get; }
+ ///
+ /// Altitude
+ ///
+ public double Altitude { get; }
- ///
- /// Altitude units ('M' for Meters)
- ///
- public string AltitudeUnits { get; }
-
- ///
- /// Height of geoid (mean sea level) above WGS84
- ///
- public double HeightOfGeoid { get; }
+ ///
+ /// Altitude units ('M' for Meters)
+ ///
+ public string AltitudeUnits { get; }
+
+ ///
+ /// Height of geoid (mean sea level) above WGS84
+ ///
+ public double HeightOfGeoid { get; }
- ///
- /// Altitude units ('M' for Meters)
- ///
- public string HeightOfGeoidUnits { get; }
+ ///
+ /// Altitude units ('M' for Meters)
+ ///
+ public string HeightOfGeoidUnits { get; }
- ///
- /// Time since last DGPS update
- ///
- public TimeSpan TimeSinceLastDgpsUpdate { get; }
+ ///
+ /// Time since last DGPS update
+ ///
+ public TimeSpan TimeSinceLastDgpsUpdate { get; }
- ///
- /// DGPS Station ID Number
- ///
- public int DgpsStationId { get; }
+ ///
+ /// DGPS Station ID Number
+ ///
+ public int DgpsStationId { get; }
///
/// Fix quality
diff --git a/src/NmeaParser/Nmea/Gll.cs b/src/NmeaParser/Nmea/Gll.cs
index 61966a8..60086f1 100644
--- a/src/NmeaParser/Nmea/Gll.cs
+++ b/src/NmeaParser/Nmea/Gll.cs
@@ -22,7 +22,7 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gll")]
[NmeaMessageType("--GLL")]
public class Gll : NmeaMessage
- {
+ {
///
/// Initializes a new instance of the class.
///
@@ -31,14 +31,14 @@ namespace NmeaParser.Nmea
public Gll(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 4)
- throw new ArgumentException("Invalid GPGLL", "message");
- Latitude = NmeaMessage.StringToLatitude(message[0], message[1]);
- Longitude = NmeaMessage.StringToLongitude(message[2], message[3]);
- if (message.Length >= 5) //Some older GPS doesn't broadcast fix time
- {
- FixTime = StringToTimeSpan(message[4]);
- }
- DataActive = (message.Length < 6 || message[5] == "A");
+ throw new ArgumentException("Invalid GPGLL", "message");
+ Latitude = NmeaMessage.StringToLatitude(message[0], message[1]);
+ Longitude = NmeaMessage.StringToLongitude(message[2], message[3]);
+ if (message.Length >= 5) //Some older GPS doesn't broadcast fix time
+ {
+ FixTime = StringToTimeSpan(message[4]);
+ }
+ DataActive = (message.Length < 6 || message[5] == "A");
ModeIndicator = DataActive ? Mode.Autonomous : Mode.DataNotValid;
if (message.Length > 6)
{
@@ -54,28 +54,28 @@ namespace NmeaParser.Nmea
}
}
- ///
- /// Latitude
- ///
- public double Latitude { get; }
+ ///
+ /// Latitude
+ ///
+ public double Latitude { get; }
- ///
- /// Longitude
- ///
- public double Longitude { get; }
+ ///
+ /// Longitude
+ ///
+ public double Longitude { get; }
- ///
- /// Time since last DGPS update
- ///
- public TimeSpan FixTime { get; }
+ ///
+ /// Time since last DGPS update
+ ///
+ public TimeSpan FixTime { get; }
- ///
- /// Gets a value indicating whether data is active.
- ///
- ///
- /// true if data is active; otherwise, false.
- ///
- public bool DataActive { get; }
+ ///
+ /// Gets a value indicating whether data is active.
+ ///
+ ///
+ /// true if data is active; otherwise, false.
+ ///
+ public bool DataActive { get; }
///
/// Positioning system Mode Indicator
@@ -113,5 +113,5 @@ namespace NmeaParser.Nmea
///
DataNotValid
}
- }
+ }
}
diff --git a/src/NmeaParser/Nmea/Gns.cs b/src/NmeaParser/Nmea/Gns.cs
index db70972..3a5e31e 100644
--- a/src/NmeaParser/Nmea/Gns.cs
+++ b/src/NmeaParser/Nmea/Gns.cs
@@ -24,7 +24,7 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gns")]
[NmeaMessageType("--GNS")]
public class Gns : NmeaMessage
- {
+ {
/*
* Example of GNS messages:
* $GNGNS,014035.00,4332.69262,S,17235.48549,E,RR,13,0.9,25.63,11.24,,*70 //GLONASS
@@ -116,11 +116,11 @@ namespace NmeaParser.Nmea
}
///
- /// Initializes a new instance of the class.
- ///
+ /// Initializes a new instance of the class.
+ ///
/// The message type
- /// The NMEA message values.
- public Gns(string type, string[] message) : base(type, message)
+ /// The NMEA message values.
+ public Gns(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 12)
throw new ArgumentException("Invalid GNS", "message");
@@ -162,20 +162,20 @@ namespace NmeaParser.Nmea
}
}
- ///
- /// Time of day fix was taken
- ///
- public TimeSpan FixTime { get; }
-
- ///
- /// Latitude
- ///
- public double Latitude { get; }
+ ///
+ /// Time of day fix was taken
+ ///
+ public TimeSpan FixTime { get; }
+
+ ///
+ /// Latitude
+ ///
+ public double Latitude { get; }
- ///
- /// Longitude
- ///
- public double Longitude { get; }
+ ///
+ /// Longitude
+ ///
+ public double Longitude { get; }
///
/// Mode indicator for GPS
@@ -207,7 +207,7 @@ namespace NmeaParser.Nmea
/// Horizontal Dilution of Precision (HDOP), calculated using all the satellites (GPS, GLONASS, and any future satellites) used in computing the solution reported in each GNS sentence.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hdop")]
- public double Hdop { get; }
+ public double Hdop { get; }
///
/// Orthometric height in meters (MSL reference)
@@ -222,11 +222,11 @@ namespace NmeaParser.Nmea
///
/// Age of differential data - if talker ID is GN, additional GNS messages follow with GP and/or GL Age of differential data
- ///
- public TimeSpan TimeSinceLastDgpsUpdate { get; }
+ ///
+ public TimeSpan TimeSinceLastDgpsUpdate { get; }
- ///
- /// eference station ID1, range 0000-4095 - Null if talker ID is GN, additional GNS messages follow with GP and/or GL Reference station ID
+ ///
+ /// eference station ID1, range 0000-4095 - Null if talker ID is GN, additional GNS messages follow with GP and/or GL Reference station ID
///
public string? DgpsStationId { get; }
@@ -234,5 +234,5 @@ namespace NmeaParser.Nmea
/// Navigational status
///
public NavigationalStatus Status { get; }
- }
+ }
}
diff --git a/src/NmeaParser/Nmea/LaserRange/LaserRangeMessage.cs b/src/NmeaParser/Nmea/LaserRange/LaserRangeMessage.cs
index d5a8de2..c95ab1c 100644
--- a/src/NmeaParser/Nmea/LaserRange/LaserRangeMessage.cs
+++ b/src/NmeaParser/Nmea/LaserRange/LaserRangeMessage.cs
@@ -30,62 +30,62 @@ namespace NmeaParser.Nmea.LaserRange
protected LaserRangeMessage(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 9)
- throw new ArgumentException("Invalid Laser Range Message", "message");
-
- HorizontalVector = message[0];
- HorizontalDistance = double.Parse(message[1], CultureInfo.InvariantCulture);
- HorizontalDistanceUnits = message[2][0];
- HorizontalAngle = double.Parse(message[3], CultureInfo.InvariantCulture);
- HorizontalAngleUnits = message[4][0];
- VerticalAngle = double.Parse(message[5], CultureInfo.InvariantCulture);
- VerticalAngleUnits = message[6][0];
- SlopeDistance = double.Parse(message[7], CultureInfo.InvariantCulture);
- SlopeDistanceUnits = message[8][0];
- }
+ throw new ArgumentException("Invalid Laser Range Message", "message");
+
+ HorizontalVector = message[0];
+ HorizontalDistance = double.Parse(message[1], CultureInfo.InvariantCulture);
+ HorizontalDistanceUnits = message[2][0];
+ HorizontalAngle = double.Parse(message[3], CultureInfo.InvariantCulture);
+ HorizontalAngleUnits = message[4][0];
+ VerticalAngle = double.Parse(message[5], CultureInfo.InvariantCulture);
+ VerticalAngleUnits = message[6][0];
+ SlopeDistance = double.Parse(message[7], CultureInfo.InvariantCulture);
+ SlopeDistanceUnits = message[8][0];
+ }
- ///
- /// Gets the horizontal vector.
- ///
- public string HorizontalVector { get; }
+ ///
+ /// Gets the horizontal vector.
+ ///
+ public string HorizontalVector { get; }
- ///
- /// Gets the horizontal distance.
- ///
- public double HorizontalDistance { get; }
+ ///
+ /// Gets the horizontal distance.
+ ///
+ public double HorizontalDistance { get; }
- ///
- /// Gets the units of the value.
- ///
- public char HorizontalDistanceUnits { get; }
+ ///
+ /// Gets the units of the value.
+ ///
+ public char HorizontalDistanceUnits { get; }
- ///
- /// Gets the horizontal angle.
- ///
- public double HorizontalAngle { get; }
+ ///
+ /// Gets the horizontal angle.
+ ///
+ public double HorizontalAngle { get; }
- ///
- /// Gets the units of the value.
- ///
- public char HorizontalAngleUnits { get; }
+ ///
+ /// Gets the units of the value.
+ ///
+ public char HorizontalAngleUnits { get; }
- ///
- /// Gets the vertical angle.
- ///
- public double VerticalAngle { get; }
+ ///
+ /// Gets the vertical angle.
+ ///
+ public double VerticalAngle { get; }
- ///
- /// Gets the units of the value.
- ///
- public char VerticalAngleUnits { get; }
+ ///
+ /// Gets the units of the value.
+ ///
+ public char VerticalAngleUnits { get; }
- ///
- /// Gets the slope distance.
- ///
- public double SlopeDistance { get; }
+ ///
+ /// Gets the slope distance.
+ ///
+ public double SlopeDistance { get; }
- ///
- /// Gets the units of the value.
- ///
- public char SlopeDistanceUnits { get; }
- }
+ ///
+ /// Gets the units of the value.
+ ///
+ public char SlopeDistanceUnits { get; }
+ }
}
diff --git a/src/NmeaParser/Nmea/LaserRange/LaserTech/PLTIT.cs b/src/NmeaParser/Nmea/LaserRange/LaserTech/PLTIT.cs
index e479bfb..7390d86 100644
--- a/src/NmeaParser/Nmea/LaserRange/LaserTech/PLTIT.cs
+++ b/src/NmeaParser/Nmea/LaserRange/LaserTech/PLTIT.cs
@@ -18,8 +18,8 @@ namespace NmeaParser.Nmea.LaserRange.LaserTech
/// Laser Range
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pltit")]
- [NmeaMessageType("PLTIT")]
- public class Pltit : LaserRangeMessage
+ [NmeaMessageType("PLTIT")]
+ public class Pltit : LaserRangeMessage
{
///
/// Initializes a new instance of the class.
diff --git a/src/NmeaParser/Nmea/LaserRange/Trimble/PTNLA.cs b/src/NmeaParser/Nmea/LaserRange/Trimble/PTNLA.cs
index 453d8a8..17c31bb 100644
--- a/src/NmeaParser/Nmea/LaserRange/Trimble/PTNLA.cs
+++ b/src/NmeaParser/Nmea/LaserRange/Trimble/PTNLA.cs
@@ -18,8 +18,8 @@ namespace NmeaParser.Nmea.LaserRange.Trimble
/// Burden finder
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ptnla")]
- [NmeaMessageType("PTNLA")]
- public class Ptnla : LaserRangeMessage
+ [NmeaMessageType("PTNLA")]
+ public class Ptnla : LaserRangeMessage
{
///
/// Initializes a new instance of the class.
diff --git a/src/NmeaParser/Nmea/NmeaMessage.cs b/src/NmeaParser/Nmea/NmeaMessage.cs
index 076b484..a773dec 100644
--- a/src/NmeaParser/Nmea/NmeaMessage.cs
+++ b/src/NmeaParser/Nmea/NmeaMessage.cs
@@ -24,21 +24,21 @@ namespace NmeaParser.Nmea
/// Nmea message attribute type used on concrete implementations.
///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
- public sealed class NmeaMessageTypeAttribute : Attribute
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The type.
- public NmeaMessageTypeAttribute(string nmeaType)
- {
- NmeaType = nmeaType;
- }
- ///
- /// Gets or sets the NMEA message type.
- ///
- public string NmeaType { get; private set; }
- }
+ public sealed class NmeaMessageTypeAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The type.
+ public NmeaMessageTypeAttribute(string nmeaType)
+ {
+ NmeaType = nmeaType;
+ }
+ ///
+ /// Gets or sets the NMEA message type.
+ ///
+ public string NmeaType { get; private set; }
+ }
///
/// NMEA Message base class.
@@ -169,14 +169,14 @@ namespace NmeaParser.Nmea
/// A that represents this instance.
///
public override string ToString()
- {
- return string.Format(CultureInfo.InvariantCulture, "${0},{1}*{2:X2}", MessageType, string.Join(",", MessageParts), Checksum);
- }
+ {
+ return string.Format(CultureInfo.InvariantCulture, "${0},{1}*{2:X2}", MessageType, string.Join(",", MessageParts), Checksum);
+ }
- ///
- /// Gets the checksum value of the message.
- ///
- public byte Checksum => GetChecksum(MessageType, MessageParts);
+ ///
+ /// Gets the checksum value of the message.
+ ///
+ public byte Checksum => GetChecksum(MessageType, MessageParts);
internal static byte GetChecksum(string messageType, IReadOnlyList messageParts)
{
@@ -194,43 +194,43 @@ namespace NmeaParser.Nmea
return Convert.ToByte(checksumTest);
}
- internal static double StringToLatitude(string value, string ns)
- {
- if (value == null || value.Length < 3)
- return double.NaN;
- double latitude = int.Parse(value.Substring(0, 2), CultureInfo.InvariantCulture) + double.Parse(value.Substring(2), CultureInfo.InvariantCulture) / 60;
- if (ns == "S")
- latitude *= -1;
- return latitude;
- }
+ internal static double StringToLatitude(string value, string ns)
+ {
+ if (value == null || value.Length < 3)
+ return double.NaN;
+ double latitude = int.Parse(value.Substring(0, 2), CultureInfo.InvariantCulture) + double.Parse(value.Substring(2), CultureInfo.InvariantCulture) / 60;
+ if (ns == "S")
+ latitude *= -1;
+ return latitude;
+ }
- internal static double StringToLongitude(string value, string ew)
- {
- if (value == null || value.Length < 4)
- return double.NaN;
- double longitude = int.Parse(value.Substring(0, 3), CultureInfo.InvariantCulture) + double.Parse(value.Substring(3), CultureInfo.InvariantCulture) / 60;
- if (ew == "W")
- longitude *= -1;
- return longitude;
- }
+ internal static double StringToLongitude(string value, string ew)
+ {
+ if (value == null || value.Length < 4)
+ return double.NaN;
+ double longitude = int.Parse(value.Substring(0, 3), CultureInfo.InvariantCulture) + double.Parse(value.Substring(3), CultureInfo.InvariantCulture) / 60;
+ if (ew == "W")
+ longitude *= -1;
+ return longitude;
+ }
- internal static double StringToDouble(string value)
- {
- if(value != null && double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double result))
- {
- return result;
- }
- return double.NaN;
- }
- internal static TimeSpan StringToTimeSpan(string value)
- {
- if (value != null && value.Length >= 6)
- {
- return new TimeSpan(int.Parse(value.Substring(0, 2), CultureInfo.InvariantCulture),
- int.Parse(value.Substring(2, 2), CultureInfo.InvariantCulture), 0)
- .Add(TimeSpan.FromSeconds(double.Parse(value.Substring(4), CultureInfo.InvariantCulture)));
- }
- return TimeSpan.Zero;
- }
- }
+ internal static double StringToDouble(string value)
+ {
+ if(value != null && double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double result))
+ {
+ return result;
+ }
+ return double.NaN;
+ }
+ internal static TimeSpan StringToTimeSpan(string value)
+ {
+ if (value != null && value.Length >= 6)
+ {
+ return new TimeSpan(int.Parse(value.Substring(0, 2), CultureInfo.InvariantCulture),
+ int.Parse(value.Substring(2, 2), CultureInfo.InvariantCulture), 0)
+ .Add(TimeSpan.FromSeconds(double.Parse(value.Substring(4), CultureInfo.InvariantCulture)));
+ }
+ return TimeSpan.Zero;
+ }
+ }
}
diff --git a/src/NmeaParser/Nmea/Rmc.cs b/src/NmeaParser/Nmea/Rmc.cs
index 89af646..1cfdd1e 100644
--- a/src/NmeaParser/Nmea/Rmc.cs
+++ b/src/NmeaParser/Nmea/Rmc.cs
@@ -23,7 +23,7 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprmc")]
[NmeaMessageType("--RMC")]
public class Rmc : NmeaMessage
- {
+ {
///
/// Initializes a new instance of the class.
///
@@ -32,60 +32,60 @@ namespace NmeaParser.Nmea
public Rmc(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 11)
- throw new ArgumentException("Invalid GPRMC", "message");
-
- if (message[8].Length == 6 && message[0].Length >= 6)
- {
- FixTime = new DateTime(int.Parse(message[8].Substring(4, 2), CultureInfo.InvariantCulture) + 2000,
- int.Parse(message[8].Substring(2, 2), CultureInfo.InvariantCulture),
- int.Parse(message[8].Substring(0, 2), CultureInfo.InvariantCulture),
- int.Parse(message[0].Substring(0, 2), CultureInfo.InvariantCulture),
- int.Parse(message[0].Substring(2, 2), CultureInfo.InvariantCulture),
- 0, DateTimeKind.Utc).AddSeconds(double.Parse(message[0].Substring(4), CultureInfo.InvariantCulture));
- }
- Active = (message[1] == "A");
- Latitude = NmeaMessage.StringToLatitude(message[2], message[3]);
- Longitude = NmeaMessage.StringToLongitude(message[4], message[5]);
- Speed = NmeaMessage.StringToDouble(message[6]);
- Course = NmeaMessage.StringToDouble(message[7]);
- MagneticVariation = NmeaMessage.StringToDouble(message[9]);
- if (!double.IsNaN(MagneticVariation) && message[10] == "W")
- MagneticVariation *= -1;
- }
+ throw new ArgumentException("Invalid GPRMC", "message");
+
+ if (message[8].Length == 6 && message[0].Length >= 6)
+ {
+ FixTime = new DateTime(int.Parse(message[8].Substring(4, 2), CultureInfo.InvariantCulture) + 2000,
+ int.Parse(message[8].Substring(2, 2), CultureInfo.InvariantCulture),
+ int.Parse(message[8].Substring(0, 2), CultureInfo.InvariantCulture),
+ int.Parse(message[0].Substring(0, 2), CultureInfo.InvariantCulture),
+ int.Parse(message[0].Substring(2, 2), CultureInfo.InvariantCulture),
+ 0, DateTimeKind.Utc).AddSeconds(double.Parse(message[0].Substring(4), CultureInfo.InvariantCulture));
+ }
+ Active = (message[1] == "A");
+ Latitude = NmeaMessage.StringToLatitude(message[2], message[3]);
+ Longitude = NmeaMessage.StringToLongitude(message[4], message[5]);
+ Speed = NmeaMessage.StringToDouble(message[6]);
+ Course = NmeaMessage.StringToDouble(message[7]);
+ MagneticVariation = NmeaMessage.StringToDouble(message[9]);
+ if (!double.IsNaN(MagneticVariation) && message[10] == "W")
+ MagneticVariation *= -1;
+ }
- ///
- /// Fix Time
- ///
- public DateTime FixTime { get; }
+ ///
+ /// Fix Time
+ ///
+ public DateTime FixTime { get; }
- ///
- /// Gets a value whether the device is active
- ///
- public bool Active { get; }
+ ///
+ /// Gets a value whether the device is active
+ ///
+ public bool Active { get; }
- ///
- /// Latitude
- ///
- public double Latitude { get; }
+ ///
+ /// Latitude
+ ///
+ public double Latitude { get; }
- ///
- /// Longitude
- ///
- public double Longitude { get; }
+ ///
+ /// Longitude
+ ///
+ public double Longitude { get; }
- ///
- /// Speed over the ground in knots
- ///
- public double Speed { get; }
+ ///
+ /// Speed over the ground in knots
+ ///
+ public double Speed { get; }
- ///
- /// Track angle in degrees True
- ///
- public double Course { get; }
+ ///
+ /// Track angle in degrees True
+ ///
+ public double Course { get; }
- ///
- /// Magnetic Variation
- ///
- public double MagneticVariation { get; }
- }
+ ///
+ /// Magnetic Variation
+ ///
+ public double MagneticVariation { get; }
+ }
}
diff --git a/src/NmeaParser/Nmea/UnknownMessage.cs b/src/NmeaParser/Nmea/UnknownMessage.cs
index cba4f01..f5a0d86 100644
--- a/src/NmeaParser/Nmea/UnknownMessage.cs
+++ b/src/NmeaParser/Nmea/UnknownMessage.cs
@@ -20,12 +20,12 @@ namespace NmeaParser.Nmea
/// Represents an unknown message type
///
public class UnknownMessage : NmeaMessage
- {
+ {
internal UnknownMessage(string type, string[] messageParts) : base(type, messageParts) { }
- ///
- /// Gets the nmea value array.
- ///
- public IReadOnlyList Values { get { return base.MessageParts; } }
- }
+ ///
+ /// Gets the nmea value array.
+ ///
+ public IReadOnlyList Values { get { return base.MessageParts; } }
+ }
}
diff --git a/src/NmeaParser/Nmea/Vtg.cs b/src/NmeaParser/Nmea/Vtg.cs
index 5ffd659..3c84dbf 100644
--- a/src/NmeaParser/Nmea/Vtg.cs
+++ b/src/NmeaParser/Nmea/Vtg.cs
@@ -17,12 +17,12 @@ using System;
namespace NmeaParser.Nmea
{
///
- /// Course over ground and ground speed
- ///
+ /// Course over ground and ground speed
+ ///
///
/// The actual course and speed relative to the ground.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "GPVTG")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "GPVTG")]
[NmeaMessageType("--VTG")]
public class Vtg : NmeaMessage
{
diff --git a/src/NmeaParser/NmeaDevice.cs b/src/NmeaParser/NmeaDevice.cs
index b0b1ed4..8f20a95 100644
--- a/src/NmeaParser/NmeaDevice.cs
+++ b/src/NmeaParser/NmeaDevice.cs
@@ -22,41 +22,41 @@ using System.Threading;
namespace NmeaParser
{
- ///
- /// A generic abstract NMEA device
- ///
- public abstract class NmeaDevice : IDisposable
- {
- private readonly object m_lockObject = new object();
- private string m_message = "";
- private Stream? m_stream;
- private CancellationTokenSource? m_cts;
- private bool m_isOpening;
+ ///
+ /// A generic abstract NMEA device
+ ///
+ public abstract class NmeaDevice : IDisposable
+ {
+ private readonly object m_lockObject = new object();
+ private string m_message = "";
+ private Stream? m_stream;
+ private CancellationTokenSource? m_cts;
+ private bool m_isOpening;
private Task? m_ParserTask;
///
/// Initializes a new instance of the class.
///
protected NmeaDevice()
- {
- }
+ {
+ }
///
- /// Opens the device connection.
- ///
- ///
- public async Task OpenAsync()
- {
- lock (m_lockObject)
- {
- if (IsOpen || m_isOpening) return;
+ /// Opens the device connection.
+ ///
+ ///
+ public async Task OpenAsync()
+ {
+ lock (m_lockObject)
+ {
+ if (IsOpen || m_isOpening) return;
m_isOpening = true;
- }
- m_cts = new CancellationTokenSource();
- m_stream = await OpenStreamAsync();
- StartParser(m_cts.Token);
- _lastMultiMessage = null;
- lock (m_lockObject)
+ }
+ m_cts = new CancellationTokenSource();
+ m_stream = await OpenStreamAsync();
+ StartParser(m_cts.Token);
+ _lastMultiMessage = null;
+ lock (m_lockObject)
{
IsOpen = true;
m_isOpening = false;
@@ -64,30 +64,30 @@ namespace NmeaParser
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "_")]
- private void StartParser(CancellationToken token)
- {
- System.Diagnostics.Debug.WriteLine("Starting parser...");
+ private void StartParser(CancellationToken token)
+ {
+ System.Diagnostics.Debug.WriteLine("Starting parser...");
m_ParserTask = Task.Run(async () =>
- {
- byte[] buffer = new byte[1024];
- while (!token.IsCancellationRequested)
- {
- int readCount = 0;
- try
- {
- readCount = await ReadAsync(buffer, 0, 1024, token).ConfigureAwait(false);
- }
- catch { }
- if (token.IsCancellationRequested)
- break;
- if (readCount > 0)
- {
- OnData(buffer.Take(readCount).ToArray());
- }
- await Task.Delay(50);
- }
- });
- }
+ {
+ byte[] buffer = new byte[1024];
+ while (!token.IsCancellationRequested)
+ {
+ int readCount = 0;
+ try
+ {
+ readCount = await ReadAsync(buffer, 0, 1024, token).ConfigureAwait(false);
+ }
+ catch { }
+ if (token.IsCancellationRequested)
+ break;
+ if (readCount > 0)
+ {
+ OnData(buffer.Take(readCount).ToArray());
+ }
+ await Task.Delay(50);
+ }
+ });
+ }
///
/// Performs a read operation of the stream
@@ -116,84 +116,84 @@ namespace NmeaParser
///
protected abstract Task OpenStreamAsync();
- ///
- /// Closes the device.
- ///
- ///
- public async Task CloseAsync()
- {
- if (m_cts != null)
- {
- if (m_cts != null)
- m_cts.Cancel();
- m_cts = null;
- }
+ ///
+ /// Closes the device.
+ ///
+ ///
+ public async Task CloseAsync()
+ {
+ if (m_cts != null)
+ {
+ if (m_cts != null)
+ m_cts.Cancel();
+ m_cts = null;
+ }
if (m_ParserTask != null)
await m_ParserTask;
if (m_stream != null)
await CloseStreamAsync(m_stream);
- _lastMultiMessage = null;
- m_stream = null;
+ _lastMultiMessage = null;
+ m_stream = null;
lock (m_lockObject)
{
m_isOpening = false;
IsOpen = false;
}
- }
- ///
- /// Closes the stream the NmeaDevice is working on top off.
- ///
- /// The stream.
- ///
- protected abstract Task CloseStreamAsync(Stream stream);
+ }
+ ///
+ /// Closes the stream the NmeaDevice is working on top off.
+ ///
+ /// The stream.
+ ///
+ protected abstract Task CloseStreamAsync(Stream stream);
- private void OnData(byte[] data)
- {
- var nmea = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
- List lines = new List();
- lock (m_lockObject)
- {
- m_message += nmea;
+ private void OnData(byte[] data)
+ {
+ var nmea = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
+ List lines = new List();
+ lock (m_lockObject)
+ {
+ m_message += nmea;
- var lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal);
- while (lineEnd > -1)
- {
- string line = m_message.Substring(0, lineEnd).Trim();
- m_message = m_message.Substring(lineEnd + 1);
- if (!string.IsNullOrEmpty(line))
- lines.Add(line);
- lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal);
- }
- }
- foreach(var line in lines)
- ProcessMessage(line);
- }
+ var lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal);
+ while (lineEnd > -1)
+ {
+ string line = m_message.Substring(0, lineEnd).Trim();
+ m_message = m_message.Substring(lineEnd + 1);
+ if (!string.IsNullOrEmpty(line))
+ lines.Add(line);
+ lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal);
+ }
+ }
+ foreach(var line in lines)
+ ProcessMessage(line);
+ }
- private IMultiSentenceMessage? _lastMultiMessage;
+ private IMultiSentenceMessage? _lastMultiMessage;
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="Must silently handle invalid/corrupt input")]
- private void ProcessMessage(string p)
- {
- try
- {
- var msg = NmeaParser.Nmea.NmeaMessage.Parse(p, _lastMultiMessage);
- if(msg is IMultiSentenceMessage multi)
- {
- if (!multi.IsComplete)
- {
- _lastMultiMessage = multi; //Keep it around until next time
- return;
- }
- }
- _lastMultiMessage = null;
- if (msg != null)
- OnMessageReceived(msg);
- }
- catch { }
- }
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="Must silently handle invalid/corrupt input")]
+ private void ProcessMessage(string p)
+ {
+ try
+ {
+ var msg = NmeaParser.Nmea.NmeaMessage.Parse(p, _lastMultiMessage);
+ if(msg is IMultiSentenceMessage multi)
+ {
+ if (!multi.IsComplete)
+ {
+ _lastMultiMessage = multi; //Keep it around until next time
+ return;
+ }
+ }
+ _lastMultiMessage = null;
+ if (msg != null)
+ OnMessageReceived(msg);
+ }
+ catch { }
+ }
- private void OnMessageReceived(Nmea.NmeaMessage msg)
+ private void OnMessageReceived(Nmea.NmeaMessage msg)
{
if (msg == null)
return;
@@ -201,49 +201,49 @@ namespace NmeaParser
MessageReceived?.Invoke(this, new NmeaMessageReceivedEventArgs(msg));
}
- //private readonly Dictionary> MultiPartMessageCache = new Dictionary>();
+ //private readonly Dictionary> MultiPartMessageCache = new Dictionary>();
- ///
- /// Occurs when an NMEA message is received.
- ///
- public event EventHandler? MessageReceived;
+ ///
+ /// Occurs when an NMEA message is received.
+ ///
+ public event EventHandler? MessageReceived;
- ///
- /// Releases unmanaged and - optionally - managed resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
- ///
- /// Releases unmanaged and - optionally - managed resources.
- ///
- /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
- protected virtual void Dispose(bool disposing)
- {
- if (m_stream != null)
- {
- if (m_cts != null)
- {
- m_cts.Cancel();
- m_cts = null;
- }
- CloseStreamAsync(m_stream);
- if (disposing && m_stream != null)
- m_stream.Dispose();
- m_stream = null;
- }
- }
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (m_stream != null)
+ {
+ if (m_cts != null)
+ {
+ m_cts.Cancel();
+ m_cts = null;
+ }
+ CloseStreamAsync(m_stream);
+ if (disposing && m_stream != null)
+ m_stream.Dispose();
+ m_stream = null;
+ }
+ }
- ///
- /// Gets a value indicating whether this device is open.
- ///
- ///
- /// true if this instance is open; otherwise, false.
- ///
- public bool IsOpen { get; private set; }
+ ///
+ /// Gets a value indicating whether this device is open.
+ ///
+ ///
+ /// true if this instance is open; otherwise, false.
+ ///
+ public bool IsOpen { get; private set; }
///
/// Gets a value indicating whether this device supports writing
@@ -255,34 +255,34 @@ namespace NmeaParser
/// Writes to the device stream. Useful for transmitting RTCM corrections to the device
/// Check the property before calling this method.
///
- /// The byte array that contains the data to write to the port.
- /// The zero-based byte offset in the buffer parameter at which to begin copying
- /// bytes to the port.
- /// The number of bytes to write.
+ /// The byte array that contains the data to write to the port.
+ /// The zero-based byte offset in the buffer parameter at which to begin copying
+ /// bytes to the port.
+ /// The number of bytes to write.
/// Task
///
public virtual Task WriteAsync(byte[] buffer, int offset, int length)
{
throw new NotSupportedException();
}
- }
+ }
- ///
- /// Event argument for the
- ///
- public sealed class NmeaMessageReceivedEventArgs : EventArgs
- {
- internal NmeaMessageReceivedEventArgs(Nmea.NmeaMessage message)
+ ///
+ /// Event argument for the
+ ///
+ public sealed class NmeaMessageReceivedEventArgs : EventArgs
+ {
+ internal NmeaMessageReceivedEventArgs(Nmea.NmeaMessage message)
{
- Message = message;
- }
+ Message = message;
+ }
- ///
- /// Gets the nmea message.
- ///
- ///
- /// The nmea message.
- ///
- public Nmea.NmeaMessage Message { get; }
- }
+ ///
+ /// Gets the nmea message.
+ ///
+ ///
+ /// The nmea message.
+ ///
+ public Nmea.NmeaMessage Message { get; }
+ }
}
diff --git a/src/NmeaParser/NmeaFileDevice.cs b/src/NmeaParser/NmeaFileDevice.cs
index e7f7d13..48bdc88 100644
--- a/src/NmeaParser/NmeaFileDevice.cs
+++ b/src/NmeaParser/NmeaFileDevice.cs
@@ -21,13 +21,13 @@ using System.Threading.Tasks;
namespace NmeaParser
{
- ///
- /// A file-based NMEA device reading from a NMEA log file.
- ///
- public class NmeaFileDevice : BufferedStreamDevice
- {
+ ///
+ /// A file-based NMEA device reading from a NMEA log file.
+ ///
+ public class NmeaFileDevice : BufferedStreamDevice
+ {
#if NETFX_CORE
- private Windows.Storage.IStorageFile? m_storageFile;
+ private Windows.Storage.IStorageFile? m_storageFile;
#endif
private string m_filename;
@@ -36,7 +36,7 @@ namespace NmeaParser
/// Initializes a new instance of the class.
///
///
- public NmeaFileDevice(string fileName) : this(fileName, 1000)
+ public NmeaFileDevice(string fileName) : this(fileName, 1000)
{
}
@@ -46,18 +46,18 @@ namespace NmeaParser
///
///
public NmeaFileDevice(Windows.Storage.IStorageFile storageFile) : this(storageFile, 1000)
- {
- }
+ {
+ }
#endif
///
/// Initializes a new instance of the class.
///
///
/// The time to wait between each group of lines being read in milliseconds
- public NmeaFileDevice(string fileName, int readSpeed) : base(readSpeed)
- {
- m_filename = fileName;
- }
+ public NmeaFileDevice(string fileName, int readSpeed) : base(readSpeed)
+ {
+ m_filename = fileName;
+ }
#if NETFX_CORE
///
@@ -73,24 +73,24 @@ namespace NmeaParser
}
#endif
- ///
- /// Gets the name of the nmea file this device is using.
- ///
- public string FileName
- {
- get
+ ///
+ /// Gets the name of the nmea file this device is using.
+ ///
+ public string FileName
+ {
+ get
{
return m_filename;
}
- }
+ }
///
/// Gets the stream to perform buffer reads on.
///
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
protected override Task GetStreamAsync()
- {
+ {
#if NETFX_CORE
if (m_storageFile != null)
@@ -102,5 +102,5 @@ namespace NmeaParser
return Task.FromResult(System.IO.File.OpenRead(m_filename));
#endif
}
- }
+ }
}
diff --git a/src/NmeaParser/Properties/NmeaParser.rd.xml b/src/NmeaParser/Properties/NmeaParser.rd.xml
index 9c46111..0b133a3 100644
--- a/src/NmeaParser/Properties/NmeaParser.rd.xml
+++ b/src/NmeaParser/Properties/NmeaParser.rd.xml
@@ -27,7 +27,7 @@
-
+
diff --git a/src/NmeaParser/SerialPortDevice.Desktop.cs b/src/NmeaParser/SerialPortDevice.Desktop.cs
index 7c84311..bad59e3 100644
--- a/src/NmeaParser/SerialPortDevice.Desktop.cs
+++ b/src/NmeaParser/SerialPortDevice.Desktop.cs
@@ -22,22 +22,22 @@ using System.Threading.Tasks;
namespace NmeaParser
{
- ///
- /// A Serial Port NMEA device
- ///
- public class SerialPortDevice : NmeaDevice
- {
+ ///
+ /// A Serial Port NMEA device
+ ///
+ public class SerialPortDevice : NmeaDevice
+ {
///
/// Initializes a new instance of the class.
///
/// The serial port.
/// port
public SerialPortDevice(System.IO.Ports.SerialPort port)
- {
- if (port == null)
- throw new ArgumentNullException("port");
- Port = port;
- }
+ {
+ if (port == null)
+ throw new ArgumentNullException("port");
+ Port = port;
+ }
///
/// Gets the active serial port.
@@ -49,35 +49,35 @@ namespace NmeaParser
///
///
protected override Task OpenStreamAsync()
- {
+ {
if (!Port.IsOpen)
Port.Open();
- return Task.FromResult(Port.BaseStream);
- }
+ return Task.FromResult(Port.BaseStream);
+ }
- ///
- /// Closes the stream the NmeaDevice is working on top off.
- ///
- /// The stream.
- ///
- protected override Task CloseStreamAsync(System.IO.Stream stream)
- {
+ ///
+ /// Closes the stream the NmeaDevice is working on top off.
+ ///
+ /// The stream.
+ ///
+ protected override Task CloseStreamAsync(System.IO.Stream stream)
+ {
if (Port.IsOpen)
Port.Close();
- return Task.FromResult