예제 #1
0
        /// <summary>
        /// Creates a <see cref="HexLinePositionInfo"/>
        /// </summary>
        /// <param name="linePosition">Line position</param>
        /// <returns></returns>
        public HexLinePositionInfo GetLinePositionInfo(int linePosition)
        {
            if (linePosition >= Text.Length)
            {
                return(HexLinePositionInfo.CreateVirtualSpace(linePosition, Text.Length));
            }

            if (IsOffsetColumnPresent)
            {
                var span = GetOffsetSpan();
                if (span.Contains(linePosition))
                {
                    return(HexLinePositionInfo.CreateOffset(linePosition, linePosition - span.Start));
                }
            }

            if (IsValuesColumnPresent)
            {
                var valuesSpan = GetValuesSpan(onlyVisibleCells: false);
                if (valuesSpan.Contains(linePosition))
                {
                    int cellIndex = (linePosition - valuesSpan.Start) / LineProvider.GetCharsPerCellIncludingSeparator(HexColumnType.Values);
                    var cell      = ValueCells[cellIndex];
                    if (cell.SeparatorSpan.Contains(linePosition))
                    {
                        return(HexLinePositionInfo.CreateValueCellSeparator(linePosition, cell));
                    }
                    return(HexLinePositionInfo.CreateValue(linePosition, cell));
                }
            }

            if (IsAsciiColumnPresent)
            {
                var asciiSpan = GetAsciiSpan(onlyVisibleCells: false);
                if (asciiSpan.Contains(linePosition))
                {
                    int cellIndex = linePosition - asciiSpan.Start;
                    var cell      = AsciiCells[cellIndex];
                    return(HexLinePositionInfo.CreateAscii(linePosition, cell));
                }
            }

            foreach (var column in ColumnOrder)
            {
                var span = GetSpan(column, onlyVisibleCells: false);
                if (span.End == linePosition)
                {
                    return(HexLinePositionInfo.CreateColumnSeparator(linePosition));
                }
            }

            throw new InvalidOperationException();
        }
예제 #2
0
        HexLinePositionInfo?GetClosestCellPosition(int linePosition)
        {
            (HexColumnType columnType, HexCell cell)? closest = null;
            int cellPosition = -1;

            foreach (var info in GetCells())
            {
                var cell = info.cell;
                if (closest == null || Compare(linePosition, cell, closest.Value.cell) < 0)
                {
                    closest      = info;
                    cellPosition = linePosition - info.cell.CellSpan.Start;
                    if (cellPosition < 0)
                    {
                        cellPosition = 0;
                    }
                    else if (cellPosition >= info.cell.CellSpan.Length)
                    {
                        cellPosition = info.cell.CellSpan.Length - 1;
                    }
                }
            }
            if (closest == null)
            {
                return(null);
            }
            if (cellPosition < 0 || cellPosition >= closest.Value.cell.CellSpan.Length)
            {
                throw new InvalidOperationException();
            }
            int pos = closest.Value.cell.CellSpan.Start + cellPosition;

            if (closest.Value.columnType == HexColumnType.Values)
            {
                return(HexLinePositionInfo.CreateValue(pos, closest.Value.cell));
            }
            if (closest.Value.columnType == HexColumnType.Ascii)
            {
                return(HexLinePositionInfo.CreateAscii(pos, closest.Value.cell));
            }
            throw new InvalidOperationException();
        }
