From 9ce8ca2e3a7ac0bb87f4447811b77d43a42d8d77 Mon Sep 17 00:00:00 2001 From: Jeff Greene Date: Tue, 29 Oct 2019 13:25:46 -0700 Subject: [PATCH 1/2] convert json-rpc serialization to use System.Text.Json --- TraditionalBridge/DataObjectBase.dbl | 26 +- TraditionalBridge/RoutineDispatcher.dbl | 304 +------- TraditionalBridge/Serializer.V11.dbl | 756 ++++++++++++++++++++ TraditionalBridge/Serializer.dbl | 207 +++++- TraditionalBridge/TraditionalBridge.synproj | 3 + 5 files changed, 1000 insertions(+), 296 deletions(-) create mode 100644 TraditionalBridge/Serializer.V11.dbl diff --git a/TraditionalBridge/DataObjectBase.dbl b/TraditionalBridge/DataObjectBase.dbl index ad164f45..10ef09fb 100644 --- a/TraditionalBridge/DataObjectBase.dbl +++ b/TraditionalBridge/DataObjectBase.dbl @@ -254,30 +254,12 @@ namespace Harmony.TraditionalBridge ;;override this in a dataobjectbase where we have to deal with binary data being sent from a big endian to a little endian system public virtual method Serialize, void serializer, @JsonSerializer - ;;TODO maybe add serializer options here? + optional name, @string proc - DataObjectBase.Serialize(serializer, SynergyRecord, Metadata.RPSStructureName, mGlobalRFA, Metadata.RPSStructureHasBinaryData) - endmethod - - public static method Serialize, void - serializer, @JsonSerializer - dataValue, a - dataType, a - grfa, a - dataNeedsEncoding, boolean - proc - serializer.MapOpen() - serializer.Pair("Type", dataType) - if(!dataNeedsEncoding) then - begin - serializer.Pair("Value", dataValue) - end + if(^passed(name)) then + serializer.ObjectData(SynergyRecord, Metadata.RPSStructureName, mGlobalRFA, Metadata.RPSStructureHasBinaryData, name) else - begin - serializer.Pair("Base64Value", Convert.ToBase64String(dataValue)) - end - serializer.Pair("GRFA", grfa) - serializer.MapClose() + serializer.ObjectData(SynergyRecord, Metadata.RPSStructureName, mGlobalRFA, Metadata.RPSStructureHasBinaryData, ^null) endmethod public abstract property Metadata, @DataObjectMetadataBase diff --git a/TraditionalBridge/RoutineDispatcher.dbl b/TraditionalBridge/RoutineDispatcher.dbl index cdb41320..537d036e 100644 --- a/TraditionalBridge/RoutineDispatcher.dbl +++ b/TraditionalBridge/RoutineDispatcher.dbl @@ -601,59 +601,6 @@ namespace Harmony.TraditionalBridge mreturn result endmethod - ;;; - ;;; - ;;; - ;;; - ;;; - public virtual method SerializeObject, void - obj, @DataObjectBase - serializer, @DispatchSerializer - proc - obj.Serialize(serializer) - endmethod - - ;;Protocol note: its not entirely decided how explicit we need to be about types for things - ;;most things in synergy dont jump from one primative type to another - ;;its possible for this to happen with an arraylist but this might be an acceptable tradoff for the significant protocol efficiancy gains - ;;in only specifying the element type once - - ;;; - ;;; - ;;; - ;;; - ;;; - public virtual method SerializeObjectCollection, void - obj, @ArrayList - serializer, @DispatchSerializer - record - doElement, @DataObjectBase - primativeElement, @object - endrecord - proc - ;;determine the collection type from the first element type then serialize assuming we dont switch between primatives and objects - serializer.ArrayOpen() - if(obj.Count > 0) - begin - if(obj[0] .is. @DataObjectBase) then - begin - foreach doElement in obj - begin - doElement.Serialize(serializer) - end - end - else - begin - ;;this should encode something like this - ;;serializer.String("ElementSize") - ;;serializer.Int(^size(unboxedElement)) - ;;get the unboxed type and put that in as serializer.String("ElementType") - throw new Exception("primative arrays not yet supported") - end - end - serializer.ArrayClose() - endmethod - ;;; ;;; ;;; @@ -756,27 +703,6 @@ namespace Harmony.TraditionalBridge end endmethod - ;;; - ;;; - ;;; - ;;; - ;;; - public method SerializeObject, void - obj, @object - serializer, @DispatchSerializer - proc - if(obj .is. @DataObjectBase) then - SerializeObject((@DataObjectBase)obj, serializer) - else if(obj .is. @ArrayList) then - SerializeObjectCollection((@ArrayList)obj, serializer) - else if(obj .is. @a || obj .is. @d || obj .is. @id || obj .is. @string) then - serializer.String(obj.ToString()) - else if(obj .is. @i) then - serializer.Integer((i)obj) - else - throw new Exception("Attempted to serialize an unknown object type") - endmethod - ;;; ;;; ;;; @@ -927,7 +853,7 @@ namespace Harmony.TraditionalBridge parsedJson = jsonReader.ParseJson(innerString.Substring(0, readerPosition - 1)) if (!(parsedJson .is. @JsonObject) && !(parsedJson .is. @JsonArray)) begin - ReportError("failed to parse json request", (int)-32700, (int)-1, serializer) + serializer.ReportError("failed to parse json request", (int)-32700, (int)-1) mreturn true end @@ -958,168 +884,17 @@ namespace Harmony.TraditionalBridge end else begin - ReportError("failed to parse json request", (int)-32700, (int)-1, serializer) + serializer.ReportError("failed to parse json request", (int)-32700, (int)-1) end - end + end serializer.ArrayClose() - end + end + serializer.Flush() flush(ttChannel) mreturn result endmethod - public method ReportError, void - errorText, @string - errorCode, int - messageId, int - serializer, @DispatchSerializer - record - scopeLog, @ArrayList - loggerSettings, @LoggerScopeSettings - proc - serializer.OutputScopeAbort() - - if(messageId != -1) then - begin - serializer.MapOpen() - serializer.Pair("jsonrpc", "2.0") - serializer.String("error") - serializer.MapOpen() - serializer.Pair("code", errorCode) - - serializer.Pair("message", Convert.ToBase64String(errorText)) - - ;;if scope logging is active return everything that was logged as part of this request scope - if(Logger.Instance.ShouldAttachLogsToExceptions) - begin - scopeLog = Logger.Instance.CurrentScopeLog() - if(scopeLog != ^null && scopeLog.Count > 0) - begin - - data logEntry, @string - MaybeLog(2, "Dispatcher: attaching in memory logs to thrown exception") - - serializer.MapOpen("data") - serializer.String("logs") - serializer.ArrayOpen() - - foreach logEntry in scopeLog as @String - begin - serializer.String(Convert.ToBase64String(logEntry)) - end - - serializer.ArrayClose() - - loggerSettings = Logger.Instance.CurrentLogSettings() - - serializer.MapOpen("log_settings") - serializer.Pair("ScopeIdentifier", loggerSettings.ScopeIdentifier) - serializer.PairBool("LogToMemory", loggerSettings.LogToMemory) - serializer.PairBool("LogToDisk", loggerSettings.LogToDisk) - serializer.Pair("LogLocation", loggerSettings.LogLocation) - serializer.PairBool("FlushLog", loggerSettings.FlushLog) - serializer.Pair("OnDiskLogLevel", loggerSettings.OnDiskLogLevel) - serializer.Pair("InMemoryLogLevel", loggerSettings.InMemoryLogLevel) - serializer.PairBool("AttachLogsToExceptions", loggerSettings.AttachLogsToExceptions) - serializer.MapClose() - - serializer.MapClose() - end - end - - serializer.MapClose() - - if(messageId > -1) then - serializer.Pair("id", messageId) - else - serializer.PairNull("id") - - serializer.MapClose() - - MaybeLog(1, "ReportError: " + errorText + " messageId" + %string(messageId)) - end - else - begin - MaybeLog(5, "ReportError: Notify -> " + errorText) - end - endmethod - - public method ReportResult, void - requestId, int - result, @string - serializer, @DispatchSerializer - proc - if(requestId != -1) then - begin - serializer.MapOpen() - serializer.Pair("jsonrpc", "2.0") - serializer.Pair("result", result) - - if(requestId > -1) then - serializer.Pair("id", requestId) - else - serializer.PairNull("id") - - serializer.MapClose() - - MaybeLog(5, "ReportResult: " + result + " messageId" + %string(requestId)) - end - else - begin - MaybeLog(5, "ReportResult: Notify") - end - - endmethod - - public method ReportResult, void - requestId, int - result, n - serializer, @DispatchSerializer - proc - if(requestId != -1) then - begin - serializer.MapOpen() - serializer.Pair("jsonrpc", "2.0") - serializer.Pair("result", result) - - if(requestId > -1) then - serializer.Pair("id", requestId) - else - serializer.PairNull("id") - - serializer.MapClose() - MaybeLog(5, "ReportResult: " + %string(result) + " messageId" + %string(requestId)) - end - else - begin - MaybeLog(5, "ReportResult: Notify") - end - endmethod - - public method ReportResult, void - requestId, int - result, [#]@object - inputSet, [#]boolean - resultTypes, [#]FieldDataType - serializer, @DispatchSerializer - record - arg, @object - ii, int - proc - serializer.ArrayOpen() - ii = 0 - foreach arg in result - begin - incr ii - if(inputSet[ii]) - begin - ;;TODO input set - end - end - MaybeLog(5, "ReportResult: array(" + %string(result.Length) + ") messageId" + %string(requestId)) - - endmethod - ;;; ;;; ;;; @@ -1213,7 +988,7 @@ namespace Harmony.TraditionalBridge try begin data serializer = new DispatchSerializer(new ChannelOutputStream(ttChannel)) - ReportError(ex.ToString(), (int)-32603, (int)-1, serializer) + serializer.ReportError(ex.ToString(), (int)-32603, (int)-1) end catch(ex2, @Exception) begin @@ -1247,7 +1022,7 @@ namespace Harmony.TraditionalBridge if(!jsonData.TryGetProperty("method", name)) begin - ReportError("method name missing", (int)-32600, requestId, serializer) + serializer.ReportError("method name missing", (int)-32600, requestId) end MaybeLog(5, "Dispatcher: method target was " + name) @@ -1261,17 +1036,17 @@ namespace Harmony.TraditionalBridge if(name == "rpc.shutdown") then begin ;;we've been asked to shutdown so return false and let the outer loop take care of it - ReportResult(requestId, 0, serializer) + serializer.ReportResult(requestId, 0) serializer.OutputScopeClose() mreturn false end else if(name == "rpc.ping") then begin - ReportResult(requestId, 0, serializer) + serializer.ReportResult(requestId, 0) end else if(name == "rpc.serializer_protocol") then begin - ReportResult(requestId, "1.0", serializer) + serializer.ReportResult(requestId, "1.0") end else if(name == "rpc.set_log_level") then begin @@ -1279,7 +1054,7 @@ namespace Harmony.TraditionalBridge argArrayList = ((@JsonArray)jsonData.GetProperty("params")).arrayValues if(argArrayList.Count != 1 || !(argArrayList[0] .is. JsonObject)) then - ReportError("invalid parameters for rpc.set_log_level", (int)-32602, requestId, serializer) + serializer.ReportError("invalid parameters for rpc.set_log_level", (int)-32602, requestId) else begin data settingsArgumentData = (@JsonObject)argArrayList[0] @@ -1287,7 +1062,7 @@ namespace Harmony.TraditionalBridge data passedValue = (@JsonObject)passedValueProp data targetLogSettings = new LoggerScopeSettings() if(passedValue == ^null) - ReportError("invalid parameters for rpc.set_log_level", (int)-32602, requestId, serializer) + serializer.ReportError("invalid parameters for rpc.set_log_level", (int)-32602, requestId) passedValue.TryGetProperty("ScopeIdentifier", targetLogSettings.ScopeIdentifier) passedValue.TryGetProperty("LogLocation", targetLogSettings.LogLocation) @@ -1301,19 +1076,19 @@ namespace Harmony.TraditionalBridge Logger.Instance.SetRootScope(targetLogSettings) - ReportResult(requestId, 0, serializer) + serializer.ReportResult(requestId, 0) end end else if(name == "rpc.chain") then begin ;;TODO: flush everything out and stop chain to ourselves - ReportError("rpc.chain not yet implemented", -32603, requestId, serializer) + serializer.ReportError("rpc.chain not yet implemented", -32603, requestId) end else begin ;;extension method was called but isnt supported - ReportError("unknown extension method", -32601, requestId, serializer) + serializer.ReportError("unknown extension method", -32601, requestId) end end else @@ -1334,13 +1109,13 @@ namespace Harmony.TraditionalBridge catch(rtnNotFound, @RoutineNotFound) begin serializer.OutputScopeAbort() - ReportError(rtnNotFound.ToString(), -32601, requestId, serializer) + serializer.ReportError(rtnNotFound.ToString(), -32601, requestId) end catch(ex, @Exception) begin serializer.OutputScopeAbort() ;;TODO maybe this should be a specific type, we might need to do additional processing for certain exception types here - ReportError(ex.ToString(), -32000, requestId, serializer) + serializer.ReportError(ex.ToString(), -32000, requestId) end endtry @@ -1367,37 +1142,20 @@ namespace Harmony.TraditionalBridge dispatcher, @RoutineDispatcher proc - endmethod - - public method Dispatch, void - name, @string - callFrame, @JsonObject - serializer, @DispatchSerializer - dispatcher, @RoutineDispatcher - record - requestId, int - proc - serializer.MapOpen() - serializer.Pair("jsonrpc", "2.0") - - if(callFrame.TryGetProperty("id", requestId)) then - serializer.Pair("id", requestId) - else - serializer.PairNull("id") - - serializer.String("result") - serializer.ArrayOpen() - - DispatchInternal(name, callFrame, serializer, dispatcher) - - ;;Terminate the "ReturnParameters" array - serializer.ArrayClose() - - ;;Terminate the "Result" object - serializer.MapClose() - ;;Terminate the response object - serializer.MapClose() - endmethod + endmethod + + public method Dispatch, void + name, @string + callFrame, @JsonObject + serializer, @DispatchSerializer + dispatcher, @RoutineDispatcher + record + requestId, int + proc + serializer.ReportResponseProlog(callFrame.TryGetProperty("id", requestId), requestId) + DispatchInternal(name, callFrame, serializer, dispatcher) + serializer.ReportResponseEpilog() + endmethod public method RCBInit, void required in targetMethod, a diff --git a/TraditionalBridge/Serializer.V11.dbl b/TraditionalBridge/Serializer.V11.dbl new file mode 100644 index 00000000..7e060d42 --- /dev/null +++ b/TraditionalBridge/Serializer.V11.dbl @@ -0,0 +1,756 @@ +.ifdef DBLV11 +import System.Collections +import Harmony.TraditionalBridge +import System.Text.Json +import System.Text + +.define MaybeLog(priority, msg) if((priority) <= Logger.LogLevel) Logger.Instance.Log(msg) + +namespace Json + + ;;; + ;;; Builds a Harmony Core TraditionalBridge JSON message and writes it to a channel. + ;;; + public abstract class JsonSerializer + + protected outStream, @OutputStream + private buffer, @StringBuilder + protected jsonWriter, @Utf8JsonWriter + ;;; + ;;; Constructs a new serializer associated with an open channel. + ;;; + ;;; Channel to write JSON data to. + public method JsonSerializer + required in stream, @OutputStream + proc + buffer = new StringBuilder() + outStream = stream + jsonWriter = Utf8JsonWriter.CreateUtf8JsonWriter(buffer) + endmethod + +.region "Serialization methods" + public method OutputScopeOpen, void + proc + + endmethod + + ;;abort the current output scope, rolling back any output in the buffer back to the last OutputScopeOpen call + public method OutputScopeAbort, void + proc + jsonWriter.Reset() + buffer.Clear() + endmethod + + + public method OutputScopeClose, void + proc + + endmethod + + public abstract method ObjectData, void + dataValue, a + dataType, a + grfa, a + dataNeedsEncoding, boolean + name, @string + proc + endmethod + +.endregion + +.region "Other public members" + + public property CurrentBuffer, string + method get + proc + mreturn buffer.ToString() + endmethod + endproperty + +.endregion + +.region "Helper methods" + + ;;; + ;;; Constructs the TraditionalBridge protocol message and sends it to the channel. + ;;; After sending the message the JSON buffer is cleared. + ;;; + ;;; The complete protocol message that was sent. + public method Flush, void + stack record + message, string + messageLength, int + endrecord + proc + + + ;;clear and reset utf8jsonwriter + jsonWriter.Flush() + message = buffer.ToString() + jsonWriter.Reset() + + messageLength = message.length + + if(messageLength == 0) + mreturn + + if(6 <= Logger.LogLevel) then + begin + data lengthheader, string + lengthHeader = "Content-Length:" + %string(messageLength) + %char(13) + %char(10) + %char(13) + %char(10) + MaybeLog(6, "Serializer: " + lengthHeader) + outStream.FlushData(lengthHeader) + end + else + outStream.FlushData("Content-Length:" + %string(messageLength) + %char(13) + %char(10) + %char(13) + %char(10)) + + MaybeLog(6, "Serializer: " + message) + outStream.FlushData(message) + + endmethod + +.endregion + + endclass + + public class DispatchSerializer extends JsonSerializer + public method DispatchSerializer + stream, @OutputStream + parent(stream) + proc + endmethod + + public method ArgumentData, void + required in argPos, int + required in value, string + required in type, FieldDataType + required in size, int + required in precision, int + required in hasBinaryData, boolean + proc + ArgumentData(argPos, (a)value, type, size, precision, hasBinaryData) + endmethod + + public override method ObjectData, void + dataValue, a + dataType, a + grfa, a + dataNeedsEncoding, boolean + name, @string + proc + if(name != ^null) then + jsonWriter.WriteStartObject(name) + else + jsonWriter.WriteStartObject() + + jsonWriter.WriteString("Type", dataType) + if(!dataNeedsEncoding) then + begin + jsonWriter.WriteString("Value", dataValue) + end + else + begin + jsonWriter.WriteString("Base64Value", Convert.ToBase64String(dataValue)) + end + jsonWriter.WriteString("GRFA", grfa) + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + required in argPos, int + required in value, a + optional in type, FieldDataType + optional in size, int + optional in precision, int + optional in hasBinaryData, boolean + record + encodeElement, boolean + proc + if(^passed(hasBinaryData)) then + encodeElement = hasBinaryData + else + encodeElement = false + + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.AlphaField) + if(encodeElement) then + begin + if(^passed(size) && ^size(value) > size) then + jsonWriter.WriteString("Base64Value", Convert.ToBase64String(value(1:size))) + else + jsonWriter.WriteString("Base64Value", Convert.ToBase64String(value)) + end + else + begin + if(^passed(size) && ^size(value) > size) then + jsonWriter.WriteString("PassedValue", %atrim(value(1:size))) + else + jsonWriter.WriteString("PassedValue", %atrim(value)) + end + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + required in argPos, int + required in value, d + optional in type, FieldDataType + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DecimalField) + jsonWriter.WriteNumber("PassedValue", ^d(value, 0)) + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + required in argPos, int + required in value, id + required in type, FieldDataType + required in size, int + required in precision, int + required in hasBinaryData, boolean + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.ImpliedDecimal) + jsonWriter.WriteNumber("ElementSize", size) + jsonWriter.WriteNumber("DecimalPrecision", precision) + jsonWriter.WriteNumber("PassedValue", value) + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + required in argPos, int + required in value, i + optional in type, FieldDataType + optional in size, int + optional in precision, int + optional in hasBinaryData, boolean + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.IntegerField) + jsonWriter.WriteNumber("PassedValue", value) + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, @ArrayList + record + item, @object + doElement, @DataObjectBase + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + if(item .is. @DataObjectBase) then + begin + doElement = (@DataObjectBase)item + doElement.Serialize(this) + end + else if(item .is. @string) then + jsonWriter.WriteStringValue((@string)item) + else if(item .is. @i) then + jsonWriter.WriteNumberValue((@i)item) + else if(item .is. @d) then + jsonWriter.WriteNumberValue((@d)item) + else if(item .is. @id) then + jsonWriter.WriteNumberValue((@id)item) + else if(item .is. @boolean) + jsonWriter.WriteBooleanValue((@boolean)item) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, [#]@DataObjectBase + record + doElement, @DataObjectBase + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach doElement in value + begin + doElement.Serialize(this) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, @DataObjectBase + record + item, @object + doElement, @DataObjectBase + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectField) + value.Serialize(this, "PassedValue") + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, @ArrayList + type, FieldDataType + elementSize, int + elementPrecision, int + hasBinaryData, boolean + record + item, @object + doElement, @DataObjectBase + proc + throw new Exception("Not Yet Implemented") + endmethod + + public method ArgumentData, void + argPos, int + value, @ArrayList + type, FieldDataType + elementSize, int + elementType, a + hasBinaryData, boolean + record + item, @object + doElement, @DataObjectBase + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteString("ElementType", elementType) + jsonWriter.WriteBoolean("ElementIsEncoded", hasBinaryData) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + if(hasBinaryData) then + jsonWriter.WriteStringValue(Convert.FromBase64String((a)item)) + else + jsonWriter.WriteStringValue((a)item) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, [#]@string + record + item, @string + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + jsonWriter.WriteStringValue(item) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, [#]int + record + item, int + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + jsonWriter.WriteNumberValue(item) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, [#]@a + record + item, @a + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + jsonWriter.WriteStringValue(%atrim(item)) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, [#]@id + record + item, @id + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteStartArray("PassedValue") + foreach item in value + begin + jsonWriter.WriteNumberValue(item) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentData, void + argPos, int + value, a + type, FieldDataType + structureSize, int + structureName, a + binaryData, boolean + record + item, @id + i, int + structureCount, int + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteString("ElementType", structureName) + jsonWriter.WriteBoolean("ElementIsEncoded", binaryData) + jsonWriter.WriteStartArray("PassedValue") + + structureCount = ^size(value) / structureSize + + for i from 0 thru structureCount by 1 + begin + if(!binaryData) then + begin + jsonWriter.WriteStringValue(value((i * structureSize) + 1 : structureSize)) + end + else + begin + jsonWriter.WriteStringValue(Convert.ToBase64String(value((i * structureSize) + 1 : structureSize))) + end + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentHandleData, void + argPos, int + value, D_HANDLE + type, FieldDataType + structureSize, int + structureName, a + elementCount, int + binaryData, boolean + record + item, @id + i, int + structureCount, int + structure fake + fld1, a1 + endstructure + + proc + MaybeLog(4, "serializing argument handle data, structureSize was " + %string(structureSize) + " element count was " + %string(elementCount) + " handle length was " + %string(^size(^m(value)))) + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)FieldDataType.DataObjectCollectionField) + jsonWriter.WriteString("ElementType", structureName) + jsonWriter.WriteBoolean("ElementIsEncoded", binaryData) + jsonWriter.WriteStartArray("PassedValue") + + for i from 0 thru elementCount - 1 by 1 + begin + if(!binaryData) then + begin + jsonWriter.WriteStringValue(^m(fake.fld1((i * structureSize) + 1 : structureSize), value)) + end + else + begin + jsonWriter.WriteStringValue(Convert.ToBase64String(^m(fake.fld1((i * structureSize) + 1 : structureSize), value))) + end + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArgumentHandleData, void + argPos, int + value, D_HANDLE + type, FieldDataType + elementSize, int + precision, int + elementCount, int + binaryData, boolean + record + item, @id + i, int + structure fake + fld1, a1 + endstructure + + proc + MaybeLog(4, "serializing argument handle data, elementSize was " + %string(elementSize) + " element count was " + %string(elementCount) + " handle length was " + %string(^size(^m(value)))) + + jsonWriter.WriteStartObject() + jsonWriter.WriteNumber("Position", argPos) + jsonWriter.WriteStartObject("Value") + + jsonWriter.WriteNumber("DataType", (i)type) + jsonWriter.WriteBoolean("ElementIsEncoded", binaryData) + jsonWriter.WriteStartArray("PassedValue") + + for i from 0 thru elementCount - 1 by 1 + begin + if(type == FieldDataType.AlphaArrayField) then + begin + if(!binaryData) then + begin + jsonWriter.WriteStringValue(^m(fake.fld1((i * elementSize) + 1 : elementSize), value)) + end + else + begin + jsonWriter.WriteStringValue(Convert.ToBase64String(^m(fake.fld1((i * elementSize) + 1 : elementSize), value))) + end + end + else if(type == FieldDataType.DecimalArrayField) then + begin + jsonWriter.WriteNumberValue(^d(^m(fake.fld1((i * elementSize) + 1 : elementSize), value), 0)) + end + else if(type == FieldDataType.ImpliedDecimalArrayField) then + begin + jsonWriter.WriteNumberValue(^d(^m(fake.fld1((i * elementSize) + 1 : elementSize), value), precision)) + end + else if(type == FieldDataType.IntegerArrayField) then + begin + jsonWriter.WriteNumberValue(^i(^m(fake.fld1((i * elementSize) + 1 : elementSize), value))) + end + else + throw new Exception("element type not implemented " + %string(type)) + end + jsonWriter.WriteEndArray() + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + endmethod + + public method ArrayOpen, void + proc + jsonWriter.WriteStartArray() + endmethod + + public method ArrayClose, void + proc + jsonWriter.WriteEndArray() + endmethod + + public method ReportResponseProlog, void + hasId, boolean + requestId, i4 + proc + jsonWriter.WriteStartObject() + jsonWriter.WriteString("jsonrpc", "2.0") + + if(hasId) then + jsonWriter.WriteNumber("id", requestId) + else + jsonWriter.WriteNull("id") + + jsonWriter.WriteStartArray("result") + endmethod + + public method ReportResponseEpilog, void + proc + ;;Terminate the "ReturnParameters" array + jsonWriter.WriteEndArray() + + ;;Terminate the "Result" object + jsonWriter.WriteEndObject() + endmethod + + public method ReportError, void + errorText, @string + errorCode, int + messageId, int + record + scopeLog, @ArrayList + loggerSettings, @LoggerScopeSettings + proc + OutputScopeAbort() + + if(messageId != -1) then + begin + jsonWriter.WriteStartObject() + jsonWriter.WriteString("jsonrpc", "2.0") + jsonWriter.WriteStartObject("error") + jsonWriter.WriteNumber("code", errorCode) + + jsonWriter.WriteString("message", Convert.ToBase64String(errorText)) + + ;;if scope logging is active return everything that was logged as part of this request scope + if(Logger.Instance.ShouldAttachLogsToExceptions) + begin + scopeLog = Logger.Instance.CurrentScopeLog() + if(scopeLog != ^null && scopeLog.Count > 0) + begin + + data logEntry, @string + MaybeLog(2, "Dispatcher: attaching in memory logs to thrown exception") + + jsonWriter.WriteStartObject("data") + jsonWriter.WriteStartArray("logs") + + foreach logEntry in scopeLog as @String + begin + jsonWriter.WriteStringValue(Convert.ToBase64String(logEntry)) + end + + jsonWriter.WriteEndArray() + + loggerSettings = Logger.Instance.CurrentLogSettings() + + jsonWriter.WriteStartObject("log_settings") + jsonWriter.WriteString("ScopeIdentifier", loggerSettings.ScopeIdentifier) + jsonWriter.WriteBoolean("LogToMemory", loggerSettings.LogToMemory) + jsonWriter.WriteBoolean("LogToDisk", loggerSettings.LogToDisk) + jsonWriter.WriteString("LogLocation", loggerSettings.LogLocation) + jsonWriter.WriteBoolean("FlushLog", loggerSettings.FlushLog) + jsonWriter.WriteNumber("OnDiskLogLevel", loggerSettings.OnDiskLogLevel) + jsonWriter.WriteNumber("InMemoryLogLevel", loggerSettings.InMemoryLogLevel) + jsonWriter.WriteBoolean("AttachLogsToExceptions", loggerSettings.AttachLogsToExceptions) + jsonWriter.WriteEndObject() + jsonWriter.WriteEndObject() + end + end + + jsonWriter.WriteEndObject() + + if(messageId > -1) then + jsonWriter.WriteNumber("id", messageId) + else + jsonWriter.WriteNull("id") + + jsonWriter.WriteEndObject() + + MaybeLog(1, "ReportError: " + errorText + " messageId" + %string(messageId)) + end + else + begin + MaybeLog(5, "ReportError: Notify -> " + errorText) + end + this.Flush() + endmethod + + public method ReportResult, void + requestId, int + result, @string + proc + if(requestId != -1) then + begin + jsonWriter.WriteStartObject() + jsonWriter.WriteString("jsonrpc", "2.0") + jsonWriter.WriteString("result", result) + + if(requestId > -1) then + jsonWriter.WriteNumber("id", requestId) + else + jsonWriter.WriteNull("id") + + jsonWriter.WriteEndObject() + + MaybeLog(5, "ReportResult: " + result + " messageId" + %string(requestId)) + end + else + begin + MaybeLog(5, "ReportResult: Notify") + end + this.Flush() + endmethod + + public method ReportResult, void + requestId, int + result, n + proc + if(requestId != -1) then + begin + jsonWriter.WriteStartObject() + jsonWriter.WriteString("jsonrpc", "2.0") + jsonWriter.WriteNumber("result", result) + + if(requestId > -1) then + jsonWriter.WriteNumber("id", requestId) + else + jsonWriter.WriteNull("id") + + jsonWriter.WriteEndObject() + MaybeLog(5, "ReportResult: " + %string(result) + " messageId" + %string(requestId)) + end + else + begin + MaybeLog(5, "ReportResult: Notify") + end + this.Flush() + endmethod + + + endclass + +endnamespace +.endc \ No newline at end of file diff --git a/TraditionalBridge/Serializer.dbl b/TraditionalBridge/Serializer.dbl index dda554a1..c9922a85 100644 --- a/TraditionalBridge/Serializer.dbl +++ b/TraditionalBridge/Serializer.dbl @@ -78,6 +78,7 @@ namespace Json endmethod endclass +.ifndef DBLV11 ;;; ;;; Builds a Harmony Core TraditionalBridge JSON message and writes it to a channel. ;;; @@ -112,6 +113,31 @@ namespace Json serializerStack.Add((@SerializerStackType)SerializerStackType.None) endmethod + public method ObjectData, void + dataValue, a + dataType, a + grfa, a + dataNeedsEncoding, boolean + name, @string + proc + if(name == ^null) then + MapOpen() + else + MapOpen(name) + + Pair("Type", dataType) + if(!dataNeedsEncoding) then + begin + Pair("Value", dataValue) + end + else + begin + Pair("Base64Value", Convert.ToBase64String(dataValue)) + end + Pair("GRFA", grfa) + MapClose() + endmethod + ;;; ;;; Adds a new serializer state to the top of the stack. The stack indicates ;;; whether the serializer is currently processing an onject or an array. @@ -566,7 +592,10 @@ namespace Json mreturn buffer endmethod endproperty - + public method Flush, void + proc + ;;do nothing this is managed automatically + endmethod .endregion .region "Helper methods" @@ -1107,5 +1136,181 @@ namespace Json MapClose() endmethod + public method ReportResponseProlog, void + hasId, boolean + requestId, i4 + proc + MapOpen() + Pair("jsonrpc", "2.0") + + if(hasId) then + Pair("id", requestId) + else + PairNull("id") + + String("result") + ArrayOpen() + endmethod + + public method ReportResponseEpilog, void + proc + ;;Terminate the "ReturnParameters" array + ArrayClose() + + ;;Terminate the "Result" object + MapClose() + ;;Terminate the response object + MapClose() + endmethod + + public method ReportError, void + errorText, @string + errorCode, int + messageId, int + record + scopeLog, @ArrayList + loggerSettings, @LoggerScopeSettings + proc + OutputScopeAbort() + + if(messageId != -1) then + begin + MapOpen() + Pair("jsonrpc", "2.0") + String("error") + MapOpen() + Pair("code", errorCode) + + Pair("message", Convert.ToBase64String(errorText)) + + ;;if scope logging is active return everything that was logged as part of this request scope + if(Logger.Instance.ShouldAttachLogsToExceptions) + begin + scopeLog = Logger.Instance.CurrentScopeLog() + if(scopeLog != ^null && scopeLog.Count > 0) + begin + + data logEntry, @string + MaybeLog(2, "Dispatcher: attaching in memory logs to thrown exception") + + MapOpen("data") + String("logs") + ArrayOpen() + + foreach logEntry in scopeLog as @String + begin + String(Convert.ToBase64String(logEntry)) + end + + ArrayClose() + + loggerSettings = Logger.Instance.CurrentLogSettings() + + MapOpen("log_settings") + Pair("ScopeIdentifier", loggerSettings.ScopeIdentifier) + PairBool("LogToMemory", loggerSettings.LogToMemory) + PairBool("LogToDisk", loggerSettings.LogToDisk) + Pair("LogLocation", loggerSettings.LogLocation) + PairBool("FlushLog", loggerSettings.FlushLog) + Pair("OnDiskLogLevel", loggerSettings.OnDiskLogLevel) + Pair("InMemoryLogLevel", loggerSettings.InMemoryLogLevel) + PairBool("AttachLogsToExceptions", loggerSettings.AttachLogsToExceptions) + MapClose() + + MapClose() + end + end + + MapClose() + + if(messageId > -1) then + Pair("id", messageId) + else + PairNull("id") + + MapClose() + + MaybeLog(1, "ReportError: " + errorText + " messageId" + %string(messageId)) + end + else + begin + MaybeLog(5, "ReportError: Notify -> " + errorText) + end + endmethod + + public method ReportResult, void + requestId, int + result, @string + proc + if(requestId != -1) then + begin + MapOpen() + Pair("jsonrpc", "2.0") + Pair("result", result) + + if(requestId > -1) then + Pair("id", requestId) + else + PairNull("id") + + MapClose() + + MaybeLog(5, "ReportResult: " + result + " messageId" + %string(requestId)) + end + else + begin + MaybeLog(5, "ReportResult: Notify") + end + + endmethod + + public method ReportResult, void + requestId, int + result, n + proc + if(requestId != -1) then + begin + MapOpen() + Pair("jsonrpc", "2.0") + Pair("result", result) + + if(requestId > -1) then + Pair("id", requestId) + else + PairNull("id") + + MapClose() + MaybeLog(5, "ReportResult: " + %string(result) + " messageId" + %string(requestId)) + end + else + begin + MaybeLog(5, "ReportResult: Notify") + end + endmethod + + public method ReportResult, void + requestId, int + result, [#]@object + inputSet, [#]boolean + resultTypes, [#]FieldDataType + record + arg, @object + ii, int + proc + ArrayOpen() + ii = 0 + foreach arg in result + begin + incr ii + if(inputSet[ii]) + begin + ;;TODO input set + end + end + MaybeLog(5, "ReportResult: array(" + %string(result.Length) + ") messageId" + %string(requestId)) + + endmethod + endclass +.endc endnamespace diff --git a/TraditionalBridge/TraditionalBridge.synproj b/TraditionalBridge/TraditionalBridge.synproj index c3d9d73a..8d65caaf 100644 --- a/TraditionalBridge/TraditionalBridge.synproj +++ b/TraditionalBridge/TraditionalBridge.synproj @@ -70,6 +70,8 @@ false Optimize True + 10030303 + 10030303 False @@ -108,6 +110,7 @@ + From 12e0382060682e6bbff0bfaaa74bca135de5fe2b Mon Sep 17 00:00:00 2001 From: Jeff Greene Date: Tue, 29 Oct 2019 13:47:15 -0700 Subject: [PATCH 2/2] target v11 --- TraditionalBridge/TraditionalBridge.synproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TraditionalBridge/TraditionalBridge.synproj b/TraditionalBridge/TraditionalBridge.synproj index 8d65caaf..dfc7f884 100644 --- a/TraditionalBridge/TraditionalBridge.synproj +++ b/TraditionalBridge/TraditionalBridge.synproj @@ -70,8 +70,8 @@ false Optimize True - 10030303 - 10030303 + 11010100 + 11010100 False