This is an automated email from the ASF dual-hosted git repository.
davin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git
The following commit(s) were added to refs/heads/main by this push:
new b807720 Implemented Relative Seek Offset Traversal
b807720 is described below
commit b807720b89abf737afeb67e4f366ba5184761cb9
Author: Robert Strickland <[email protected]>
AuthorDate: Thu Aug 31 09:06:45 2023 -1000
Implemented Relative Seek Offset Traversal
- Added Relative and Absolute seek offset determination and traversal.
Closes #799
---
.../DataDisplays/Header/DisplayHeader.svelte | 19 +++++-
src/svelte/src/components/Error/Error.svelte | 7 ++-
.../Header/fieldsets/SearchReplace.svelte | 17 +++++-
.../components/Header/fieldsets/SearchReplace.ts | 7 +++
src/svelte/src/components/dataEditor.svelte | 4 --
src/svelte/src/stores/index.ts | 67 +++++++++++++++++++---
6 files changed, 102 insertions(+), 19 deletions(-)
diff --git a/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte
b/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte
index 055cb2d..ce26a4b 100644
--- a/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte
+++ b/src/svelte/src/components/DataDisplays/Header/DisplayHeader.svelte
@@ -22,6 +22,7 @@ limitations under the License.
seekOffset,
seekOffsetInput,
selectionDataStore,
+ seekOffsetSearchType,
selectionSize,
bytesPerRow,
viewport,
@@ -35,6 +36,7 @@ limitations under the License.
} from '../../../stores/configuration'
import { UIThemeCSSClass } from '../../../utilities/colorScheme'
import { createEventDispatcher } from 'svelte'
+ import { OffsetSearchType } from '../../Header/fieldsets/SearchReplace'
type ViewportDivSpread = '24px' | '28px' | '68px'
@@ -103,9 +105,20 @@ limitations under the License.
function updateAddressValue(event: Event) {
const addrSelect = event.target as HTMLSelectElement
- const newSeekInput = $seekOffset.toString(parseInt(addrSelect.value))
- $seekOffsetInput = newSeekInput === 'NaN' ? '0' : newSeekInput
- $addressRadix = parseInt(addrSelect.value) as RadixValues
+ const newAddrRadix = parseInt(addrSelect.value) as RadixValues
+
+ if ($seekOffsetSearchType === OffsetSearchType.RELATIVE) {
+ const sign = $seekOffsetInput.substring(0, 1)
+ const value = parseInt(
+ $seekOffsetInput.substring(1),
+ $addressRadix
+ ).toString(newAddrRadix)
+ $seekOffsetInput = value === 'NaN' ? '0' : sign + value
+ } else {
+ const newSeekInput = $seekOffset.toString(parseInt(addrSelect.value))
+ $seekOffsetInput = newSeekInput === 'NaN' ? '0' : newSeekInput
+ }
+ $addressRadix = newAddrRadix
}
function clearDataDisplays() {
diff --git a/src/svelte/src/components/Error/Error.svelte
b/src/svelte/src/components/Error/Error.svelte
index 7e672b7..86e170c 100644
--- a/src/svelte/src/components/Error/Error.svelte
+++ b/src/svelte/src/components/Error/Error.svelte
@@ -15,15 +15,18 @@ See the License for the specific language governing
permissions and
limitations under the License.
-->
<script lang="ts">
+ import Tooltip from '../layouts/Tooltip.svelte'
import type { ErrorStore } from './Error'
export let err: ErrorStore
export let display: boolean
</script>
-<div class="display" title={$err}>
+<div class="display">
{#if display}
- {@html err.innerHTML()}
+ <Tooltip alwaysEnabled={true} description={$err}>
+ {@html err.innerHTML()}
+ </Tooltip>
{/if}
</div>
diff --git a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
index 0ba4114..12c8c90 100644
--- a/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
+++ b/src/svelte/src/components/Header/fieldsets/SearchReplace.svelte
@@ -29,7 +29,8 @@ limitations under the License.
searchErr,
searchQuery,
seekErr,
- dataFeedAwaitRefresh,
+ seekOffsetSearchType,
+ seekOffset,
} from '../../../stores'
import { vscode } from '../../../utilities/vscode'
import { MessageCommand } from '../../../utilities/message'
@@ -47,6 +48,8 @@ limitations under the License.
} from '../../../utilities/highlights'
import { viewport } from '../../../stores'
import { EditActionRestrictions } from '../../../stores/configuration'
+ import { OffsetSearchType } from './SearchReplace'
+ import Tooltip from '../../layouts/Tooltip.svelte'
const eventDispatcher = createEventDispatcher()
@@ -281,7 +284,17 @@ limitations under the License.
allowDefaultInput="true"
bind:value={$seekOffsetInput}
on:inputEnter={handleInputEnter}
- />
+ >
+ {#if $seekOffsetSearchType === OffsetSearchType.RELATIVE}
+ <Tooltip
+ alwaysEnabled={true}
+ description={'Offset input is relative to current offset: ' +
+ $seekOffset.toString($addressRadix)}
+ >
+ <span class="btn-icon material-symbols-outlined">my_location</span>
+ </Tooltip>
+ {/if}
+ </Input>
<Error
err={seekErr}
display={$seekOffsetInput.length > 0 && !$seekable.valid}
diff --git a/src/svelte/src/components/Header/fieldsets/SearchReplace.ts
b/src/svelte/src/components/Header/fieldsets/SearchReplace.ts
index 089ec07..e1f739b 100644
--- a/src/svelte/src/components/Header/fieldsets/SearchReplace.ts
+++ b/src/svelte/src/components/Header/fieldsets/SearchReplace.ts
@@ -19,6 +19,13 @@ import { SimpleWritable } from '../../../stores/localStore'
import { addressRadix, seekOffsetInput } from '../../../stores'
import { get } from 'svelte/store'
+export enum OffsetSearchType {
+ ABSOLUTE,
+ RELATIVE,
+}
+
+export type RelativeSeekSign = '+' | '-'
+
interface QueryableData {
input: string
processing: boolean
diff --git a/src/svelte/src/components/dataEditor.svelte
b/src/svelte/src/components/dataEditor.svelte
index 5ed6520..c4984bf 100644
--- a/src/svelte/src/components/dataEditor.svelte
+++ b/src/svelte/src/components/dataEditor.svelte
@@ -112,10 +112,6 @@ limitations under the License.
return boundaryTripped
}
- function target_offset_in_viewport(offset: number): boolean {
- return offset >= $viewport.fileOffset && offset <= $viewport.length
- }
-
function seek(offsetArg?: number) {
if (!offsetArg) offsetArg = $seekOffset
diff --git a/src/svelte/src/stores/index.ts b/src/svelte/src/stores/index.ts
index 185cba1..5c7eaee 100644
--- a/src/svelte/src/stores/index.ts
+++ b/src/svelte/src/stores/index.ts
@@ -22,6 +22,7 @@ import { derived, writable } from 'svelte/store'
import { SimpleWritable } from './localStore'
import { ErrorComponentType, ErrorStore } from '../components/Error/Error'
import {
+ line_num_to_file_offset,
radixBytePad,
regexEditDataTest,
validateEncodingStr,
@@ -32,6 +33,7 @@ import {
type ByteValue,
} from '../components/DataDisplays/CustomByteDisplay/BinaryData'
import {
+ OffsetSearchType,
ReplaceQuery,
SearchQuery,
} from '../components/Header/fieldsets/SearchReplace'
@@ -150,6 +152,18 @@ export const regularSizedFile = derived(fileMetrics,
($fileMetrics) => {
return $fileMetrics.computedSize >= 2
})
+export const dataFeedLineTopOffset = derived(
+ [dataFeedLineTop, viewport, bytesPerRow],
+ ([$dataFeedLineTop, $viewport, $bytesPerRow]) => {
+ const offset = line_num_to_file_offset(
+ $dataFeedLineTop,
+ $viewport.fileOffset,
+ $bytesPerRow
+ )
+ return Math.min(Math.max(0, offset), viewport.offsetMax)
+ }
+)
+
export const searchable = derived(
[searchQuery, editorEncoding],
([$searchQuery, $editorEncoding]) => {
@@ -218,14 +232,38 @@ export const selectionSize = derived(
}
)
+// How to handle the offset given in the input field for seek
+export const seekOffsetSearchType = derived(
+ seekOffsetInput,
+ ($seekOffsetInput) => {
+ const sign = $seekOffsetInput.substring(0, 1)
+ return sign === '+' || sign === '-'
+ ? OffsetSearchType.RELATIVE
+ : OffsetSearchType.ABSOLUTE
+ },
+ OffsetSearchType.ABSOLUTE
+)
+
// derived from the seek offset input and the current address radix
export const seekOffset = derived(
- [seekOffsetInput, addressRadix],
- ([$seekOffsetInput, $addressRadix]) => {
- return $seekOffsetInput.length > 0
- ? Math.max(0, parseInt($seekOffsetInput, $addressRadix))
- : 0
- }
+ [seekOffsetInput, seekOffsetSearchType, dataFeedLineTopOffset, addressRadix],
+ ([
+ $seekOffsetInput,
+ $seekOffsetSearchType,
+ $dataFeedLineTopOffset,
+ $addressRadix,
+ ]) => {
+ if ($seekOffsetSearchType === OffsetSearchType.ABSOLUTE) {
+ return $seekOffsetInput.length > 0
+ ? Math.max(0, parseInt($seekOffsetInput, $addressRadix))
+ : 0
+ } else
+ return (
+ Math.max(0, $dataFeedLineTopOffset) +
+ parseInt($seekOffsetInput, $addressRadix)
+ )
+ },
+ 0
)
// derived readable string whose value is the selected encoded byte value with
respect to the current focused viewport
@@ -371,11 +409,24 @@ export const applicable = derived(
// derived readable boolean that indicates if the seek offset input is valid
export const seekable = derived(
- [seekOffset, seekOffsetInput, viewport, addressRadix],
- ([$seekOffset, $seekOffsetInput, $viewport, $addressRadix]) => {
+ [seekOffset, seekOffsetInput, seekOffsetSearchType, viewport, addressRadix],
+ ([
+ $seekOffset,
+ $seekOffsetInput,
+ $seekOffsetSearchType,
+ $viewport,
+ $addressRadix,
+ ]) => {
+ $seekOffsetInput =
+ $seekOffsetSearchType === OffsetSearchType.RELATIVE
+ ? $seekOffsetInput.substring(1)
+ : $seekOffsetInput
+
if ($seekOffsetInput.length <= 0) return { valid: false, seekErrMsg: '' }
if ($seekOffset > viewport.offsetMax)
return { valid: false, seekErrMsg: 'Exceeds filesize' }
+ if ($seekOffset < 0)
+ return { valid: false, seekErrMsg: 'Target offset < 0' }
if (!regexEditDataTest($seekOffsetInput, $addressRadix))
return { valid: false, seekErrMsg: 'Invalid characters' }
return { valid: true, seekErrMsg: '' }