<lambda>null1 // Copyright 2021 Code Intelligence GmbH
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 @file:JvmName("Utils")
15
16 package com.code_intelligence.jazzer.utils
17
18 import java.lang.reflect.Executable
19 import java.lang.reflect.Method
20 import java.nio.ByteBuffer
21 import java.nio.channels.FileChannel
22
23 val Class<*>.descriptor: String
24 get() = when {
25 isPrimitive -> {
26 when (this) {
27 Boolean::class.javaPrimitiveType -> "Z"
28 Byte::class.javaPrimitiveType -> "B"
29 Char::class.javaPrimitiveType -> "C"
30 Short::class.javaPrimitiveType -> "S"
31 Int::class.javaPrimitiveType -> "I"
32 Long::class.javaPrimitiveType -> "J"
33 Float::class.javaPrimitiveType -> "F"
34 Double::class.javaPrimitiveType -> "D"
35 java.lang.Void::class.javaPrimitiveType -> "V"
36 else -> throw IllegalStateException("Unknown primitive type: $name")
37 }
38 }
39 isArray -> "[${componentType.descriptor}"
40 java.lang.Object::class.java.isAssignableFrom(this) -> "L${name.replace('.', '/')};"
41 else -> throw IllegalArgumentException("Unknown class type: $name")
42 }
43
44 val Class<*>.readableDescriptor: String
45 get() = when {
46 isPrimitive -> {
47 when (this) {
48 Boolean::class.javaPrimitiveType -> "boolean"
49 Byte::class.javaPrimitiveType -> "byte"
50 Char::class.javaPrimitiveType -> "char"
51 Short::class.javaPrimitiveType -> "short"
52 Int::class.javaPrimitiveType -> "int"
53 Long::class.javaPrimitiveType -> "long"
54 Float::class.javaPrimitiveType -> "float"
55 Double::class.javaPrimitiveType -> "double"
56 java.lang.Void::class.javaPrimitiveType -> "void"
57 else -> throw IllegalStateException("Unknown primitive type: $name")
58 }
59 }
60 isArray -> "${componentType.readableDescriptor}[]"
61 java.lang.Object::class.java.isAssignableFrom(this) -> name
62 else -> throw IllegalArgumentException("Unknown class type: $name")
63 }
64
65 val Executable.descriptor: String
parameterTypenull66 get() = parameterTypes.joinToString(separator = "", prefix = "(", postfix = ")") { parameterType ->
67 parameterType.descriptor
68 } + if (this is Method) returnType.descriptor else "V"
69
70 // This does not include the return type as the parameter descriptors already uniquely identify the executable.
71 val Executable.readableDescriptor: String
parameterTypenull72 get() = parameterTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { parameterType ->
73 parameterType.readableDescriptor
74 }
75
simpleFastHashnull76 fun simpleFastHash(vararg strings: String): Int {
77 var hash = 0
78 for (string in strings) {
79 for (c in string) {
80 hash = hash * 11 + c.code
81 }
82 }
83 return hash
84 }
85
86 /**
87 * Reads the [FileChannel] to the end as a UTF-8 string.
88 */
FileChannelnull89 fun FileChannel.readFully(): String {
90 check(size() <= Int.MAX_VALUE)
91 val buffer = ByteBuffer.allocate(size().toInt())
92 while (buffer.hasRemaining()) {
93 when (read(buffer)) {
94 0 -> throw IllegalStateException("No bytes read")
95 -1 -> break
96 }
97 }
98 return String(buffer.array())
99 }
100
101 /**
102 * Appends [string] to the end of the [FileChannel].
103 */
FileChannelnull104 fun FileChannel.append(string: String) {
105 position(size())
106 write(ByteBuffer.wrap(string.toByteArray()))
107 }
108