| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.summary.flat_buffers; | 5 library analyzer.src.summary.flat_buffers; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:math'; | 9 import 'dart:math'; |
| 10 import 'dart:typed_data'; | 10 import 'dart:typed_data'; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN); | 56 _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN); |
| 57 | 57 |
| 58 int _getInt8([int delta = 0]) => _buffer.getInt8(_offset + delta); | 58 int _getInt8([int delta = 0]) => _buffer.getInt8(_offset + delta); |
| 59 | 59 |
| 60 int _getUint16([int delta = 0]) => | 60 int _getUint16([int delta = 0]) => |
| 61 _buffer.getUint16(_offset + delta, Endianness.LITTLE_ENDIAN); | 61 _buffer.getUint16(_offset + delta, Endianness.LITTLE_ENDIAN); |
| 62 | 62 |
| 63 int _getUint32([int delta = 0]) => | 63 int _getUint32([int delta = 0]) => |
| 64 _buffer.getUint32(_offset + delta, Endianness.LITTLE_ENDIAN); | 64 _buffer.getUint32(_offset + delta, Endianness.LITTLE_ENDIAN); |
| 65 | 65 |
| 66 int _getUint8([int delta = 0]) => _buffer.getUint8(_offset + delta); |
| 67 |
| 66 /** | 68 /** |
| 67 * If the [byteList] is already a [Uint8List] return it. | 69 * If the [byteList] is already a [Uint8List] return it. |
| 68 * Otherwise return a [Uint8List] copy of the [byteList]. | 70 * Otherwise return a [Uint8List] copy of the [byteList]. |
| 69 */ | 71 */ |
| 70 static Uint8List _asUint8List(List<int> byteList) { | 72 static Uint8List _asUint8List(List<int> byteList) { |
| 71 if (byteList is Uint8List) { | 73 if (byteList is Uint8List) { |
| 72 return byteList; | 74 return byteList; |
| 73 } else { | 75 } else { |
| 74 return new Uint8List.fromList(byteList); | 76 return new Uint8List.fromList(byteList); |
| 75 } | 77 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 Builder({this.initialSize: 1024}) { | 121 Builder({this.initialSize: 1024}) { |
| 120 reset(); | 122 reset(); |
| 121 } | 123 } |
| 122 | 124 |
| 123 /** | 125 /** |
| 124 * Add the [field] with the given boolean [value]. The field is not added if | 126 * Add the [field] with the given boolean [value]. The field is not added if |
| 125 * the [value] is equal to [def]. Booleans are stored as 8-bit fields with | 127 * the [value] is equal to [def]. Booleans are stored as 8-bit fields with |
| 126 * `0` for `false` and `1` for `true`. | 128 * `0` for `false` and `1` for `true`. |
| 127 */ | 129 */ |
| 128 void addBool(int field, bool value, [bool def]) { | 130 void addBool(int field, bool value, [bool def]) { |
| 129 if (_currentVTable == null) { | 131 _ensureCurrentVTable(); |
| 130 throw new StateError('Start a table before adding values.'); | |
| 131 } | |
| 132 if (value != null && value != def) { | 132 if (value != null && value != def) { |
| 133 int size = 1; | 133 int size = 1; |
| 134 _prepare(size, 1); | 134 _prepare(size, 1); |
| 135 _trackField(field); | 135 _trackField(field); |
| 136 _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0); | 136 _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 /** | 140 /** |
| 141 * Add the [field] with the given 32-bit signed integer [value]. The field is | 141 * Add the [field] with the given 32-bit signed integer [value]. The field is |
| 142 * not added if the [value] is equal to [def]. | 142 * not added if the [value] is equal to [def]. |
| 143 */ | 143 */ |
| 144 void addInt32(int field, int value, [int def]) { | 144 void addInt32(int field, int value, [int def]) { |
| 145 if (_currentVTable == null) { | 145 _ensureCurrentVTable(); |
| 146 throw new StateError('Start a table before adding values.'); | |
| 147 } | |
| 148 if (value != null && value != def) { | 146 if (value != null && value != def) { |
| 149 int size = 4; | 147 int size = 4; |
| 150 _prepare(size, 1); | 148 _prepare(size, 1); |
| 151 _trackField(field); | 149 _trackField(field); |
| 152 _setInt32AtTail(_buf, _tail, value); | 150 _setInt32AtTail(_buf, _tail, value); |
| 153 } | 151 } |
| 154 } | 152 } |
| 155 | 153 |
| 156 /** | 154 /** |
| 157 * Add the [field] with the given 8-bit signed integer [value]. The field is | 155 * Add the [field] with the given 8-bit signed integer [value]. The field is |
| 158 * not added if the [value] is equal to [def]. | 156 * not added if the [value] is equal to [def]. |
| 159 */ | 157 */ |
| 160 void addInt8(int field, int value, [int def]) { | 158 void addInt8(int field, int value, [int def]) { |
| 161 if (_currentVTable == null) { | 159 _ensureCurrentVTable(); |
| 162 throw new StateError('Start a table before adding values.'); | |
| 163 } | |
| 164 if (value != null && value != def) { | 160 if (value != null && value != def) { |
| 165 int size = 1; | 161 int size = 1; |
| 166 _prepare(size, 1); | 162 _prepare(size, 1); |
| 167 _trackField(field); | 163 _trackField(field); |
| 168 _buf.setInt8(_buf.lengthInBytes - _tail, value); | 164 _buf.setInt8(_buf.lengthInBytes - _tail, value); |
| 169 } | 165 } |
| 170 } | 166 } |
| 171 | 167 |
| 172 /** | 168 /** |
| 173 * Add the [field] referencing an object with the given [offset]. | 169 * Add the [field] referencing an object with the given [offset]. |
| 174 */ | 170 */ |
| 175 void addOffset(int field, Offset offset) { | 171 void addOffset(int field, Offset offset) { |
| 176 if (_currentVTable == null) { | 172 _ensureCurrentVTable(); |
| 177 throw new StateError('Start a table before adding values.'); | |
| 178 } | |
| 179 if (offset != null) { | 173 if (offset != null) { |
| 180 _prepare(4, 1); | 174 _prepare(4, 1); |
| 181 _trackField(field); | 175 _trackField(field); |
| 182 _setUint32AtTail(_buf, _tail, _tail - offset._tail); | 176 _setUint32AtTail(_buf, _tail, _tail - offset._tail); |
| 183 } | 177 } |
| 184 } | 178 } |
| 185 | 179 |
| 186 /** | 180 /** |
| 187 * Add the [field] with the given 32-bit unsigned integer [value]. The field | 181 * Add the [field] with the given 32-bit unsigned integer [value]. The field |
| 188 * is not added if the [value] is equal to [def]. | 182 * is not added if the [value] is equal to [def]. |
| 189 */ | 183 */ |
| 190 void addUint32(int field, int value, [int def]) { | 184 void addUint32(int field, int value, [int def]) { |
| 191 if (_currentVTable == null) { | 185 _ensureCurrentVTable(); |
| 192 throw new StateError('Start a table before adding values.'); | |
| 193 } | |
| 194 if (value != null && value != def) { | 186 if (value != null && value != def) { |
| 195 int size = 4; | 187 int size = 4; |
| 196 _prepare(size, 1); | 188 _prepare(size, 1); |
| 197 _trackField(field); | 189 _trackField(field); |
| 198 _setUint32AtTail(_buf, _tail, value); | 190 _setUint32AtTail(_buf, _tail, value); |
| 199 } | 191 } |
| 200 } | 192 } |
| 201 | 193 |
| 202 /** | 194 /** |
| 195 * Add the [field] with the given 8-bit unsigned integer [value]. The field |
| 196 * is not added if the [value] is equal to [def]. |
| 197 */ |
| 198 void addUint8(int field, int value, [int def]) { |
| 199 _ensureCurrentVTable(); |
| 200 if (value != null && value != def) { |
| 201 int size = 1; |
| 202 _prepare(size, 1); |
| 203 _trackField(field); |
| 204 _setUint8AtTail(_buf, _tail, value); |
| 205 } |
| 206 } |
| 207 |
| 208 /** |
| 203 * End the current table and return its offset. | 209 * End the current table and return its offset. |
| 204 */ | 210 */ |
| 205 Offset endTable() { | 211 Offset endTable() { |
| 206 if (_currentVTable == null) { | 212 if (_currentVTable == null) { |
| 207 throw new StateError('Start a table before ending it.'); | 213 throw new StateError('Start a table before ending it.'); |
| 208 } | 214 } |
| 209 // Prepare for writing the VTable. | 215 // Prepare for writing the VTable. |
| 210 _prepare(4, 1); | 216 _prepare(4, 1); |
| 211 int tableTail = _tail; | 217 int tableTail = _tail; |
| 212 // Prepare the size of the current table. | 218 // Prepare the size of the current table. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 throw new StateError('Inline tables are not supported.'); | 306 throw new StateError('Inline tables are not supported.'); |
| 301 } | 307 } |
| 302 _currentVTable = new _VTable(); | 308 _currentVTable = new _VTable(); |
| 303 _currentTableEndTail = _tail; | 309 _currentTableEndTail = _tail; |
| 304 } | 310 } |
| 305 | 311 |
| 306 /** | 312 /** |
| 307 * Write the given list of [values]. | 313 * Write the given list of [values]. |
| 308 */ | 314 */ |
| 309 Offset writeList(List<Offset> values) { | 315 Offset writeList(List<Offset> values) { |
| 310 if (_currentVTable != null) { | 316 _ensureNoVTable(); |
| 311 throw new StateError( | |
| 312 'Cannot write a non-scalar value while writing a table.'); | |
| 313 } | |
| 314 _prepare(4, 1 + values.length); | 317 _prepare(4, 1 + values.length); |
| 315 Offset result = new Offset(_tail); | 318 Offset result = new Offset(_tail); |
| 316 int tail = _tail; | 319 int tail = _tail; |
| 317 _setUint32AtTail(_buf, tail, values.length); | 320 _setUint32AtTail(_buf, tail, values.length); |
| 318 tail -= 4; | 321 tail -= 4; |
| 319 for (Offset value in values) { | 322 for (Offset value in values) { |
| 320 _setUint32AtTail(_buf, tail, tail - value._tail); | 323 _setUint32AtTail(_buf, tail, tail - value._tail); |
| 321 tail -= 4; | 324 tail -= 4; |
| 322 } | 325 } |
| 323 return result; | 326 return result; |
| 324 } | 327 } |
| 325 | 328 |
| 326 /** | 329 /** |
| 327 * Write the given list of 64-bit float [values]. | 330 * Write the given list of 64-bit float [values]. |
| 328 */ | 331 */ |
| 329 Offset writeListFloat64(List<double> values) { | 332 Offset writeListFloat64(List<double> values) { |
| 330 if (_currentVTable != null) { | 333 _ensureNoVTable(); |
| 331 throw new StateError( | |
| 332 'Cannot write a non-scalar value while writing a table.'); | |
| 333 } | |
| 334 _prepare(8, 1 + values.length); | 334 _prepare(8, 1 + values.length); |
| 335 Offset result = new Offset(_tail); | 335 Offset result = new Offset(_tail); |
| 336 int tail = _tail; | 336 int tail = _tail; |
| 337 _setUint32AtTail(_buf, tail, values.length); | 337 _setUint32AtTail(_buf, tail, values.length); |
| 338 tail -= 8; | 338 tail -= 8; |
| 339 for (double value in values) { | 339 for (double value in values) { |
| 340 _setFloat64AtTail(_buf, tail, value); | 340 _setFloat64AtTail(_buf, tail, value); |
| 341 tail -= 8; | 341 tail -= 8; |
| 342 } | 342 } |
| 343 return result; | 343 return result; |
| 344 } | 344 } |
| 345 | 345 |
| 346 /** | 346 /** |
| 347 * Write the given list of signed 32-bit integer [values]. | 347 * Write the given list of signed 32-bit integer [values]. |
| 348 */ | 348 */ |
| 349 Offset writeListInt32(List<int> values) { | 349 Offset writeListInt32(List<int> values) { |
| 350 if (_currentVTable != null) { | 350 _ensureNoVTable(); |
| 351 throw new StateError( | |
| 352 'Cannot write a non-scalar value while writing a table.'); | |
| 353 } | |
| 354 _prepare(4, 1 + values.length); | 351 _prepare(4, 1 + values.length); |
| 355 Offset result = new Offset(_tail); | 352 Offset result = new Offset(_tail); |
| 356 int tail = _tail; | 353 int tail = _tail; |
| 357 _setUint32AtTail(_buf, tail, values.length); | 354 _setUint32AtTail(_buf, tail, values.length); |
| 358 tail -= 4; | 355 tail -= 4; |
| 359 for (int value in values) { | 356 for (int value in values) { |
| 360 _setInt32AtTail(_buf, tail, value); | 357 _setInt32AtTail(_buf, tail, value); |
| 361 tail -= 4; | 358 tail -= 4; |
| 362 } | 359 } |
| 363 return result; | 360 return result; |
| 364 } | 361 } |
| 365 | 362 |
| 366 /** | 363 /** |
| 367 * Write the given list of unsigned 32-bit integer [values]. | 364 * Write the given list of unsigned 32-bit integer [values]. |
| 368 */ | 365 */ |
| 369 Offset writeListUint32(List<int> values) { | 366 Offset writeListUint32(List<int> values) { |
| 370 if (_currentVTable != null) { | 367 _ensureNoVTable(); |
| 371 throw new StateError( | |
| 372 'Cannot write a non-scalar value while writing a table.'); | |
| 373 } | |
| 374 _prepare(4, 1 + values.length); | 368 _prepare(4, 1 + values.length); |
| 375 Offset result = new Offset(_tail); | 369 Offset result = new Offset(_tail); |
| 376 int tail = _tail; | 370 int tail = _tail; |
| 377 _setUint32AtTail(_buf, tail, values.length); | 371 _setUint32AtTail(_buf, tail, values.length); |
| 378 tail -= 4; | 372 tail -= 4; |
| 379 for (int value in values) { | 373 for (int value in values) { |
| 380 _setUint32AtTail(_buf, tail, value); | 374 _setUint32AtTail(_buf, tail, value); |
| 381 tail -= 4; | 375 tail -= 4; |
| 382 } | 376 } |
| 383 return result; | 377 return result; |
| 384 } | 378 } |
| 385 | 379 |
| 386 /** | 380 /** |
| 381 * Write the given list of unsigned 8-bit integer [values]. |
| 382 */ |
| 383 Offset writeListUint8(List<int> values) { |
| 384 _ensureNoVTable(); |
| 385 _prepare(4, 1, additionalBytes: values.length); |
| 386 Offset result = new Offset(_tail); |
| 387 int tail = _tail; |
| 388 _setUint32AtTail(_buf, tail, values.length); |
| 389 tail -= 4; |
| 390 for (int value in values) { |
| 391 _setUint8AtTail(_buf, tail, value); |
| 392 tail -= 1; |
| 393 } |
| 394 return result; |
| 395 } |
| 396 |
| 397 /** |
| 387 * Write the given string [value] and return its [Offset], or `null` if | 398 * Write the given string [value] and return its [Offset], or `null` if |
| 388 * the [value] is equal to [def]. | 399 * the [value] is equal to [def]. |
| 389 */ | 400 */ |
| 390 Offset<String> writeString(String value, [String def]) { | 401 Offset<String> writeString(String value, [String def]) { |
| 391 if (_currentVTable != null) { | 402 _ensureNoVTable(); |
| 392 throw new StateError( | |
| 393 'Cannot write a non-scalar value while writing a table.'); | |
| 394 } | |
| 395 if (value != def) { | 403 if (value != def) { |
| 396 return _strings.putIfAbsent(value, () { | 404 return _strings.putIfAbsent(value, () { |
| 397 // TODO(scheglov) optimize for ASCII strings | 405 // TODO(scheglov) optimize for ASCII strings |
| 398 List<int> bytes = UTF8.encode(value); | 406 List<int> bytes = UTF8.encode(value); |
| 399 int length = bytes.length; | 407 int length = bytes.length; |
| 400 _prepare(4, 1, additionalBytes: length); | 408 _prepare(4, 1, additionalBytes: length); |
| 401 Offset<String> result = new Offset(_tail); | 409 Offset<String> result = new Offset(_tail); |
| 402 _setUint32AtTail(_buf, _tail, length); | 410 _setUint32AtTail(_buf, _tail, length); |
| 403 int offset = _buf.lengthInBytes - _tail + 4; | 411 int offset = _buf.lengthInBytes - _tail + 4; |
| 404 for (int i = 0; i < length; i++) { | 412 for (int i = 0; i < length; i++) { |
| 405 _buf.setUint8(offset++, bytes[i]); | 413 _buf.setUint8(offset++, bytes[i]); |
| 406 } | 414 } |
| 407 return result; | 415 return result; |
| 408 }); | 416 }); |
| 409 } | 417 } |
| 410 return null; | 418 return null; |
| 411 } | 419 } |
| 412 | 420 |
| 413 /** | 421 /** |
| 422 * Throw an exception if there is not currently a vtable. |
| 423 */ |
| 424 void _ensureCurrentVTable() { |
| 425 if (_currentVTable == null) { |
| 426 throw new StateError('Start a table before adding values.'); |
| 427 } |
| 428 } |
| 429 |
| 430 /** |
| 431 * Throw an exception if there is currently a vtable. |
| 432 */ |
| 433 void _ensureNoVTable() { |
| 434 if (_currentVTable != null) { |
| 435 throw new StateError( |
| 436 'Cannot write a non-scalar value while writing a table.'); |
| 437 } |
| 438 } |
| 439 |
| 440 /** |
| 414 * Prepare for writing the given [count] of scalars of the given [size]. | 441 * Prepare for writing the given [count] of scalars of the given [size]. |
| 415 * Additionally allocate the specified [additionalBytes]. Update the current | 442 * Additionally allocate the specified [additionalBytes]. Update the current |
| 416 * tail pointer to point at the allocated space. | 443 * tail pointer to point at the allocated space. |
| 417 */ | 444 */ |
| 418 void _prepare(int size, int count, {int additionalBytes: 0}) { | 445 void _prepare(int size, int count, {int additionalBytes: 0}) { |
| 419 // Update the alignment. | 446 // Update the alignment. |
| 420 if (_maxAlign < size) { | 447 if (_maxAlign < size) { |
| 421 _maxAlign = size; | 448 _maxAlign = size; |
| 422 } | 449 } |
| 423 // Prepare amount of required space. | 450 // Prepare amount of required space. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 454 _buf.setFloat64(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); | 481 _buf.setFloat64(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); |
| 455 } | 482 } |
| 456 | 483 |
| 457 static void _setInt32AtTail(ByteData _buf, int tail, int x) { | 484 static void _setInt32AtTail(ByteData _buf, int tail, int x) { |
| 458 _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); | 485 _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); |
| 459 } | 486 } |
| 460 | 487 |
| 461 static void _setUint32AtTail(ByteData _buf, int tail, int x) { | 488 static void _setUint32AtTail(ByteData _buf, int tail, int x) { |
| 462 _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); | 489 _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN); |
| 463 } | 490 } |
| 491 |
| 492 static void _setUint8AtTail(ByteData _buf, int tail, int x) { |
| 493 _buf.setUint8(_buf.lengthInBytes - tail, x); |
| 494 } |
| 464 } | 495 } |
| 465 | 496 |
| 466 /** | 497 /** |
| 467 * The reader of lists of 64-bit float values. | 498 * The reader of lists of 64-bit float values. |
| 468 * | 499 * |
| 469 * The returned unmodifiable lists lazily read values on access. | 500 * The returned unmodifiable lists lazily read values on access. |
| 470 */ | 501 */ |
| 471 class Float64ListReader extends Reader<List<double>> { | 502 class Float64ListReader extends Reader<List<double>> { |
| 472 const Float64ListReader(); | 503 const Float64ListReader(); |
| 473 | 504 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 const Uint32Reader() : super(); | 658 const Uint32Reader() : super(); |
| 628 | 659 |
| 629 @override | 660 @override |
| 630 int get size => 4; | 661 int get size => 4; |
| 631 | 662 |
| 632 @override | 663 @override |
| 633 int read(BufferPointer bp) => bp._getUint32(); | 664 int read(BufferPointer bp) => bp._getUint32(); |
| 634 } | 665 } |
| 635 | 666 |
| 636 /** | 667 /** |
| 668 * The reader of unsigned 8-bit integers. |
| 669 */ |
| 670 class Uint8Reader extends Reader<int> { |
| 671 const Uint8Reader() : super(); |
| 672 |
| 673 @override |
| 674 int get size => 1; |
| 675 |
| 676 @override |
| 677 int read(BufferPointer bp) => bp._getUint8(); |
| 678 } |
| 679 |
| 680 /** |
| 637 * The list backed by 64-bit values - Uint64 length and Float64. | 681 * The list backed by 64-bit values - Uint64 length and Float64. |
| 638 */ | 682 */ |
| 639 class _FbFloat64List extends _FbList<double> { | 683 class _FbFloat64List extends _FbList<double> { |
| 640 List<double> _items; | 684 List<double> _items; |
| 641 | 685 |
| 642 _FbFloat64List(BufferPointer bp) : super(bp); | 686 _FbFloat64List(BufferPointer bp) : super(bp); |
| 643 | 687 |
| 644 @override | 688 @override |
| 645 double operator [](int i) { | 689 double operator [](int i) { |
| 646 _items ??= new List<double>(length); | 690 _items ??= new List<double>(length); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 // Table size. | 832 // Table size. |
| 789 buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN); | 833 buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN); |
| 790 bufOffset += 2; | 834 bufOffset += 2; |
| 791 // Field offsets. | 835 // Field offsets. |
| 792 for (int fieldOffset in fieldOffsets) { | 836 for (int fieldOffset in fieldOffsets) { |
| 793 buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN); | 837 buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN); |
| 794 bufOffset += 2; | 838 bufOffset += 2; |
| 795 } | 839 } |
| 796 } | 840 } |
| 797 } | 841 } |
| OLD | NEW |