Diff of /branches/develop/mqttsparkplug/mqttsparkplug/Sparkplug™ MQTT edge and host/Function Blocks/FB_Payload_1/FB_Payload/svnobj [r918] .. [r919]  Maximize  Restore

Switch to side-by-side view

--- a/branches/develop/mqttsparkplug/mqttsparkplug/Sparkplug™ MQTT edge and host/Function Blocks/FB_Payload_1/FB_Payload/svnobj
+++ b/branches/develop/mqttsparkplug/mqttsparkplug/Sparkplug™ MQTT edge and host/Function Blocks/FB_Payload_1/FB_Payload/svnobj
@@ -1,5 +1,5 @@
-Gx_l}Œ!0…jüoXp(ð31ýö¶Ð)System.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
-TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText^                            //This IF statementFIF xDecode AND xEncode THEN //ERROR4    xDecodeDone  := FALSE;4    xDecodeBusy  := FALSE;2    xDecodeError := TRUE;j    eDecodeError := ERROR.PayloadYouCantDoBothAtOnce;4    xEncodeDone  := FALSE;4    xEncodeBusy  := FALSE;2    xEncodeError := TRUE;j    eEncodeError := ERROR.PayloadYouCantDoBothAtOnce;ˆELSIF NOT xDecode AND NOT xEncode THEN //DO NOTHING, ALL OUTPUTS OFF4    xDecodeError := FALSE;F    eDecodeError := ERROR.NO_ERROR;4    xEncodeError := FALSE;F    eEncodeError := ERROR.NO_ERROR;VELSIF xDecode AND NOT xEncode THEN //Decode 2    xDecodeBusy  := TRUE;!VELSIF NOT xDecode AND xEncode THEN //Encode"2    xEncodeBusy  := TRUE;#END_IF$%&IF xDecodeBusy THEN&F    InitializeStructuredPayload( );'œ    //OK, now we are listening to the user as to how many bytes in the payload(N    _diPayloadSize := protobufBlobSize;)*    SetArrayBounds();*t    eDecodeState := PayloadDecodeStates.payload_getmember;+š    FOR i := _protobufBlobLower TO _protobufBlobLower + _diPayloadSize - 1 DO,`        // loop through every byte and decode it-\        //start off looking for the messageID:.8        CASE eDecodeState OF/d            PayloadDecodeStates.payload_getmember:0R                CASE myProtobufBlob[i] OF1z                    16#00: //end of data? padding byte? ERROR2Z                        xDecodeError := TRUE;3z                        eDecodeError := ERROR.PayloadFound00;4Æ                        i            := _protobufBlobLower + _diPayloadSize - 1; //break out of FOR5Þ                    ProtobufedId.Payload_timestamp:                              //payload timestamp 01<<3 | 006¢                        eDecodeState := PayloadDecodeStates.payload_gettimestamp;7ž                    ProtobufedId.Payload_metrics: //start of metrics 02<<3 | 028œ                        eDecodeState := PayloadDecodeStates.payload_getmetric;9¤                    ProtobufedId.Payload_seq: //payload sequence number 03<<3 | 00:–                        eDecodeState := PayloadDecodeStates.payload_getseq;;                    ProtobufedId.Payload_uuid: //payload uuid 04<<3 | 02<˜                        eDecodeState := PayloadDecodeStates.payload_getUuid;=¾                    ProtobufedId.Payload_body: //payload with just raw bytes to send 05<<3 | 02>˜                        eDecodeState := PayloadDecodeStates.payload_getBody;?R                ELSE //extension... error@R                    xDecodeError := TRUE;A‚                    eDecodeError := ERROR.PayloadFoundExtensions;B¾                    i            := _protobufBlobLower + _diPayloadSize - 1; //break out of FORC0                END_CASEDj            PayloadDecodeStates.payload_gettimestamp:EN                _xHasTimeStamp := TRUE;F¬                dviTemp        := DecodeNextVarInt(); //updates i to end of the varintGl                _uliTimestamp  := dviTemp.uliDateTime;H                eDecodeState   := PayloadDecodeStates.payload_getmember;Id            PayloadDecodeStates.payload_getmetric:J¦                //So i imagine, a metric should be able to decode itself, in one goK¨                recentlyClaimedMetric REF= AddMetricBlank( eError => eDecodeError );Lj                IF eDecodeError = ERROR.NO_ERROR THENMž                    //i starts off now pointing to the first byte of the MetricN‚                    THIS^.recentlyClaimedMetric( xDecode := TRUE,O„                                                 xEncode := FALSE,Pâ                                                 protobufBlobMaxIndex := _protobufBlobLower + _diPayloadSize - 1,QŽ                                                 OwnerPayload := THIS^,R                                                 ProtobufBlobIndex := i,S¤                                                 myProtobufBlob := myProtobufBlob,T€                                                 xDecodeDone =>,U€                                                 xDecodeBusy =>,V‚                                                 xDecodeError =>,W†                                                 eDecodeError => );Xz                    IF recentlyClaimedMetric.xDecodeDone THENY’                        //SUCCESS! the latest Metric has now been decodedZž                        //i is now pointing to the very last byte of the Metric[œ                        eDecodeState := PayloadDecodeStates.payload_getmember;\0                    ELSE]Ê                        //FAIL! OR actually, maybe just busy? so far it will all be taken as an error^„                        IF recentlyClaimedMetric.xDecodeError THEN_ž                            eDecodeError := recentlyClaimedMetric.eDecodeError;`8                        ELSEaÄ                            eDecodeError := ERROR.PayloadMetricBusyButMultiCycleNotYetImplemented;b<                        END_IFc°                        i := _protobufBlobLower + _diPayloadSize - 1; //break out of FORd4                    END_IFe(                ELSEf~                    //eDecodeError := ERROR.Can't Claim Metric;g¨                    i := _protobufBlobLower + _diPayloadSize - 1; //break out of FORh.                END_IF;i^            PayloadDecodeStates.payload_getseq:jJ                _xHasSeq     := TRUE;k¨                dviTemp      := DecodeNextVarInt(); //updates i to end of the varintl^                _uliSeq      := dviTemp.UInt64;mŒ                eDecodeState := PayloadDecodeStates.payload_getmember;n`            PayloadDecodeStates.payload_getUuid:oJ                _xHasUuid    := TRUE;p                 _sUuid       := DecodeNextString(); //updates i to end of stringq`            PayloadDecodeStates.payload_getBody:rD                _xHasBody := TRUE;s†                DecodeNextBinaryData( numBytes => _diHasBody_bytes,tÈ                                      BodyStartIndex => _diStartOfBody ); //updates i to end of Bodyu        ELSEv4            // Here not...wB            xDecodeError := TRUE;x€            eDecodeError := ERROR.OhMy_ThatShouldNotHaveHappenedy                 ; //This isn't even a possible value of the PayloadDecodeStates;zÌ            i := _protobufBlobLower + _diPayloadSize - 1; //break out of FOR   NO IDEA WHAT TO DO HERE{         END_CASE|    END_FOR}Z    eDecodeState := PayloadDecodeStates.idle;~J    xDecodeDone  := NOT xDecodeError;END_IF;€&IF xEncodeBusy THENh    //NOTE: BLOB Data will not be initialized to 00.‚\    //But we will start with a 0 byte payload.ƒ*    InitializeBlob();„8    i := _protobufBlobLower;…N    //Encode Timestamp (Field Number 1)†x    IF eEncodeError = ERROR.NO_ERROR AND _xHasTimestamp THEN‡„        //{info 'todo: i-campbell Make these field numbers a GVL'}ˆZ        dviTemp.uliDateTime := _uliTimestamp;‰”        eEncodeError        := EncodeNextVarInt( ValueToEncode := dviTemp,Š˜                                                 ProtobufFieldNumber := 1 );‹n        xEncodeError := eEncodeError <> ERROR.NO_ERROR;Œ    END_IF;0    //Encode All MetricsŽp    _Metrics.ItterateRestart( HasNext => _COL_HasNext );z    WHILE _COL_HasNext AND (eEncodeError = ERROR.NO_ERROR) DOt        _Metrics.ItterateNext( itfElement => _COL_Element,‘r                               HasNext => _COL_HasNext );’P        IF __QUERYPOINTER( _COL_Element,“h                           nextMetricToEncode ) THEN”d            nextMetricToEncode^( xDecode := FALSE,•b                                 xEncode := TRUE,–p                                 ProtobufBlobIndex := i,—˜                                 protobufBlobMaxIndex := _protobufBlobUpper,˜n                                 OwnerPayload := THIS^,™„                                 myProtobufBlob := myProtobufBlob,š`                                 xDecodeDone =>,›`                                 xDecodeBusy =>,œb                                 xDecodeError =>,b                                 eDecodeError =>,ž`                                 xEncodeDone =>,Ÿ`                                 xEncodeBusy =>, |                                 xEncodeError => xEncodeError,¡€                                 eEncodeError => eEncodeError );¢        END_IF;£    END_WHILE¤     //Encode Seq¥l    IF eEncodeError = ERROR.NO_ERROR AND _xHasSeq THEN¦D        dviTemp.Uint64 := _uliSeq;§Š        eEncodeError   := EncodeNextVarInt( ValueToEncode := dviTemp,¨Ž                                            ProtobufFieldNumber := 3 );©"    //Encode UUIDªn    IF eEncodeError = ERROR.NO_ERROR AND _xHasUuid THEN«„        eEncodeError := EncodeNextString( ValueToEncode := _sUuid,¬Š                                          ProtobufFieldNumber := 4 );­"    //Encode Body®j    //{info 'todo: i-campbell implement encode body'}¯n    IF eEncodeError = ERROR.NO_ERROR AND _xHasBody THEN°Z        eEncodeError := ERROR.NotImplemented;±¶    // i is pointing to the array index 1 after the end of the payload so return the length²^    _diPayloadSize   := i - _protobufBlobLower;³N    protobufBlobSize := _diPayloadSize;´    //DONE :)µH    xEncodeDone := NOT xEncodeError;¶2    xEncodeBusy := FALSE;·Interface¸L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}¹(*ºÆ    Represents the sparkplugb data to be sent in a MQTT Publisher or received by an MQTT Subscriber»ž	It contains data for both the raw bytes and also a structured view of the data¼|	It contains code to transform either from or to the raw bytes½º	IF BOTH xDecode and xEncode are set, an error will be given for both and nothing will happen¾*)¿${attribute 'hide'}À2FUNCTION_BLOCK FB_PayloadÁVAR_INPUTÂ<    (*Trigers for conversion*)Ãâ    xDecode                : BOOL;                 //Based on CBML.LCon.  Current implementation, It will always xDone or xError every cycle, it never takes more than one cycle Äà    xEncode                : BOOL;                 //Based on CBML.LCon.  Current implementation, It will always xDone or xError every cycle, it never takes more than one cycleÅÐ    protobufBlobStartIndex : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use LOWER_BOUNDÆÐ    protobufBlobMaxIndex   : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use UPPER_BOUNDǬ    myBodyPool             : POINTER TO BYTE;      //for example Payload.Metric[].BodyȦ    myBodyPoolSize         : __XINT;               //Size in bytes of the Body PoolÉEND_VARÊVAR_IN_OUTËD    protobufBlobSize        : DINTÌ´    ;                                           //size in bytes.  for encode, this FB will write the size here.  for decode, the caller must tell the sizeÍÀ    myProtobufBlob          : ARRAY[*] OF BYTE; //array of bytes containing the protobuf payloadÎVAR_OUTPUTÏæ    xDecodeDone, xDecodeBusy, xDecodeError : BOOL; //Based on CBML.LCon, but will automatically be reset if xDecodeÐf    eDecodeError                           : ERROR;Ñæ    xEncodeDone, xEncodeBusy, xEncodeError : BOOL; //Based on CBML.LCon, but will automatically be reset if xEncodeÒf    eEncodeError                           : ERROR;ÓVARÔT    i                              : DINT;Õr    eDecodeState                   : PayloadDecodeStates;Öf    dviTemp                        : DecodedVarInt;×x    KeysPool                       : List;             //OF Øx    PropertySetValuesPool          : List;             //OF Ùx    PropertySetsPool               : List;             //OF Úx    DataSetColumnsPool             : List;             //OF Ûx    DataSetTypesPool               : List;             //OF Üx    RowsPool                       : List;             //OF Ýx    ElementsPool                   : List;             //OF Þx    ParametersPool                 : List;             //OF ßn	MetricsFactory                 : PayloadMetricFactory;à˜    MetricsPool                    : List;             //OF FB_PayloadMetricáN	BodyPoolFreeIndex              : DINT;↠   recentlyClaimedMetric          : REFERENCE TO FB_PayloadMetric;ã‚    nextMetricToEncode             : POINTER TO FB_PayloadMetric;äT    _COL_HasNext                   : BOOL;å\    _COL_Element                   : IElement;æ*    (* Binary Blob *)ç¸    //_pbPayload : MOVED_TO_myPayloadARRAY__OF_BYTE; //array of bytes containing the payloadè®    _diPayloadSize     : DINT;                 //Size in Bytes.  Actual size of messageéÈ    _protobufBlobLower : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use LOWER_BOUNDêÈ    _protobufBlobUpper : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use UPPER_BOUNDë2    (* Structured data *)ì¶    //     optional uint64   timestamp     = 1;        // Timestamp at message sending timeí4    _xHasTimestamp : BOOL;î@    _uliTimestamp  : T_DateTime;ïÒ    //     repeated Metric   metrics       = 2;        // Repeated forever - no limit in Google Protobufsð8    //uliHasMetrics : ULINT;ñŽ    //uliMaxMetrics : ULINT;                //Size of the Metrics arrayòb    _Metrics : List; //Array of FB_PayloadMetricsó’    //     optional uint64   seq           = 3;        // Sequence numberô(    _xHasSeq : BOOL;õP    _uliSeq  : ULINT; // Sequence numberöæ    //     optional string   uuid          = 4;        // UUID to track message type in terms of schema definitions÷*    _xHasUuid : BOOL;øª    _sUuid    : WSTRING; // UUID to track message type in terms of schema definitionsùÒ    //     optional bytes    body          = 5;        // To optionally bypass the whole definition aboveúÆ    _xHasBody        : BOOL; // it is feasible for a "body" to have 0 bytes, so we use this as wellûÌ    _diHasBody_bytes : DINT; // there's only at most 1 body, but this number represents how many bytesüÀ    _diStartOfBody   : DINT; // Array Index to the start position in FB_Payload.myBodyPool[] make up the "body", To optionally bypass the whole definition aboveý¨    //     extensions                      6 to max;   // For third party extensionsþ<    //     IC: NOT IMPLEMENTEDÿ"UniqueIdGenerator€3421POULevel‚L{8e575c5b-1d37-49c6-941b-5c0ec7874787}ƒStandard„ ChildObjectGuids…8System.Collections.ArrayList†,AddAttributeSubsequent‡boolÐÐ-ÐÐ	E
+Gx_lG¨!0…jüo	qóŚC¤P¸€System.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
+TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText^                            //This IF statementFIF xDecode AND xEncode THEN //ERROR4    xDecodeDone  := FALSE;4    xDecodeBusy  := FALSE;2    xDecodeError := TRUE;j    eDecodeError := ERROR.PayloadYouCantDoBothAtOnce;4    xEncodeDone  := FALSE;4    xEncodeBusy  := FALSE;2    xEncodeError := TRUE;j    eEncodeError := ERROR.PayloadYouCantDoBothAtOnce;ˆELSIF NOT xDecode AND NOT xEncode THEN //DO NOTHING, ALL OUTPUTS OFF4    xDecodeError := FALSE;F    eDecodeError := ERROR.NO_ERROR;4    xEncodeError := FALSE;F    eEncodeError := ERROR.NO_ERROR;VELSIF xDecode AND NOT xEncode THEN //Decode 2    xDecodeBusy  := TRUE;!VELSIF NOT xDecode AND xEncode THEN //Encode"2    xEncodeBusy  := TRUE;#END_IF$%&IF xDecodeBusy THEN&F    InitializeStructuredPayload( );'œ    //OK, now we are listening to the user as to how many bytes in the payload(N    _diPayloadSize := protobufBlobSize;)*    SetArrayBounds();*t    eDecodeState := PayloadDecodeStates.payload_getmember;+š    FOR i := _protobufBlobLower TO _protobufBlobLower + _diPayloadSize - 1 DO,`        // loop through every byte and decode it-\        //start off looking for the messageID:.8        CASE eDecodeState OF/d            PayloadDecodeStates.payload_getmember:0R                CASE myProtobufBlob[i] OF1z                    16#00: //end of data? padding byte? ERROR2Z                        xDecodeError := TRUE;3z                        eDecodeError := ERROR.PayloadFound00;4Æ                        i            := _protobufBlobLower + _diPayloadSize - 1; //break out of FOR5Þ                    ProtobufedId.Payload_timestamp:                              //payload timestamp 01<<3 | 006¢                        eDecodeState := PayloadDecodeStates.payload_gettimestamp;7ž                    ProtobufedId.Payload_metrics: //start of metrics 02<<3 | 028œ                        eDecodeState := PayloadDecodeStates.payload_getmetric;9¤                    ProtobufedId.Payload_seq: //payload sequence number 03<<3 | 00:–                        eDecodeState := PayloadDecodeStates.payload_getseq;;                    ProtobufedId.Payload_uuid: //payload uuid 04<<3 | 02<˜                        eDecodeState := PayloadDecodeStates.payload_getUuid;=¾                    ProtobufedId.Payload_body: //payload with just raw bytes to send 05<<3 | 02>˜                        eDecodeState := PayloadDecodeStates.payload_getBody;?R                ELSE //extension... error@R                    xDecodeError := TRUE;A‚                    eDecodeError := ERROR.PayloadFoundExtensions;B¾                    i            := _protobufBlobLower + _diPayloadSize - 1; //break out of FORC0                END_CASEDj            PayloadDecodeStates.payload_gettimestamp:EN                _xHasTimeStamp := TRUE;F¬                dviTemp        := DecodeNextVarInt(); //updates i to end of the varintGl                _uliTimestamp  := dviTemp.uliDateTime;H                eDecodeState   := PayloadDecodeStates.payload_getmember;Id            PayloadDecodeStates.payload_getmetric:J¦                //So i imagine, a metric should be able to decode itself, in one goK¨                recentlyClaimedMetric REF= AddMetricBlank( eError => eDecodeError );Lj                IF eDecodeError = ERROR.NO_ERROR THENMž                    //i starts off now pointing to the first byte of the MetricN‚                    THIS^.recentlyClaimedMetric( xDecode := TRUE,O„                                                 xEncode := FALSE,Pâ                                                 protobufBlobMaxIndex := _protobufBlobLower + _diPayloadSize - 1,QŽ                                                 OwnerPayload := THIS^,R                                                 ProtobufBlobIndex := i,S¤                                                 myProtobufBlob := myProtobufBlob,T€                                                 xDecodeDone =>,U€                                                 xDecodeBusy =>,V‚                                                 xDecodeError =>,W†                                                 eDecodeError => );Xz                    IF recentlyClaimedMetric.xDecodeDone THENY’                        //SUCCESS! the latest Metric has now been decodedZž                        //i is now pointing to the very last byte of the Metric[œ                        eDecodeState := PayloadDecodeStates.payload_getmember;\0                    ELSE]Ê                        //FAIL! OR actually, maybe just busy? so far it will all be taken as an error^„                        IF recentlyClaimedMetric.xDecodeError THEN_ž                            eDecodeError := recentlyClaimedMetric.eDecodeError;`8                        ELSEaÄ                            eDecodeError := ERROR.PayloadMetricBusyButMultiCycleNotYetImplemented;b<                        END_IFc°                        i := _protobufBlobLower + _diPayloadSize - 1; //break out of FORd4                    END_IFe(                ELSEf~                    //eDecodeError := ERROR.Can't Claim Metric;g¨                    i := _protobufBlobLower + _diPayloadSize - 1; //break out of FORh.                END_IF;i^            PayloadDecodeStates.payload_getseq:jJ                _xHasSeq     := TRUE;k¨                dviTemp      := DecodeNextVarInt(); //updates i to end of the varintl^                _uliSeq      := dviTemp.UInt64;mŒ                eDecodeState := PayloadDecodeStates.payload_getmember;n`            PayloadDecodeStates.payload_getUuid:oJ                _xHasUuid    := TRUE;p                 _sUuid       := DecodeNextString(); //updates i to end of stringq`            PayloadDecodeStates.payload_getBody:rD                _xHasBody := TRUE;s†                DecodeNextBinaryData( numBytes => _diHasBody_bytes,tÈ                                      BodyStartIndex => _diStartOfBody ); //updates i to end of Bodyu        ELSEv4            // Here not...wB            xDecodeError := TRUE;x€            eDecodeError := ERROR.OhMy_ThatShouldNotHaveHappenedy                 ; //This isn't even a possible value of the PayloadDecodeStates;zÌ            i := _protobufBlobLower + _diPayloadSize - 1; //break out of FOR   NO IDEA WHAT TO DO HERE{         END_CASE|    END_FOR}Z    eDecodeState := PayloadDecodeStates.idle;~J    xDecodeDone  := NOT xDecodeError;END_IF;€&IF xEncodeBusy THENh    //NOTE: BLOB Data will not be initialized to 00.‚\    //But we will start with a 0 byte payload.ƒ*    InitializeBlob();„8    i := _protobufBlobLower;…N    //Encode Timestamp (Field Number 1)†x    IF eEncodeError = ERROR.NO_ERROR AND _xHasTimestamp THEN‡„        //{info 'todo: i-campbell Make these field numbers a GVL'}ˆZ        dviTemp.uliDateTime := _uliTimestamp;‰”        eEncodeError        := EncodeNextVarInt( ValueToEncode := dviTemp,Š˜                                                 ProtobufFieldNumber := 1 );‹n        xEncodeError := eEncodeError <> ERROR.NO_ERROR;Œ    END_IF;0    //Encode All MetricsŽp    _Metrics.ItterateRestart( HasNext => _COL_HasNext );z    WHILE _COL_HasNext AND (eEncodeError = ERROR.NO_ERROR) DOt        _Metrics.ItterateNext( itfElement => _COL_Element,‘r                               HasNext => _COL_HasNext );’P        IF __QUERYPOINTER( _COL_Element,“h                           nextMetricToEncode ) THEN”d            nextMetricToEncode^( xDecode := FALSE,•b                                 xEncode := TRUE,–p                                 ProtobufBlobIndex := i,—˜                                 protobufBlobMaxIndex := _protobufBlobUpper,˜n                                 OwnerPayload := THIS^,™„                                 myProtobufBlob := myProtobufBlob,š`                                 xDecodeDone =>,›`                                 xDecodeBusy =>,œb                                 xDecodeError =>,b                                 eDecodeError =>,ž`                                 xEncodeDone =>,Ÿ`                                 xEncodeBusy =>, |                                 xEncodeError => xEncodeError,¡€                                 eEncodeError => eEncodeError );¢        END_IF;£    END_WHILE¤     //Encode Seq¥l    IF eEncodeError = ERROR.NO_ERROR AND _xHasSeq THEN¦D        dviTemp.Uint64 := _uliSeq;§Š        eEncodeError   := EncodeNextVarInt( ValueToEncode := dviTemp,¨Ž                                            ProtobufFieldNumber := 3 );©"    //Encode UUIDªn    IF eEncodeError = ERROR.NO_ERROR AND _xHasUuid THEN«„        eEncodeError := EncodeNextString( ValueToEncode := _sUuid,¬Š                                          ProtobufFieldNumber := 4 );­"    //Encode Body®j    //{info 'todo: i-campbell implement encode body'}¯n    IF eEncodeError = ERROR.NO_ERROR AND _xHasBody THEN°Z        eEncodeError := ERROR.NotImplemented;±¶    // i is pointing to the array index 1 after the end of the payload so return the length²^    _diPayloadSize   := i - _protobufBlobLower;³N    protobufBlobSize := _diPayloadSize;´    //DONE :)µH    xEncodeDone := NOT xEncodeError;¶2    xEncodeBusy := FALSE;·Interface¸L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}¹(*ºÆ    Represents the sparkplugb data to be sent in a MQTT Publisher or received by an MQTT Subscriber»ž	It contains data for both the raw bytes and also a structured view of the data¼|	It contains code to transform either from or to the raw bytes½º	IF BOTH xDecode and xEncode are set, an error will be given for both and nothing will happen¾*)¿${attribute 'hide'}À2FUNCTION_BLOCK FB_PayloadÁVAR_INPUTÂ<    (*Trigers for conversion*)Ãâ    xDecode                : BOOL;                 //Based on CBML.LCon.  Current implementation, It will always xDone or xError every cycle, it never takes more than one cycle Äà    xEncode                : BOOL;                 //Based on CBML.LCon.  Current implementation, It will always xDone or xError every cycle, it never takes more than one cycleÅÐ    protobufBlobStartIndex : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use LOWER_BOUNDÆÐ    protobufBlobMaxIndex   : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use UPPER_BOUNDǬ    myBodyPool             : POINTER TO BYTE;      //for example Payload.Metric[].BodyȦ    myBodyPoolSize         : __XINT;               //Size in bytes of the Body PoolÉEND_VARÊVAR_IN_OUTËD    protobufBlobSize        : DINTÌ´    ;                                           //size in bytes.  for encode, this FB will write the size here.  for decode, the caller must tell the sizeÍÀ    myProtobufBlob          : ARRAY[*] OF BYTE; //array of bytes containing the protobuf payloadÎVAR_OUTPUTÏæ    xDecodeDone, xDecodeBusy, xDecodeError : BOOL; //Based on CBML.LCon, but will automatically be reset if xDecodeÐf    eDecodeError                           : ERROR;Ñæ    xEncodeDone, xEncodeBusy, xEncodeError : BOOL; //Based on CBML.LCon, but will automatically be reset if xEncodeÒf    eEncodeError                           : ERROR;ÓVARÔT    i                              : DINT;Õr    eDecodeState                   : PayloadDecodeStates;Öf    dviTemp                        : DecodedVarInt;×x    KeysPool                       : List;             //OF Ø„    PropertySetValuesFactory       : PayloadPropertyValueFactory; Ù 	PropertySetValuesPool          : List;             //OF FB_PayloadPropertyValueÚx    PropertySetsPool               : List;             //OF Ûx    DataSetColumnsPool             : List;             //OF Üx    DataSetTypesPool               : List;             //OF Ýx    RowsPool                       : List;             //OF Þx    ElementsPool                   : List;             //OF ßx    ParametersPool                 : List;             //OF àn	MetricsFactory                 : PayloadMetricFactory;ᘠ   MetricsPool                    : List;             //OF FB_PayloadMetricâN	BodyPoolFreeIndex              : DINT;ㆠ   recentlyClaimedMetric          : REFERENCE TO FB_PayloadMetric;ä‚    nextMetricToEncode             : POINTER TO FB_PayloadMetric;åT    _COL_HasNext                   : BOOL;æ\    _COL_Element                   : IElement;ç*    (* Binary Blob *)è¸    //_pbPayload : MOVED_TO_myPayloadARRAY__OF_BYTE; //array of bytes containing the payloadé®    _diPayloadSize     : DINT;                 //Size in Bytes.  Actual size of messageêÈ    _protobufBlobLower : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use LOWER_BOUNDëÈ    _protobufBlobUpper : DINT := 16#7FFF_FFFF; //It is conceivable, you don't want to pass me the whole array. If this value is MaxDint, I will just use UPPER_BOUNDì2    (* Structured data *)í¶    //     optional uint64   timestamp     = 1;        // Timestamp at message sending timeî4    _xHasTimestamp : BOOL;ï@    _uliTimestamp  : T_DateTime;ðÒ    //     repeated Metric   metrics       = 2;        // Repeated forever - no limit in Google Protobufsñ8    //uliHasMetrics : ULINT;òŽ    //uliMaxMetrics : ULINT;                //Size of the Metrics arrayób    _Metrics : List; //Array of FB_PayloadMetricsô’    //     optional uint64   seq           = 3;        // Sequence numberõ(    _xHasSeq : BOOL;öP    _uliSeq  : ULINT; // Sequence number÷æ    //     optional string   uuid          = 4;        // UUID to track message type in terms of schema definitionsø*    _xHasUuid : BOOL;ùª    _sUuid    : WSTRING; // UUID to track message type in terms of schema definitionsúÒ    //     optional bytes    body          = 5;        // To optionally bypass the whole definition aboveûÆ    _xHasBody        : BOOL; // it is feasible for a "body" to have 0 bytes, so we use this as wellüÌ    _diHasBody_bytes : DINT; // there's only at most 1 body, but this number represents how many bytesýÀ    _diStartOfBody   : DINT; // Array Index to the start position in FB_Payload.myBodyPool[] make up the "body", To optionally bypass the whole definition aboveþ¨    //     extensions                      6 to max;   // For third party extensionsÿ<    //     IC: NOT IMPLEMENTED€"UniqueIdGenerator3422‚POULevelƒL{8e575c5b-1d37-49c6-941b-5c0ec7874787}„Standard… ChildObjectGuids†8System.Collections.ArrayList‡,AddAttributeSubsequentˆboolÐÐ-ÐÐ	E
 ÙÐÐ
