Skip to content

6.2.0

Latest

Choose a tag to compare

@Rickedb Rickedb released this 09 Aug 03:43
· 1 commit to master since this release

Every MID in the library was rewritten to describe its data fields through attributes on the properties themselves, instead of building a Dictionary<int, List<DataField>> by hand and lazily converting values on every property access. Parsing now walks the package as a ReadOnlySpan<char> and writes the converted value straight into the property, and packing reads it back from there.

These change are possibly fixing #92 and #129

Breaking changes

Property type changes

MID Property Before After
Mid0008 SubscriptionMid string int
Mid0009 UnsubscriptionMid string int
Mid0105, Mid0106, Mid0107 DataNumberSystem int long
Mid1201 ResultDataIdentifier int long
Mid1201 ResultStatus bool int

MID 0008/0009 now expose the subscribed/unsubscribed MID as an int, matching the documentation (and matching Mid0006.RequestedMid, which was already an int).

Removed / changed members

  • Mid0702.ToolNumber was removed — MID 0702 is answered from a MID 0006 request whose extra data carries the tool number, so it now lives in Mid0702ExtraData. Mid0702.NumberOfToolParameters (read-only) became the settable NumberOfToolPIDs.
  • DataField.String/Boolean/Timestamp/... factory methods now return DataField<T> instead of DataField. Source compatible when the result is assigned to a DataField, binary breaking.
  • VariableDataField.ParseAll and OpenProtocolConvert.ToString(...) for variable data fields now work with List<VariableDataField> instead of IEnumerable<VariableDataField>.

Custom MIDs inheriting from Mid

The parse/pack pipeline is span based, so MIDs that override it need their signatures adjusted:

  • ProcessDataFields(string)ProcessDataFields(ReadOnlySpan<char>) (plus the new per-field hook ProcessDataField(DataField, ReadOnlySpan<char>), which is usually what you want to override now)
  • Pack(int revision, ref int prefixIndex)Pack(int revision)
  • Pack(List<DataField>, ref int prefixIndex)Pack(IEnumerable<DataField>)
  • GetValue(DataField, string)GetValue(DataField, ReadOnlySpan<char>)

RegisterDatafields() is still virtual and still works exactly as before, so a custom MID written against the old style keeps working as long as it doesn't override the methods above.

Packaging

  • The netstandard2.0 target now depends on System.Memory (4.5.5) for Span<T>.

Improvements

  • Changed way of parsing Mid properties, previously it would "lazy parse/convert" values at get/set, with this new way, the datafield is directly attached to the property and it is updated at the time the parsing happens. Reflection over the attributes happens once per MID type and is cached in a static dictionary; field registration itself became lazy, so a MID that is only constructed to be packed doesn't pay for it upfront.
  • Added packing tests not only parsing which could make not testing setting properties — the suite went from 573 to 860 test methods (1202 test cases, all green), and several packing bugs surfaced because of it (see below).
  • Revamped logos, updated badges and linking in the README.
  • Parsing is span based end to end (Header, Mid, DataField, OpenProtocolConvert), slicing the package instead of allocating substrings. netstandard2.0 keeps the old string path behind #if.
  • Header.Parse(string) / Header.Parse(ReadOnlySpan<char>) are now public, so you can read the MID number, revision and length without going through MidInterpreter (#118).
  • Added OpenProtocolConvert overloads for DateTimeOffset/unix timestamps and span inputs.
  • README largely rewritten accordingly with the newest update

New Features

  • Added support to set a DefaultEncoding property at Mid and an overload at byte[] methods (#117)
  • Added support to setting Mid0006, Mid0008 and Mid0009 Extra data based on pre build extra data, also, enabled to create your own with IExtraDataRequest, IExtraDataSubscription and IExtraDataUnsubscription interfaces. (#104)
  • Mid.GetField(string propertyName) and GetField<T>(int revision, int field) for the cases where a field's size only becomes known after another field has been read.

Bug fixes

  • Fixed MID 0140 packing (the collection size wasn't being enforced before packing).
  • Fixed parsing an enum-backed property through Int32DataFieldDefinition — the underlying value wasn't being converted to the enum type.
  • Fixed the unix epoch calculation on netstandard2.0, which has no DateTimeOffset.UnixEpoch.
  • Fixed data field counting/indexing on several MIDs where the field index was wrong or missing: Mid0001, Mid0002, Mid0004, Mid0005, Mid0006, Mid0008, Mid0009, Mid0061, Mid0200, Mid0214, Mid0215, Mid0251, Mid0254, Mid0255, Mid0265, Mid0401, Mid0411.

Mids updates

  • New Mid2502 (password request)
  • New Mid2503 (password response).
  • MIDs updated to specification 2.18.0:
    • Mid0001/Mid0002 (OptionalKeepAlive, OptionalToolLockAtDisconnection, OptionalEarlyLock, StationCellId)
    • Mid0045 (ExtendedCalibrationValue, TransducerNumber)
    • Mid0065
    • New ToolType values (XPBM, ExBC, ExD).
  • Mid0015
  • Mid0035
  • Mid0061
  • Mid0065 (JointId, SelectedIdentifierNumber, NumberOfStagesInMultistage, NumberOfStageResults).
  • PIDRestriction type added for Mid0704.

Funding

Added .github/FUNDING.yml with GitHub Sponsors and Buy Me a Coffee (rickedb on both), so the repository shows the "Sponsor" button. This project has been maintained on free time for years — if it saves you or your company some of it, that button is now there. It changes nothing about the license or the roadmap: the library stays MIT and issues/PRs are handled the same way.

Related issues