/// <summary> /// Plus a GLOBCNT by 1. /// </summary> /// <param name="g">A GLOBCNT instance.</param> /// <returns>The next GLOBCNT value.</returns> public static GLOBCNT Inc(GLOBCNT g) { byte c = 0; byte[] tmp = StructureSerializer.Serialize(g); if (tmp[5] == byte.MaxValue) { tmp[5] = 0; c = 1; } else { tmp[5]++; c = 0; } for (int i = 4; i > -1; i--) { if (tmp[i] == byte.MaxValue && c == 1) { tmp[i] = 0; c = 1; } else { tmp[i] += c; c = 0; } } return(StructureSerializer.Deserialize <GLOBCNT>(tmp)); }
/// <summary> /// Initializes a new instance of the GLOBCNTRange structure. /// </summary> /// <param name="start">The starting GLOBCNT of the range.</param> /// <param name="end">The end GLOBCNT of the range.</param> public GLOBCNTRange(GLOBCNT start, GLOBCNT end) { if (start > end) { AdapterHelper.Site.Assert.Fail("The start GLOBCNT should not large than the end GLOBCNT."); } this.startGLOBCNT = start; this.endGLOBCNT = end; }
/// <summary> /// Initializes a new instance of the GLOBCNTRange structure. /// </summary> /// <param name="start">The starting GLOBCNT of the range.</param> /// <param name="end">The end GLOBCNT of the range.</param> public GLOBCNTRange(GLOBCNT start, GLOBCNT end) { if (start > end) { AdapterHelper.Site.Assert.Fail("The start GLOBCNT should not large than the end GLOBCNT."); } this.startGLOBCNT = start; this.endGLOBCNT = end; }
/// <summary> /// Compresses a singleton GLOBCNTRange. /// </summary> /// <param name="index">The index of the GLOBCNTRange.</param> /// <returns>The count of bytes have been wrote to the stream.</returns> private int CompressSingleton(int index) { this.Verify(this.globcntRangeList[index].StartGLOBCNT == this.globcntRangeList[index].EndGLOBCNT); int byteCount = 6 - this.stack.Bytes; GLOBCNT cnt = this.globcntRangeList[index].StartGLOBCNT; byte[] tmp = new byte[byteCount]; Array.Copy( StructureSerializer.Serialize(cnt), 6 - byteCount, tmp, 0, byteCount); return(this.Push(this.stream, tmp)); }
/// <summary> /// Get GLOBCNTs from a GLOBCNTRange list. /// </summary> /// <param name="rangeList">A GLOBCNTRange list.</param> /// <returns>A GLOBCNT list corresponding to the GLOBCNTRange list.</returns> public static List <GLOBCNT> GetGLOBCNTList(List <GLOBCNTRange> rangeList) { List <GLOBCNT> cnts = new List <GLOBCNT>(); foreach (GLOBCNTRange range in rangeList) { GLOBCNT tmp = range.StartGLOBCNT; cnts.Add(tmp); tmp = GLOBCNT.Inc(tmp); while (tmp <= range.EndGLOBCNT) { cnts.Add(tmp); tmp = GLOBCNT.Inc(tmp); } } return(cnts); }
/// <summary> /// Compresses GLOBCNTRanges in the GLOBCNTRange list to as a bitmask command. /// </summary> /// <param name="startIndex">The start index of the GLOBCNTRange in the GLOBCNTRange list to compress.</param> /// <param name="endIndex">The end index of the GLOBCNTRange in the GLOBCNTRange list to compress.</param> /// <returns>The count of bytes have been wrote to the stream.</returns> private int CompressBitmask(int startIndex, int endIndex) { this.Verify(startIndex <= endIndex); List <GLOBCNT> list = GetGLOBCNTList( this.globcntRangeList.GetRange(startIndex, endIndex - startIndex + 1)); byte bitmask = 0; GLOBCNT tmp = list[0]; byte startValue = tmp.Byte6; tmp = GLOBCNT.Inc(tmp); this.Verify(list.Count < 10); for (int i = 0; i < 9; i++) { if (list.Contains(tmp)) { bitmask |= checked ((byte)(1 << i)); } tmp = GLOBCNT.Inc(tmp); } return(this.Bitmask(this.stream, startValue, bitmask)); }
/// <summary> /// Compresses a GLOBCNTRange in the GLOBCNTRange list to as a bitmask command. /// </summary> /// <param name="index">The index of the GLOBCNTRange.</param> /// <returns>The count of bytes have been wrote to the stream.</returns> private int CompressRange(int index) { int bytes = 6 - this.stack.Bytes; GLOBCNT cnt1 = this.globcntRangeList[index].StartGLOBCNT; GLOBCNT cnt2 = this.globcntRangeList[index].EndGLOBCNT; byte[] tmp1 = new byte[bytes]; Array.Copy( StructureSerializer.Serialize(cnt1), 6 - bytes, tmp1, 0, bytes); byte[] tmp2 = new byte[bytes]; Array.Copy( StructureSerializer.Serialize( cnt2), 6 - bytes, tmp2, 0, bytes); return(this.Range(this.stream, tmp1, tmp2)); }
/// <summary> /// Indicates whether has the GLOBCNT. /// </summary> /// <param name="cnt">The GLOBCNT.</param> /// <returns>If the GLOBCNT is in this range, return true, else false.</returns> public bool Contains(GLOBCNT cnt) { return this.StartGLOBCNT <= cnt && this.EndGLOBCNT >= cnt; }
/// <summary> /// Plus a GLOBCNT by 1. /// </summary> /// <param name="g">A GLOBCNT instance.</param> /// <returns>The next GLOBCNT value.</returns> public static GLOBCNT Inc(GLOBCNT g) { byte c = 0; byte[] tmp = StructureSerializer.Serialize(g); if (tmp[5] == byte.MaxValue) { tmp[5] = 0; c = 1; } else { tmp[5]++; c = 0; } for (int i = 4; i > -1; i--) { if (tmp[i] == byte.MaxValue && c == 1) { tmp[i] = 0; c = 1; } else { tmp[i] += c; c = 0; } } return StructureSerializer.Deserialize<GLOBCNT>(tmp); }
/// <summary> /// Indicates whether has the GLOBCNT. /// </summary> /// <param name="cnt">The GLOBCNT.</param> /// <returns>If the GLOBCNT is in this range, return true, else false.</returns> public bool Contains(GLOBCNT cnt) { return(this.StartGLOBCNT <= cnt && this.EndGLOBCNT >= cnt); }
/// <summary> /// Get GLOBCNTRanges from a GLOBCNT list. /// </summary> /// <param name="globcntList">A GLOBCNT list.</param> /// <returns>A GLOBCNTRange list corresponding to the GLOBCNT list.</returns> public static List <GLOBCNTRange> GetGLOBCNTRange(List <GLOBCNT> globcntList) { // _REPLID = id; int i, j; List <GLOBCNT> list = new List <GLOBCNT>(); List <GLOBCNTRange> globSETRangeList = new List <GLOBCNTRange>(); // Do a copy. for (i = 0; i < globcntList.Count; i++) { list.Add(globcntList[i]); } // Remove all the duplicate GLOBCNT values. for (i = 0; i < list.Count - 1; i++) { j = i + 1; while (j < list.Count) { if (list[i] == list[j]) { list.RemoveAt(j); continue; } else { j++; } } } // Sort GLOBCNT. list.Sort(new Comparison <GLOBCNT>(delegate(GLOBCNT c1, GLOBCNT c2) { if (c1 < c2) { return(-1); } if (c1 > c2) { return(1); } return(0); })); // Make a GLOBCNTRange list. i = 0; while (i < list.Count) { GLOBCNT start = list[i]; GLOBCNT end = start; GLOBCNT next = end; j = i + 1; while (j < list.Count) { end = next; next = GLOBCNT.Inc(end); if (list[j] == next) { list.RemoveAt(j); continue; } else { break; } } globSETRangeList.Add(new GLOBCNTRange(start, end)); i++; } return(globSETRangeList); }
/// <summary> /// Deserializes a list of GLOBCNTRanges from a bitmask command. /// </summary> /// <param name="commonBytes">The common bytes in the common byte stack.</param> /// <param name="startValue">The startValue of the bitmask command.</param> /// <param name="bitmask">The bitmaskValue of the bitmask command.</param> /// <returns>A list of GLOBCNTRanges.</returns> private List <GLOBCNTRange> FromBitmask( byte[] commonBytes, byte startValue, byte bitmask) { int bitIndex = 0; List <GLOBCNTRange> ranges = new List <GLOBCNTRange>(); this.Verify(commonBytes.Length == 5); byte[] buffer = new byte[6]; Array.Copy(commonBytes, buffer, 5); buffer[5] = startValue; byte start = startValue; GLOBCNT cnt1 = StructureSerializer.Deserialize <GLOBCNT>(buffer); GLOBCNT cnt2; do { if (((1 << bitIndex) & bitmask) == 0) { // Use previous bitmask. // ==bitIndex + 1 -1; start = (byte)bitIndex; start = checked ((byte)(start + startValue)); buffer[5] = start; cnt2 = StructureSerializer.Deserialize <GLOBCNT>(buffer); ranges.Add(new GLOBCNTRange(cnt1, cnt2)); bitIndex++; while (bitIndex < 8 && ((1 << bitIndex) & bitmask) == 0) { bitIndex++; } if (bitIndex == 8) { break; } else { start = (byte)(bitIndex + 1); start = checked ((byte)(start + startValue)); buffer[5] = start; cnt1 = StructureSerializer.Deserialize <GLOBCNT>(buffer); bitIndex++; } } else { bitIndex++; } }while (bitIndex < 8); if (((1 << 7) & bitmask) != 0) { start = (byte)8; start = checked ((byte)(8 + startValue)); buffer[5] = start; cnt2 = StructureSerializer.Deserialize <GLOBCNT>(buffer); ranges.Add(new GLOBCNTRange(cnt1, cnt2)); } return(ranges); }