Commit d35e56c5 authored by Dag Brattli's avatar Dag Brattli

Code refactor and cleanup

parent 5cfd3d4f
......@@ -7,6 +7,10 @@ open System.Runtime.InteropServices //for OutAttribute
open FParsec
open NAisParser.Ais
type MessageType =
| Type123 of MessageType123
| Type4 of MessageType4
| Type5 of MessageType5
type public Parser() =
let fragments = new List<ParserResult<AisResult, unit>>()
......@@ -70,12 +74,8 @@ type public Parser() =
match res with
| Success (message, _, _) ->
match message with
| Type123 cnb ->
result <- cnb
true
| _ ->
false
result <- message
true
| Failure (error, _, _) ->
raise (System.ArgumentException(error))
......@@ -88,8 +88,7 @@ type public Parser() =
/// A MessageType5 that will be set if the method returns true.
/// </param>
/// <returns>
/// True if parsing of the packet completed. False if this is not
/// a message of type 4.
/// True if parsing of the packet completed.
/// </returns>
/// <exception cref="System.ArgumentException">Thrown if the data
/// payload is invalid and parsing of the packet failed.
......@@ -101,12 +100,8 @@ type public Parser() =
match res with
| Success (message, _, _) ->
match message with
| Type4 cnb ->
result <- cnb
true
| _ ->
false
result <- message
true
| Failure (error, _, _) ->
raise (System.ArgumentException(error))
......@@ -119,8 +114,7 @@ type public Parser() =
/// A MessageType5 that will be set if the method returns true.
/// </param>
/// <returns>
/// True if parsing of the packet completed. False if this is not
/// a message of type 5.
/// True if parsing of the packet completed.
/// </returns>
/// <exception cref="System.ArgumentException">Thrown if the data
/// payload is invalid and parsing of the packet failed.
......@@ -132,11 +126,7 @@ type public Parser() =
match res with
| Success (message, _, _) ->
match message with
| Type5 cnb ->
result <- cnb
true
| _ ->
false
result <- message
true
| Failure (error, _, _) ->
raise (System.ArgumentException(error))
......@@ -72,76 +72,6 @@ type ManeuverIndicator =
| NoSpecialManeuver = 0
| SpecialManeuver = 1
// Common Navigation Block
type MessageType123 = {
Type: byte;
Repeat: byte;
Mmsi: int;
Status: NavigationStatus;
RateOfTurn: float;
SpeedOverGround: int;
PositionAccuracy: bool;
Longitude: float;
Latitude: float;
CourseOverGround: float;
TrueHeading: int;
TimeStamp: int;
ManeuverIndicator: ManeuverIndicator;
RaimFlag: bool;
RadioStatus: int
}
// Base Station Report
type MessageType4 = {
Repeat: byte;
Mmsi: int;
Year: int;
Month: int;
Day: int;
Hour: int;
Minute: int;
Second: int;
FixQuality: bool;
Longitude: float;
Latitude: float;
Epfd: EpfdFixType;
RaimFlag: bool;
RadioStatus: int
}
// Static And Voyage Related Data
type MessageType5 = {
Repeat: byte;
Mmsi: int;
Version: byte;
ImoNumber: int;
CallSign: string;
VesselName: string;
ShipType: ShipType;
ToBow: int;
ToStern: int;
ToPort: int;
ToStarBoard: int;
Epfd: EpfdFixType;
Month: int;
Day: int;
Hour: int;
Minute: int;
Draught: float;
Destination: string;
Dte: bool;
}
type BaseStationReport = {
Repeat: byte;
Mmsi: int;
}
type MessageType =
| Type123 of MessageType123
| Type4 of MessageType4
| Type5 of MessageType5
module Common =
// Allowed characters in payload
let allowedChars = List.map char [48..119]
......@@ -179,9 +109,9 @@ module Common =
<|> pstring type3
|>> fun x -> Convert.ToByte(x, 2)
let parseRepeat = Core.parseUint2
let parseRepeat = Core.parseByteN 2
let parseMmsi = Core.parseUint30
let parseMmsi = Core.parseIntN 30
let parseLongitude =
Core.parseBits 28
......@@ -196,18 +126,11 @@ module Common =
|>> fun x -> float(x) / 600000.0
let parseEpfd =
Core.parseBits 4
|>> (fun x ->
let value = Convert.ToInt32(x, 2)
enum<EpfdFixType>(value)
)
Core.parseIntN 4
|>> fun x -> enum<EpfdFixType>(x)
let parseSpare =
Core.parseBits 3
let parseSpare = Core.parseBits 3
let parseRaimFlag =
Core.parseBool
let parseRaimFlag = Core.parseBool
let parseRadioStatus =
Core.parseBits 19
|>> fun x -> Convert.ToInt32(x, 2)
\ No newline at end of file
let parseRadioStatus = Core.parseIntN 19
......@@ -17,14 +17,14 @@ module Core =
parseBits 1
|>> fun x -> Convert.ToByte(x, 2) = 1uy
let parseUint2 =
parseBits 2
|>> fun x -> Convert.ToByte(x, 2)
let parseUint30 =
parseBits 30
let parseIntN bits =
parseBits bits
|>> fun x -> Convert.ToInt32(x, 2)
let parseByteN bits =
parseBits bits
|>> fun x -> Convert.ToByte(x, 2)
let parseSByte =
parseBits 8
|>> fun x -> Convert.ToSByte(x, 2)
......
......@@ -5,8 +5,27 @@ open FParsec
open NAisParser.Core
// Common Navigation Block
type MessageType123 = {
Type: byte;
Repeat: byte;
Mmsi: int;
Status: NavigationStatus;
RateOfTurn: float;
SpeedOverGround: int;
PositionAccuracy: bool;
Longitude: float;
Latitude: float;
CourseOverGround: float;
TrueHeading: int;
TimeStamp: int;
ManeuverIndicator: ManeuverIndicator;
RaimFlag: bool;
RadioStatus: int
}
module Type123 =
let messageType123 type' repeat mmsi status turn speed accuracy lon
lat course heading second maneuver raim radio: MessageType123=
{
......@@ -50,38 +69,25 @@ module Type123 =
Core.parseSByte
|>> fun x -> squareSigned((float x) / 4.733)
let parseSpeedOverGround =
Core.parseBits 10
|>> fun x -> Convert.ToInt32(x, 2)
let parseSpeedOverGround = Core.parseIntN 10
let parsePositionAccuracy =
Core.parseBool
let parsePositionAccuracy = Core.parseBool
let parseCourseOverGround =
Core.parseBits 12
|>> fun x -> Convert.ToInt32(x, 2)
Core.parseIntN 12
|>> fun x -> float(x) / 10.0
let parseStatus =
Core.parseBits 4
|>> (fun x ->
let value = Convert.ToInt32(x, 2)
enum<NavigationStatus>(value)
)
Core.parseIntN 4
|>> fun x -> enum<NavigationStatus>(x)
let parseTrueHeading =
Core.parseBits 9
|>> fun x -> Convert.ToInt32(x, 2)
let parseTrueHeading = Core.parseIntN 9
let parseTimeStamp =
Core.parseBits 6
|>> fun x -> Convert.ToInt32(x, 2)
let parseTimeStamp = Core.parseIntN 6
let parseManeuverIndicator =
Core.parseBits 2
|>> fun x ->
let value = Convert.ToInt32(x, 2)
enum<ManeuverIndicator>(value)
Core.parseIntN 2
|>> fun x -> enum<ManeuverIndicator>(x)
let parseType123 : Parser<_> =
// A little repetitive, but better to do it here at declaration time
......@@ -104,5 +110,4 @@ module Type123 =
<*> parseManeuverIndicator
<* Common.parseSpare
<*> Common.parseRaimFlag
<*> Common.parseRadioStatus
|>> Type123
\ No newline at end of file
<*> Common.parseRadioStatus
\ No newline at end of file
namespace NAisParser
open System
open FParsec
open NAisParser.Core
// Base Station Report
type MessageType4 = {
Repeat: byte;
Mmsi: int;
Year: int;
Month: int;
Day: int;
Hour: int;
Minute: int;
Second: int;
FixQuality: bool;
Longitude: float;
Latitude: float;
Epfd: EpfdFixType;
RaimFlag: bool;
RadioStatus: int
}
module Type4 =
let messageType4 repeat mmsi year month day hour minute second
accuracy lat lon epfd raim radio
......@@ -42,31 +59,23 @@ module Type4 =
RadioStatus = 0
}
let parseYear =
Core.parseBits 14
|>> fun x -> Convert.ToInt32(x, 2)
let parseYear = Core.parseIntN 14
let parseMonth =
Core.parseBits 4
|>> fun x -> Convert.ToInt32(x, 2)
let parseMonth = Core.parseIntN 4
let parseDay =
Core.parseBits 5
|>> fun x -> Convert.ToInt32(x, 2)
let parseDay = Core.parseIntN 5
let parseHour = parseDay
let parseHour = Core.parseIntN 5
let parseMinute =
Core.parseBits 6
|>> fun x -> Convert.ToInt32(x, 2)
let parseMinute = Core.parseIntN 6
let parseSecond = parseMinute
let parseSecond = Core.parseIntN 6
let parseFixQuality = Core.parseBool
let parseType4 = Common.parseType <| Common.toPaddedBinary 4
let parseMessageType4: Parser<MessageType> =
let parseMessageType4: Parser<_> =
preturn messageType4
*> parseType4
<*> Common.parseRepeat
......@@ -83,6 +92,4 @@ module Type4 =
<*> Common.parseEpfd
<* Common.parseSpare
<*> Common.parseRaimFlag
<*> Common.parseRadioStatus
|>> Type4
<*> Common.parseRadioStatus
\ No newline at end of file
namespace NAisParser
open System
open FParsec
open NAisParser.Core
// Static And Voyage Related Data
type MessageType5 = {
Repeat: byte;
Mmsi: int;
Version: byte;
ImoNumber: int;
CallSign: string;
VesselName: string;
ShipType: ShipType;
ToBow: int;
ToStern: int;
ToPort: int;
ToStarBoard: int;
Epfd: EpfdFixType;
Month: int;
Day: int;
Hour: int;
Minute: int;
Draught: float;
Destination: string;
Dte: bool;
}
module Type5 =
let messageType5 repeat mmsi version imo
callsign shipname shiptype tobow tostern toport tostarboard epfd
......@@ -53,53 +75,37 @@ module Type5 =
Dte = false;
}
let parseVersion =
Core.parseBits 2
|>> fun x -> Convert.ToByte(x, 2)
let parseVersion = Core.parseByteN 2
let parseImoNumber =
Core.parseBits 30
|>> fun x -> Convert.ToInt32(x, 2)
let parseImoNumber = Core.parseIntN 30
let parseShipType =
Core.parseBits 8
|>> fun x ->
let value = Convert.ToInt32(x, 2)
enum<ShipType>(value)
Core.parseIntN 8
|>> fun x -> enum<ShipType>(x)
let parseCallSign = Core.parseAscii 42
let parseVesselName = Core.parseAscii 120
let parseToBow =
Core.parseBits 9
|>> fun x -> Convert.ToInt32(x, 2)
let parseToBow = Core.parseIntN 9
let parseToStern = parseToBow
let parseToPort =
Core.parseBits 6
|>> fun x -> Convert.ToInt32(x, 2)
let parseToPort = Core.parseIntN 6
let parseToStarboard = parseToPort
let parseMonth =
Core.parseBits 4
|>> fun x -> Convert.ToInt32(x, 2)
let parseMonth = Core.parseIntN 4
let parseDay =
Core.parseBits 5
|>> fun x -> Convert.ToInt32(x, 2)
let parseDay = Core.parseIntN 5
let parseHour = parseDay
let parseHour = Core.parseIntN 5
let parseMinute =
Core.parseBits 6
|>> fun x -> Convert.ToInt32(x, 2)
let parseMinute = Core.parseIntN 6
let parseDraught =
Core.parseBits 8
|>> fun x -> (Convert.ToInt32(x, 2) |> float) / 10.0
Core.parseIntN 8
|>> fun x -> float x / 10.0
let parseDestination = Core.parseAscii 120
......@@ -107,7 +113,7 @@ module Type5 =
let parseType5 = Common.parseType <| Common.toPaddedBinary 5
let parseMessageType5: Parser<MessageType> =
let parseMessageType5: Parser<_> =
preturn messageType5
*> parseType5
<*> Common.parseRepeat
......@@ -129,5 +135,3 @@ module Type5 =
<*> parseDraught
<*> parseDestination
<*> parseDte
|>> Type5
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment