| OLD | NEW |
| (Empty) | |
| 1 library input.transformer; |
| 2 |
| 3 import 'dart:convert'; |
| 4 |
| 5 import 'instrumentation_input_converter.dart'; |
| 6 import 'operation.dart'; |
| 7 |
| 8 final int NINE = '9'.codeUnitAt(0); |
| 9 final int ZERO = '0'.codeUnitAt(0); |
| 10 |
| 11 /** |
| 12 * [InputConverter] converts an input stream |
| 13 * into a series of operations to be sent to the analysis server. |
| 14 * The input stream can be either an instrumenation or log file. |
| 15 */ |
| 16 class InputConverter extends Converter<String, Operation> { |
| 17 |
| 18 /** |
| 19 * The number of lines read before the underlying converter was determined |
| 20 * or the end of file was reached. |
| 21 */ |
| 22 int headerLineCount = 0; |
| 23 |
| 24 /** |
| 25 * The underlying converter used to translate lines into operations |
| 26 * or `null` if it has not yet been determined. |
| 27 */ |
| 28 Converter<String, Operation> converter; |
| 29 |
| 30 @override |
| 31 Operation convert(String line) { |
| 32 if (converter != null) { |
| 33 return converter.convert(line); |
| 34 } |
| 35 if (headerLineCount == 20) { |
| 36 throw 'Failed to determine input file format'; |
| 37 } |
| 38 if (InstrumentationInputConverter.isFormat(line)) { |
| 39 converter = new InstrumentationInputConverter(); |
| 40 } else if (LogFileInputConverter.isFormat(line)) { |
| 41 converter = new LogFileInputConverter(); |
| 42 } |
| 43 if (converter != null) { |
| 44 return converter.convert(line); |
| 45 } |
| 46 print(line); |
| 47 return null; |
| 48 } |
| 49 |
| 50 @override |
| 51 _InputSink startChunkedConversion(outSink) { |
| 52 return new _InputSink(this, outSink); |
| 53 } |
| 54 } |
| 55 |
| 56 /** |
| 57 * [LogFileInputConverter] converts a log file stream |
| 58 * into a series of operations to be sent to the analysis server. |
| 59 */ |
| 60 class LogFileInputConverter extends Converter<String, Operation> { |
| 61 @override |
| 62 Operation convert(String line) { |
| 63 throw 'not implemented yet'; |
| 64 } |
| 65 |
| 66 /** |
| 67 * Determine if the given line is from an instrumentation file. |
| 68 * For example: |
| 69 * `1428347977499 <= {"event":"server.connected","params":{"version":"1.6.0"}}
` |
| 70 */ |
| 71 static bool isFormat(String line) { |
| 72 String timeStampString = _parseTimeStamp(line); |
| 73 int start = timeStampString.length; |
| 74 int end = start + 5; |
| 75 return start > 10 && |
| 76 line.length > end && |
| 77 line.substring(start, end) == ' <= {"event":"server.connected"'; |
| 78 } |
| 79 |
| 80 /** |
| 81 * Parse the given line and return the millisecond timestamp or `null` |
| 82 * if it cannot be determined. |
| 83 */ |
| 84 static String _parseTimeStamp(String line) { |
| 85 int index = 0; |
| 86 while (index < line.length) { |
| 87 int code = line.codeUnitAt(index); |
| 88 if (code < ZERO || NINE < code) { |
| 89 return line.substring(0, index); |
| 90 } |
| 91 ++index; |
| 92 } |
| 93 return line; |
| 94 } |
| 95 } |
| 96 |
| 97 class _InputSink extends ChunkedConversionSink<String> { |
| 98 final Converter<String, Operation> converter; |
| 99 final outSink; |
| 100 |
| 101 _InputSink(this.converter, this.outSink); |
| 102 |
| 103 @override |
| 104 void add(String line) { |
| 105 Operation op = converter.convert(line); |
| 106 if (op != null) { |
| 107 outSink.add(op); |
| 108 } |
| 109 } |
| 110 |
| 111 @override |
| 112 void close() { |
| 113 outSink.close(); |
| 114 } |
| 115 } |
| OLD | NEW |