You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/08/19 15:37:39 UTC
[plc4x] branch develop updated: fix(asciiBox): fixed long outstanding bug which distorted boxes
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 24edb1eb4 fix(asciiBox): fixed long outstanding bug which distorted boxes
24edb1eb4 is described below
commit 24edb1eb4e6d08338058a78a650d7c5a53fa6452
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Fri Aug 19 17:37:32 2022 +0200
fix(asciiBox): fixed long outstanding bug which distorted boxes
+ As boxes are gettings repackaged the writer keeps forgetting what was a box. Therefore we keep track of used box sets. This way we can check that we don't disturb other boxes
---
plc4go/spi/utils/asciiBox.go | 90 ++++++++++++++++++++++++++++-----------
plc4go/spi/utils/asciiBox_test.go | 4 +-
plc4go/spi/utils/dumpUtils.go | 2 +-
3 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/plc4go/spi/utils/asciiBox.go b/plc4go/spi/utils/asciiBox.go
index bb03fd512..1e4918bde 100644
--- a/plc4go/spi/utils/asciiBox.go
+++ b/plc4go/spi/utils/asciiBox.go
@@ -28,8 +28,9 @@ import (
// AsciiBox is a string surrounded by an ascii border (and an optional name)
type AsciiBox struct {
- data string
- asciiBoxWriter *asciiBoxWriter
+ data string
+ asciiBoxWriter *asciiBoxWriter
+ compressedBoxSet string
}
// DebugAsciiBox set to true to get debug messages
@@ -73,14 +74,16 @@ func NewAsciiBoxWriter() AsciiBoxWriter {
func NewAsciiBoxWriterWithCustomBorders(upperLeftCorner string, upperRightCorner string, horizontalLine string, verticalLine string, lowerLeftCorner string, lowerRightCorner string) AsciiBoxWriter {
return &asciiBoxWriter{
- upperLeftCorner: upperLeftCorner,
- upperRightCorner: upperRightCorner,
- horizontalLine: horizontalLine,
- verticalLine: verticalLine,
- lowerLeftCorner: lowerLeftCorner,
- lowerRightCorner: lowerRightCorner,
- newLine: '\n',
- emptyPadding: " ",
+ boxSet: boxSet{
+ upperLeftCorner: upperLeftCorner,
+ upperRightCorner: upperRightCorner,
+ horizontalLine: horizontalLine,
+ verticalLine: verticalLine,
+ lowerLeftCorner: lowerLeftCorner,
+ lowerRightCorner: lowerRightCorner,
+ },
+ newLine: '\n',
+ emptyPadding: " ",
// the name gets prefixed with a extra symbol for indent
extraNameCharIndent: 1,
borderWidth: 1,
@@ -95,15 +98,47 @@ func NewAsciiBoxWriterWithCustomBorders(upperLeftCorner string, upperRightCorner
// Internal section
//
-type asciiBoxWriter struct {
+type boxSet struct {
upperLeftCorner string
upperRightCorner string
horizontalLine string
verticalLine string
lowerLeftCorner string
lowerRightCorner string
- newLine rune
- emptyPadding string
+}
+
+func (b boxSet) compressBoxSet() string {
+ return b.upperLeftCorner + b.upperRightCorner + b.horizontalLine + b.verticalLine + b.lowerLeftCorner + b.lowerRightCorner
+}
+
+func (b boxSet) contributeToCompressedBoxSet(box AsciiBox) string {
+ actualSet := b.compressBoxSet()
+ if strings.ContainsAny(box.compressedBoxSet, actualSet) {
+ // we have nothing to add
+ return box.compressedBoxSet
+ }
+ return box.compressedBoxSet + "," + actualSet
+}
+
+func combineCompressedBoxSets(box1, box2 AsciiBox) string {
+ allSets := make(map[string]any)
+ for _, s := range strings.Split(box1.compressedBoxSet, ",") {
+ allSets[s] = true
+ }
+ for _, s := range strings.Split(box2.compressedBoxSet, ",") {
+ allSets[s] = true
+ }
+ var foundSets []string
+ for set, _ := range allSets {
+ foundSets = append(foundSets, set)
+ }
+ return strings.Join(foundSets, ",")
+}
+
+type asciiBoxWriter struct {
+ boxSet
+ newLine rune
+ emptyPadding string
// the name gets prefixed with a extra symbol for indent
extraNameCharIndent int
borderWidth int
@@ -112,7 +147,7 @@ type asciiBoxWriter struct {
}
func (a *asciiBoxWriter) boxString(name string, data string, charWidth int) AsciiBox {
- rawBox := AsciiBox{data, a}
+ rawBox := AsciiBox{data, a, a.compressBoxSet()}
longestLine := rawBox.Width()
if charWidth < longestLine {
if DebugAsciiBox {
@@ -140,7 +175,7 @@ func (a *asciiBoxWriter) boxString(name string, data string, charWidth int) Asci
}
bottomPadding := namePadding + countChars(name) + a.extraNameCharIndent
boxedString.WriteString(a.lowerLeftCorner + strings.Repeat(a.horizontalLine, bottomPadding) + a.lowerRightCorner)
- return AsciiBox{boxedString.String(), a}
+ return AsciiBox{boxedString.String(), a, a.compressBoxSet()}
}
func (a *asciiBoxWriter) getBoxName(box AsciiBox) string {
@@ -160,13 +195,15 @@ func (a *asciiBoxWriter) changeBoxName(box AsciiBox, newName string) AsciiBox {
}
minimumWidthWithNewName := countChars(a.upperLeftCorner + a.horizontalLine + newName + a.upperRightCorner)
nameLengthDifference := minimumWidthWithNewName - (a.unwrap(box).Width() + a.borderWidth + a.borderWidth)
- return a.BoxString(newName, a.unwrap(box).String(), box.Width()+nameLengthDifference)
+ newBox := a.BoxString(newName, a.unwrap(box).String(), box.Width()+nameLengthDifference)
+ newBox.compressedBoxSet = a.contributeToCompressedBoxSet(box)
+ return newBox
}
func (a *asciiBoxWriter) mergeHorizontal(boxes []AsciiBox) AsciiBox {
switch len(boxes) {
case 0:
- return AsciiBox{"", a}
+ return AsciiBox{"", a, a.compressBoxSet()}
case 1:
return boxes[0]
case 2:
@@ -193,7 +230,7 @@ func (a *asciiBoxWriter) expandBox(box AsciiBox, desiredWidth int) AsciiBox {
newBox.WriteRune(a.newLine)
}
}
- return AsciiBox{newBox.String(), a}
+ return AsciiBox{newBox.String(), a, a.contributeToCompressedBoxSet(box)}
}
func (a *asciiBoxWriter) unwrap(box AsciiBox) AsciiBox {
@@ -202,6 +239,7 @@ func (a *asciiBoxWriter) unwrap(box AsciiBox) AsciiBox {
}
originalLines := box.Lines()
newLines := make([]string, len(originalLines)-2)
+ completeBoxSet := a.contributeToCompressedBoxSet(box)
for i, line := range originalLines {
if i == 0 {
// we ignore the first line
@@ -214,13 +252,13 @@ func (a *asciiBoxWriter) unwrap(box AsciiBox) AsciiBox {
runes := []rune(line)
// Strip the vertical Lines and trim the padding
unwrappedLine := string(runes[1 : len(runes)-1])
- if !strings.ContainsAny(unwrappedLine, a.verticalLine+a.horizontalLine) {
+ if !strings.ContainsAny(unwrappedLine, strings.ReplaceAll(completeBoxSet, ",", "")) {
// only trim boxes witch don't contain other boxes
unwrappedLine = strings.Trim(unwrappedLine, a.emptyPadding)
}
newLines[i-1] = unwrappedLine
}
- return AsciiBox{strings.Join(newLines, string(a.newLine)), a}
+ return AsciiBox{strings.Join(newLines, string(a.newLine)), a, completeBoxSet}
}
func (a *asciiBoxWriter) hasBorders(box AsciiBox) bool {
@@ -286,7 +324,9 @@ func (m AsciiBox) String() string {
// BoxBox boxes a box
func (a *asciiBoxWriter) BoxBox(name string, box AsciiBox, charWidth int) AsciiBox {
// TODO: if there is a box bigger then others in that this will get distorted
- return a.BoxString(name, box.data, charWidth)
+ newBox := a.BoxString(name, box.data, charWidth)
+ newBox.compressedBoxSet = a.contributeToCompressedBoxSet(box)
+ return newBox
}
// BoxString boxes a newline separated string into a beautiful box
@@ -297,7 +337,7 @@ func (a *asciiBoxWriter) BoxString(name string, data string, charWidth int) Asci
// AlignBoxes aligns all boxes to a desiredWidth and orders them from left to right and top to bottom (size will be at min the size of the biggest box)
func (a *asciiBoxWriter) AlignBoxes(boxes []AsciiBox, desiredWidth int) AsciiBox {
if len(boxes) == 0 {
- return AsciiBox{"", a}
+ return AsciiBox{"", a, a.compressBoxSet()}
}
actualWidth := desiredWidth
for _, box := range boxes {
@@ -312,7 +352,7 @@ func (a *asciiBoxWriter) AlignBoxes(boxes []AsciiBox, desiredWidth int) AsciiBox
if DebugAsciiBox {
log.Debug().Msgf("Working with %d chars", actualWidth)
}
- bigBox := AsciiBox{"", a}
+ bigBox := AsciiBox{"", a, a.compressBoxSet()}
currentBoxRow := make([]AsciiBox, 0)
currentRowLength := 0
for _, box := range boxes {
@@ -376,7 +416,7 @@ func (a *asciiBoxWriter) BoxSideBySide(box1, box2 AsciiBox) AsciiBox {
aggregateBox.WriteRune('\n')
}
}
- return AsciiBox{aggregateBox.String(), a}
+ return AsciiBox{aggregateBox.String(), a, combineCompressedBoxSets(box1, box2)}
}
// BoxBelowBox renders two boxes below
@@ -388,5 +428,5 @@ func (a *asciiBoxWriter) BoxBelowBox(box1, box2 AsciiBox) AsciiBox {
} else if box2Width < box1Width {
box2 = a.expandBox(box2, box1Width)
}
- return AsciiBox{box1.String() + "\n" + box2.String(), a}
+ return AsciiBox{box1.String() + "\n" + box2.String(), a, combineCompressedBoxSets(box1, box2)}
}
diff --git a/plc4go/spi/utils/asciiBox_test.go b/plc4go/spi/utils/asciiBox_test.go
index 1ea952b92..3b6cff4a2 100644
--- a/plc4go/spi/utils/asciiBox_test.go
+++ b/plc4go/spi/utils/asciiBox_test.go
@@ -871,9 +871,9 @@ func BenchmarkExpandBox(b *testing.B) {
}
func trimBox(box AsciiBox) AsciiBox {
- return AsciiBox{strings.Trim(box.String(), "\n"), AsciiBoxWriterDefault.(*asciiBoxWriter)}
+ return AsciiBox{strings.Trim(box.String(), "\n"), AsciiBoxWriterDefault.(*asciiBoxWriter), AsciiBoxWriterDefault.(*asciiBoxWriter).compressBoxSet()}
}
func asciiBox(value string) AsciiBox {
- return AsciiBox{value, AsciiBoxWriterDefault.(*asciiBoxWriter)}
+ return AsciiBox{value, AsciiBoxWriterDefault.(*asciiBoxWriter), AsciiBoxWriterDefault.(*asciiBoxWriter).compressBoxSet()}
}
diff --git a/plc4go/spi/utils/dumpUtils.go b/plc4go/spi/utils/dumpUtils.go
index 533f76de6..357242baa 100644
--- a/plc4go/spi/utils/dumpUtils.go
+++ b/plc4go/spi/utils/dumpUtils.go
@@ -85,7 +85,7 @@ func BoxAnything(name string, anything interface{}, charWidth int) AsciiBox {
hexDigits := reflect.TypeOf(anything).Bits() / 4
return AsciiBoxWriterDefault.BoxString(name, fmt.Sprintf("%#0*x %d", hexDigits, anything, anything), 0)
case []byte:
- return AsciiBox{DumpFixedWidth(anything.([]byte), charWidth), AsciiBoxWriterDefault.(*asciiBoxWriter)}
+ return AsciiBox{DumpFixedWidth(anything.([]byte), charWidth), AsciiBoxWriterDefault.(*asciiBoxWriter), AsciiBoxWriterDefault.(*asciiBoxWriter).compressBoxSet()}
case string:
return AsciiBoxWriterDefault.BoxString(name, anything.(string), charWidth)
case fmt.Stringer: