1 package fi.vtt.simantics.procore.internal;
3 import org.simantics.db.AsyncReadGraph;
4 import org.simantics.db.DirectStatements;
5 import org.simantics.db.ReadGraph;
6 import org.simantics.db.RelationInfo;
7 import org.simantics.db.Resource;
8 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
9 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
10 import org.simantics.db.exception.AssumptionException;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.db.exception.NoSingleResultException;
13 import org.simantics.db.impl.ClusterI;
14 import org.simantics.db.impl.ClusterI.ClusterTypeEnum;
15 import org.simantics.db.impl.ForEachObjectContextProcedure;
16 import org.simantics.db.impl.ForEachObjectProcedure;
17 import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;
18 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
19 import org.simantics.db.impl.ResourceImpl;
20 import org.simantics.db.impl.TransientGraph;
21 import org.simantics.db.impl.graph.ReadGraphImpl;
22 import org.simantics.db.procedure.AsyncContextMultiProcedure;
23 import org.simantics.db.procedure.AsyncContextProcedure;
24 import org.simantics.db.procedure.AsyncMultiProcedure;
25 import org.simantics.db.procedure.AsyncProcedure;
26 import org.simantics.db.procedure.Procedure;
27 import org.simantics.db.procedure.SyncProcedure;
28 import org.simantics.db.procore.cluster.ClusterBig;
29 import org.simantics.db.procore.cluster.ClusterImpl;
30 import org.simantics.db.procore.cluster.ClusterSmall;
31 import org.simantics.db.procore.cluster.ResourceTableSmall;
32 import org.simantics.db.procore.cluster.ValueTableSmall;
33 import org.simantics.db.request.AsyncRead;
34 import org.simantics.db.service.DirectQuerySupport;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 public class DirectQuerySupportImpl implements DirectQuerySupport {
40 private static final Logger LOGGER = LoggerFactory.getLogger(DirectQuerySupportImpl.class);
42 final private SessionImplSocket session;
44 DirectQuerySupportImpl(SessionImplSocket session) {
45 this.session = session;
49 final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
50 ReadGraphImpl impl = (ReadGraphImpl)graph;
51 impl.processor.forEachDirectStatement(impl, subject, procedure, true);
55 final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
56 ReadGraphImpl impl = (ReadGraphImpl)graph;
57 impl.processor.forEachDirectStatement(impl, subject, procedure, false);
61 public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure) {
62 forEachDirectStatement(graph, subject, new SyncToAsyncProcedure<DirectStatements>(procedure));
66 public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure) {
67 ReadGraphImpl impl = (ReadGraphImpl)graph;
68 impl.processor.forEachDirectStatement(impl, subject, procedure);
72 public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure) {
73 ReadGraphImpl impl = (ReadGraphImpl)graph;
74 impl.processor.forRelationInfo(impl, subject, procedure);
78 public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure) {
79 forRelationInfo(graph, subject, new SyncToAsyncProcedure<RelationInfo>(procedure));
83 public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure) {
84 forRelationInfo(graph, subject, new NoneToAsyncProcedure<RelationInfo>(procedure));
88 public AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure<Resource> user) {
91 RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
94 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
95 forRelationInfo(graph, relation, procedure);
99 public int threadHash() {
104 public int getFlags() {
109 final int predicateKey = ((ResourceImpl)relation).id;
110 return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);
111 } catch (DatabaseException e) {
118 public <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure<C, Resource> user) {
121 RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
124 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
125 forRelationInfo(graph, relation, procedure);
129 public int threadHash() {
134 public int getFlags() {
139 final int predicateKey = ((ResourceImpl)relation).id;
140 return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);
141 } catch (DatabaseException e) {
148 public <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure<T> user) {
151 RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
154 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
155 forRelationInfo(graph, relation, procedure);
159 public int threadHash() {
164 public int getFlags() {
169 final int predicateKey = ((ResourceImpl)relation).id;
170 return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);
171 } catch (DatabaseException e) {
178 public <C, T> AsyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure<C, T> user) {
181 RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
184 public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
185 forRelationInfo(graph, relation, procedure);
189 public int threadHash() {
194 public int getFlags() {
199 final int predicateKey = ((ResourceImpl)relation).id;
200 return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);
201 } catch (DatabaseException e) {
208 public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure<Resource> procedure) {
210 assert(subject != null);
212 final ForEachObjectProcedure proc = (ForEachObjectProcedure)procedure;
213 // final RelationInfo info = proc.info;
215 final ReadGraphImpl impl = (ReadGraphImpl)graph;
216 final int subjectId = ((ResourceImpl)subject).id;
218 // int callerThread = impl.callerThread;
219 // int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;
223 // if(callerThread == suggestSchedule) {
225 // if(info.isFunctional) {
226 // querySupport.getObjects4(impl, subjectId, proc);
228 session.querySupport.getObjects4(impl, subjectId, proc);
233 // impl.state.barrier.inc();
234 // impl.state.barrier.dec(callerThread);
236 // queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {
239 // public void run(int thread) {
241 // impl.state.barrier.inc(thread);
242 // impl.state.barrier.dec();
244 // if(info.isFunctional) {
245 // querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);
247 // querySupport.getObjects4(impl.newAsync(thread), subjectId, proc);
253 // public String toString() {
264 public <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure<C, Resource> procedure) {
266 assert(subject != null);
268 final ForEachObjectContextProcedure<C> proc = (ForEachObjectContextProcedure<C>)procedure;
269 final RelationInfo info = proc.info;
271 final ReadGraphImpl impl = (ReadGraphImpl)graph;
272 final int subjectId = ((ResourceImpl)subject).id;
274 // int callerThread = impl.callerThread;
275 // int suggestSchedule = (subjectId>>16) & queryProvider2.THREAD_MASK;
279 if(info.isFunctional) {
280 session.querySupport.getObjects4(impl, subjectId, context, proc);
282 session.querySupport.getObjects4(impl, subjectId, context, proc);
288 public <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure<T> procedure) {
290 assert(subject != null);
292 final ForPossibleRelatedValueProcedure<T> proc = (ForPossibleRelatedValueProcedure<T>)procedure;
293 final RelationInfo info = proc.info;
295 final ReadGraphImpl impl = (ReadGraphImpl)graph;
296 final int subjectId = ((ResourceImpl)subject).id;
298 // int callerThread = impl.callerThread;
299 // int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;
303 // if(callerThread == suggestSchedule) {
305 if(info.isFunctional) {
306 getRelatedValue4(impl, subjectId, proc);
308 getRelatedValue4(impl, subjectId, proc);
313 // impl.state.barrier.inc();
314 // impl.state.barrier.dec(callerThread);
316 // queryProvider2.schedule(callerThread, new SessionTask(suggestSchedule) {
319 // public void run(int thread) {
321 // impl.state.barrier.inc(thread);
322 // impl.state.barrier.dec();
324 // if(info.isFunctional) {
325 // getRelatedValue4(impl.newAsync(thread), subjectId, proc);
327 // getRelatedValue4(impl.newAsync(thread), subjectId, proc);
333 // public String toString() {
344 public <C, T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure<C, T> procedure) {
346 assert(subject != null);
348 final ForPossibleRelatedValueContextProcedure<C, T> proc = (ForPossibleRelatedValueContextProcedure<C, T>)procedure;
349 final RelationInfo info = proc.info;
351 final ReadGraphImpl impl = (ReadGraphImpl)graph;
352 final int subjectId = ((ResourceImpl)subject).id;
354 // int callerThread = impl.callerThread;
355 // int suggestSchedule = (subjectId>>16) & session.queryProvider2.THREAD_MASK;
359 if(info.isFunctional) {
360 getRelatedValue4(impl, subjectId, context, proc);
362 getRelatedValue4(impl, subjectId, context, proc);
368 public <T> void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure<Resource> procedure) {
370 assert(subject != null);
372 final ReadGraphImpl impl = (ReadGraphImpl)graph;
373 final int subjectId = ((ResourceImpl)subject).id;
377 final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);
378 if(!cluster.isLoaded()) {
380 // impl.state.inc(0);
382 session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {
389 int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
390 procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));
392 // impl.state.dec(0);
394 } catch (DatabaseException e) {
404 int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
405 procedure.execute(graph, new ResourceImpl(session.resourceSupport, result));
409 } catch (DatabaseException e) {
418 public <C> void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure<C, Resource> procedure) {
420 assert(subject != null);
422 final ReadGraphImpl impl = (ReadGraphImpl)graph;
423 final int subjectId = ((ResourceImpl)subject).id;
427 final ClusterI cluster = session.clusterTable.getClusterByResourceKey(subjectId);
428 if(!cluster.isLoaded()) {
430 // impl.state.inc(0);
432 session.queryProvider2.requestCluster(impl, cluster.getClusterId(), new Runnable() {
439 ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);
440 if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
441 int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
442 procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));
444 procedure.execute(graph, context, null);
447 // impl.state.dec(0);
449 } catch (DatabaseException e) {
459 ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subjectId, session.clusterTranslator);
460 if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
461 int result = cluster.getCompleteObjectKey(subjectId, session.clusterTranslator);
462 procedure.execute(graph, context, new ResourceImpl(session.resourceSupport, result));
464 procedure.execute(graph, context, null);
469 } catch (DatabaseException e) {
471 procedure.execute(graph, context, null);
473 } catch (Throwable t) {
476 procedure.execute(graph, context, null);
483 private <C, T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
487 final int predicate = procedure.predicateKey;
491 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
492 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
493 g -> getRelatedValue4(g, subject, context, procedure)
498 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
499 for (int id : g.getObjects(subject, predicate)) {
501 procedure.exception(graph, new DatabaseException("Multiple objects"));
512 procedure.exception(graph, new DatabaseException("No objects for " + subject ));
518 getValue4(graph, null, result, context, procedure);
525 final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
526 if(!cluster.isLoaded()) {
527 cluster.load(session.clusterTranslator, () -> getRelatedValue4(graph, subject, context, procedure));
531 if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
533 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
534 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
535 g -> getRelatedValue4(g, subject, context, procedure)
540 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
541 for (int id : g.getObjects(subject, predicate)) {
543 procedure.exception(graph, new DatabaseException("Multiple objects"));
552 getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);
556 getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);
562 private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
564 Object result = null;
568 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
569 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
570 g -> getValue4(g, containerCluster, subject, procedure)
575 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
576 Object value = g.getValue(subject);
579 procedure.exception(graph, new DatabaseException("Multiple values"));
588 procedure.execute(graph, (T)"name");
594 ClusterImpl cluster = containerCluster;
595 if(!containerCluster.contains(subject)) {
596 cluster = session.clusterTable.getClusterByResourceKey(subject);
597 if(!cluster.isLoaded()) {
598 cluster.load(session.clusterTranslator, new Runnable() {
602 getValue4(graph, containerCluster, subject, procedure);
610 if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
612 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
613 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
614 g -> getValue4(g, containerCluster, subject, procedure)
619 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
620 Object value = g.getValue(subject);
623 procedure.exception(graph, new DatabaseException("Multiple values"));
634 procedure.execute(graph, (T)result);
635 // graph.state.barrier.dec();
639 if(ClusterTypeEnum.SMALL == cluster.getType())
640 getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
642 getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
647 if(ClusterTypeEnum.SMALL == cluster.getType())
648 getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
650 getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
656 private <C, T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
658 Object result = null;
662 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
663 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
664 g -> getValue4(g, containerCluster, subject, context, procedure)
669 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
670 Object value = g.getValue(subject);
673 procedure.exception(graph, new DatabaseException("Multiple values"));
682 procedure.execute(graph, context, (T)"name");
688 ClusterImpl cluster = containerCluster;
689 if(!containerCluster.contains(subject)) {
690 cluster = session.clusterTable.getClusterByResourceKey(subject);
691 if(!cluster.isLoaded()) {
692 cluster.load(session.clusterTranslator, new Runnable() {
696 getValue4(graph, containerCluster, subject, context, procedure);
704 if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
706 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
707 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
708 g -> getValue4(g, containerCluster, subject, context, procedure)
713 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
714 Object value = g.getValue(subject);
717 procedure.exception(graph, new DatabaseException("Multiple values"));
728 procedure.execute(graph, context, (T)result);
729 // graph.state.barrier.dec();
733 if(ClusterTypeEnum.SMALL == cluster.getType())
734 getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
736 getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
741 if(ClusterTypeEnum.SMALL == cluster.getType())
742 getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
744 getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
750 private <T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) {
754 int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
757 procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));
760 getValue4(graph, cluster, result, procedure);
764 getValue4(graph, cluster, so, procedure);
766 procedure.exception(graph, new DatabaseException("Multiple objects"));
771 } catch (DatabaseException e) {
777 private <C, T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
781 int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
784 procedure.exception(graph, new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result));
787 getValue4(graph, cluster, result, context, procedure);
791 getValue4(graph, cluster, so, context, procedure);
793 procedure.exception(graph, new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result));
798 } catch (DatabaseException e) {
799 LOGGER.error("Could not compute related value for subject {} with predicate {}", subject, procedure.predicateKey);
804 public <T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
808 final int predicate = procedure.predicateKey;
812 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
813 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
814 g -> getRelatedValue4(g, subject, procedure)
819 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
820 for (int id : g.getObjects(subject, predicate)) {
822 procedure.exception(graph, new DatabaseException("Multiple objects"));
833 procedure.exception(graph, new DatabaseException("No objects for " + subject ));
839 getValue4(graph, null, result, procedure);
846 final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
847 if(!cluster.isLoaded()) {
848 cluster.load(session.clusterTranslator, new Runnable() {
852 getRelatedValue4(graph, subject, procedure);
859 if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
861 if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
862 SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
863 g -> getRelatedValue4(graph, subject, procedure)
868 for(TransientGraph g : session.virtualGraphServerSupport.providers) {
869 for (int id : g.getObjects(subject, predicate)) {
871 procedure.exception(graph, new DatabaseException("Multiple objects"));
880 getRelatedDirectValue4(graph, cluster, subject, result, procedure);
884 getRelatedDirectValue4(graph, cluster, subject, 0, procedure);
890 private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
893 byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
894 T value = (T)utf(bytes);
895 procedure.execute(graph, context, value);
896 } catch (DatabaseException e) {
897 procedure.execute(graph, context, null);
904 private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
907 byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
908 T value = (T)utf(bytes);
909 procedure.execute(graph, value);
910 } catch (DatabaseException e) {
911 procedure.execute(graph, null);
918 private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
921 byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
923 procedure.execute(graph, context, null);
925 T value = (T)utf(bytes);
926 procedure.execute(graph, context, value);
928 } catch (DatabaseException e) {
929 procedure.execute(graph, context, null);
936 private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
938 ResourceTableSmall rt = cluster.resourceTable;
939 ValueTableSmall vt = cluster.valueTable;
941 byte[] bs = vt.table;
942 long[] ls = rt.table;
944 int index = ((subject&0xFFFF) << 1) - 1 + rt.offset;
946 int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset;
948 int size = (int)bs[valueIndex++]-1;
949 char[] chars = new char[size];
951 for(int i=0;i<size;i++) {
952 chars[i] = (char)bs[valueIndex++];
955 T value = (T)new String(chars);
957 procedure.execute(graph, value);
962 final private String utf(byte[] bytes) throws AssumptionException {
964 if(bytes == null) return null;
966 // Read databoard int32 using Length encoding
967 // https://dev.simantics.org/index.php/Databoard_Specification#Length
969 int length = bytes[index++]&0xff;
975 length += ((bytes[index++]&0xff)<<3);
976 length += ((bytes[index++]&0xff)<<11);
977 length += ((bytes[index++]&0xff)<<19);
978 length += 0x10204080;
982 length += ((bytes[index++]&0xff)<<4);
983 length += ((bytes[index++]&0xff)<<12);
984 length += ((bytes[index++]&0xff)<<20);
990 length += ((bytes[index++]&0xff)<<5);
991 length += ((bytes[index++]&0xff)<<13);
997 length += ((bytes[index++]&0xff)<<6);
1002 // Copied from DataInputStream
1003 int utflen = length;
1004 char[] chararr = new char[utflen];
1006 int c, char2, char3;
1008 int target = index + length;
1009 int chararr_count=0;
1011 while (count < target) {
1012 c = (int) bytes[count] & 0xff;
1015 chararr[chararr_count++]=(char)c;
1018 while (count < target) {
1019 c = (int) bytes[count] & 0xff;
1021 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
1024 chararr[chararr_count++]=(char)c;
1027 /* 110x xxxx 10xx xxxx*/
1030 throw new AssumptionException(
1031 "malformed input: partial character at end (" + (count-index) + " > " + utflen + ")");
1032 char2 = (int) bytes[count-1];
1033 if ((char2 & 0xC0) != 0x80)
1034 throw new AssumptionException(
1035 "malformed input around byte " + count);
1036 chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
1040 /* 1110 xxxx 10xx xxxx 10xx xxxx */
1043 throw new AssumptionException(
1044 "malformed input: partial character at end (" + (count-index) + " > " + utflen + ")");
1045 char2 = (int) bytes[count-2];
1046 char3 = (int) bytes[count-1];
1047 if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
1048 throw new AssumptionException(
1049 "malformed input around byte " + (count-1));
1050 chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
1051 ((char2 & 0x3F) << 6) |
1052 ((char3 & 0x3F) << 0));
1055 /* 10xx xxxx, 1111 xxxx */
1056 throw new AssumptionException(
1057 "malformed input around byte " + count);
1061 // The number of chars produced may be less than utflen
1062 return new String(chararr, 0, chararr_count);