­aÚÐ-ÐÐ
­bÚÐ-ÐÐ
­cÚÐ-ÐÐ
­dÚÐ-ÐÐ
­eÚÐ-ÐÐ
­fÚÐ-ÐÐ
­gÚÐ-ÐÐ
­hÚÐ-ÐÐ
­iÚÐ-ÐÐ
­jÚÐ-ÐÐ
­kÚÐ-ÐÐ
­lÚÐ-ÐÐ
­mÚÐ-ÐÐ
­nÚÐ-ÐÐ
­oÚÐ-ÐÐ
­pÚÐ-ÐÐ
­qÚÐ-ÐÐ
­rÚÐ-ÐÐ
­sÚÐ-ÐÐ
­tÚÐ-ÐÐ
­uÚÐ-ÐÐ
­vÚÐ- ÐÐ
­wÚÐ-ÐÐ
­xÚÐ-ÐÐ
­yÚÐ-ÐÐ
­zÚÐ-ÐÐ
­{ÚÐ-ÐÐ
­|ÚÐ-ÐÐ
­}ÚÐ-!ÐÐ
­~ÚÐ-ÐÐ
­ÚÐ-ÐÐ
­€ÚÐ-ÐÐ
­ÚÐ-ÐÐ
­‚ÚÐ-ÐÐ
­ƒÚÐ-"ÐÐ
­„ÚÐ-ÐÐ
­…ÚÐ-ÐÐ
­†ÚÐ-#ÐÐ
­‡ÚÐ-$ÐÐ
­ˆÚÐ-%ÐÐ
­’ÚÐ-&ÐÐ
­“ÚÐ-$ÐÐ
­”ÚÐ-'ÐÐ
­•ÚÐ-(ÐÐ
­–ÚÐ-)ÐÐ
­—ÚÐ-*ÐÐ
­˜ÚÐ-+ÐÐ
­™ÚÐ-,ÐÐ
­šÚÐ--ÐÐ
­›ÚÐ-.ÐÐ
­œÚÐ-/ÐÐ
­ÚÐ-0ÐÐ
­žÚÐ-1ÐÐ
­ŸÚÐ-2ÐÐ
­ ÚÐ-3ÐÐ
­¡ÚÐ-4ÐÐ
­¢ÚÐ-5ÐÐ
­£ÚÐ-6ÐÐ
­¤ÚÐ-7ÐÐ
­¥ÚÐ-8ÐÐ
­¦ÚÐ-9ÐÐ
­§ÚÐ-:ÐÐ
­¨ÚÐ-;ÐÐ
­©ÚÐ-<ÐÐ
­ªÚÐ-=ÐÐ
­«ÚÐ->ÐÐ
­¬ÚÐ-?ÐÐ
­­ÚÐ-@ÐÐ
­®ÚÐ-AÐÐ
­¯ÚÐ-BÐÐ
­°ÚÐ-CÐÐ
­±ÚÐ-DÐÐ
­²ÚÐ-EÐÐ
­³ÚÐ-FÐÐ
­´ÚÐ-GÐÐ
­µÚÐ-HÐÐ
­¶ÚÐ-IÐÐ
­·ÚÐ-JÐÐ
­¸ÚÐ-KÐÐ
­ºÚÐ-$ÐÐ
­»ÚÐ-LÐÐ
­¼ÚÐ-MÐÐ
­½ÚÐ-NÐÐ
­¾ÚÐ-OÐÐ
­¿ÚÐ-PÐÐ
­ÀÚÐ-QÐÐ
­ÁÚÐ-RÐÐ
­ÂÚÐ-SÐÐ
­ÍÚÐ-TÐÐ
­ÎÚÐ-UÐÐ
­ÏÚÐ-VÐÐ
­ÐÚÐ-WÐÐ
­ÑÚÐ-$ÐÐ
­ÒÚÐ-XÐÐ
­ÓÚÐ-YÐÐ
­ÔÚÐ-ZÐÐ
­ÕÚÐ-[ÐÐ
­ÖÚÐ-\ÐÐ
­×ÚÐ-]ÐÐ
­ØÚÐ-2ÐÐ
­ÙÚÐ-^ÐÐ
­ÚÚÐ-_ÐÐ
­ÛÚÐ-`ÐÐ
­ÜÚÐ-aÐÐ
­ÝÚÐ-bÐÐ
­ÞÚÐ-$ÐÐ
­ßÚÐ-cÐÐ
­àÚÐ-dÐÐ
­áÚÐ-eÐÐ
­âÚÐ-@ÐÐ
­ãÚÐ-fÐÐ
­äÚÐ-gÐÐ
­åÚÐ-hÐÐ
­æÚÐ-iÐÐ
­çÚÐ-jÐÐ
­èÚÐ-kÐÐ
­éÚÐ-lÐÐ
­êÚÐ-mÐÐ
­ëÚÐ-nÐÐ
­ìÚÐ-oÐÐ
­íÚÐ-pÐÐ
­îÚÐ-mÐÐ
­ïÚÐ-qÐÐ
­ðÚÐ-rÐÐ
­ñÚÐ-sÐÐ
­òÚÐ-tÐÐ
­óÚÐ-$ÐÐ
­ôÚÐ-mÐÐ
­õÚÐ-uÐÐ
­öÚÐ-vÐÐ
­÷ÚÐ-wÐÐ
­øÚÐ-xÐÐ
­ùÚÐ-yÐÐ
­úÚÐ-$ÐÐ
­ûÚÐ-zÐÐ
­üÚÐ-{ÐÐ
­ýÚÐ-|ÐÐ
­þÚÐ-$ÐÐ
­ÿÚÐ-}ÐÐ
­
ÚÐ-~ÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-$ÐÐ
­
ÚÐ-€ÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-‚ÐÐ
­
ÚÐ-ƒÐÐ
­
ÚÐ-)ÐÐ
­	
ÚÐ-„ÐÐ
­
 
ÚÐ-…ÐÐ
­
ÚÐ-†ÐÐ
­
ÚÐ-‡ÐÐ
­

ÚÐ-ˆÐÐ
­
ÚÐ-‰ÐÐ
­
ÚÐ-ŠÐÐ
­
ÚÐ-$ÐÐ
­
ÚÐ-‹ÐÐ
­
ÚÐ-ŒÐÐ
­
ÚÐ-$ÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-ŽÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-ÐÐ
­
ÚÐ-‘ÐÐ
­
ÚÐ-$ÐÐ
­
ÚÐ-’ÐÐ
­
ÚÐ-“ÐÐ
­
ÚÐ-”ÐÐ
­
ÚÐ-•ÐÐ
­
ÚÐ-–ÐÐ
­
ÚÐ-—ÐÐ
­ 
ÚÐ-˜ÐÐ
­!
ÚÐ-™ÐÐ
­,
ÚÐ-šÐÐ
­-
ÚÐ-›ÐÐ
­.
ÚÐ-œÐÐ
­/
ÚÐ-ÐÐ
­0
ÚÐ-žÐÐ
­1
ÚÐ-ŸÐÐ
­2
ÚÐ- ÐÐ
­3
ÚÐ-¡ÐÐ
­4
ÚÐ-¢ÐÐ
­5
ÚÐ-£ÐÐ
­6
ÚÐ-$ÐÐ
­7
ÚÐ-¤ÐÐ
­8
ÚÐ-¥ÐÐ
­9
ÚÐ-‡ÐÐ
­:
ÚÐ-¦ÐÐ
­;
ÚÐ-§ÐÐ
­<
ÚÐ-¨ÐÐ
­=
ÚÐ-$ÐÐ
­>
ÚÐ-‹ÐÐ
­?
ÚÐ-ŒÐÐ
­@
ÚÐ-$ÐÐ
­A
ÚÐ-©ÐÐ
­B
ÚÐ-ªÐÐ
­C
ÚÐ-‡ÐÐ
­D
ÚÐ-«ÐÐ
­E
ÚÐ-¬ÐÐ
­F
ÚÐ-$ÐÐ
­G
ÚÐ-‹ÐÐ
­H
ÚÐ-ŒÐÐ
­I
ÚÐ-$ÐÐ
­J
ÚÐ-­ÐÐ
­K
ÚÐ-®ÐÐ
­L
ÚÐ-¯ÐÐ
­M
ÚÐ-°ÐÐ
­N
ÚÐ-‹ÐÐ
­O
ÚÐ-ŒÐÐ
­P
ÚÐ-$ÐÐ
­Q
ÚÐ-±ÐÐ
­R
ÚÐ-²ÐÐ
­S
ÚÐ-³ÐÐ
­T
ÚÐ-´ÐÐ
­U
ÚÐ-µÐÐ
­V
ÚÐ-¶ÐÐ
­	ÚÐ-з¸Ð	E
-IÐÐ
­ÚÐ-¹ÐÐ
­ÚÐ-ºÐÐ
­ÚÐ-»ÐÐ
­ÚÐ-¼ÐÐ
­ÚÐ-½ÐÐ
­ÚÐ-¾ÐÐ
­ÚÐ-¿ÐÐ
­ÚÐ-ÀÐÐ
­ÚÐ-ÁÐÐ
­ÚÐ-ÂÐÐ
­ÚÐ-ÃÐÐ
­ÚÐ-ÄÐÐ
­ÚÐ-ÅÐÐ
­ ÚÐ-ÆÐÐ
­X
ÚÐ-ÇÐÐ
­Y
ÚÐ-ÈÐÐ
­!ÚÐ-ÉÐÐ
­"ÚÐ-ÊÐÐ
­#ÚÐ-ËÐÐ
­$ÚÐ-ÌÐÐ
­%ÚÐ-ÍÐÐ
­0ÚÐ-ÉÐÐ
­1ÚÐ-ÎÐÐ
­2ÚÐ-ÏÐÐ
­3ÚÐ-ÐÐÐ
­4ÚÐ-ÑÐÐ
­5ÚÐ-ÒÐÐ
­6ÚÐ-ÉÐÐ
­7ÚÐ-ÓÐÐ
­8ÚÐ-ÔÐÐ
­9ÚÐ-ÕÐÐ
­:ÚÐ-ÖÐÐ
­;ÚÐ-×ÐÐ
­<ÚÐ-ØÐÐ
­=ÚÐ-ÙÐÐ
­>ÚÐ-ÚÐÐ
­?ÚÐ-ÛÐÐ
­@ÚÐ-ÜÐÐ
­AÚÐ-ÝÐÐ
­BÚÐ-ÞÐÐ
­[
ÚÐ-ßÐÐ
­CÚÐ-àÐÐ
­Z
ÚÐ-áÐÐ
­DÚÐ-âÐÐ
­EÚÐ-ãÐÐ
­FÚÐ-äÐÐ
­GÚÐ-åÐÐ
­HÚÐ-æÐÐ
­IÚÐ-çÐÐ
­JÚÐ-èÐÐ
­KÚÐ-éÐÐ
­LÚÐ-êÐÐ
­MÚÐ-ëÐÐ
­NÚÐ-ìÐÐ
­OÚÐ-íÐÐ
­PÚÐ-îÐÐ
­QÚÐ-ïÐÐ
­RÚÐ-ðÐÐ
­SÚÐ-ñÐÐ
­TÚÐ-òÐÐ
­UÚÐ-óÐÐ
­VÚÐ-ôÐÐ
­WÚÐ-õÐÐ
­XÚÐ-öÐÐ
­YÚÐ-÷ÐÐ
­ZÚÐ-øÐÐ
­[ÚÐ-ùÐÐ
­\ÚÐ-úÐÐ
­]ÚÐ-ûÐÐ
­^ÚÐ-üÐÐ
­_ÚÐ-ýÐÐ
­`ÚÐ-þÐÐ
­ÚÐ-ÉÐÿ-€Ё‚-ƒ„…І‡­
\ No newline at end of file
+JÐÐ
­ÚÐ-¹ÐÐ
­ÚÐ-ºÐÐ
­ÚÐ-»ÐÐ
­ÚÐ-¼ÐÐ
­ÚÐ-½ÐÐ
­ÚÐ-¾ÐÐ
­ÚÐ-¿ÐÐ
­ÚÐ-ÀÐÐ
­ÚÐ-ÁÐÐ
­ÚÐ-ÂÐÐ
­ÚÐ-ÃÐÐ
­ÚÐ-ÄÐÐ
­ÚÐ-ÅÐÐ
­ ÚÐ-ÆÐÐ
­X
ÚÐ-ÇÐÐ
­Y
ÚÐ-ÈÐÐ
­!ÚÐ-ÉÐÐ
­"ÚÐ-ÊÐÐ
­#ÚÐ-ËÐÐ
­$ÚÐ-ÌÐÐ
­%ÚÐ-ÍÐÐ
­0ÚÐ-ÉÐÐ
­1ÚÐ-ÎÐÐ
­2ÚÐ-ÏÐÐ
­3ÚÐ-ÐÐÐ
­4ÚÐ-ÑÐÐ
­5ÚÐ-ÒÐÐ
­6ÚÐ-ÉÐÐ
­7ÚÐ-ÓÐÐ
­8ÚÐ-ÔÐÐ
­9ÚÐ-ÕÐÐ
­:ÚÐ-ÖÐÐ
­;ÚÐ-×ÐÐ
­<ÚÐ-ØÐÐ
­^
ÚÐ-ÙÐÐ
­=ÚÐ-ÚÐÐ
­>ÚÐ-ÛÐÐ
­?ÚÐ-ÜÐÐ
­@ÚÐ-ÝÐÐ
­AÚÐ-ÞÐÐ
­BÚÐ-ßÐÐ
­[
ÚÐ-àÐÐ
­CÚÐ-áÐÐ
­Z
ÚÐ-âÐÐ
­DÚÐ-ãÐÐ
­EÚÐ-äÐÐ
­FÚÐ-åÐÐ
­GÚÐ-æÐÐ
­HÚÐ-çÐÐ
­IÚÐ-èÐÐ
­JÚÐ-éÐÐ
­KÚÐ-êÐÐ
­LÚÐ-ëÐÐ
­MÚÐ-ìÐÐ
­NÚÐ-íÐÐ
­OÚÐ-îÐÐ
­PÚÐ-ïÐÐ
­QÚÐ-ðÐÐ
­RÚÐ-ñÐÐ
­SÚÐ-òÐÐ
­TÚÐ-óÐÐ
­UÚÐ-ôÐÐ
­VÚÐ-õÐÐ
­WÚÐ-öÐÐ
­XÚÐ-÷ÐÐ
­YÚÐ-øÐÐ
­ZÚÐ-ùÐÐ
­[ÚÐ-úÐÐ
­\ÚÐ-ûÐÐ
­]ÚÐ-üÐÐ
­^ÚÐ-ýÐÐ
­_ÚÐ-þÐÐ
­`ÚÐ-ÿÐÐ
­ÚÐ-ÉЀ-Ђƒ-„…†Їˆ­
\ No newline at end of file