2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015-2015 - Scilab Enterprises - Clement DAVID
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
12 package org.scilab.modules.xcos.io.writer;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.Map.Entry;
18 import java.util.logging.Level;
20 import javax.xml.stream.XMLStreamException;
22 import org.scilab.modules.types.ScilabBoolean;
23 import org.scilab.modules.types.ScilabDouble;
24 import org.scilab.modules.types.ScilabInteger;
25 import org.scilab.modules.types.ScilabString;
26 import org.scilab.modules.types.ScilabType;
27 import org.scilab.modules.types.ScilabTypeEnum;
28 import org.scilab.modules.xcos.Kind;
29 import org.scilab.modules.xcos.ObjectProperties;
30 import org.scilab.modules.xcos.VectorOfDouble;
31 import org.scilab.modules.xcos.VectorOfInt;
32 import org.scilab.modules.xcos.VectorOfString;
33 import org.scilab.modules.xcos.io.ScilabTypeCoder;
35 public class RawDataWriter extends ScilabWriter {
38 * Shared map information used to avoid duplicated entry on the dictionary
40 private final HashMap<ScilabType, Integer> dictionaryMap;
42 public RawDataWriter(XcosWriter writer) {
45 dictionaryMap = new HashMap<>();
49 * Fill the shared dictinary with the encoded mapping
51 public void fillSharedDictionary() {
52 if (shared.dictionary == null) {
56 // reserve the size with null values
57 shared.dictionary.addAll(Collections.nCopies(dictionaryMap.size(), new ScilabDouble()));
59 // push all the values
60 for (Entry<ScilabType, Integer> entry : dictionaryMap.entrySet()) {
61 shared.dictionary.set(entry.getValue(), entry.getKey());
66 public void write(long uid, Kind kind) throws XMLStreamException {
70 writeBlock(uid, kind);
73 writeContext(uid, kind);
75 case LINK: // no break on purpose
76 case ANNOTATION: // no break on purpose
82 private void writeContext(long uid, Kind kind) throws XMLStreamException {
83 VectorOfString context = new VectorOfString();
84 shared.controller.getObjectProperty(uid, kind, ObjectProperties.DIAGRAM_CONTEXT, context);
86 String[] value = new String[context.size()];
87 for (int i = 0; i < value.length; i++) {
88 value[i] = context.get(i);
90 write(value, "context");
93 private void writeBlock(long uid, Kind kind) throws XMLStreamException {
94 VectorOfDouble vDouble = new VectorOfDouble();
95 VectorOfInt vInt = new VectorOfInt();
97 shared.controller.getObjectProperty(uid, kind, ObjectProperties.EXPRS, vDouble);
98 write(new ScilabTypeCoder().vec2var(vDouble), "exprs");
100 shared.controller.getObjectProperty(uid, kind, ObjectProperties.RPAR, vDouble);
101 write(vDouble, "realParameters");
103 shared.controller.getObjectProperty(uid, kind, ObjectProperties.IPAR, vInt);
104 write(vInt, "integerParameters");
106 shared.controller.getObjectProperty(uid, kind, ObjectProperties.OPAR, vDouble);
107 write(new ScilabTypeCoder().vec2var(vDouble), "objectsParameters");
109 shared.controller.getObjectProperty(uid, kind, ObjectProperties.NZCROSS, vInt);
110 write(vInt, "nbZerosCrossing");
112 shared.controller.getObjectProperty(uid, kind, ObjectProperties.NMODE, vInt);
113 write(vInt, "nmode");
115 shared.controller.getObjectProperty(uid, kind, ObjectProperties.DSTATE, vDouble);
116 write(vDouble, "dState");
118 shared.controller.getObjectProperty(uid, kind, ObjectProperties.EQUATIONS, vDouble);
119 write(new ScilabTypeCoder().vec2var(vDouble), "equations");
123 * Low-level serialization methods
126 private void write(String[] value, String as) throws XMLStreamException {
127 shared.stream.writeStartElement("Array");
128 shared.stream.writeAttribute("as", as);
129 shared.stream.writeAttribute("scilabClass", "String[]");
131 for (String v : value) {
132 shared.stream.writeEmptyElement("add");
133 shared.stream.writeAttribute("value", v);
136 shared.stream.writeEndElement(); // Array
139 private void write(ScilabType value, String as) throws XMLStreamException {
140 if (shared.dictionary == null) {
141 writeAsXml(value, as);
143 writeAsBinary(value, as);
147 private void writeAsXml(ScilabType value, String as) throws XMLStreamException {
148 ScilabTypeEnum type = value.getType();
149 final String localName;
150 final String scilabClass;
151 final String intPrecision;
154 * Get the right descriptor
158 localName = "ScilabBoolean";
163 localName = "ScilabInteger";
165 intPrecision = ((ScilabInteger) value).getPrec().name();
168 localName = "ScilabDouble";
173 localName = "ScilabString";
179 scilabClass = "ScilabList";
184 scilabClass = "ScilabMList";
189 scilabClass = "ScilabTList";
193 throw new XMLStreamException("Not handled ScilabType : " + type.name());
199 final int len = value.getHeight() * value.getWidth();
201 shared.stream.writeStartElement(localName);
203 shared.stream.writeEmptyElement(localName);
206 shared.stream.writeAttribute("as", as);
209 if (value instanceof ArrayList) {
210 writeList(value, scilabClass);
212 writeMatrix(value, type, intPrecision);
216 shared.stream.writeEndElement();
220 private void writeList(ScilabType value, final String scilabClass) throws XMLStreamException {
221 shared.stream.writeAttribute("scilabClass", scilabClass);
223 @SuppressWarnings("unchecked")
224 ArrayList<ScilabType> values = (ArrayList<ScilabType>) value;
225 for (ScilabType subValue : values) {
226 write(subValue, null);
230 @SuppressWarnings("incomplete-switch")
231 private void writeMatrix(ScilabType value, ScilabTypeEnum type, final String intPrecision) throws XMLStreamException {
232 shared.stream.writeAttribute("height", Integer.toString(value.getHeight()));
233 shared.stream.writeAttribute("width", Integer.toString(value.getWidth()));
234 if (intPrecision != null) {
235 shared.stream.writeAttribute("intPrecision", value.getType().name());
238 for (int i = 0; i < value.getHeight(); i++) {
239 for (int j = 0; j < value.getWidth(); j++) {
240 shared.stream.writeEmptyElement("data");
241 shared.stream.writeAttribute("column", Integer.toString(i));
242 shared.stream.writeAttribute("line", Integer.toString(j));
246 boolean bValue = ((ScilabBoolean)value).getElement(i, j);
247 shared.stream.writeAttribute("value", Boolean.toString(bValue));
250 long lValue = ((ScilabInteger) value).getElement(i, j);
251 shared.stream.writeAttribute("value", Long.toString(lValue));
254 double dValue = ((ScilabDouble) value).getRealElement(i, j);
255 shared.stream.writeAttribute("realPart", Double.toString(dValue));
256 if (!((ScilabDouble) value).isReal()) {
257 dValue = ((ScilabDouble) value).getImaginaryElement(i, j);
258 shared.stream.writeAttribute("imaginaryPart", Double.toString(dValue));
262 String strValue = ((ScilabString) value).getData()[i][j];
263 shared.stream.writeAttribute("value", strValue);
270 private void writeAsBinary(ScilabType value, String as) throws XMLStreamException {
271 ScilabTypeEnum type = value.getType();
272 final String localName;
275 * Get the right descriptor
279 localName = "ScilabBoolean";
282 localName = "ScilabInteger";
285 localName = "ScilabDouble";
288 localName = "ScilabString";
290 case sci_list: // no break on purpose
291 case sci_mlist: // no break on purpose
296 throw new XMLStreamException("Not handled ScilabType : " + type.name());
303 // if the value has not been mapped, then use the next position (map.size())
304 // else re-use the same position
305 Integer expectedPosition = dictionaryMap.size();
306 Integer position = dictionaryMap.putIfAbsent(value, expectedPosition);
307 if (position == null) {
308 position = expectedPosition;
311 if (XcosWriter.LOG.isLoggable(Level.FINE)) {
312 XcosWriter.LOG.fine("put:" + value.toString() + ":" + position.toString());
315 shared.stream.writeEmptyElement(localName);
316 shared.stream.writeAttribute("as", as);
317 shared.stream.writeAttribute("binary", "true");
318 shared.stream.writeAttribute("position", position.toString());
321 private void write(VectorOfDouble value, String as) throws XMLStreamException {
322 // recreate a ScilabDouble for the encoding
323 final int length = value.size();
325 double[][] data = new double[1][length];
326 value.asByteBuffer(0, length).asDoubleBuffer().get(data[0]);
327 write(new ScilabDouble(data), as);
329 write(new ScilabDouble(), as);
333 private void write(VectorOfInt value, String as) throws XMLStreamException {
334 // recreate a ScilabInteger for the encoding
335 final int length = value.size();
337 int[][] data = new int[1][length];
338 value.asByteBuffer(0, length).asIntBuffer().get(data[0]);
339 write(new ScilabInteger(data, false), as);
341 write(new ScilabDouble(), as);