style(serialize-xml): Add skipValue to NativeXmlReader

This commit is contained in:
Johannes Frohnmeyer 2024-04-17 10:44:40 +02:00
parent ef874ede77
commit 6bd1bca351
Signed by: Johannes
GPG Key ID: E76429612C2929F4
1 changed files with 88 additions and 0 deletions

View File

@ -437,6 +437,62 @@ public class NativeXmlReader implements Closeable {
}
}
public void skipValue() throws IOException {
int count = 0;
do {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
switch (p) {
case PEEKED_BEGIN_TAG -> {
if (count == 0) {
pathNames[stackSize - 1] = "<skipped>";
}
push(XmlScope.TAG_HEAD);
count++;
}
case PEEKED_END_TAG, PEEKED_END_TAG_CONCISE -> {
if (count == 0) {
pathNames[stackSize - 1] = null;
}
stackSize--;
count--;
}
case PEEKED_TEXT -> skipUntil((c, i) -> c == '<');
case PEEKED_CDATA -> {
skipUntil((c, i) -> c == ']');
if (pos + 2 < limit || fillBuffer(3)) {
if (buffer[pos] == ']' && buffer[pos + 1] == ']' && buffer[pos + 2] == '>') {
pos += 3;
peeked = PEEKED_NONE;
return;
}
} else {
throw syntaxError("Unterminated CDATA");
}
}
case PEEKED_ATTRIBUTE_NAME -> {
skipUntil((c, i) -> isName(c, pos + i + 1 < limit ? buffer[pos + i + 1] : '\0') == NameCheck.NONE);
if (count == 0) pathNames[stackSize - 1] = "<skipped>";
peeked = PEEKED_NONE;
}
case PEEKED_ATTRIBUTE_VALUE -> {
char quote = buffer[pos++];
skipUntil((c, i) -> c == quote);
pos++;
peeked = PEEKED_NONE;
}
case PEEKED_EOF -> throw new IllegalStateException("Attempt to skip led outside the document");
default -> {}
}
peeked = PEEKED_NONE;
} while (count > 0);
pathIndices[stackSize - 1]++;
if (count < 0) throw new IllegalStateException("Attempt to skip led outside its parent");
}
private String nextName() throws IOException {
return readUntil((c, i) -> isName(c, pos + i + 1 < limit ? buffer[pos + i + 1] : '\0') == NameCheck.NONE, false);
}
@ -497,6 +553,38 @@ public class NativeXmlReader implements Closeable {
return result;
}
private void skipUntil(EndPredicate character) throws IOException {
int i = 0;
findEnd:
while (true) {
for (; pos + i < limit; i++) {
char c = buffer[pos + i];
if (character.test(c, i)) {
break findEnd;
} else if (c == '\n') {
lineNumber++;
lineStart = pos + i + 1;
}
}
// Attempt to load the entire name into the buffer at once.
if (i < buffer.length) {
if (fillBuffer(i + 1)) {
continue;
} else {
break;
}
}
pos += i;
i = 0;
if (!fillBuffer(1)) {
break;
}
}
pos += i;
}
/**
* Returns the next character in the stream that is neither whitespace nor a part of a comment.
* When this returns, the returned character is always at {@code buffer[pos-1]}; this means the