From 88e84001cfe1ad1d060578dea8fa86f23bb5d18a Mon Sep 17 00:00:00 2001 From: "SmallChi(Koike)" <564952747@qq.com> Date: Thu, 21 Oct 2021 10:09:38 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9BCD=E7=9A=84=E5=86=99?= =?UTF-8?q?=E5=85=A5=E5=92=8C=E8=AF=BB=E5=8F=96=E6=96=B9=E5=BC=8F=202.?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E6=9C=9F=E6=9C=89=E9=92=88=E5=AF=B9?= =?UTF-8?q?=E6=80=A7=E7=9A=84=E5=86=99=E5=85=A5=E5=92=8C=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MessagePack/JT808MessagePackWriterTest.cs | 41 ++ src/JT808.Protocol/JT808.Protocol.xml | 134 +++++++ .../MessagePack/JT808MessagePackReader.cs | 286 +++++++++++--- .../MessagePack/JT808MessagePackWriter.cs | 360 +++++++++++++++--- 4 files changed, 728 insertions(+), 93 deletions(-) diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs index aeea4f5..a55047c 100644 --- a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs +++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs @@ -509,5 +509,46 @@ namespace JT808.Protocol.Test.MessagePack var hex = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); Assert.Equal("736D616C6C636869286B6F696B652900", hex); } + + [Fact] + public void IntToBcdTest() + { + var bytes1 = new byte[5]; + Span buffer1 = new Span(bytes1); + IntToBcd(123456700, buffer1, buffer1.Length); + Assert.NotEqual(new byte[] { 0x12, 0x34, 0x56, 0x70,0x00 }, buffer1.ToArray()); + Assert.Equal(new byte[] { 0x01, 0x23, 0x45, 0x67,0x00 }, buffer1.ToArray()); + + var bytes = new byte[6]; + Span buffer = new Span(bytes); + IntToBcd(123456700, buffer, buffer.Length); + Assert.Equal(new byte[] { 0x00, 0x01, 0x23, 0x45, 0x67, 0x00 }, buffer.ToArray()); + } + + [Fact] + public void WriteBcdTest() + { + byte[] array = new byte[100]; + var msgpackWriter = new JT808MessagePackWriter(array); + int val1 = 1234567890; + long val2 = 123456789011; + msgpackWriter.WriteBCD(val1, 5); + msgpackWriter.WriteBCD(val2, 10); + var result = msgpackWriter.FlushAndGetRealArray(); + Assert.Equal(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11 }, result); + } + + private void IntToBcd(int num, Span list, int count) + { + int level = count - 1; + var high = num / 100; + var low = num % 100; + if (high > 0) + { + IntToBcd(high, list, --count); + } + byte res = (byte)(((low / 10) << 4) + (low % 10)); + list[level] = res; + } } } diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 68b4885..7077e5f 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -18256,48 +18256,95 @@ >D2: 10 X2:16 + + + 读取六字节日期,yyMMddHHmmss + + + + + 16进制的BCD BYTE转成整型 + + 16进制的BCD BYTE转成整型 + + 读取可空类型的六字节日期,yyMMddHHmmss >D2: 10 X2:16 + + + 读取可空类型的六字节日期,yyMMddHHmmss + + 读取五字节日期,HH-mm-ss-msms|HH-mm-ss-fff D2: 10 X2:16 + + + 读取五字节日期,HH-mm-ss-msms|HH-mm-ss-fff + + 读取可空类型的五字节日期,HH-mm-ss-msms|HH-mm-ss-fff D2: 10 X2:16 + + + 读取可空类型的五字节日期,HH-mm-ss-msms|HH-mm-ss-fff + + 读取四字节日期,YYYYMMDD D2: 10 X2:16 + + + 读取四字节日期,YYYYMMDD + + 读取可空类型的四字节日期,YYYYMMDD D2: 10 X2:16 + + + 读取可空类型的四字节日期,YYYYMMDD + + 读取三字节日期,YYMMDD D2: 10 X2:16 + + + 读取三字节日期,YYMMDD + + 读取可空类型的三字节日期,YYMMDD D2: 10 X2:16 + + + 读取可空类型的三字节日期,YYMMDD + + 读取UTC时间类型 @@ -18567,6 +18614,45 @@ + + + 整型数据转为BCD BYTE + 为了兼容int类型,不使用byte做参数 + 支持0xFF一个字节的转换 + + + + + + + 整型数据转为BCD BYTE[] + + 整数值 + bytes + 字节数>=整数值 + + + + 整型数据转为BCD BYTE[] + + 整数值 + bytes + 字节数>=整数值 + + + + 写入BCD编码数据 + + 整数值 + 字节数>=整数值 + + + + 写入BCD编码数据 + + 整数值 + 字节数>=整数值 + 写入六个字节的日期类型,yyMMddHHmmss @@ -18574,6 +18660,12 @@ + + + 写入六个字节的日期类型,yyMMddHHmmss + + + 写入六个字节的可空日期类型,yyMMddHHmmss @@ -18581,6 +18673,12 @@ + + + 写入六个字节的可空日期类型,yyMMddHHmmss + + + 写入五个字节的日期类型,HH-mm-ss-msms或HH-mm-ss-fff @@ -18588,6 +18686,12 @@ + + + 写入五个字节的日期类型,HH-mm-ss-msms或HH-mm-ss-fff + + + 写入五个字节的可空日期类型,HH-mm-ss-msms或HH-mm-ss-fff @@ -18595,6 +18699,12 @@ + + + 写入五个字节的可空日期类型,HH-mm-ss-msms或HH-mm-ss-fff + + + 写入UTC日期类型 @@ -18608,6 +18718,12 @@ + + + 写入四个字节的日期类型,YYYYMMDD BCD[4] 数据形如:20200101 + + + 写入四个字节的可空日期类型,YYYYMMDD BCD[4]数据形如:20200101 @@ -18615,6 +18731,12 @@ + + + 写入四个字节的可空日期类型,YYYYMMDD BCD[4]数据形如:20200101 + + + 写入三个字节的日期类型,YYMMDD 数据形如:20200101 @@ -18622,6 +18744,12 @@ + + + 写入三个字节的日期类型,YYMMDD 数据形如:20200101 + + + 写入三个字节的可空日期类型,YYMMDD 数据形如:20200101 @@ -18629,6 +18757,12 @@ + + + 写入三个字节的可空日期类型,YYMMDD 数据形如:20200101 + + + 将指定内存块进行或运算并写入一个字节 diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs index 4aec354..06a8301 100644 --- a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs @@ -371,18 +371,19 @@ namespace JT808.Protocol.MessagePack /// 读取六字节日期,yyMMddHHmmss /// /// >D2: 10 X2:16 + [Obsolete("use ReadDateTime_yyMMddHHmmss")] public DateTime ReadDateTime6(string format = "X2") { DateTime d; try { var readOnlySpan = GetReadOnlySpan(6); - int year = Convert.ToInt32(readOnlySpan[0].ToString(format)) + JT808Constants.DateLimitYear; - int month = Convert.ToInt32(readOnlySpan[1].ToString(format)); - int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); - int hour = Convert.ToInt32(readOnlySpan[3].ToString(format)); - int minute = Convert.ToInt32(readOnlySpan[4].ToString(format)); - int second = Convert.ToInt32(readOnlySpan[5].ToString(format)); + int year = BcdToInt(readOnlySpan[0]) + JT808Constants.DateLimitYear; + int month = BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); + int hour = BcdToInt(readOnlySpan[3]); + int minute = BcdToInt(readOnlySpan[4]); + int second = BcdToInt(readOnlySpan[5]); d = new DateTime(year, month, day, hour, minute, second); } catch (Exception) @@ -392,21 +393,81 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// 读取六字节日期,yyMMddHHmmss + /// + public DateTime ReadDateTime_yyMMddHHmmss() + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(6); + int year = BcdToInt(readOnlySpan[0]) + JT808Constants.DateLimitYear; + int month = BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); + int hour = BcdToInt(readOnlySpan[3]); + int minute = BcdToInt(readOnlySpan[4]); + int second = BcdToInt(readOnlySpan[5]); + d = new DateTime(year, month, day, hour, minute, second); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// + /// 16进制的BCD BYTE转成整型 + /// + /// 16进制的BCD BYTE转成整型 + /// + public int BcdToInt(byte value) + { + int high = value >> 4; + int low = value & 0xF; + int number = 10 * high + low; + return number; + } + /// /// 读取可空类型的六字节日期,yyMMddHHmmss /// /// >D2: 10 X2:16 + [Obsolete("use ReadDateTimeNull_yyMMddHHmmss")] public DateTime? ReadDateTimeNull6(string format = "X2") { DateTime? d; try { var readOnlySpan = GetReadOnlySpan(6); - int year = Convert.ToInt32(readOnlySpan[0].ToString(format)) ; - int month = Convert.ToInt32(readOnlySpan[1].ToString(format)); - int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); - int hour = Convert.ToInt32(readOnlySpan[3].ToString(format)); - int minute = Convert.ToInt32(readOnlySpan[4].ToString(format)); - int second = Convert.ToInt32(readOnlySpan[5].ToString(format)); + int year = BcdToInt(readOnlySpan[0]); + int month = BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); + int hour = BcdToInt(readOnlySpan[3]); + int minute = BcdToInt(readOnlySpan[4]); + int second = BcdToInt(readOnlySpan[5]); + if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) return null; + d = new DateTime(year + JT808Constants.DateLimitYear, month, day, hour, minute, second); + } + catch (Exception) + { + return null; + } + return d; + } + /// + /// 读取可空类型的六字节日期,yyMMddHHmmss + /// + public DateTime? ReadDateTimeNull_yyMMddHHmmss() + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(6); + int year = BcdToInt(readOnlySpan[0]); + int month = BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); + int hour = BcdToInt(readOnlySpan[3]); + int minute = BcdToInt(readOnlySpan[4]); + int second = BcdToInt(readOnlySpan[5]); if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) return null; d = new DateTime(year + JT808Constants.DateLimitYear, month, day, hour, minute, second); } @@ -420,23 +481,45 @@ namespace JT808.Protocol.MessagePack /// 读取五字节日期,HH-mm-ss-msms|HH-mm-ss-fff /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTime_HHmmssfff")] public DateTime ReadDateTime5(string format = "X2") { DateTime d; try { var readOnlySpan = GetReadOnlySpan(5); - StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[3].ToString(format)); - sb.Append(readOnlySpan[4].ToString(format)); + var fff = BcdToInt(readOnlySpan[3]) * 100 + BcdToInt(readOnlySpan[4]); + d = new DateTime( + DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + BcdToInt(readOnlySpan[0]), + BcdToInt(readOnlySpan[1]), + BcdToInt(readOnlySpan[2]), fff); + } + catch + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// + /// 读取五字节日期,HH-mm-ss-msms|HH-mm-ss-fff + /// + public DateTime ReadDateTime_HHmmssfff() + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(5); + var fff = BcdToInt(readOnlySpan[3]) * 100 + BcdToInt(readOnlySpan[4]); d = new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, - Convert.ToInt32(readOnlySpan[0].ToString(format)), - Convert.ToInt32(readOnlySpan[1].ToString(format)), - Convert.ToInt32(readOnlySpan[2].ToString(format)), - Convert.ToInt32(sb.ToString().TrimStart())); + BcdToInt(readOnlySpan[0]), + BcdToInt(readOnlySpan[1]), + BcdToInt(readOnlySpan[2]), fff); } catch { @@ -448,20 +531,47 @@ namespace JT808.Protocol.MessagePack /// 读取可空类型的五字节日期,HH-mm-ss-msms|HH-mm-ss-fff /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTimeNull_HHmmssfff")] public DateTime? ReadDateTimeNull5(string format = "X2") { DateTime? d; try { var readOnlySpan = GetReadOnlySpan(5); - StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[3].ToString("X2")); - sb.Append(readOnlySpan[4].ToString("X2")); - int hour = Convert.ToInt32(readOnlySpan[0].ToString(format)); - int minute = Convert.ToInt32(readOnlySpan[1].ToString(format)); - int second = Convert.ToInt32(readOnlySpan[2].ToString(format)); - int millisecond = Convert.ToInt32(sb.ToString().TrimStart()); - if (hour == 0 && minute == 0 && second == 0 && millisecond == 0) return null; + int hour = BcdToInt(readOnlySpan[0]); + int minute = BcdToInt(readOnlySpan[1]); + int second = BcdToInt(readOnlySpan[2]); + var fff = BcdToInt(readOnlySpan[3]) * 100 + BcdToInt(readOnlySpan[4]); + if (hour == 0 && minute == 0 && second == 0 && fff == 0) return null; + d = new DateTime( + DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + hour, + minute, + second, + fff); + } + catch + { + return null; + } + return d; + } + /// + /// 读取可空类型的五字节日期,HH-mm-ss-msms|HH-mm-ss-fff + /// + public DateTime? ReadDateTimeNull_HHmmssfff() + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(5); + int hour = BcdToInt(readOnlySpan[0]); + int minute = BcdToInt(readOnlySpan[1]); + int second = BcdToInt(readOnlySpan[2]); + var fff = BcdToInt(readOnlySpan[3]) * 100 + BcdToInt(readOnlySpan[4]); + if (hour == 0 && minute == 0 && second == 0 && fff == 0) return null; d = new DateTime( DateTime.Now.Year, DateTime.Now.Month, @@ -469,7 +579,7 @@ namespace JT808.Protocol.MessagePack hour, minute, second, - millisecond); + fff); } catch { @@ -481,19 +591,18 @@ namespace JT808.Protocol.MessagePack /// 读取四字节日期,YYYYMMDD /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTime_YYYYMMDD")] public DateTime ReadDateTime4(string format = "X2") { DateTime d; try { var readOnlySpan = GetReadOnlySpan(4); - StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[0].ToString(format)); - sb.Append(readOnlySpan[1].ToString(format)); + var year = BcdToInt(readOnlySpan[0]) * 100 + BcdToInt(readOnlySpan[1]); d = new DateTime( - Convert.ToInt32(sb.ToString()), - Convert.ToInt32(readOnlySpan[2].ToString(format)), - Convert.ToInt32(readOnlySpan[3].ToString(format))); + year, + BcdToInt(readOnlySpan[2]), + BcdToInt(readOnlySpan[3])); } catch (Exception) { @@ -502,21 +611,61 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// 读取四字节日期,YYYYMMDD + /// + public DateTime ReadDateTime_YYYYMMDD() + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(4); + var year = BcdToInt(readOnlySpan[0]) * 100 + BcdToInt(readOnlySpan[1]); + d = new DateTime( + year, + BcdToInt(readOnlySpan[2]), + BcdToInt(readOnlySpan[3])); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// /// 读取可空类型的四字节日期,YYYYMMDD /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTimeNull_YYYYMMDD")] public DateTime? ReadDateTimeNull4(string format = "X2") { DateTime? d; try { var readOnlySpan = GetReadOnlySpan(4); - StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[0].ToString(format)); - sb.Append(readOnlySpan[1].ToString(format)); - int year = Convert.ToInt32(sb.ToString()); - int month = Convert.ToInt32(readOnlySpan[2].ToString(format)); - int day = Convert.ToInt32(readOnlySpan[3].ToString(format)); + var year = BcdToInt(readOnlySpan[0]) * 100 + BcdToInt(readOnlySpan[1]); + int month = BcdToInt(readOnlySpan[2]); + int day = BcdToInt(readOnlySpan[3]); + if (year == 0 && month == 0 && day == 0) return null; + d = new DateTime(year, month, day); + } + catch (Exception) + { + return null; + } + return d; + } + /// + /// 读取可空类型的四字节日期,YYYYMMDD + /// + public DateTime? ReadDateTimeNull_YYYYMMDD() + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(4); + var year = BcdToInt(readOnlySpan[0]) * 100 + BcdToInt(readOnlySpan[1]); + int month = BcdToInt(readOnlySpan[2]); + int day = BcdToInt(readOnlySpan[3]); if (year == 0 && month == 0 && day == 0) return null; d = new DateTime(year, month, day); } @@ -530,6 +679,7 @@ namespace JT808.Protocol.MessagePack /// 读取三字节日期,YYMMDD /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTime_YYMMDD")] public DateTime ReadDateTime3(string format = "X2") { DateTime d; @@ -537,9 +687,29 @@ namespace JT808.Protocol.MessagePack { var readOnlySpan = GetReadOnlySpan(3); d = new DateTime( - Convert.ToInt32(readOnlySpan[0].ToString(format)) + JT808Constants.DateLimitYear, - Convert.ToInt32(readOnlySpan[1].ToString(format)), - Convert.ToInt32(readOnlySpan[2].ToString(format))); + BcdToInt(readOnlySpan[0]) + JT808Constants.DateLimitYear, + BcdToInt(readOnlySpan[1]), + BcdToInt(readOnlySpan[2])); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// + /// 读取三字节日期,YYMMDD + /// + public DateTime ReadDateTime_YYMMDD() + { + DateTime d; + try + { + var readOnlySpan = GetReadOnlySpan(3); + d = new DateTime( + BcdToInt(readOnlySpan[0]) + JT808Constants.DateLimitYear, + BcdToInt(readOnlySpan[1]), + BcdToInt(readOnlySpan[2])); } catch (Exception) { @@ -551,15 +721,16 @@ namespace JT808.Protocol.MessagePack /// 读取可空类型的三字节日期,YYMMDD /// /// D2: 10 X2:16 + [Obsolete("use ReadDateTimeNull_YYMMDD")] public DateTime? ReadDateTimeNull3(string format = "X2") { DateTime? d; try { var readOnlySpan = GetReadOnlySpan(3); - int year =Convert.ToInt32(readOnlySpan[0].ToString(format)); - int month=Convert.ToInt32(readOnlySpan[1].ToString(format)); - int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); + int year = BcdToInt(readOnlySpan[0]); + int month= BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); if (year == 0 && month == 0 && day == 0) return null; d = new DateTime( year + JT808Constants.DateLimitYear, month,day @@ -572,6 +743,29 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// 读取可空类型的三字节日期,YYMMDD + /// + public DateTime? ReadDateTimeNull_YYMMDD() + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(3); + int year = BcdToInt(readOnlySpan[0]); + int month = BcdToInt(readOnlySpan[1]); + int day = BcdToInt(readOnlySpan[2]); + if (year == 0 && month == 0 && day == 0) return null; + d = new DateTime( + year + JT808Constants.DateLimitYear, month, day + ); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } + /// /// 读取UTC时间类型 /// /// diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs index c66eef8..32a230b 100644 --- a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs @@ -3,6 +3,7 @@ using JT808.Protocol.Enums; using System; using System.Buffers; using System.Buffers.Binary; +using System.Collections.Generic; using System.Text; namespace JT808.Protocol.MessagePack @@ -309,27 +310,133 @@ namespace JT808.Protocol.MessagePack { src.CopyTo(writer.Written.Slice(position)); } + + /// + /// 整型数据转为BCD BYTE + /// 为了兼容int类型,不使用byte做参数 + /// 支持0xFF一个字节的转换 + /// + /// + /// + public byte IntToBcd(int value) + { + byte result = 0; + if (value <= 0xFF) + { + //19 00010011 + //0001 1001 + int high = value / 10; + int low = value % 10; + result = (byte)(high << 4 | low); + } + return result; + } + + /// + /// 整型数据转为BCD BYTE[] + /// + /// 整数值 + /// bytes + /// 字节数>=整数值 + public void IntToBcd(int value, Span list, int count) + { + int level = count - 1; + var high = value / 100; + var low = value % 100; + if (high > 0) + { + IntToBcd(high, list, --count); + } + byte res = (byte)(((low / 10) << 4) + (low % 10)); + list[level] = res; + } + + /// + /// 整型数据转为BCD BYTE[] + /// + /// 整数值 + /// bytes + /// 字节数>=整数值 + public void IntToBcd(long value, Span list, int byteCount) + { + int level = byteCount - 1; + if (level < 0) return; + var high = value / 100; + var low = value % 100; + if (high > 0) + { + IntToBcd(high, list, --byteCount); + } + byte res = (byte)(((low / 10) << 4) + (low % 10)); + list[level] = res; + } + + /// + /// 写入BCD编码数据 + /// + /// 整数值 + /// 字节数>=整数值 + public void WriteBCD(in long value, in int byteCount) + { + var span = writer.Free; + IntToBcd(value, writer.Free, byteCount); + writer.Advance(byteCount); + } + + /// + /// 写入BCD编码数据 + /// + /// 整数值 + /// 字节数>=整数值 + public void WriteBCD(in int value, in int count) + { + var span = writer.Free; + IntToBcd(value, writer.Free, count); + writer.Advance(count); + } + /// /// 写入六个字节的日期类型,yyMMddHHmmss /// /// /// + [Obsolete("use WriteDateTime_yyMMddHHmmss")] public void WriteDateTime6(in DateTime value, in int fromBase = 16) { var span = writer.Free; - span[0] = Convert.ToByte(value.ToString("yy"), fromBase); - span[1] = Convert.ToByte(value.ToString("MM"), fromBase); - span[2] = Convert.ToByte(value.ToString("dd"), fromBase); - span[3] = Convert.ToByte(value.ToString("HH"), fromBase); - span[4] = Convert.ToByte(value.ToString("mm"), fromBase); - span[5] = Convert.ToByte(value.ToString("ss"), fromBase); + int yy = value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Month); + span[2] = IntToBcd(value.Day); + span[3] = IntToBcd(value.Hour); + span[4] = IntToBcd(value.Minute); + span[5] = IntToBcd(value.Second); writer.Advance(6); } + + /// + /// 写入六个字节的日期类型,yyMMddHHmmss + /// + /// + public void WriteDateTime_yyMMddHHmmss(in DateTime value) + { + var span = writer.Free; + int yy = value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Month); + span[2] = IntToBcd(value.Day); + span[3] = IntToBcd(value.Hour); + span[4] = IntToBcd(value.Minute); + span[5] = IntToBcd(value.Second); + writer.Advance(6); + } + /// /// 写入六个字节的可空日期类型,yyMMddHHmmss /// /// /// + [Obsolete("use WriteDateTime_yyMMddHHmmss")] public void WriteDateTime6(in DateTime? value, in int fromBase = 16) { var span = writer.Free; @@ -344,58 +451,136 @@ namespace JT808.Protocol.MessagePack } else { - span[0] = Convert.ToByte(value.Value.ToString("yy"), fromBase); - span[1] = Convert.ToByte(value.Value.ToString("MM"), fromBase); - span[2] = Convert.ToByte(value.Value.ToString("dd"), fromBase); - span[3] = Convert.ToByte(value.Value.ToString("HH"), fromBase); - span[4] = Convert.ToByte(value.Value.ToString("mm"), fromBase); - span[5] = Convert.ToByte(value.Value.ToString("ss"), fromBase); + int yy = value.Value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Value.Month); + span[2] = IntToBcd(value.Value.Day); + span[3] = IntToBcd(value.Value.Hour); + span[4] = IntToBcd(value.Value.Minute); + span[5] = IntToBcd(value.Value.Second); + } + writer.Advance(6); + } + + /// + /// 写入六个字节的可空日期类型,yyMMddHHmmss + /// + /// + public void WriteDateTime_yyMMddHHmmss(in DateTime? value) + { + var span = writer.Free; + if (value == null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + span[4] = 0; + span[5] = 0; + } + else + { + int yy = value.Value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Value.Month); + span[2] = IntToBcd(value.Value.Day); + span[3] = IntToBcd(value.Value.Hour); + span[4] = IntToBcd(value.Value.Minute); + span[5] = IntToBcd(value.Value.Second); } writer.Advance(6); } + /// /// 写入五个字节的日期类型,HH-mm-ss-msms或HH-mm-ss-fff /// /// /// + [Obsolete("use WriteDateTime_HHmmssfff")] public void WriteDateTime5(in DateTime value, in int fromBase = 16) { var span = writer.Free; - span[0] = Convert.ToByte(value.ToString("HH"), fromBase); - span[1] = Convert.ToByte(value.ToString("mm"), fromBase); - span[2] = Convert.ToByte(value.ToString("ss"), fromBase); - var msSpan = value.Millisecond.ToString().PadLeft(4,'0').AsSpan(); - span[3] = Convert.ToByte(msSpan.Slice(0, 2).ToString(), fromBase); - span[4] = Convert.ToByte(msSpan.Slice(2, 2).ToString(), fromBase); - writer.Advance(5); + span[0] = IntToBcd(value.Hour); + span[1] = IntToBcd(value.Minute); + span[2] = IntToBcd(value.Second); + writer.Advance(3); + IntToBcd(value.Millisecond, writer.Free, 2); + writer.Advance(2); + } + + /// + /// 写入五个字节的日期类型,HH-mm-ss-msms或HH-mm-ss-fff + /// + /// + public void WriteDateTime_HHmmssfff(in DateTime value) + { + var span = writer.Free; + span[0] = IntToBcd(value.Hour); + span[1] = IntToBcd(value.Minute); + span[2] = IntToBcd(value.Second); + writer.Advance(3); + IntToBcd(value.Millisecond, writer.Free, 2); + writer.Advance(2); } + /// /// 写入五个字节的可空日期类型,HH-mm-ss-msms或HH-mm-ss-fff /// /// /// + [Obsolete("use WriteDateTime_HHmmssfff")] public void WriteDateTime5(in DateTime? value, in int fromBase = 16) { - var span = writer.Free; if (value == null || value.HasValue) { + var span = writer.Free; span[0] = 0; span[1] = 0; span[2] = 0; span[3] = 0; span[4] = 0; + writer.Advance(5); } else { - span[0] = Convert.ToByte(value.Value.ToString("HH"), fromBase); - span[1] = Convert.ToByte(value.Value.ToString("mm"), fromBase); - span[2] = Convert.ToByte(value.Value.ToString("ss"), fromBase); - var msSpan = value.Value.Millisecond.ToString().PadLeft(4, '0').AsSpan(); - span[3] = Convert.ToByte(msSpan.Slice(0, 2).ToString(), fromBase); - span[4] = Convert.ToByte(msSpan.Slice(2, 2).ToString(), fromBase); + var span = writer.Free; + span[0] = IntToBcd(value.Value.Hour); + span[1] = IntToBcd(value.Value.Minute); + span[2] = IntToBcd(value.Value.Second); + writer.Advance(3); + IntToBcd(value.Value.Millisecond, writer.Free, 2); + writer.Advance(2); } - writer.Advance(5); } + + /// + /// 写入五个字节的可空日期类型,HH-mm-ss-msms或HH-mm-ss-fff + /// + /// + public void WriteDateTime_HHmmssfff(in DateTime? value) + { + if (value == null || value.HasValue) + { + var span = writer.Free; + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + span[4] = 0; + writer.Advance(5); + } + else + { + var span = writer.Free; + span[0] = IntToBcd(value.Value.Hour); + span[1] = IntToBcd(value.Value.Minute); + span[2] = IntToBcd(value.Value.Second); + writer.Advance(3); + IntToBcd(value.Value.Millisecond, writer.Free, 2); + writer.Advance(2); + } + } + /// /// 写入UTC日期类型 /// @@ -412,20 +597,35 @@ namespace JT808.Protocol.MessagePack } writer.Advance(8); } + /// /// 写入四个字节的日期类型,YYYYMMDD BCD[4] 数据形如:20200101 /// /// /// + [Obsolete("use WriteDateTime_YYYYMMDD")] public void WriteDateTime4(in DateTime value, in int fromBase = 16) { + IntToBcd(value.Year, writer.Free, 2); + writer.Advance(2); var span = writer.Free; - var yearSpan=value.ToString("yyyy").AsSpan(); - span[0] = Convert.ToByte(yearSpan.Slice(0, 2).ToString(), fromBase); - span[1] = Convert.ToByte(yearSpan.Slice(2, 2).ToString(), fromBase); - span[2] = Convert.ToByte(value.ToString("MM"), fromBase); - span[3] = Convert.ToByte(value.ToString("dd"), fromBase); - writer.Advance(4); + span[0] = IntToBcd(value.Month); + span[1] = IntToBcd(value.Day); + writer.Advance(2); + } + + /// + /// 写入四个字节的日期类型,YYYYMMDD BCD[4] 数据形如:20200101 + /// + /// + public void WriteDateTime_YYYYMMDD(in DateTime value) + { + IntToBcd(value.Year, writer.Free, 2); + writer.Advance(2); + var span = writer.Free; + span[0] = IntToBcd(value.Month); + span[1] = IntToBcd(value.Day); + writer.Advance(2); } /// @@ -433,25 +633,53 @@ namespace JT808.Protocol.MessagePack /// /// /// + [Obsolete("use WriteDateTime_YYYYMMDD")] public void WriteDateTime4(in DateTime? value, in int fromBase = 16) { - var span = writer.Free; if (value==null || value.HasValue) { + var span = writer.Free; span[0] = 0; span[1] = 0; span[2] = 0; span[3] = 0; + writer.Advance(4); } else { - var yearSpan = value.Value.ToString("yyyy").AsSpan(); - span[0] = Convert.ToByte(yearSpan.Slice(0, 2).ToString(), fromBase); - span[1] = Convert.ToByte(yearSpan.Slice(2, 2).ToString(), fromBase); - span[2] = Convert.ToByte(value.Value.ToString("MM"), fromBase); - span[3] = Convert.ToByte(value.Value.ToString("dd"), fromBase); + IntToBcd(value.Value.Year, writer.Free, 2); + writer.Advance(2); + var span = writer.Free; + span[0] = IntToBcd(value.Value.Month); + span[1] = IntToBcd(value.Value.Day); + writer.Advance(2); + } + } + + /// + /// 写入四个字节的可空日期类型,YYYYMMDD BCD[4]数据形如:20200101 + /// + /// + public void WriteDateTime_YYYYMMDD(in DateTime? value) + { + if (value == null || value.HasValue) + { + var span = writer.Free; + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + writer.Advance(4); + } + else + { + IntToBcd(value.Value.Year, writer.Free, 2); + writer.Advance(2); + var span = writer.Free; + span[0] = IntToBcd(value.Value.Month); + span[1] = IntToBcd(value.Value.Day); + writer.Advance(2); } - writer.Advance(4); } /// @@ -459,20 +687,35 @@ namespace JT808.Protocol.MessagePack /// /// /// + [Obsolete("use WriteDateTime_YYMMDD")] public void WriteDateTime3(in DateTime value, in int fromBase = 16) { var span = writer.Free; - span[0] = Convert.ToByte(value.ToString("yy"), fromBase); - span[1] = Convert.ToByte(value.ToString("MM"), fromBase); - span[2] = Convert.ToByte(value.ToString("dd"), fromBase); + int yy = value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Month); + span[2] = IntToBcd(value.Day); + writer.Advance(3); + } + /// + /// 写入三个字节的日期类型,YYMMDD 数据形如:20200101 + /// + /// + public void WriteDateTime_YYMMDD(in DateTime value) + { + var span = writer.Free; + int yy = value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Month); + span[2] = IntToBcd(value.Day); writer.Advance(3); } - /// /// 写入三个字节的可空日期类型,YYMMDD 数据形如:20200101 /// /// /// + [Obsolete("use WriteDateTime_YYMMDD")] public void WriteDateTime3(in DateTime? value, in int fromBase = 16) { var span = writer.Free; @@ -484,9 +727,32 @@ namespace JT808.Protocol.MessagePack } else { - span[0] = Convert.ToByte(value.Value.ToString("yy"), fromBase); - span[1] = Convert.ToByte(value.Value.ToString("MM"), fromBase); - span[2] = Convert.ToByte(value.Value.ToString("dd"), fromBase); + int yy = value.Value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Value.Month); + span[2] = IntToBcd(value.Value.Day); + } + writer.Advance(3); + } + /// + /// 写入三个字节的可空日期类型,YYMMDD 数据形如:20200101 + /// + /// + public void WriteDateTime_YYMMDD(in DateTime? value) + { + var span = writer.Free; + if (value == null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + } + else + { + int yy = value.Value.Year - JT808Constants.DateLimitYear; + span[0] = IntToBcd(yy); + span[1] = IntToBcd(value.Value.Month); + span[2] = IntToBcd(value.Value.Day); } writer.Advance(3); }