1 /* 2 * Copyright 2023 Code Intelligence GmbH 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 * http://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 package com.code_intelligence.jazzer.mutation.api; 18 19 import static com.code_intelligence.jazzer.mutation.support.ExceptionSupport.asUnchecked; 20 21 import com.google.errorprone.annotations.ForOverride; 22 import java.io.ByteArrayInputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 26 /** 27 * Combines an {@link InPlaceMutator} with a {@link Serializer} for objects of type {@code T}. 28 * 29 * <p>If {@code T} can't be mutated in place, implement {@link SerializingMutator} instead. 30 * 31 * <p>Implementing classes SHOULD be declared final. 32 */ 33 public abstract class SerializingInPlaceMutator<T> 34 extends SerializingMutator<T> implements InPlaceMutator<T> { 35 // ByteArrayInputStream#close is documented as being a no-op, so it is safe to reuse an instance 36 // here. 37 // TODO: Introduce a dedicated empty InputStream implementation. 38 private static final InputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); 39 40 /** 41 * Constructs a default instance of {@code T}. 42 * 43 * <p>The returned value is immediately passed to {@link #initInPlace(Object, PseudoRandom)}. 44 * 45 * <p>Implementing classes SHOULD provide a more efficient implementation. 46 * 47 * @return a default instance of {@code T} 48 */ 49 @ForOverride makeDefaultInstance()50 protected T makeDefaultInstance() { 51 try { 52 return readExclusive(emptyInputStream); 53 } catch (IOException e) { 54 throw asUnchecked(e); 55 } 56 } 57 58 @Override init(PseudoRandom prng)59 public final T init(PseudoRandom prng) { 60 T value = makeDefaultInstance(); 61 initInPlace(value, prng); 62 return value; 63 } 64 65 @Override mutate(T value, PseudoRandom prng)66 public final T mutate(T value, PseudoRandom prng) { 67 mutateInPlace(value, prng); 68 return value; 69 } 70 71 @Override crossOver(T value, T otherValue, PseudoRandom prng)72 public final T crossOver(T value, T otherValue, PseudoRandom prng) { 73 crossOverInPlace(value, otherValue, prng); 74 return value; 75 } 76 } 77