summaryrefslogtreecommitdiff
path: root/matlab/lib/+IceInternal/EncapsEncoder10.m
blob: 9eb5b0ae4a4943a8f8bd5a6bac66db9037799742 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
%{
**********************************************************************

Copyright (c) 2003-present ZeroC, Inc. All rights reserved.

This copy of Ice is licensed to you under the terms described in the
ICE_LICENSE file included in this distribution.

**********************************************************************
%}

classdef EncapsEncoder10 < IceInternal.EncapsEncoder
    methods
        function obj = EncapsEncoder10(os, encaps)
            obj = obj@IceInternal.EncapsEncoder(os, encaps);
            obj.sliceType = IceInternal.SliceType.NoSlice;
            obj.valueIdIndex = 0;
            obj.toBeMarshaledMap = containers.Map('KeyType', 'int32', 'ValueType', 'any');
            obj.marshaledMap = containers.Map('KeyType', 'int32', 'ValueType', 'any');
        end

        function writeValue(obj, v)
            %
            % Object references are encoded as a negative integer in 1.0.
            %
            if ~isempty(v)
                obj.os.writeInt(-obj.registerValue(v));
            else
                obj.os.writeInt(0);
            end
        end

        function startInstance(obj, sliceType, slicedData)
            obj.sliceType = sliceType;
        end

        function endInstance(obj)
            if obj.sliceType == IceInternal.SliceType.ValueSlice
                %
                % Write the Object slice.
                %
                obj.startSlice(Ice.Value.ice_staticId(), -1, true);
                obj.os.writeSize(0); % For compatibility with the old AFM.
                obj.endSlice();
            end
            obj.sliceType = IceInternal.SliceType.NoSlice;
        end

        function startSlice(obj, typeId, compactId, last)
            %
            % For instance slices, encode a boolean to indicate how the type ID
            % is encoded and the type ID either as a string or index. For
            % exception slices, always encode the type ID as a string.
            %
            if obj.sliceType == IceInternal.SliceType.ValueSlice
                index = obj.registerTypeId(typeId);
                if index < 0
                    obj.os.writeBool(false);
                    obj.os.writeString(typeId);
                else
                    obj.os.writeBool(true);
                    obj.os.writeSize(index);
                end
            else
                obj.os.writeString(typeId);
            end

            %obj.os.writeInt(0); % Placeholder for the slice length.
            obj.os.buf.resize(obj.os.buf.size + 4);

            obj.writeSlice = obj.os.getPos() + 1;
        end

        function endSlice(obj)
            %
            % Write the slice length.
            %
            sz = obj.os.getPos() - obj.writeSlice + 4 + 1;
            obj.os.rewriteInt(sz, obj.writeSlice - 4);
        end

        function writePendingValues(obj)
            while obj.toBeMarshaledMap.Count > 0
                %
                % Consider the to be marshalled instances as marshaled now,
                % this is necessary to avoid adding again the "to be
                % marshaled instances" into toBeMarshaledMap while writing
                % instances.
                %
                obj.marshaledMap = [obj.marshaledMap; obj.toBeMarshaledMap];

                savedMap = obj.toBeMarshaledMap;
                obj.toBeMarshaledMap = containers.Map('KeyType', 'int32', 'ValueType', 'any');
                obj.os.writeSize(savedMap.Count);
                keys = savedMap.keys();
                for i = 1:length(keys)
                    %
                    % Ask the instance to marshal itself. Any new class
                    % instances that are triggered by the classes marshaled
                    % are added to toBeMarshaledMap.
                    %
                    obj.os.writeInt(keys{i});

                    v = savedMap(keys{i});
                    try
                        v.ice_preMarshal();
                    catch ex
                        msg = sprintf('exception raised by ice_preMarshal:\n%s', getReport(ex, 'extended'));
                        obj.os.getCommunicator().getLogger().warning(msg);
                    end

                    v.iceWrite(obj.os);
                end
            end
            obj.os.writeSize(0); % Zero marker indicates end of sequence of sequences of instances.
        end
    end
    methods(Access=protected)
        function r = registerValue(obj, v)
            assert(~isempty(v));

            %
            % Use the identifier assigned by the Value constructor.
            %
            r = v.iceInternal_;

            %
            % Look for this instance in the to-be-marshaled map.
            %
            if obj.toBeMarshaledMap.isKey(r)
                return;
            end

            %
            % Didn't find it, try the marshaled map next.
            %
            if obj.marshaledMap.isKey(r)
                return;
            end

            %
            % We haven't seen this instance previously, create a new
            % index, and insert it into the to-be-marshaled map.
            %
            obj.toBeMarshaledMap(r) = v;
        end
    end
    properties(Access=private)
        sliceType
        writeSlice
        valueIdIndex
        toBeMarshaledMap
        marshaledMap
    end
end