| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart 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 file. | |
| 4 | |
| 5 /** | |
| 6 * A class for holding onto the data for a date so that it can be built | |
| 7 * up incrementally. | |
| 8 */ | |
| 9 class _DateBuilder { | |
| 10 // Default the date values to the EPOCH so that there's a valid date | |
| 11 // in case the format doesn't set them. | |
| 12 int year = 1970, | |
| 13 month = 1, | |
| 14 day = 1, | |
| 15 hour = 0, | |
| 16 minute = 0, | |
| 17 second = 0, | |
| 18 fractionalSecond = 0; | |
| 19 bool pm = false; | |
| 20 bool utc = false; | |
| 21 | |
| 22 // Functions that exist just to be closurized so we can pass them to a general | |
| 23 // method. | |
| 24 void setYear(x) { year = x; } | |
| 25 void setMonth(x) { month = x; } | |
| 26 void setDay(x) { day = x; } | |
| 27 void setHour(x) { hour = x; } | |
| 28 void setMinute(x) { minute = x; } | |
| 29 void setSecond(x) { second = x; } | |
| 30 void setFractionalSecond(x) { fractionalSecond = x; } | |
| 31 | |
| 32 /** | |
| 33 * Return a date built using our values. If no date portion is set, | |
| 34 * use the "Epoch" of January 1, 1970. | |
| 35 */ | |
| 36 Date asDate() { | |
| 37 // TODO(alanknight): Validate the date, especially for things which | |
| 38 // can crash the VM, e.g. large month values. | |
| 39 return new Date( | |
| 40 year, | |
| 41 month, | |
| 42 day, | |
| 43 pm ? hour + 12 : hour, | |
| 44 minute, | |
| 45 second, | |
| 46 fractionalSecond, | |
| 47 utc); | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 /** | |
| 52 * A simple and not particularly general stream class to make parsing | |
| 53 * dates from strings simpler. It is general enough to operate on either | |
| 54 * lists or strings. | |
| 55 */ | |
| 56 class _Stream { | |
| 57 var contents; | |
| 58 int index = 0; | |
| 59 | |
| 60 _Stream(this.contents); | |
| 61 | |
| 62 bool atEnd() => index >= contents.length; | |
| 63 | |
| 64 Dynamic next() => contents[index++]; | |
| 65 | |
| 66 /** | |
| 67 * Return the next [howMany] items, or as many as there are remaining. | |
| 68 * Advance the stream by that many positions. | |
| 69 */ | |
| 70 read([howMany = 1]) { | |
| 71 var result = peek(howMany); | |
| 72 index += howMany; | |
| 73 return result; | |
| 74 } | |
| 75 | |
| 76 /** | |
| 77 * Return the next [howMany] items, or as many as there are remaining. | |
| 78 * Does not modify the stream position. | |
| 79 */ | |
| 80 peek([howMany = 1]) { | |
| 81 var result; | |
| 82 if (contents is String) { | |
| 83 result = contents.substring( | |
| 84 index, | |
| 85 min(index + howMany, contents.length)); | |
| 86 } else { | |
| 87 // Assume List | |
| 88 result = contents.getRange(index, howMany); | |
| 89 } | |
| 90 return result; | |
| 91 } | |
| 92 | |
| 93 /** Return the remaining contents of the stream */ | |
| 94 rest() => peek(contents.length - index); | |
| 95 | |
| 96 /** | |
| 97 * Find the index of the first element for which [f] returns true. | |
| 98 * Advances the stream to that position. | |
| 99 */ | |
| 100 int findIndex(Function f) { | |
| 101 while (!atEnd()) { | |
| 102 if (f(next())) return index - 1; | |
| 103 } | |
| 104 return null; | |
| 105 } | |
| 106 | |
| 107 /** | |
| 108 * Find the indexes of all the elements for which [f] returns true. | |
| 109 * Leaves the stream positioned at the end. | |
| 110 */ | |
| 111 List findIndexes(Function f) { | |
| 112 var results = []; | |
| 113 while (!atEnd()) { | |
| 114 if (f(next())) results.add(index - 1); | |
| 115 } | |
| 116 return results; | |
| 117 } | |
| 118 | |
| 119 /** | |
| 120 * Assuming that the contents are characters, read as many digits as we | |
| 121 * can see and then return the corresponding integer. Advance the stream. | |
| 122 */ | |
| 123 var digitMatcher = const RegExp(@'\d+'); | |
| 124 int nextInteger() { | |
| 125 var string = digitMatcher.stringMatch(rest()); | |
| 126 if (string == null || string.isEmpty()) return null; | |
| 127 read(string.length); | |
| 128 return int.parse(string); | |
| 129 } | |
| 130 } | |
| OLD | NEW |