public static T As <T>(this byte[] arr, int start, int len) where T : struct { switch (Type.GetTypeCode(typeof(T))) { case TypeCode.Byte: return((T)(object)(byte)arr[start]); case TypeCode.SByte: return((T)(object)(sbyte)arr[start]); case TypeCode.UInt16: return((T)(object)BitConverter.ToUInt16(arr, start)); case TypeCode.UInt32: return((T)(object)BitConverter.ToUInt32(arr, start)); case TypeCode.UInt64: return((T)(object)BitConverter.ToUInt64(arr, start)); case TypeCode.Int16: return((T)(object)BitConverter.ToInt16(arr, start)); case TypeCode.Int32: return((T)(object)BitConverter.ToInt32(arr, start)); case TypeCode.Int64: return((T)(object)BitConverter.ToInt64(arr, start)); case TypeCode.Single: return((T)(object)BitConverter.ToSingle(arr, start)); case TypeCode.Double: return((T)(object)BitConverter.ToDouble(arr, start)); case TypeCode.Boolean: return((T)(object)BitConverter.ToBoolean(arr, start)); case TypeCode.Char: return((T)(object)BitConverter.ToChar(arr, start)); case TypeCode.String: return((T)(object)Encoding.UTF8.GetString(arr, start, len)); default: { if (start + len < Marshal.SizeOf(typeof(T))) { throw new Exception($"As<T>: Insufficient data. {Marshal.SizeOf(typeof(T))} bytes required, {len - start} available"); } using var handle = GCHandle_.Alloc(arr, GCHandleType.Pinned); return(Marshal.PtrToStructure <T>(handle.Handle.AddrOfPinnedObject() + start)); } } }
/// <summary>Refresh the control with text from the vt100 buffer</summary> private void UpdateText(object sender = null, EventArgs args = null) { var buf = Buffer; // No buffer = empty display if (buf == null) { ClearAll(); return; } // Get the buffer region that has changed var region = buf.InvalidRect; buf.ValidateRect(); if (region.IsEmpty) { return; } using (this.SuspendRedraw(true)) using (ScrollScope()) { // Grow the text in the control to the required number of lines (if necessary) var line_count = LineCount; if (line_count < region.Bottom) { var pad = new byte[region.Bottom - line_count].Memset(0x0a); using (var p = GCHandle_.Alloc(pad, GCHandleType.Pinned)) Cmd(Sci.SCI_APPENDTEXT, pad.Length, p.Handle.AddrOfPinnedObject()); } // Update the text in the control from the invalid buffer region for (int i = region.Top, iend = region.Bottom; i != iend; ++i) { // Update whole lines, to hard to bother with x ranges // Note, the invalid region can be outside the buffer when the buffer gets cleared if (i >= buf.LineCount) { break; } var line = buf.Lines[i]; byte sty = 0; foreach (var span in line.Spans) { var str = Encoding.UTF8.GetBytes(span.m_str); sty = SciStyle(span.m_sty); foreach (var c in str) { m_cells.Add(c, sty); } } m_cells.Add(0x0a, sty); } // Remove the last newline if the last line updated is also the last line in the buffer, // and append a null terminator so that 'InsertStyledText' can determine the length. if (buf.LineCount == region.Bottom) { m_cells.Pop(1); } m_cells.Add(0, 0); // Determine the character range to be updated var beg = PositionFromLine(region.Top); var end = PositionFromLine(region.Bottom); if (beg < 0) { beg = 0; } if (end < 0) { end = TextLength; } // Overwrite the visible lines with the buffer of cells DeleteRange(beg, end - beg); InsertStyledText(beg, m_cells); // Reset, ready for next time m_cells.Length = 0; } // Auto scroll to the bottom if told to and the last line is off the bottom if (AutoScrollToBottom) { ScrollToBottom(); } }
public BufPtr(Cell[] cells, int ofs, int length) { m_scope = GCHandle_.Alloc(cells, GCHandleType.Pinned); Pointer = m_scope.Handle.AddrOfPinnedObject() + ofs * R <Cell> .SizeOf; SizeInBytes = length * R <Cell> .SizeOf; }