| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE.md file. | |
| 4 | |
| 5 library struct; | |
| 6 | |
| 7 import "dart:ffi"; | |
| 8 | |
| 9 Reader getRoot(Reader reader, Foreign request) { | |
| 10 int segments = request.getInt32(40); | |
| 11 if (segments == 0) { | |
| 12 MessageReader messageReader = new MessageReader(); | |
| 13 Segment segment = new Segment(messageReader, request); | |
| 14 messageReader.segments.add(segment); | |
| 15 reader._segment = segment; | |
| 16 reader._offset = 48; | |
| 17 return reader; | |
| 18 } else { | |
| 19 return getSegmentedRoot(reader, request, segments); | |
| 20 } | |
| 21 } | |
| 22 | |
| 23 Reader getSegmentedRoot(Reader reader, Foreign request, int segments) { | |
| 24 MessageReader messageReader = new MessageReader(); | |
| 25 int offset = 56; | |
| 26 for (int i = 0; i < segments; i++) { | |
| 27 int address = (Foreign.bitsPerMachineWord == 32) | |
| 28 ? request.getUint32(offset) | |
| 29 : request.getUint64(offset); | |
| 30 int size = request.getInt32(offset + 8); | |
| 31 Foreign memory = new Foreign.fromAddress(address, size); | |
| 32 Segment segment = new Segment(messageReader, memory); | |
| 33 messageReader.segments.add(segment); | |
| 34 offset += 16; | |
| 35 } | |
| 36 reader._segment = messageReader.segments.first; | |
| 37 reader._offset = 48; | |
| 38 return reader; | |
| 39 } | |
| 40 | |
| 41 int getResultMessage(Builder builder) { | |
| 42 BuilderSegment segment = builder._segment; | |
| 43 if (segment._next == null) { | |
| 44 // Mark result as being non-segmented. | |
| 45 Foreign memory = segment.memory; | |
| 46 memory.setInt32(0, 0); | |
| 47 memory.setInt32(4, memory.length); | |
| 48 return memory.value; | |
| 49 } | |
| 50 | |
| 51 // The result is a segmented message. Build a memory block that | |
| 52 // contains the addresses and sizes of all of them. | |
| 53 int segments = segment._builder._segments; | |
| 54 int size = 8 + (segments * 16); | |
| 55 Foreign buffer = new Foreign.allocated(size); | |
| 56 // Mark the result as being segmented. | |
| 57 buffer.setInt32(0, segments); | |
| 58 int offset = 8; | |
| 59 do { | |
| 60 buffer.setInt64(offset, segment.memory.value); | |
| 61 buffer.setInt32(offset + 8, segment._used); | |
| 62 segment = segment._next; | |
| 63 offset += 16; | |
| 64 } while (segment != null); | |
| 65 return buffer.value; | |
| 66 } | |
| 67 | |
| 68 class MessageReader { | |
| 69 final List<Segment> segments = []; | |
| 70 MessageReader(); | |
| 71 | |
| 72 Segment getSegment(int id) => segments[id]; | |
| 73 } | |
| 74 | |
| 75 class Segment { | |
| 76 final MessageReader reader; | |
| 77 final Foreign memory; | |
| 78 Segment(this.reader, this.memory); | |
| 79 } | |
| 80 | |
| 81 class Reader { | |
| 82 Segment _segment; | |
| 83 int _offset; | |
| 84 | |
| 85 Segment get segment => _segment; | |
| 86 void set segment(Segment value) { | |
| 87 _segment = value; | |
| 88 } | |
| 89 | |
| 90 int get offset => _offset; | |
| 91 void set offset(int value) { | |
| 92 _offset = value; | |
| 93 } | |
| 94 | |
| 95 readStruct(Reader reader, int offset) { | |
| 96 Segment segment = _segment; | |
| 97 offset += _offset; | |
| 98 while (true) { | |
| 99 Foreign memory = segment.memory; | |
| 100 int lo = memory.getInt32(offset + 0); | |
| 101 int hi = memory.getInt32(offset + 4); | |
| 102 int tag = lo & 3; | |
| 103 if (tag == 0) { | |
| 104 throw new UnimplementedError("Cannot read uninitialized structs"); | |
| 105 } else if (tag == 1) { | |
| 106 reader._segment = segment; | |
| 107 reader._offset = lo >> 2; | |
| 108 return reader; | |
| 109 } else { | |
| 110 segment = segment.reader.getSegment(hi); | |
| 111 offset = lo >> 2; | |
| 112 } | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 readList(ListReader reader, int offset) { | |
| 117 Segment segment = _segment; | |
| 118 offset += _offset; | |
| 119 while (true) { | |
| 120 Foreign memory = segment.memory; | |
| 121 int lo = memory.getInt32(offset + 0); | |
| 122 int hi = memory.getInt32(offset + 4); | |
| 123 int tag = lo & 3; | |
| 124 if (tag == 0) { | |
| 125 // If the list hasn't been initialized, then | |
| 126 // we return an empty list. | |
| 127 reader._length = 0; | |
| 128 return reader; | |
| 129 } else if (tag == 2) { | |
| 130 reader._segment = segment; | |
| 131 reader._offset = lo >> 2; | |
| 132 reader._length = hi; | |
| 133 return reader; | |
| 134 } else { | |
| 135 segment = segment.reader.getSegment(hi); | |
| 136 offset = lo >> 2; | |
| 137 } | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 String readString(ListReader reader, int offset) { | |
| 142 List<int> charCodes = readList(reader, offset); | |
| 143 return new String.fromCharCodes(charCodes); | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 class ListReader extends Reader { | |
| 148 int _length; | |
| 149 int get length => _length; | |
| 150 | |
| 151 readListElement(Reader reader, int index, int size) { | |
| 152 reader._segment = _segment; | |
| 153 reader._offset = _offset + index * size; | |
| 154 return reader; | |
| 155 } | |
| 156 | |
| 157 // TODO(zerny): Move this to a mixin base. | |
| 158 Iterator get iterator { throw new UnsupportedError("ListBuilder::iterator"); } | |
| 159 Iterable map(Function f) { throw new UnsupportedError("ListBuilder::map"); } | |
| 160 Iterable where(Function test) { throw new UnsupportedError("ListBuilder::where
"); } | |
| 161 Iterable expand(Function f) { throw new UnsupportedError("ListBuilder::expand"
); } | |
| 162 bool contains(Object element) { throw new UnsupportedError("ListBuilder::conta
ins"); } | |
| 163 void forEach(Function f) { throw new UnsupportedError("ListBuilder::forEach");
} | |
| 164 reduce(Function combine) { throw new UnsupportedError("ListBuilder::reduce");
} | |
| 165 dynamic fold(init, Function combine) { throw new UnsupportedError("ListBuilder
::fold"); } | |
| 166 bool every(Function test) { throw new UnsupportedError("ListBuilder::every");
} | |
| 167 String join([String separator = ""]) { throw new UnsupportedError("ListBuilder
::join"); } | |
| 168 bool any(Function test) { throw new UnsupportedError("ListBuilder::any"); } | |
| 169 List toList({ bool growable: true }) { throw new UnsupportedError("ListBuilder
::toList"); } | |
| 170 Set toSet() { throw new UnsupportedError("ListBuilder::toSet"); } | |
| 171 bool get isEmpty { throw new UnsupportedError("ListBuilder::isEmpty"); } | |
| 172 bool get isNotEmpty { throw new UnsupportedError("ListBuilder::isNotEmpty"); } | |
| 173 Iterable take(int count) { throw new UnsupportedError("ListBuilder::take"); } | |
| 174 Iterable takeWhile(Function test) { throw new UnsupportedError("ListBuilder::t
akeWhile"); } | |
| 175 Iterable skip(int count) { throw new UnsupportedError("ListBuilder::skip"); } | |
| 176 Iterable skipWhile(Function test) { throw new UnsupportedError("ListBuilder::s
kipWhile"); } | |
| 177 get first { throw new UnsupportedError("ListBuilder::first"); } | |
| 178 get last { throw new UnsupportedError("ListBuilder::last"); } | |
| 179 get single { throw new UnsupportedError("ListBuilder::single"); } | |
| 180 firstWhere(Function test, { orElse() }) { throw new UnsupportedError("ListBuil
der::firstWhere"); } | |
| 181 lastWhere(Function test, { orElse() }) { throw new UnsupportedError("ListBuild
er::lastWhere"); } | |
| 182 singleWhere(Function test) { throw new UnsupportedError("ListBuilder::singleWh
ere"); } | |
| 183 elementAt(int index) { throw new UnsupportedError("ListBuilder::elementAt"); } | |
| 184 void operator []=(int index, value) { throw new UnsupportedError("ListBuilder:
:operator []="); } | |
| 185 void set length(int newLength) { throw new UnsupportedError("ListBuilder::set"
); } | |
| 186 void add(value) { throw new UnsupportedError("ListBuilder::add"); } | |
| 187 void addAll(Iterable iterable) { throw new UnsupportedError("ListBuilder::addA
ll"); } | |
| 188 Iterable get reversed { throw new UnsupportedError("ListBuilder::reversed"); } | |
| 189 void sort([int compare(a, b)]) { throw new UnsupportedError("ListBuilder::sort
"); } | |
| 190 void shuffle([random]) { throw new UnsupportedError("ListBuilder::shuffle"); } | |
| 191 int indexOf(element, [int start = 0]) { throw new UnsupportedError("ListBuilde
r::indexOf"); } | |
| 192 int lastIndexOf(element, [int start]) { throw new UnsupportedError("ListBuilde
r::lastIndexOf"); } | |
| 193 void clear() { throw new UnsupportedError("ListBuilder::clear"); } | |
| 194 void insert(int index, element) { throw new UnsupportedError("ListBuilder::ins
ert"); } | |
| 195 void insertAll(int index, Iterable iterable) { throw new UnsupportedError("Lis
tBuilder::insertAll"); } | |
| 196 void setAll(int index, Iterable iterable) { throw new UnsupportedError("ListBu
ilder::setAll"); } | |
| 197 bool remove(Object value) { throw new UnsupportedError("ListBuilder::remove");
} | |
| 198 removeAt(int index) { throw new UnsupportedError("ListBuilder::removeAt"); } | |
| 199 removeLast() { throw new UnsupportedError("ListBuilder::removeLast"); } | |
| 200 void removeWhere(Function test) { throw new UnsupportedError("ListBuilder::rem
oveWhere"); } | |
| 201 void retainWhere(Function test) { throw new UnsupportedError("ListBuilder::ret
ainWhere"); } | |
| 202 List sublist(int start, [int end]) { throw new UnsupportedError("ListBuilder::
sublist"); } | |
| 203 Iterable getRange(int start, int end) { throw new UnsupportedError("ListBuilde
r::getRange"); } | |
| 204 void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { th
row new UnsupportedError("ListBuilder::setRange"); } | |
| 205 void removeRange(int start, int end) { throw new UnsupportedError("ListBuilder
::removeRange"); } | |
| 206 void fillRange(int start, int end, [fillValue]) { throw new UnsupportedError("
ListBuilder::fillRange"); } | |
| 207 void replaceRange(int start, int end, Iterable replacement) { throw new Unsupp
ortedError("ListBuilder::replaceRange"); } | |
| 208 Map asMap() { throw new UnsupportedError("ListBuilder::asMap"); } | |
| 209 } | |
| 210 | |
| 211 class BuilderSegment { | |
| 212 final MessageBuilder _builder; | |
| 213 final Foreign memory; | |
| 214 int _id; | |
| 215 int _used = 0; | |
| 216 BuilderSegment _next; | |
| 217 | |
| 218 BuilderSegment(this._builder, this._id, int space) | |
| 219 : memory = new Foreign.allocated(space); | |
| 220 | |
| 221 bool HasSpaceForBytes(int bytes) => _used + bytes <= memory.length; | |
| 222 | |
| 223 int Allocate(int bytes) { | |
| 224 if (!HasSpaceForBytes(bytes)) return -1; | |
| 225 var result = _used; | |
| 226 _used += bytes; | |
| 227 return result; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 class MessageBuilder { | |
| 232 BuilderSegment _first; | |
| 233 BuilderSegment _last; | |
| 234 int _segments = 1; | |
| 235 | |
| 236 MessageBuilder(int space) { | |
| 237 _first = new BuilderSegment(this, 0, space); | |
| 238 _last = _first; | |
| 239 } | |
| 240 | |
| 241 Builder initRoot(Builder builder, int size) { | |
| 242 int offset = _first.Allocate(8 + size); | |
| 243 builder._segment = _first; | |
| 244 builder._offset = offset + 8; | |
| 245 return builder; | |
| 246 } | |
| 247 | |
| 248 BuilderSegment FindSegmentForBytes(int bytes) { | |
| 249 if (_last.HasSpaceForBytes(bytes)) return _last; | |
| 250 int capacity = (bytes > 8192) ? bytes : 8192; | |
| 251 BuilderSegment segment = new BuilderSegment(this, _segments++, capacity); | |
| 252 _last._next = segment; | |
| 253 _last = segment; | |
| 254 return segment; | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 class Builder { | |
| 259 BuilderSegment _segment; | |
| 260 int _offset; | |
| 261 | |
| 262 Segment get segment => _segment; | |
| 263 void set segment(Segment value) { | |
| 264 _segment = value; | |
| 265 } | |
| 266 | |
| 267 int get offset => _offset; | |
| 268 void set offset(int value) { | |
| 269 _offset = value; | |
| 270 } | |
| 271 | |
| 272 Builder NewStruct(Builder builder, int offset, int size) { | |
| 273 offset += _offset; | |
| 274 BuilderSegment segment = _segment; | |
| 275 while (true) { | |
| 276 int result = segment.Allocate(size); | |
| 277 Foreign memory = segment.memory; | |
| 278 if (result >= 0) { | |
| 279 memory.setInt32(offset + 0, (result << 2) | 1); | |
| 280 memory.setInt32(offset + 4, 0); | |
| 281 builder._segment = segment; | |
| 282 builder._offset = result; | |
| 283 return builder; | |
| 284 } | |
| 285 | |
| 286 BuilderSegment other = segment._builder.FindSegmentForBytes(size + 8); | |
| 287 int target = other.Allocate(8); | |
| 288 memory.setInt32(offset + 0, (target << 2) | 3); | |
| 289 memory.setInt32(offset + 4, other._id); | |
| 290 | |
| 291 segment = other; | |
| 292 offset = target; | |
| 293 } | |
| 294 } | |
| 295 | |
| 296 ListBuilder NewList(ListBuilder list, | |
| 297 int offset, | |
| 298 int length, | |
| 299 int size) { | |
| 300 list._length = length; | |
| 301 offset += _offset; | |
| 302 size *= length; | |
| 303 BuilderSegment segment = _segment; | |
| 304 while (true) { | |
| 305 int result = segment.Allocate(size); | |
| 306 Foreign memory = segment.memory; | |
| 307 if (result >= 0) { | |
| 308 memory.setInt32(offset + 0, (result << 2) | 1); | |
| 309 memory.setInt32(offset + 4, length); | |
| 310 list._segment = segment; | |
| 311 list._offset = result; | |
| 312 return list; | |
| 313 } | |
| 314 | |
| 315 BuilderSegment other = segment._builder.FindSegmentForBytes(size + 8); | |
| 316 int target = other.Allocate(8); | |
| 317 memory.setInt32(offset + 0, (target << 2) | 3); | |
| 318 memory.setInt32(offset + 4, other._id); | |
| 319 | |
| 320 segment = other; | |
| 321 offset = target; | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 void NewString(ListBuilder list, int offset, String value) { | |
| 326 NewList(list, offset, value.length, 2); | |
| 327 for (int i = 0; i < value.length; i++) { | |
| 328 list[i] = value.codeUnitAt(i); | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 | |
| 333 class ListBuilder extends Builder { | |
| 334 int _length; | |
| 335 int get length => _length; | |
| 336 | |
| 337 readListElement(Builder builder, int index, int size) { | |
| 338 builder._segment = _segment; | |
| 339 builder._offset = _offset + index * size; | |
| 340 return builder; | |
| 341 } | |
| 342 | |
| 343 // TODO(zerny): Move this to a mixin base. | |
| 344 Iterator get iterator { throw new UnsupportedError("ListBuilder::iterator"); } | |
| 345 Iterable map(Function f) { throw new UnsupportedError("ListBuilder::map"); } | |
| 346 Iterable where(Function test) { throw new UnsupportedError("ListBuilder::where
"); } | |
| 347 Iterable expand(Function f) { throw new UnsupportedError("ListBuilder::expand"
); } | |
| 348 bool contains(Object element) { throw new UnsupportedError("ListBuilder::conta
ins"); } | |
| 349 void forEach(Function f) { throw new UnsupportedError("ListBuilder::forEach");
} | |
| 350 reduce(Function combine) { throw new UnsupportedError("ListBuilder::reduce");
} | |
| 351 dynamic fold(init, Function combine) { throw new UnsupportedError("ListBuilder
::fold"); } | |
| 352 bool every(Function test) { throw new UnsupportedError("ListBuilder::every");
} | |
| 353 String join([String separator = ""]) { throw new UnsupportedError("ListBuilder
::join"); } | |
| 354 bool any(Function test) { throw new UnsupportedError("ListBuilder::any"); } | |
| 355 List toList({ bool growable: true }) { throw new UnsupportedError("ListBuilder
::toList"); } | |
| 356 Set toSet() { throw new UnsupportedError("ListBuilder::toSet"); } | |
| 357 bool get isEmpty { throw new UnsupportedError("ListBuilder::isEmpty"); } | |
| 358 bool get isNotEmpty { throw new UnsupportedError("ListBuilder::isNotEmpty"); } | |
| 359 Iterable take(int count) { throw new UnsupportedError("ListBuilder::take"); } | |
| 360 Iterable takeWhile(Function test) { throw new UnsupportedError("ListBuilder::t
akeWhile"); } | |
| 361 Iterable skip(int count) { throw new UnsupportedError("ListBuilder::skip"); } | |
| 362 Iterable skipWhile(Function test) { throw new UnsupportedError("ListBuilder::s
kipWhile"); } | |
| 363 get first { throw new UnsupportedError("ListBuilder::first"); } | |
| 364 get last { throw new UnsupportedError("ListBuilder::last"); } | |
| 365 get single { throw new UnsupportedError("ListBuilder::single"); } | |
| 366 firstWhere(Function test, { orElse() }) { throw new UnsupportedError("ListBuil
der::firstWhere"); } | |
| 367 lastWhere(Function test, { orElse() }) { throw new UnsupportedError("ListBuild
er::lastWhere"); } | |
| 368 singleWhere(Function test) { throw new UnsupportedError("ListBuilder::singleWh
ere"); } | |
| 369 elementAt(int index) { throw new UnsupportedError("ListBuilder::elementAt"); } | |
| 370 void operator []=(int index, value) { throw new UnsupportedError("ListBuilder:
:operator []="); } | |
| 371 void set length(int newLength) { throw new UnsupportedError("ListBuilder::set"
); } | |
| 372 void add(value) { throw new UnsupportedError("ListBuilder::add"); } | |
| 373 void addAll(Iterable iterable) { throw new UnsupportedError("ListBuilder::addA
ll"); } | |
| 374 Iterable get reversed { throw new UnsupportedError("ListBuilder::reversed"); } | |
| 375 void sort([int compare(a, b)]) { throw new UnsupportedError("ListBuilder::sort
"); } | |
| 376 void shuffle([random]) { throw new UnsupportedError("ListBuilder::shuffle"); } | |
| 377 int indexOf(element, [int start = 0]) { throw new UnsupportedError("ListBuilde
r::indexOf"); } | |
| 378 int lastIndexOf(element, [int start]) { throw new UnsupportedError("ListBuilde
r::lastIndexOf"); } | |
| 379 void clear() { throw new UnsupportedError("ListBuilder::clear"); } | |
| 380 void insert(int index, element) { throw new UnsupportedError("ListBuilder::ins
ert"); } | |
| 381 void insertAll(int index, Iterable iterable) { throw new UnsupportedError("Lis
tBuilder::insertAll"); } | |
| 382 void setAll(int index, Iterable iterable) { throw new UnsupportedError("ListBu
ilder::setAll"); } | |
| 383 bool remove(Object value) { throw new UnsupportedError("ListBuilder::remove");
} | |
| 384 removeAt(int index) { throw new UnsupportedError("ListBuilder::removeAt"); } | |
| 385 removeLast() { throw new UnsupportedError("ListBuilder::removeLast"); } | |
| 386 void removeWhere(Function test) { throw new UnsupportedError("ListBuilder::rem
oveWhere"); } | |
| 387 void retainWhere(Function test) { throw new UnsupportedError("ListBuilder::ret
ainWhere"); } | |
| 388 List sublist(int start, [int end]) { throw new UnsupportedError("ListBuilder::
sublist"); } | |
| 389 Iterable getRange(int start, int end) { throw new UnsupportedError("ListBuilde
r::getRange"); } | |
| 390 void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { th
row new UnsupportedError("ListBuilder::setRange"); } | |
| 391 void removeRange(int start, int end) { throw new UnsupportedError("ListBuilder
::removeRange"); } | |
| 392 void fillRange(int start, int end, [fillValue]) { throw new UnsupportedError("
ListBuilder::fillRange"); } | |
| 393 void replaceRange(int start, int end, Iterable replacement) { throw new Unsupp
ortedError("ListBuilder::replaceRange"); } | |
| 394 Map asMap() { throw new UnsupportedError("ListBuilder::asMap"); } | |
| 395 } | |
| OLD | NEW |