1% 2% Copyright (c) ZeroC, Inc. All rights reserved. 3% 4 5classdef (Abstract) EncapsDecoder < handle 6 methods 7 function obj = EncapsDecoder(is, encaps, sliceValues, valueFactoryManager, classResolver) 8 obj.is = is; 9 obj.encaps = encaps; 10 obj.sliceValues = sliceValues; 11 obj.valueFactoryManager = valueFactoryManager; 12 obj.classResolver = classResolver; 13 obj.patchMap = containers.Map('KeyType', 'int32', 'ValueType', 'any'); 14 obj.unmarshaledMap = containers.Map('KeyType', 'int32', 'ValueType', 'any'); 15 obj.typeIdMap = containers.Map('KeyType', 'int32', 'ValueType', 'char'); 16 obj.typeIdIndex = 0; 17 obj.valueList = {}; 18 obj.delayedPostUnmarshal = {}; 19 end 20 21 function r = readOptional(obj, readTag, expectedFormat) 22 r = false; 23 end 24 25 function readPendingValues(obj) 26 end 27 28 function finish(obj) 29 % 30 % This is our opportunity for unmarshaled values to do some post processing after the initial round 31 % of unmarshaling is complete. 32 % 33 if ~isempty(obj.delayedPostUnmarshal) 34 % 35 % First call icePostUnmarshal on every instance. This allows the generated code to finish its tasks. 36 % 37 for i = 1:length(obj.delayedPostUnmarshal) 38 v = obj.delayedPostUnmarshal{i}; 39 v.icePostUnmarshal(); 40 end 41 % 42 % Then call ice_postUnmarshal on every instance. This is the application's interception point. 43 % 44 for i = 1:length(obj.delayedPostUnmarshal) 45 v = obj.delayedPostUnmarshal{i}; 46 try 47 v.ice_postUnmarshal(); 48 catch ex 49 msg = sprintf('exception raised by ice_postUnmarshal:\n%s', getReport(ex, 'extended')); 50 obj.is.getCommunicator().getLogger().warning(msg); 51 end 52 end 53 54 obj.delayedPostUnmarshal = {}; 55 end 56 end 57 end 58 methods(Abstract) 59 readValue(obj, cb) 60 throwException(obj) 61 startInstance(obj, sliceType) 62 r = endInstance(obj, preserve) 63 r = startSlice(obj) 64 endSlice(obj) 65 skipSlice(obj) 66 end 67 methods(Access=protected) 68 function r = readTypeId(obj, isIndex) 69 if isIndex 70 index = obj.is.readSize(); 71 % 72 % The map raises an exception if the key isn't present. 73 % 74 try 75 r = obj.typeIdMap(index); 76 catch ex 77 throw(Ice.UnmarshalOutOfBoundsException()); 78 end 79 else 80 r = obj.is.readString(); 81 obj.typeIdIndex = obj.typeIdIndex + 1; 82 obj.typeIdMap(obj.typeIdIndex) = r; 83 end 84 end 85 86 function r = newInstance(obj, typeId) 87 % 88 % Try to find a factory registered for the specific type. 89 % 90 userFactory = obj.valueFactoryManager.find(typeId); 91 v = []; 92 if ~isempty(userFactory) 93 v = userFactory(typeId); 94 end 95 96 % 97 % If that fails, invoke the default factory if one has been registered. 98 % 99 if isempty(v) 100 userFactory = obj.valueFactoryManager.find(''); 101 if ~isempty(userFactory) 102 v = userFactory(typeId); 103 end 104 end 105 106 % 107 % Last chance: ask the class resolver to find it. 108 % 109 if isempty(v) 110 constructor = obj.classResolver.resolve(typeId); 111 if ~isempty(constructor) 112 try 113 v = constructor(); % Invoke the constructor. 114 catch e 115 reason = sprintf('constructor failed for %s', typeId); 116 ex = Ice.NoValueFactoryException('', reason, reason, typeId); 117 ex.addCause(e); 118 throw(ex); 119 end 120 end 121 end 122 123 r = v; 124 end 125 126 function addPatchEntry(obj, index, cb) 127 assert(index > 0); 128 129 % 130 % Check if we have already unmarshalled the instance. If that's the case, 131 % just invoke the callback and we're done. 132 % 133 if obj.unmarshaledMap.isKey(index) 134 v = obj.unmarshaledMap(index); 135 cb(v); 136 return; 137 end 138 139 % 140 % Add patch entry if the instance isn't unmarshaled yet, 141 % the callback will be called when the instance is 142 % unmarshaled. 143 % 144 pl = []; 145 if obj.patchMap.isKey(index) 146 pl = obj.patchMap(index); 147 else 148 % 149 % We have no outstanding instances to be patched for this 150 % index, so make a new entry in the patch map. 151 % 152 pl = IceInternal.PatchList(); 153 obj.patchMap(index) = pl; 154 end 155 156 % 157 % Append a patch entry for this instance. 158 % 159 pl.list{end + 1} = cb; 160 end 161 162 function unmarshal(obj, index, v) 163 % 164 % Add the instance to the map of unmarshaled instances, this must 165 % be done before reading the instances (for circular references). 166 % 167 obj.unmarshaledMap(index) = v; 168 169 % 170 % Read the instance. 171 % 172 v.iceRead(obj.is); 173 174 if ~isempty(obj.patchMap) && obj.patchMap.isKey(index) 175 % 176 % Patch all instances now that the instance is unmarshaled. 177 % 178 l = obj.patchMap(index); 179 assert(length(l.list) > 0); 180 181 % 182 % Patch all pointers that refer to the instance. 183 % 184 for i = 1:length(l.list) 185 cb = l.list{i}; 186 cb(v); 187 end 188 189 % 190 % Clear out the patch map for that index -- there is nothing left 191 % to patch for that index for the time being. 192 % 193 obj.patchMap.remove(index); 194 end 195 196 if (isempty(obj.patchMap) || obj.patchMap.Count == 0) && isempty(obj.valueList) 197 if v.iceDelayPostUnmarshal() 198 obj.delayedPostUnmarshal{end + 1} = v; % See finish() 199 else 200 try 201 v.ice_postUnmarshal(); 202 catch ex 203 msg = sprintf('exception raised by ice_postUnmarshal:\n%s', getReport(ex, 'extended')); 204 obj.is.getCommunicator().getLogger().warning(msg); 205 end 206 end 207 else 208 obj.valueList{end + 1} = v; 209 210 if isempty(obj.patchMap) || obj.patchMap.Count == 0 211 % 212 % Iterate over the instance list and invoke ice_postUnmarshal on 213 % each instance. We must do this after all instances have been 214 % unmarshaled in order to ensure that any instance data members 215 % have been properly patched. 216 % 217 for i = 1:length(obj.valueList) 218 p = obj.valueList{i}; 219 if p.iceDelayPostUnmarshal() 220 obj.delayedPostUnmarshal{end + 1} = p; % See finish() 221 else 222 try 223 p.ice_postUnmarshal(); 224 catch ex 225 msg = sprintf('exception raised by ice_postUnmarshal:\n%s', getReport(ex, 'extended')); 226 obj.is.getCommunicator().getLogger().warning(msg); 227 end 228 end 229 end 230 obj.valueList = {}; 231 end 232 end 233 end 234 end 235 properties(Access=protected) 236 is 237 encaps 238 sliceValues 239 valueFactoryManager 240 classResolver 241 patchMap 242 end 243 properties(Access=private) 244 unmarshaledMap 245 typeIdMap 246 typeIdIndex 247 valueList 248 delayedPostUnmarshal 249 end 250end 251