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