1 /*
<lambda>null2 * Copyright 2017 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 import trebuchet.extractors.ExtractorRegistry
18 import trebuchet.extras.InputStreamAdapter
19 import trebuchet.extras.findSampleData
20 import trebuchet.importers.ImporterRegistry
21 import trebuchet.io.BufferProducer
22 import trebuchet.io.StreamingReader
23 import trebuchet.util.PrintlnImportFeedback
24 import java.io.File
25 import java.io.OutputStream
26
27 fun validateSrcDest(source: File, destDir: File) {
28 if (!source.exists()) {
29 throw IllegalArgumentException("No such file '$source'")
30 }
31 if (!destDir.exists()) {
32 destDir.mkdirs()
33 if (!destDir.exists() && destDir.isDirectory) {
34 throw IllegalArgumentException("'$destDir' isn't a directory")
35 }
36 }
37 }
38
findTracesnull39 fun findTraces(stream: BufferProducer,
40 onlyKnownFormats: Boolean,
41 traceFound: (StreamingReader) -> Unit) {
42 val importFeedback = PrintlnImportFeedback()
43 try {
44 val reader = StreamingReader(stream)
45 reader.loadIndex(reader.keepLoadedSize.toLong())
46 val extractor = ExtractorRegistry.extractorFor(reader, importFeedback)
47 if (extractor != null) {
48 extractor.extract(reader, {
49 subStream -> findTraces(subStream, onlyKnownFormats, traceFound)
50 })
51 } else {
52 if (onlyKnownFormats) {
53 val importer = ImporterRegistry.importerFor(reader, importFeedback)
54 if (importer != null) {
55 traceFound(reader)
56 }
57 } else {
58 traceFound(reader)
59 }
60 }
61 } catch (ex: Throwable) {
62 importFeedback.reportImportException(ex)
63 } finally {
64 stream.close()
65 }
66 }
67
copynull68 fun copy(reader: StreamingReader, output: OutputStream) {
69 reader.windows.forEach {
70 val slice = it.slice
71 output.write(slice.buffer, slice.startIndex, slice.length)
72 }
73 var next = reader.source.next()
74 while (next != null) {
75 output.write(next.buffer, next.startIndex, next.length)
76 next = reader.source.next()
77 }
78 }
79
extractnull80 fun extract(source: File, destDir: File) {
81 validateSrcDest(source, destDir)
82 println("Extracting ${source.name} to ${destDir.path}")
83 var traceCount = 0
84 findTraces(InputStreamAdapter(source), onlyKnownFormats = false) {
85 trace ->
86 val destFile = File(destDir, "${source.nameWithoutExtension}_$traceCount")
87 println("Found subtrace, extracting to $destFile")
88 val outputStream = destFile.outputStream()
89 copy(trace, outputStream)
90 traceCount++
91 }
92
93 }
94
mainnull95 fun main(args: Array<String>) {
96 if (args.size != 2) {
97 println("Usage: <source file> <dest dir>")
98 return
99 }
100 try {
101 val source = File(args[0])
102 val destDir = File(args[1])
103 extract(source, destDir)
104 } catch (ex: Exception) {
105 println(ex.message)
106 }
107 }
108