]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/binary/BinaryString.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / accessor / binary / BinaryString.java
1 /*******************************************************************************\r
2  *  Copyright (c) 2010 Association for Decentralized Information Management in\r
3  *  Industry THTH ry.\r
4  *  All rights reserved. This program and the accompanying materials\r
5  *  are made available under the terms of the Eclipse Public License v1.0\r
6  *  which accompanies this distribution, and is available at\r
7  *  http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  *  Contributors:\r
10  *      VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.databoard.accessor.binary;
13
14 import java.io.IOException;\r
15 \r
16 import org.simantics.databoard.Bindings;\r
17 import org.simantics.databoard.accessor.Accessor;\r
18 import org.simantics.databoard.accessor.StringAccessor;\r
19 import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
20 import org.simantics.databoard.accessor.error.AccessorException;\r
21 import org.simantics.databoard.accessor.error.ReferenceException;\r
22 import org.simantics.databoard.accessor.event.Event;\r
23 import org.simantics.databoard.accessor.event.ValueAssigned;\r
24 import org.simantics.databoard.accessor.file.FileStringAccessor;\r
25 import org.simantics.databoard.accessor.impl.AccessorParams;\r
26 import org.simantics.databoard.accessor.impl.ListenerEntry;\r
27 import org.simantics.databoard.accessor.interestset.StringInterestSet;\r
28 import org.simantics.databoard.accessor.reference.ChildReference;\r
29 import org.simantics.databoard.binding.Binding;\r
30 import org.simantics.databoard.binding.StringBinding;\r
31 import org.simantics.databoard.binding.error.BindingException;\r
32 import org.simantics.databoard.type.StringType;\r
33 import org.simantics.databoard.util.binary.Blob;\r
34 import org.simantics.databoard.util.binary.Endian;\r
35 import org.simantics.databoard.util.binary.UTF8;\r
36
37 public class BinaryString extends BinaryObject implements StringAccessor, FileStringAccessor {
38
39         public BinaryString(BinaryObject parent, Blob blob, StringType type, AccessorParams params) 
40         throws AccessorConstructionException {
41                 super(parent, blob, type, params);
42         }
43
44         @Override
45         public StringType type() {
46                 return (StringType) type;
47         }
48
49         @Override
50         Event applyLocal(Event e, boolean makeRollback) throws AccessorException {
51                 Event rollback = makeRollback ? new ValueAssigned( Bindings.STRING, getValue() ) : null;                \r
52                 if (e instanceof ValueAssigned) {\r
53                         ValueAssigned va = (ValueAssigned) e;\r
54                         if (va.newValue == null) throw new AccessorException("String value expected, got null");                        \r
55                         setValueNoflush(va.newValue.getBinding(), va.newValue.getValue());\r
56                         return rollback;\r
57                 } else {\r
58                         throw new AccessorException("Cannot apply "+e.getClass().getName()+" to String");\r
59                 }
60         }
61
62         @SuppressWarnings("unchecked")
63         @Override
64         public <T extends Accessor> T getComponent(ChildReference reference)
65                         throws AccessorConstructionException {
66                 if (reference==null) return (T) this;           
67                 throw new ReferenceException(reference.getClass()+" is not a subreference of StringType");      
68         }
69         
70         @Override
71         public Object getValue(Binding binding) throws AccessorException {\r
72                 try {
73                         StringBinding bb = (StringBinding) binding; 
74                         String v = getValue();
75                         return bb.create(v);
76                 } catch(BindingException e) {           
77                         throw new AccessorException(e);
78                 }
79         }\r
80 // MODIFIED UTF-8       \r
81         @Override\r
82         public String getValue() throws AccessorException {\r
83                 assert b.isOpen();\r
84                 readLock();\r
85                 try {\r
86                         b.position(0L);         \r
87                         \r
88                         int utflen = Endian.readDynamicUInt32(b);\r
89                         return UTF8.readModifiedUTF(b, utflen);\r
90                 } catch (IOException e) {\r
91                         throw new AccessorException(e);\r
92                 } finally {\r
93                         readUnlock();\r
94                 }\r
95         }\r
96         \r
97         public void setValueNoflush(String string) throws AccessorException {\r
98                 assert b.isOpen();\r
99                 writeLock();\r
100                 try {\r
101                         // Write\r
102                         b.position(0);\r
103                         int strlen = UTF8.getModifiedUTF8EncodingByteLength(string);\r
104                         int lenlen = Endian.getDynamicUInt32Length(strlen);\r
105                         b.setLength(strlen+lenlen);\r
106                         Endian.writeDynamicUInt32(b, strlen);\r
107                         UTF8.writeModifiedUTF(b, string);\r
108                         \r
109                         // Notify\r
110                         ListenerEntry le = listeners;\r
111                         while (le!=null) {\r
112                                 StringInterestSet is = le.getInterestSet();\r
113                                 if (is.inNotifications()) {                                     \r
114                                         Event e = new ValueAssigned( Bindings.STRING, is.inValues() ? string : null );\r
115                                         emitEvent(le, e);\r
116                                 }\r
117                                 le = le.next;\r
118                         }\r
119                         \r
120                 } catch (IOException e) {\r
121                         throw new AccessorException(e);\r
122                 } finally {\r
123                         writeUnlock();\r
124                 }\r
125         }\r
126         
127 /* REAL UTF-8\r
128         @Override\r
129         public String getValue() throws AccessorException {\r
130                 readLock();\r
131                 try {\r
132                         b.position(0L);\r
133                         int length = UTF8StringSerializer.getLength(b); \r
134                         byte[] bytes = new byte[length];\r
135                         b.readFully(bytes);\r
136                         return new String(bytes, UTF8StringSerializer.UTF8);\r
137                 } catch (IOException e) {\r
138                         throw new AccessorException(e);\r
139                 } finally {\r
140                         readUnlock();\r
141                 }\r
142         }\r
143         
144         public void setValueNoflush(String string) throws AccessorException {\r
145                 writeLock();
146                 try {
147                         // Write
148                         int stringByteLength = UTF8StringSerializer.getUTF8EncodingByteLength( string ); 
149                         int lengthLength = UTF8StringSerializer.getSizeOfPutLength( stringByteLength );
150                         int len = stringByteLength + lengthLength; 
151                         
152                         b.position(0);
153                         b.setLength(len);
154                         byte[] bytes = string.getBytes( UTF8StringSerializer.UTF8 );
155                         UTF8StringSerializer.putLength(b, bytes.length);
156                         b.put(bytes);                   
157                         
158                         // Notify
159                         ListenerEntry le = listeners;
160                         while (le!=null) {
161                                 StringInterestSet is = le.getInterestSet();
162                                 if (is.inNotifications()) {                                     
163                                         Event e = new ValueAssigned( Bindings.STRING, is.inValues() ? string : null );
164                                         emitEvent(le, e);
165                                 }
166                                 le = le.next;
167                         }
168                         
169                 } catch (IOException e) {
170                         throw new AccessorException(e);
171                 } finally {\r
172                         writeUnlock();\r
173                 }
174         }
175 */      
176         @Override
177         public void setValue(String string) throws AccessorException {\r
178                 assert b.isOpen();\r
179                 writeLock();
180                 try {
181                         setValueNoflush(string);
182                         b.flush();
183                 } catch (IOException e) {
184                         throw new AccessorException(e);
185                 } finally {\r
186                         writeUnlock();\r
187                 }
188         }
189         
190         @Override
191         public void setValueNoflush(Binding binding, Object newValue)
192                         throws AccessorException {
193                 try {
194                         String nv = ((StringBinding)binding).getValue(newValue);
195                         setValueNoflush(nv);
196                 } catch (BindingException e) {
197                         throw new AccessorException(e);
198                 }
199         }
200         
201 }
202