Adjust clearing

This commit is contained in:
2026-08-31 00:00:13 +00:00
parent 27976dd31f
commit e18d2f436f
2 changed files with 28 additions and 98 deletions
@@ -63,9 +63,6 @@ public class GocaDecoder {
// Segment Store for retained graphics / segment calling (G_GCALL 0x2A)
private final java.util.Map<Integer, byte[]> segmentStore = new java.util.HashMap<>();
private final java.util.Map<Integer, Integer> segmentChainMap = new java.util.HashMap<>();
private final java.util.List<Integer> segmentOrderList = new java.util.ArrayList<>();
private final java.util.Set<Integer> chainedTargets = new java.util.HashSet<>();
private int callDepth = 0;
/**
@@ -208,9 +205,6 @@ public class GocaDecoder {
graphicCursorX = 0;
graphicCursorY = 0;
segmentStore.clear();
segmentChainMap.clear();
segmentOrderList.clear();
chainedTargets.clear();
segmentBoundsMap.clear();
activeSegmentsInOrder.clear();
currentSegId = 0;
@@ -294,61 +288,6 @@ public class GocaDecoder {
return (data[idx + 1] & 0xFF) + 2;
}
private void indexSegments(byte[] data, int offset, int length) {
int idx = offset;
int end = offset + length;
while (idx < end) {
int order = data[idx] & 0xFF;
if (order == GocaConstants.G_BEGSEGM) {
int segStart = idx;
int segLen = getOrderLength(data, idx, end);
if (segLen <= 0 || idx + 5 >= end) {
break;
}
int segId = ((data[idx + 2] & 0xFF) << 24) |
((data[idx + 3] & 0xFF) << 16) |
((data[idx + 4] & 0xFF) << 8) |
(data[idx + 5] & 0xFF);
int nextId = 0;
if (segLen >= 14 && (data[idx + 1] & 0xFF) >= 12) {
nextId = ((data[idx + 10] & 0xFF) << 24) |
((data[idx + 11] & 0xFF) << 16) |
((data[idx + 12] & 0xFF) << 8) |
(data[idx + 13] & 0xFF);
}
int searchIdx = idx + segLen;
while (searchIdx < end) {
int o = data[searchIdx] & 0xFF;
int oLen = getOrderLength(data, searchIdx, end);
if (oLen <= 0) break;
if (o == GocaConstants.G_ENDSEGM) {
searchIdx += oLen;
break;
}
searchIdx += oLen;
}
int fullSegLen = searchIdx - segStart;
if (fullSegLen > 0 && segStart + fullSegLen <= end) {
byte[] segBytes = new byte[fullSegLen];
System.arraycopy(data, segStart, segBytes, 0, fullSegLen);
segmentStore.put(segId, segBytes);
segmentOrderList.add(segId);
if (nextId != 0) {
segmentChainMap.put(segId, nextId);
chainedTargets.add(nextId);
}
}
idx = searchIdx;
} else {
int oLen = getOrderLength(data, idx, end);
if (oLen <= 0) break;
idx += oLen;
}
}
}
/**
* Decodes a stream of GOCA drawing orders (matching IBM Host On-Demand HODDecoder.decodeGOCA).
*/
@@ -386,7 +325,7 @@ public class GocaDecoder {
}
/**
* Executes a stored procedure segment by segment ID, traversing chained next segments.
* Executes a stored procedure segment by segment ID.
*/
public synchronized void procedureSegment(int segId) {
if (segId == 0) return;
@@ -401,12 +340,6 @@ public class GocaDecoder {
decodeStreamDirect(segData, 0, segData.length);
callDepth--;
currentSegId = savedSeg;
// Execute chained segments
Integer nextId = segmentChainMap.get(segId);
if (nextId != null && nextId != 0 && callDepth < 16) {
procedureSegment(nextId);
}
} else {
logger.warning("procedureSegment: Segment not found in store: " + segId);
}
@@ -444,10 +377,6 @@ public class GocaDecoder {
end = offset + length;
}
if (callDepth == 0) {
indexSegments(inputData, idx, end - idx);
}
decodeStreamDirect(inputData, idx, end - idx);
}
@@ -495,6 +424,27 @@ public class GocaDecoder {
SegmentBounds sb = segmentBoundsMap.computeIfAbsent(segId, SegmentBounds::new);
activeSegmentsInOrder.remove(sb);
activeSegmentsInOrder.add(sb);
if (segId != 0 && callDepth == 0) {
int segStart = idx;
int searchIdx = idx + orderLen;
while (searchIdx < end) {
int o = inputData[searchIdx] & 0xFF;
int oLen = getOrderLength(inputData, searchIdx, end);
if (oLen <= 0) break;
if (o == GocaConstants.G_ENDSEGM) {
searchIdx += oLen;
break;
}
searchIdx += oLen;
}
int fullSegLen = searchIdx - segStart;
if (fullSegLen > 0 && segStart + fullSegLen <= end) {
byte[] segBytes = new byte[fullSegLen];
System.arraycopy(inputData, segStart, segBytes, 0, fullSegLen);
segmentStore.put(segId, segBytes);
}
}
}
if (idx + 6 < end) flag0 = inputData[idx + 6] & 0xFF;
if (idx + 7 < end) flag1 = inputData[idx + 7] & 0xFF;
@@ -507,7 +457,6 @@ public class GocaDecoder {
}
case GocaConstants.G_ENDSEGM: { // End Segment (0x71)
logger.info(String.format("GOCA ENDSEGM: segId=%d", currentSegId));
int finishedSegId = currentSegId;
if (currentSegId != 0) {
SegmentBounds sb = segmentBoundsMap.get(currentSegId);
if (sb != null) {
@@ -519,23 +468,6 @@ public class GocaDecoder {
}
currentSegId = 0;
idx += orderLen;
if (finishedSegId != 0 && callDepth < 16) {
Integer nextId = segmentChainMap.get(finishedSegId);
if (nextId != null && nextId != 0) {
byte[] nextSeg = segmentStore.get(nextId);
if (nextSeg != null) {
logger.info("Executing chained segment nextId=" + nextId);
currentSegId = nextId;
SegmentBounds targetSb = segmentBoundsMap.computeIfAbsent(nextId, SegmentBounds::new);
activeSegmentsInOrder.remove(targetSb);
activeSegmentsInOrder.add(targetSb);
callDepth++;
decodeStreamDirect(nextSeg, 0, nextSeg.length);
callDepth--;
currentSegId = 0;
}
}
}
break;
}
@@ -901,8 +833,6 @@ public class GocaDecoder {
activeSegmentsInOrder.clear();
segmentBoundsMap.clear();
segmentStore.clear();
segmentOrderList.clear();
chainedTargets.clear();
logger.info("GOCA P_ERASE: erased graphics presentation space and cleared segment stores");
idx += 2;
break;