//============================================================== // Copyright (C) 2019 Inc. All rights reserved. // //============================================================== // Create by 种道洋 at 2019/12/27 18:45:02. // Version 1.0 // 种道洋 //============================================================== using DBRuntime.His; using DBRuntime.His.Compress; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cdy.Tag { /// /// /// public class LosslessCompressUnit2 : CompressUnitbase2 { protected MemoryBlock mMarshalMemory; protected ProtoMemory mVarintMemory; protected DoubleCompressBuffer mDCompress; protected FloatCompressBuffer mFCompress; /// /// /// protected CustomQueue emptys = new CustomQueue(604); /// /// /// public override string Desc => "无损压缩"; /// /// /// public override int TypeCode => 1; /// /// /// /// public override CompressUnitbase2 Clone() { return new LosslessCompressUnit2(); } #region Compress /// /// /// /// /// /// /// /// /// public override long Compress(IMemoryBlock source, long sourceAddr, MarshalMemoryBlock target, long targetAddr, long size) { target.WriteDatetime(targetAddr, this.StartTime); target.Write(TimeTick); switch (TagType) { case TagType.Bool: return Compress(source, sourceAddr, target, targetAddr+12, size,TagType) + 12; case TagType.Byte: return Compress(source, sourceAddr, target, targetAddr+ 12, size, TagType) + 12; case TagType.UShort: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.Short: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.UInt: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.Int: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.ULong: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.Long: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.Double: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.Float: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.String: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.IntPoint: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.UIntPoint: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.LongPoint: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.ULongPoint: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.IntPoint3: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.UIntPoint3: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.LongPoint3: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; case TagType.ULongPoint3: return Compress(source, sourceAddr, target, targetAddr + 12, size, TagType) + 12; } return 12; } ///// ///// ///// ///// ///// ///// //protected Memory CompressTimers(List timerVals, CustomQueue emptyIds) //{ // int preids = 0; // mVarintMemory.Reset(); // emptys.Reset(); // //emptys.WriteIndex = 0; // //emptyIds.ReadIndex = 0; // bool isFirst = true; // for (int i = 0; i < timerVals.Count; i++) // { // if (timerVals[i] > 0||i==0) // { // var id = timerVals[i]; // if (isFirst) // { // mVarintMemory.WriteInt32(id); // isFirst = false; // } // else // { // mVarintMemory.WriteInt32(id - preids); // } // preids = id; // } // else // { // emptyIds.Insert(i); // } // } // return mVarintMemory.DataBuffer.AsMemory(0, (int)mVarintMemory.WritePosition); //} /// /// /// /// /// /// /// /// protected virtual Memory CompressTimers(IMemoryBlock timerVals,long startaddr,int count, CustomQueue emptyIds) { int preids = 0; mVarintMemory.Reset(); emptys.Reset(); byte tlen = (timerVals as HisDataMemoryBlock).TimeLen; bool isFirst = true; int id = 0; for (int i = 0; i < count; i++) { id = tlen == 2 ? timerVals.ReadUShort((int)startaddr + i * 2) : timerVals.ReadInt((int)startaddr + i * 4); if (id > 0 || i == 0) { if (isFirst) { mVarintMemory.WriteInt32(id); isFirst = false; } else { mVarintMemory.WriteInt32(id - preids); } preids = id; } else { emptyIds.Insert(i); } } return mVarintMemory.DataBuffer.AsMemory(0, (int)mVarintMemory.WritePosition); } /// /// /// /// /// /// /// /// /// protected virtual Memory CompressValues(IMemoryBlock source,long offset,int count, CustomQueue emptyIds,TagType type) { mMarshalMemory.Position = 0; mVarintMemory.Reset(); int ig = -1; ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; bool isFirst = true; switch (type) { case TagType.Byte: for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadByte((int)offset + i); mMarshalMemory.Write(id); } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; // emptyIds.TryDequeue(out ig); } } return mMarshalMemory.StartMemory.AsMemory(0, (int)mMarshalMemory.Position); case TagType.Short: short sval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadShort((int)offset + i * 2); if (isFirst) { mVarintMemory.WriteSInt32(id); isFirst = false; sval = id; } else { mVarintMemory.WriteSInt32(id - sval); sval = id; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.UShort: ushort ssval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadUShort((int)offset + i * 2); if (isFirst) { mVarintMemory.WriteSInt32(id); isFirst = false; ssval = id; } else { mVarintMemory.WriteSInt32(id - ssval); ssval = id; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.Int: int isval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadInt((int)offset + i * 4); if (isFirst) { mVarintMemory.WriteInt32(id); isFirst = false; isval = id; } else { mVarintMemory.WriteSInt32(id - isval); isval = id; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.UInt: uint uisval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadUInt((int)offset + i * 4); if (isFirst) { mVarintMemory.WriteInt32(id); isFirst = false; uisval = id; } else { mVarintMemory.WriteSInt32((int)(id - uisval)); } uisval = id; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.Long: long lsval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadLong((int)offset + i * 8); if (isFirst) { mVarintMemory.WriteInt64(id); isFirst = false; lsval = id; } else { mVarintMemory.WriteSInt64((id - lsval)); lsval = id; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.ULong: ulong ulsval = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadULong((int)offset + i * 8); if (isFirst) { mVarintMemory.WriteInt64(id); isFirst = false; ulsval = id; } else { mVarintMemory.WriteSInt64((long)(id - ulsval)); ulsval = id; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.Double: mDCompress.Reset(); mDCompress.Precision = this.Precision; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadDouble((int)offset + i * 8); mDCompress.Append(id); // mMarshalMemory.Write(id); } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } mDCompress.Compress(); return mMarshalMemory.StartMemory.AsMemory(0, (int)mMarshalMemory.Position); case TagType.Float: mFCompress.Reset(); mFCompress.Precision = this.Precision; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadFloat((int)offset + i * 4); mFCompress.Append(id); } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } mFCompress.Compress(); return mMarshalMemory.StartMemory.AsMemory(0, (int)mMarshalMemory.Position); case TagType.IntPoint: int psval = 0; int psval2 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadInt((int)offset + i * 8); var id2 = source.ReadInt((int)offset + i * 8 + 4); if (isFirst) { mVarintMemory.WriteInt32(id); mVarintMemory.WriteInt32(id2); isFirst = false; } else { mVarintMemory.WriteSInt32(id - psval); mVarintMemory.WriteSInt32(id2 - psval2); } psval = id; psval2 = id2; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.UIntPoint: uint upsval = 0; uint upsval2 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadUInt((int)offset + i * 8); var id2 = source.ReadUInt((int)offset + i * 8 + 4); if (isFirst) { mVarintMemory.WriteInt32(id); mVarintMemory.WriteInt32(id2); isFirst = false; } else { mVarintMemory.WriteSInt32((int)(id - upsval)); mVarintMemory.WriteSInt32((int)(id2 - upsval2)); } upsval = id; upsval2 = id2; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.IntPoint3: psval = 0; psval2 = 0; int psval3 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadInt((int)offset + i * 12); var id2 = source.ReadInt((int)offset + i * 12 + 4); var id3 = source.ReadInt((int)offset + i * 12 + 8); if (isFirst) { mVarintMemory.WriteInt32(id); mVarintMemory.WriteInt32(id2); mVarintMemory.WriteInt32(id3); isFirst = false; } else { mVarintMemory.WriteSInt32((int)(id - psval)); mVarintMemory.WriteSInt32((int)(id2 - psval2)); mVarintMemory.WriteSInt32((int)(id3 - psval3)); } psval = id; psval2 = id2; psval3 = id3; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.UIntPoint3: upsval = 0; upsval2 = 0; uint upsval3 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadUInt((int)offset + i * 12); var id2 = source.ReadUInt((int)offset + i * 12 + 4); var id3 = source.ReadUInt((int)offset + i * 12 + 8); if (isFirst) { mVarintMemory.WriteInt32(id); mVarintMemory.WriteInt32(id2); mVarintMemory.WriteInt32(id3); isFirst = false; } else { mVarintMemory.WriteSInt32((int)(id - upsval)); mVarintMemory.WriteSInt32((int)(id2 - upsval2)); mVarintMemory.WriteSInt32((int)(id3 - upsval3)); } upsval = id; upsval2 = id2; upsval3 = id3; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.LongPoint: long lpsval = 0; long lpsval2 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadLong((int)offset + i * 16); var id2 = source.ReadLong((int)offset + i * 16 + 8); if (isFirst) { mVarintMemory.WriteInt64(id); mVarintMemory.WriteInt64(id2); isFirst = false; } else { mVarintMemory.WriteSInt64(id - lpsval); mVarintMemory.WriteSInt64(id2 - lpsval2); } lpsval = id; lpsval2 = id2; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.ULongPoint: ulong ulpsval = 0; ulong ulpsval2 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadULong((int)offset + i * 16); var id2 = source.ReadULong((int)offset + i * 16 + 8); if (isFirst) { mVarintMemory.WriteInt64(id); mVarintMemory.WriteInt64(id2); isFirst = false; } else { mVarintMemory.WriteSInt64((long)(id - ulpsval)); mVarintMemory.WriteSInt64((long)(id2 - ulpsval2)); } ulpsval = id; ulpsval2 = id2; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.LongPoint3: lpsval = 0; lpsval2 = 0; long lpsval3 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadLong((int)offset + i * 24); var id2 = source.ReadLong((int)offset + i * 24 + 8); var id3 = source.ReadLong((int)offset + i * 24 + 16); if (isFirst) { mVarintMemory.WriteInt64(id); mVarintMemory.WriteInt64(id2); mVarintMemory.WriteInt64(id3); isFirst = false; } else { mVarintMemory.WriteSInt64(id - lpsval); mVarintMemory.WriteSInt64(id2 - lpsval2); mVarintMemory.WriteSInt64(id3 - lpsval3); } lpsval = id; lpsval2 = id2; lpsval3 = id3; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; case TagType.ULongPoint3: ulpsval = 0; ulpsval2 = 0; ulong ulpsval3 = 0; for (int i = 0; i < count; i++) { if (i != ig) { var id = source.ReadULong((int)offset + i * 24); var id2 = source.ReadULong((int)offset + i * 24 + 8); var id3 = source.ReadULong((int)offset + i * 24 + 16); if (isFirst) { mVarintMemory.WriteInt64(id); mVarintMemory.WriteInt64(id2); mVarintMemory.WriteInt64(id3); isFirst = false; } else { mVarintMemory.WriteSInt64((long)(id - ulpsval)); mVarintMemory.WriteSInt64((long)(id2 - ulpsval2)); mVarintMemory.WriteSInt64((long)(id3 - ulpsval3)); } ulpsval = id; ulpsval2 = id2; ulpsval3 = id3; } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } break; default: break; } return mVarintMemory.DataBuffer.AsMemory(0, (int)mVarintMemory.WritePosition); } /// /// /// /// /// /// protected Memory CompressValues(List timerVals, CustomQueue emptyIds) { mMarshalMemory.Position = 0; int ig = -1; ig = emptys.ReadIndex <= emptyIds.WriteIndex ? emptys.IncRead() : -1; for (int i = 0; i < timerVals.Count; i++) { if(i != ig) { var id = timerVals[i]; mMarshalMemory.Write(id); } else { ig = emptys.ReadIndex <= emptyIds.WriteIndex ? emptys.IncRead() : -1; } } return mMarshalMemory.StartMemory.AsMemory(0, (int)mMarshalMemory.Position); } /// /// /// /// /// /// /// /// protected Memory CompressQulitys(IMemoryBlock source, long offset, int totalcount, CustomQueue emptyIds) { int count = 1; byte qus = source.ReadByte((int)offset); //using (ProtoMemory memory = new ProtoMemory(qulitys.Length * 2)) mVarintMemory.Reset(); int ig = -1; ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; //emptyIds.TryDequeue(out ig); mVarintMemory.WriteInt32(qus); for (int i = 1; i < totalcount; i++) { if (i != ig) { byte bval = source.ReadByte((int)offset + i); if (bval == qus) { count++; } else { mVarintMemory.WriteInt32(count); qus = bval; mVarintMemory.WriteInt32(qus); count = 1; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; // emptyIds.TryDequeue(out ig); } } mVarintMemory.WriteInt32(count); return mVarintMemory.DataBuffer.AsMemory(0, (int)mVarintMemory.WritePosition); } /// /// /// /// /// protected Memory CompressQulitys(byte[] qulitys, CustomQueue emptyIds) { int count = 1; byte qus = qulitys[0]; //using (ProtoMemory memory = new ProtoMemory(qulitys.Length * 2)) mVarintMemory.Reset(); int ig = -1; ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; mVarintMemory.WriteInt32(qus); for (int i = 1; i < qulitys.Length; i++) { if (i != ig) { if (qulitys[i] == qus) { count++; } else { mVarintMemory.WriteInt32(count); qus = qulitys[i]; mVarintMemory.WriteInt32(qus); count = 1; } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; } } mVarintMemory.WriteInt32(count); return mVarintMemory.DataBuffer.AsMemory(0, (int)mVarintMemory.WritePosition); } /// /// /// /// /// protected Memory CompressBoolValues(IMemoryBlock source, long offset, int totalcount, CustomQueue emptyIds) { List re = new List(totalcount); byte bval = source.ReadByte((int)offset); short scount = 1; int ig = -1; ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; //emptyIds.TryDequeue(out ig); short sval = (short)(bval << 15); for(int i=0;i< totalcount; i++) { if (i != ig) { var btmp = source.ReadByte((int)(offset + i)); if(btmp == bval) { scount++; } else { sval = (short)(sval | scount); re.Add(sval); scount = 1; bval = btmp; sval = (short)(bval << 15); } } else { ig = emptyIds.ReadIndex <= emptyIds.WriteIndex ? emptyIds.IncRead() : -1; // emptyIds.TryDequeue(out ig); } } sval = (short)(sval | scount); re.Add(sval); mMarshalMemory.Position = 0; foreach (var vv in re) { mMarshalMemory.Write(vv); } return mMarshalMemory.StartMemory.AsMemory(0, (int)mMarshalMemory.Position); } /// /// /// /// /// /// /// /// protected virtual long Compress(IMemoryBlock source, long sourceAddr, MarshalMemoryBlock target, long targetAddr, long size, TagType type) { var count = (int)(size - this.QulityOffset); if(mMarshalMemory==null) { mMarshalMemory = new MemoryBlock(count * 10); } if(mVarintMemory==null) { mVarintMemory = new ProtoMemory(count * 10); } var datas = CompressTimers(source, sourceAddr, (int)count, emptys); long rsize = 0; int rcount = count - emptys.WriteIndex - 1; target.WriteInt(targetAddr,rcount); rsize += 4; target.Write((int)datas.Length); target.Write(datas); rsize += 4; rsize += datas.Length; switch (type) { case TagType.Bool: var cval = CompressBoolValues(source, count * 2 + sourceAddr, count, emptys); target.Write(cval.Length); target.Write(cval); rsize += 4; rsize += cval.Length; emptys.ReadIndex = 0; var cqus = CompressQulitys(source, count * 3 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Byte: cval = CompressValues(source, count * 2 + sourceAddr, count, emptys,TagType); target.Write(cval.Length); target.Write(cval); rsize += 4; rsize += cval.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 3 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.UShort: var ures = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ures.Length); target.Write(ures); rsize += 4; rsize += ures.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 4 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Short: var res = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(res.Length); target.Write(res); rsize += 4; rsize += res.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 4 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.UInt: var uires = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(uires.Length); target.Write(uires); rsize += 4; rsize += uires.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 6 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Int: var ires = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ires.Length); target.Write(ires); rsize += 4; rsize += ires.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 6 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.ULong: var ulres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ulres.Length); target.Write(ulres); rsize += 4; rsize += ulres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Long: var lres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(lres.Length); target.Write(lres); rsize += 4; rsize += lres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.DateTime: var dres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(dres.Length); target.Write(dres); rsize += 4; rsize += dres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Double: if (mDCompress == null) mDCompress = new DoubleCompressBuffer(310) { MemoryBlock = mMarshalMemory, VarintMemory = mVarintMemory }; var ddres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ddres.Length); target.Write(ddres); rsize += 4; rsize += ddres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.Float: if (mFCompress == null) mFCompress = new FloatCompressBuffer(310) { MemoryBlock = mMarshalMemory, VarintMemory = mVarintMemory }; var fres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(fres.Length); target.Write(fres); rsize += 4; rsize += fres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 6 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.String: var vals = source.ReadStrings(count * 2 + (int)sourceAddr, count); var qus = source.ReadBytes(count); var sres = CompressValues(vals, emptys); target.Write(sres.Length); target.Write(sres); rsize += 4; rsize += sres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(qus, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.IntPoint: var ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.UIntPoint: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 10 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.LongPoint: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 18 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.ULongPoint: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 18 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.IntPoint3: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 14 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.UIntPoint3: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 14 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.LongPoint3: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 26 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; case TagType.ULongPoint3: ipres = CompressValues(source, count * 2 + sourceAddr, count, emptys, TagType); target.Write(ipres.Length); target.Write(ipres); rsize += 4; rsize += ipres.Length; emptys.ReadIndex = 0; cqus = CompressQulitys(source, count * 26 + sourceAddr, count, emptys); target.Write(cqus.Length); target.Write(cqus); rsize += 4; rsize += cqus.Length; break; } return rsize; } #endregion #region Decompress /// /// /// /// /// /// private List DeCompressTimers(byte[] timerVals, int count) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(timerVals)) { ushort sval = (ushort)memory.ReadInt32(); re.Add(sval); ushort preval = sval; for (int i = 1; i < count; i++) { var ss = (ushort)memory.ReadInt32(); var val = (ushort)(preval + ss); re.Add(val); preval = val; } return re; } } /// /// /// /// /// private List DeCompressQulity(byte[] values) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(values)) { while(memory.ReadPosition /// /// /// /// /// /// /// protected virtual List DeCompressValue(byte[] value, int count) { if (typeof(T) == typeof(byte)) { return value.ToList() as List; } else if (typeof(T) == typeof(short)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (short)memory.ReadInt32(); re.Add(vv); for (int i = 1; i < count; i++) { var vss = (short)memory.ReadSInt32(); re.Add((short)(vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(ushort)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (short)memory.ReadInt32(); re.Add((ushort)vv); for (int i = 1; i < count; i++) { var vss = (short)memory.ReadSInt32(); re.Add((ushort)(vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(int)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (int)memory.ReadInt32(); re.Add(vv); for (int i = 1; i < count; i++) { var vss = (int)memory.ReadSInt32(); re.Add((int)(vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(uint)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = memory.ReadInt32(); re.Add((uint)vv); for (int i = 1; i < count; i++) { var vss = memory.ReadSInt32(); re.Add((uint)((uint)vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(long)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (long)memory.ReadInt64(); re.Add(vv); for (int i = 1; i < count; i++) { var vss = (long)memory.ReadSInt64(); re.Add((long)(vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(ulong)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = memory.ReadInt64(); re.Add((ulong)vv); for (int i = 1; i < count; i++) { var vss = memory.ReadSInt64(); re.Add((ulong)(vv + vss)); vv = vss; } } return re as List; } else if (typeof(T) == typeof(DateTime)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (ulong)memory.ReadInt64(); re.Add(MemoryHelper.ReadDateTime(BitConverter.GetBytes(vv))); for (int i = 1; i < count; i++) { var vss = (ulong)memory.ReadSInt64(); re.Add(MemoryHelper.ReadDateTime(BitConverter.GetBytes((ulong)(vv + vss)))); vv = vss; } } return re as List; } else if (typeof(T) == typeof(double)) { return DoubleCompressBuffer.Decompress(value) as List; //using (MemorySpan block = new MemorySpan(value)) //{ // return block.ToDoubleList() as List; //} } else if (typeof(T) == typeof(float)) { return FloatCompressBuffer.Decompress(value) as List; //using (MemorySpan block = new MemorySpan(value)) //{ // return block.ToFloatList() as List; //} } else if (typeof(T) == typeof(string)) { using (MemorySpan block = new MemorySpan(value)) { return block.ToStringList(Encoding.Unicode) as List; } } else if (typeof(T) == typeof(bool)) { using (MemorySpan block = new MemorySpan(value)) { List re = new List(); var rtmp = block.ToShortList(); foreach (var vv in rtmp) { bool bval = (vv >> 15) > 0; short bcount = (short)(vv & 0x7FFF); for (int i = 0; i < bcount; i++) { re.Add(bval); } } return re as List; } } else if (typeof(T) == typeof(IntPointData)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (int)memory.ReadInt32(); var vv2 = (int)memory.ReadInt32(); re.Add(new IntPointData(vv,vv2)); for (int i = 2; i < count-1; i=i+2) { var vss = (int)memory.ReadSInt32(); var vss2 = (int)memory.ReadSInt32(); re.Add(new IntPointData((int)(vv + vss), (int)(vv2 + vss2))); vv = vss; vv2 = vss2; } } return re as List; } else if (typeof(T) == typeof(UIntPointData)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (int)memory.ReadInt32(); var vv2 = (int)memory.ReadInt32(); re.Add(new UIntPointData((uint)vv, (uint)vv2)); for (int i = 2; i < count - 1; i = i + 2) { var vss = (int)memory.ReadSInt32(); var vss2 = (int)memory.ReadSInt32(); re.Add(new UIntPointData((uint)(vv + vss), (uint)(vv2 + vss2))); vv = vss; vv2 = vss2; } } return re as List; } else if (typeof(T) == typeof(LongPointData)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (long)memory.ReadInt64(); var vv2 = (long)memory.ReadInt64(); re.Add(new LongPointData(vv, vv2)); for (int i = 2; i < count - 1; i = i + 2) { var vss = memory.ReadSInt64(); var vss2 = memory.ReadSInt64(); re.Add(new LongPointData((vv + vss), (vv2 + vss2))); vv = vss; vv2 = vss2; } } return re as List; } else if (typeof(T) == typeof(ULongPointData)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = memory.ReadInt64(); var vv2 = memory.ReadInt64(); re.Add(new ULongPointData((ulong)vv, (ulong)vv2)); for (int i = 2; i < count - 1; i = i + 2) { var vss = memory.ReadSInt64(); var vss2 = memory.ReadSInt64(); re.Add(new ULongPointData((ulong)(vv + vss), (ulong)(vv2 + vss2))); vv = vss; vv2 = vss2; } } return re as List; } else if (typeof(T) == typeof(IntPoint3Data)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (int)memory.ReadInt32(); var vv2 = (int)memory.ReadInt32(); var vv3 = (int)memory.ReadInt32(); re.Add(new IntPoint3Data(vv, vv2,vv3)); for (int i = 3; i < count - 2; i = i + 3) { var vss = (int)memory.ReadSInt32(); var vss2 = (int)memory.ReadSInt32(); var vss3 = (int)memory.ReadSInt32(); re.Add(new IntPoint3Data((int)(vv + vss), (int)(vv2 + vss2), (int)(vv3 + vss3))); vv = vss; vv2 = vss2; vv3 = vss3; } } return re as List; } else if (typeof(T) == typeof(UIntPoint3Data)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (int)memory.ReadInt32(); var vv2 = (int)memory.ReadInt32(); var vv3 = (int)memory.ReadInt32(); re.Add(new UIntPoint3Data((uint)vv, (uint)vv2, (uint)vv3)); for (int i = 3; i < count - 2; i = i + 3) { var vss = (int)memory.ReadSInt32(); var vss2 = (int)memory.ReadSInt32(); var vss3 = (int)memory.ReadSInt32(); re.Add(new UIntPoint3Data((uint)(vv + vss), (uint)(vv2 + vss2), (uint)(vv3 + vss3))); vv = vss; vv2 = vss2; vv3 = vss3; } } return re as List; } else if (typeof(T) == typeof(LongPoint3Data)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (long)memory.ReadInt64(); var vv2 = (long)memory.ReadInt64(); var vv3 = (long)memory.ReadInt64(); re.Add(new LongPoint3Data((long)vv, (long)vv2, (long)vv3)); for (int i = 3; i < count - 2; i = i + 3) { var vss = memory.ReadInt64(); var vss2 = memory.ReadInt64(); var vss3 = memory.ReadInt64(); re.Add(new LongPoint3Data((long)(vv + vss), (long)(vv2 + vss2), (long)(vv3 + vss3))); vv = vss; vv2 = vss2; vv3 = vss3; } } return re as List; } else if (typeof(T) == typeof(ULongPoint3Data)) { List re = new List(); using (ProtoMemory memory = new ProtoMemory(value)) { var vv = (long)memory.ReadInt64(); var vv2 = (long)memory.ReadInt64(); var vv3 = (long)memory.ReadInt64(); re.Add(new ULongPoint3Data((ulong)vv, (ulong)vv2, (ulong)vv3)); for (int i = 3; i < count - 2; i = i + 3) { var vss = memory.ReadInt64(); var vss2 = memory.ReadInt64(); var vss3 = memory.ReadInt64(); re.Add(new ULongPoint3Data((ulong)(vv + vss), (ulong)(vv2 + vss2), (ulong)(vv3 + vss3))); vv = vss; vv2 = vss2; vv3 = vss3; } } return re as List; } return null; } #endregion /// /// /// /// /// /// /// /// /// protected Dictionary GetTimers(MarshalMemoryBlock source,int sourceAddr,DateTime startTime,DateTime endTime,out int valueCount) { DateTime sTime = source.ReadDateTime(sourceAddr); int timeTick = source.ReadInt(sourceAddr + 8); Dictionary re = new Dictionary(); var count = source.ReadInt(); var datasize = source.ReadInt(); byte[] datas = source.ReadBytes(datasize); var timers = DeCompressTimers(datas, count); for (int i = 0; i < timers.Count; i++) { var vtime = sTime.AddMilliseconds(timers[i] * timeTick); if (vtime >= startTime && vtime < endTime) re.Add(i, vtime); else if(vtime>endTime && (vtime - endTime).TotalMilliseconds< timeTick) { re.Add(i, vtime); } else if (vtime < startTime && (startTime - vtime).TotalMilliseconds < timeTick) { re.Add(i, vtime); } } valueCount = count; return re; } /// /// /// /// /// /// /// /// protected Dictionary GetTimers(MarshalMemoryBlock source, int sourceAddr, out int valueCount) { DateTime sTime = source.ReadDateTime(sourceAddr); int timeTick = source.ReadInt(sourceAddr + 8); Dictionary re = new Dictionary(); var count = source.ReadInt(); var datasize = source.ReadInt(); byte[] datas = source.ReadBytes(datasize); var timers = DeCompressTimers(datas, count); for (int i = 0; i < timers.Count; i++) { re.Add(i, sTime.AddMilliseconds(timers[i] * timeTick)); } valueCount = count; return re; } /// /// /// /// /// private bool CheckTypeIsPointData(Type type) { return type == typeof(IntPointData) || type == typeof(UIntPointData) || type == typeof(LongPointData) || type == typeof(ULongPointData) || type == typeof(IntPoint3Data) || type == typeof(UIntPoint3Data) || type == typeof(LongPoint3Data) || type == typeof(ULongPoint3Data); } /// /// /// /// /// /// /// /// /// /// /// public override int DeCompressAllValue(MarshalMemoryBlock source, int sourceAddr, DateTime startTime, DateTime endTime, int timeTick, HisQueryResult result) { int count = 0; var timers = GetTimers(source, sourceAddr, startTime, endTime, out count); var valuesize = source.ReadInt(); var value = DeCompressValue(source.ReadBytes(valuesize), count); var qusize = source.ReadInt(); var qulityes = DeCompressQulity(source.ReadBytes(qusize)); int resultCount = 0; for (int i = 0; i < count; i++) { if (qulityes[i] < 100 && timers.ContainsKey(i)) { result.Add(value[i], timers[i], qulityes[i]); resultCount++; } } return resultCount; } /// /// /// /// /// /// /// /// /// /// /// public override int DeCompressValue(MarshalMemoryBlock source, int sourceAddr, List time, int timeTick, QueryValueMatchType type, HisQueryResult result) { if (CheckTypeIsPointData(typeof(T))) { return DeCompressPointValue(source, sourceAddr, time, timeTick, type, result); } int count = 0; var timers = GetTimers(source, sourceAddr, out count); var valuesize = source.ReadInt(); var value = DeCompressValue(source.ReadBytes(valuesize), count); var qusize = source.ReadInt(); var qulityes = DeCompressQulity(source.ReadBytes(qusize)); int resultCount = 0; int j = 0; foreach (var time1 in time) { for (int i = j; i < timers.Count - 1; i++) { var skey = timers[i]; var snext = timers[i + 1]; j = i; if ((time1==skey) ||(time1 < skey && (skey - time1).TotalSeconds<1)) { var val = value[i]; result.Add(val, time1, qulityes[i]); resultCount++; break; } else if (time1 > skey && time1 < snext) { switch (type) { case QueryValueMatchType.Previous: var val = value[i]; result.Add(val, time1, qulityes[i]); resultCount++; break; case QueryValueMatchType.After: val = value[i + 1]; result.Add(val, time1, qulityes[i+1]); resultCount++; break; case QueryValueMatchType.Linear: if (typeof(T) == typeof(bool)|| typeof(T) == typeof(string)|| typeof(T) == typeof(DateTime)) { var ppval = (time1 - skey).TotalMilliseconds; var ffval = (snext - time1).TotalMilliseconds; if (ppval < ffval) { val = value[i]; result.Add(val, time1, qulityes[i]); } else { val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); } resultCount++; } else { if (qulityes[i] < 20 && qulityes[i + 1] < 20) { var pval1 = (time1 - skey).TotalMilliseconds; var tval1 = (snext - skey).TotalMilliseconds; var sval1 = value[i]; var sval2 = value[i + 1]; var val1 = pval1 / tval1 * (Convert.ToDouble(sval2) - Convert.ToDouble(sval1)) + Convert.ToDouble(sval1); result.Add((object)val1, time1, 0); } else if (qulityes[i] < 20) { val = value[i]; result.Add(val, time1, qulityes[i]); } else if (qulityes[i + 1] < 20) { val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); } else { result.Add(default(T), time1, (byte)QualityConst.Null); } resultCount++; } break; case QueryValueMatchType.Closed: var pval = (time1 - skey).TotalMilliseconds; var fval = (snext - time1).TotalMilliseconds; if (pval < fval) { val = value[i]; result.Add(val, time1, qulityes[i]); } else { val = value[i+1]; result.Add(val, time1, qulityes[i + 1]); } resultCount++; break; } break; } else if (time1 == snext) { var val =value[i + 1]; result.Add(val, time1, qulityes[i+1]); resultCount++; break; } } } return resultCount; } /// /// /// /// /// /// /// /// /// /// public override object DeCompressValue(MarshalMemoryBlock source, int sourceAddr, DateTime time, int timeTick, QueryValueMatchType type) { if (CheckTypeIsPointData(typeof(T))) { return DeCompressPointValue(source, sourceAddr, time, timeTick, type); } int count = 0; var timers = GetTimers(source, sourceAddr + 8, out count); var valuesize = source.ReadInt(); var value = DeCompressValue(source.ReadBytes(valuesize), count); var qusize = source.ReadInt(); var qulityes = DeCompressQulity(source.ReadBytes(qusize)); int j = 0; for (int i = j; i < timers.Count - 1; i++) { var skey = timers[i]; var snext = timers[i + 1]; if ((time == skey) || (time < skey && (skey - time).TotalSeconds < 1)) { return value[i]; } else if (time > skey && time < snext) { switch (type) { case QueryValueMatchType.Previous: return value[i]; case QueryValueMatchType.After: return value[i + 1]; case QueryValueMatchType.Linear: if (typeof(T) == typeof(bool) || typeof(T) == typeof(string) || typeof(T) == typeof(DateTime)) { var ppval = (time - skey).TotalMilliseconds; var ffval = (snext - time).TotalMilliseconds; if (ppval < ffval) { return value[i]; } else { return value[i + 1]; } } else { if (qulityes[i] < 20 && qulityes[i + 1] < 20) { var pval1 = (time - skey).TotalMilliseconds; var tval1 = (snext - skey).TotalMilliseconds; var sval1 = value[i]; var sval2 = value[i + 1]; var val1 = pval1 / tval1 * (Convert.ToDouble(sval2) - Convert.ToDouble(sval1)) + Convert.ToDouble(sval1); if (typeof(T) == typeof(double)) { return val1; } else if (typeof(T) == typeof(float)) { return (float)val1; } else if (typeof(T) == typeof(short)) { return (short)val1; } else if (typeof(T) == typeof(ushort)) { return (ushort)val1; } else if (typeof(T) == typeof(int)) { return (int)val1; } else if (typeof(T) == typeof(uint)) { return (uint)val1; } else if (typeof(T) == typeof(long)) { return (long)val1; } else if (typeof(T) == typeof(ulong)) { return (ulong)val1; } else if (typeof(T) == typeof(byte)) { return (byte)val1; } } else if (qulityes[i] < 20) { return value[i]; } else if (qulityes[i + 1] < 20) { return value[i + 1]; } else { return null; } } break; case QueryValueMatchType.Closed: var pval = (time - skey).TotalMilliseconds; var fval = (snext - time).TotalMilliseconds; if (pval < fval) { return value[i]; } else { return value[i + 1]; } } break; } else if (time == snext) { return value[i + 1]; } } return null; } /// /// /// /// /// /// /// /// /// /// public object DeCompressPointValue(MarshalMemoryBlock source, int sourceAddr, DateTime time1, int timeTick, QueryValueMatchType type) { int count = 0; var timers = GetTimers(source, sourceAddr + 8,out count); var valuesize = source.ReadInt(); var value = DeCompressValue(source.ReadBytes(valuesize), count); var qusize = source.ReadInt(); var qulityes = DeCompressQulity(source.ReadBytes(qusize)); for (int i = 0; i < timers.Count - 1; i++) { var skey = timers[i]; var snext = timers[i + 1]; if ((time1 == skey) || (time1 < skey && (skey - time1).TotalSeconds < 1)) { return value[i]; } else if (time1 > skey && time1 < snext) { switch (type) { case QueryValueMatchType.Previous: return value[i]; case QueryValueMatchType.After: return value[i+1]; case QueryValueMatchType.Linear: if (qulityes[i] < 20 && qulityes[i + 1] < 20) { return (T)LinerValue(skey, snext, time1, value[i], value[i + 1]); } else if (qulityes[i] < 20) { return value[i]; } else if (qulityes[i + 1] < 20) { return value[i+1]; } return null; case QueryValueMatchType.Closed: var pval = (time1 - skey).TotalMilliseconds; var fval = (snext - time1).TotalMilliseconds; if (pval < fval) { return value[i]; } else { return value[i + 1]; } } break; } else if (time1 == snext) { return value[i + 1]; } } return null; } #region /// /// /// /// /// /// /// /// /// /// private object LinerValue(DateTime startTime,DateTime endTime,DateTime time,T value1,T value2) { var pval1 = (time - startTime).TotalMilliseconds; var tval1 = (endTime - startTime).TotalMilliseconds; if (typeof(T) == typeof(IntPointData)) { var sval1 = (IntPointData)((object)value1); var sval2 = (IntPointData)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); return new IntPointData((int)val1, (int)val2); } else if (typeof(T) == typeof(UIntPointData)) { var sval1 = (UIntPointData)((object)value1); var sval2 = (UIntPointData)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); return new UIntPointData((uint)val1, (uint)val2); } else if (typeof(T) == typeof(LongPointData)) { var sval1 = (LongPointData)((object)value1); var sval2 = (LongPointData)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); return new LongPointData((long)val1, (long)val2); } else if (typeof(T) == typeof(ULongPointData)) { var sval1 = (ULongPointData)((object)value1); var sval2 = (ULongPointData)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); return new ULongPointData((ulong)val1, (ulong)val2); } else if (typeof(T) == typeof(IntPoint3Data)) { var sval1 = (IntPoint3Data)((object)value1); var sval2 = (IntPoint3Data)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z); return new IntPoint3Data((int)val1, (int)val2, (int)val3); } else if (typeof(T) == typeof(UIntPoint3Data)) { var sval1 = (UIntPoint3Data)((object)value1); var sval2 = (UIntPoint3Data)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z); return new UIntPoint3Data((uint)val1, (uint)val2, (uint)val3); } else if (typeof(T) == typeof(LongPoint3Data)) { var sval1 = (LongPoint3Data)((object)value1); var sval2 = (LongPoint3Data)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z); return new LongPoint3Data((long)val1, (long)val2, (long)val3); } else if (typeof(T) == typeof(ULongPoint3Data)) { var sval1 = (ULongPoint3Data)((object)value1); var sval2 = (ULongPoint3Data)((object)value2); var val1 = pval1 / tval1 * (Convert.ToDouble(sval2.X) - Convert.ToDouble(sval1.X)) + Convert.ToDouble(sval1.X); var val2 = pval1 / tval1 * (Convert.ToDouble(sval2.Y) - Convert.ToDouble(sval1.Y)) + Convert.ToDouble(sval1.Y); var val3 = pval1 / tval1 * (Convert.ToDouble(sval2.Z) - Convert.ToDouble(sval1.Z)) + Convert.ToDouble(sval1.Z); return new ULongPoint3Data((ulong)val1, (ulong)val2, (ulong)val3); } return default(T); } /// /// /// /// /// /// /// /// /// /// /// public int DeCompressPointValue(MarshalMemoryBlock source, int sourceAddr, List time, int timeTick, QueryValueMatchType type, HisQueryResult result) { int count = 0; var timers = GetTimers(source, sourceAddr + 8,out count); var valuesize = source.ReadInt(); var value = DeCompressValue(source.ReadBytes(valuesize), count); var qusize = source.ReadInt(); var qulityes = DeCompressQulity(source.ReadBytes(qusize)); int resultCount = 0; int j = 0; foreach (var time1 in time) { for (int i = j; i < timers.Count - 1; i++) { var skey = timers[i]; var snext = timers[i + 1]; if ((time1 == skey) || (time1 < skey && (skey - time1).TotalSeconds < 1)) { var val = value[i]; result.Add(val, time1, qulityes[i]); resultCount++; break; } else if (time1 > skey && time1 < snext) { switch (type) { case QueryValueMatchType.Previous: var val = value[i]; result.Add(val, time1, qulityes[i]); resultCount++; break; case QueryValueMatchType.After: val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); resultCount++; break; case QueryValueMatchType.Linear: if (qulityes[i] < 20 && qulityes[i + 1] < 20) { result.Add(LinerValue(skey, snext, time1, value[i], value[i + 1]), time1, 0); } else if (qulityes[i] < 20) { val = value[i]; result.Add(val, time1, qulityes[i]); } else if (qulityes[i + 1] < 20) { val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); } else { result.Add(0, time1, (byte)QualityConst.Null); } resultCount++; break; case QueryValueMatchType.Closed: var pval = (time1 - skey).TotalMilliseconds; var fval = (snext - time1).TotalMilliseconds; if (pval < fval) { val = value[i]; result.Add(val, time1, qulityes[i]); } else { val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); } resultCount++; break; } break; } else if (time1 == snext) { var val = value[i + 1]; result.Add(val, time1, qulityes[i + 1]); resultCount++; break; } } } return resultCount; } #endregion } }