예제 #3
0
        /// <summary>
        /// Gets the closest cell position
        /// </summary>
        /// <param name="position">Position</param>
        /// <param name="onlyVisibleCells">true to only return cells with data</param>
        /// <returns></returns>
        public HexCellPosition?GetClosestCellPosition(HexLinePositionInfo position, bool onlyVisibleCells)
        {
            switch (position.Type)
            {
            case HexLinePositionInfoType.ValueCell:
            case HexLinePositionInfoType.AsciiCell:
                break;

            case HexLinePositionInfoType.ValueCellSeparator:
                Debug.Assert(position.Cell.CellSpan.End == position.Position);
                position = HexLinePositionInfo.CreateValue(position.Cell.CellSpan.End - 1, position.Cell);
                break;

            case HexLinePositionInfoType.Offset:
            case HexLinePositionInfoType.ColumnSeparator:
            case HexLinePositionInfoType.VirtualSpace:
                var closestPos = GetClosestCellPosition(position.Position);
                if (closestPos == null)
                {
                    return(null);
                }
                Debug.Assert(closestPos.Value.IsAsciiCell || closestPos.Value.IsValueCell);
                position = closestPos.Value;
                break;

            default:
                throw new InvalidOperationException();
            }

            var cell         = position.Cell;
            int cellPosition = position.CellPosition;

            switch (position.Type)
            {
            case HexLinePositionInfoType.AsciiCell:
                if (!IsAsciiColumnPresent)
                {
                    return(null);
                }
                if (onlyVisibleCells && !cell.HasData)
                {
                    var visible = GetVisible(AsciiCells, cell);
                    if (visible == null)
                    {
                        return(null);
                    }
                    cell         = visible.Value.cell;
                    cellPosition = visible.Value.cellPosition;
                }
                return(new HexCellPosition(HexColumnType.Ascii, cell.BufferStart, cellPosition));

            case HexLinePositionInfoType.ValueCell:
                if (!IsValuesColumnPresent)
                {
                    return(null);
                }
                if (onlyVisibleCells && !cell.HasData)
                {
                    var visible = GetVisible(ValueCells, cell);
                    if (visible == null)
                    {
                        return(null);
                    }
                    cell         = visible.Value.cell;
                    cellPosition = visible.Value.cellPosition;
                }
                return(new HexCellPosition(HexColumnType.Values, LineProvider.GetValueBufferSpan(cell, cellPosition).Start, cellPosition));

            case HexLinePositionInfoType.Offset:
            case HexLinePositionInfoType.ValueCellSeparator:
            case HexLinePositionInfoType.ColumnSeparator:
            case HexLinePositionInfoType.VirtualSpace:
            default:
                throw new InvalidOperationException();
            }
        }
예제 #4
0
		/// <summary>
		/// Gets the closest cell position
		/// </summary>
		/// <param name="position">Position</param>
		/// <param name="onlyVisibleCells">true to only return cells with data</param>
		/// <returns></returns>
		public HexCellPosition? GetClosestCellPosition(HexLinePositionInfo position, bool onlyVisibleCells) {
			switch (position.Type) {
			case HexLinePositionInfoType.ValueCell:
			case HexLinePositionInfoType.AsciiCell:
				break;

			case HexLinePositionInfoType.ValueCellSeparator:
				Debug.Assert(position.Cell.CellSpan.End == position.Position);
				position = HexLinePositionInfo.CreateValue(position.Cell.CellSpan.End - 1, position.Cell);
				break;

			case HexLinePositionInfoType.Offset:
			case HexLinePositionInfoType.ColumnSeparator:
			case HexLinePositionInfoType.VirtualSpace:
				var closestPos = GetClosestCellPosition(position.Position);
				if (closestPos == null)
					return null;
				Debug.Assert(closestPos.Value.IsAsciiCell || closestPos.Value.IsValueCell);
				position = closestPos.Value;
				break;

			default:
				throw new InvalidOperationException();
			}

			var cell = position.Cell;
			int cellPosition = position.CellPosition;
			switch (position.Type) {
			case HexLinePositionInfoType.AsciiCell:
				if (!IsAsciiColumnPresent)
					return null;
				if (onlyVisibleCells && !cell.HasData) {
					var visible = GetVisible(AsciiCells, cell);
					if (visible == null)
						return null;
					cell = visible.Value.Key;
					cellPosition = visible.Value.Value;
				}
				return new HexCellPosition(HexColumnType.Ascii, cell.BufferStart, cellPosition);

			case HexLinePositionInfoType.ValueCell:
				if (!IsValuesColumnPresent)
					return null;
				if (onlyVisibleCells && !cell.HasData) {
					var visible = GetVisible(ValueCells, cell);
					if (visible == null)
						return null;
					cell = visible.Value.Key;
					cellPosition = visible.Value.Value;
				}
				return new HexCellPosition(HexColumnType.Values, LineProvider.GetValueBufferSpan(cell, cellPosition).Start, cellPosition);

			case HexLinePositionInfoType.Offset:
			case HexLinePositionInfoType.ValueCellSeparator:
			case HexLinePositionInfoType.ColumnSeparator:
			case HexLinePositionInfoType.VirtualSpace:
			default:
				throw new InvalidOperationException();
			}
		}