aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/PositionCache.cxx
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2007-10-10 11:30:14 +0000
committernyamatongwe <devnull@localhost>2007-10-10 11:30:14 +0000
commitf8453890acd38f68249965fe05a4392b69b986e5 (patch)
treefdbdb1340f059a882a4bdf3b0f734b8b72793ebb /src/PositionCache.cxx
parenta71097b447b0391764c104f60d2bf52782e3ada7 (diff)
downloadscintilla-mirror-f8453890acd38f68249965fe05a4392b69b986e5.tar.gz
Detect and handle invalid byte sequences in UTF-8 mode by displaying each
individual invalid byte as a hex blob.
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r--src/PositionCache.cxx47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index 1763b6530..f40a15378 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -345,12 +345,23 @@ void LineLayoutCache::Dispose(LineLayout *ll) {
}
void BreakFinder::Insert(int val) {
+ // Expand if needed
+ if (saeLen >= saeSize) {
+ saeSize *= 2;
+ int *selAndEdgeNew = new int[saeSize];
+ for (unsigned int j = 0; j<saeLen; j++) {
+ selAndEdgeNew[j] = selAndEdge[j];
+ }
+ delete []selAndEdge;
+ selAndEdge = selAndEdgeNew;
+ }
+
if (val >= nextBreak) {
for (unsigned int j = 0; j<saeLen; j++) {
if (val == selAndEdge[j]) {
return;
} if (val < selAndEdge[j]) {
- for (unsigned int k = saeLen; j>k; k--) {
+ for (unsigned int k = saeLen; k>j; k--) {
selAndEdge[k] = selAndEdge[k-1];
}
saeLen++;
@@ -363,17 +374,32 @@ void BreakFinder::Insert(int val) {
}
}
-BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, int xStart) :
+extern bool BadUTF(const char *s, int len, int &trailBytes);
+
+static int NextBadU(const char *s, int p, int len, int &trailBytes) {
+ while (p < len) {
+ p++;
+ if (BadUTF(s + p, len - p, trailBytes))
+ return p;
+ }
+ return -1;
+}
+
+BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
+ utf8(utf8_),
nextBreak(lineStart_),
+ saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
subBreak(-1) {
- for (unsigned int j=0; j < sizeof(selAndEdge) / sizeof(selAndEdge[0]); j++) {
+ saeSize = 8;
+ selAndEdge = new int[saeSize];
+ for (unsigned int j=0; j < saeSize; j++) {
selAndEdge[j] = 0;
}
@@ -392,9 +418,24 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
+
+ if (utf8) {
+ int trailBytes=0;
+ for (int pos = -1;;) {
+ pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
+ if (pos < 0)
+ break;
+ Insert(pos-1);
+ Insert(pos);
+ }
+ }
saeNext = (saeLen > 0) ? selAndEdge[0] : -1;
}
+BreakFinder::~BreakFinder() {
+ delete []selAndEdge;
+}
+
int BreakFinder::First() {
return nextBreak;
}