feat[js]: javascript support compatible field

This commit is contained in:
sun
2023-09-27 17:50:14 +08:00
parent 0547c0d727
commit 3dc261eac8
3 changed files with 70 additions and 4 deletions
@@ -152,11 +152,20 @@ public abstract class GenerateJsUtils {
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var jsBuilder = new StringBuilder();
if (registration.isCompatible()) {
jsBuilder.append("const beforeWriteIndex = buffer.getWriteOffset();").append(LS);
jsBuilder.append(TAB).append(StringUtils.format("buffer.writeInt({});", registration.getPredictionLength())).append(LS);
} else {
jsBuilder.append(TAB).append("buffer.writeInt(-1);").append(LS);
}
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
jsSerializer(fieldRegistration.serializer()).writeObject(jsBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
}
if (registration.isCompatible()) {
jsBuilder.append(TAB).append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex);", registration.getPredictionLength())).append(LS);
}
return jsBuilder.toString();
}
@@ -168,9 +177,11 @@ public abstract class GenerateJsUtils {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
if (field.isAnnotationPresent(Compatible.class)) {
jsBuilder.append(TAB).append("if (!buffer.isReadable()) {").append(LS);
jsBuilder.append(TAB + TAB).append("return packet;").append(LS);
jsBuilder.append(TAB).append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS);
var compatibleReadObject = jsSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 2, field, fieldRegistration);
jsBuilder.append(TAB+ TAB).append(StringUtils.format("packet.{} = {};", field.getName(), compatibleReadObject)).append(LS);
jsBuilder.append(TAB).append("}").append(LS);
continue;
}
var readObject = jsSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 1, field, fieldRegistration);
jsBuilder.append(TAB).append(StringUtils.format("packet.{} = {};", field.getName(), readObject)).append(LS);
@@ -8,18 +8,24 @@ const {} = function({}) {
};
{}.write = function(buffer, packet) {
if (buffer.writePacketFlag(packet)) {
if (packet === null) {
buffer.writeInt(0);
return;
}
{}
};
{}.read = function(buffer) {
if (!buffer.readBoolean()) {
const length = buffer.readInt();
if (length === 0) {
return null;
}
const beforeReadIndex = buffer.getReadOffset();
const packet = new {}();
{}
if (length > 0) {
buffer.setReadOffset(beforeReadIndex + length);
}
return packet;
};
@@ -49,6 +49,32 @@ const ByteBuffer = function() {
this.buffer = new ArrayBuffer(initSize);
this.bufferView = new DataView(this.buffer, 0, this.buffer.byteLength);
this.adjustPadding = function(predictionLength, beforeWriteIndex) {
const currentWriteIndex = this.writeOffset;
const predictionCount = this.writeIntCount(predictionLength);
const length = currentWriteIndex - beforeWriteIndex - predictionCount;
const lengthCount = this.writeIntCount(length);
const padding = lengthCount - predictionCount;
if (padding === 0) {
this.setWriteOffset(beforeWriteIndex);
this.writeInt(length);
this.setWriteOffset(currentWriteIndex);
} else {
const retainedByteBuf = this.buffer.slice(currentWriteIndex - length, currentWriteIndex);
this.setWriteOffset(beforeWriteIndex);
this.writeInt(length);
this.writeBytes(retainedByteBuf);
}
}
this.compatibleRead = function(beforeReadIndex, length) {
return length !== -1 && this.getReadOffset() < length + beforeReadIndex;
}
this.getWriteOffset = function() {
return this.writeOffset;
}
this.setWriteOffset = function(writeOffset) {
if (writeOffset > this.buffer.byteLength) {
throw new Error('index out of bounds exception: readerIndex: ' + this.readOffset +
@@ -58,6 +84,10 @@ const ByteBuffer = function() {
this.writeOffset = writeOffset;
};
this.getReadOffset = function() {
return this.readOffset;
}
this.setReadOffset = function(readOffset) {
if (readOffset > this.writeOffset) {
throw new Error('index out of bounds exception: readerIndex: ' + this.readOffset +
@@ -201,6 +231,25 @@ const ByteBuffer = function() {
this.writeByte(value >>> 28);
};
this.writeIntCount = function(value) {
if (!(minInt <= value && value <= maxInt)) {
throw new Error('value must range between minInt:-2147483648 and maxInt:2147483647');
}
if (value >>> 7 === 0) {
return 1;
}
if (value >>> 14 === 0) {
return 2;
}
if (value >>> 21 === 0) {
return 3;
}
if (value >>> 28 === 0) {
return 4;
}
return 5;
}
this.readInt = function() {
let b = this.readByte();
let value = b & 0x7F;