| /* |
| * Copyright 2013, Google Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| package org.jf.dexlib2.writer; |
| |
| import com.google.common.collect.Ordering; |
| import org.jf.dexlib2.ValueType; |
| import org.jf.dexlib2.base.BaseAnnotationElement; |
| import org.jf.dexlib2.iface.reference.FieldReference; |
| import org.jf.dexlib2.iface.reference.MethodReference; |
| |
| import javax.annotation.Nonnull; |
| import java.io.IOException; |
| import java.util.Collection; |
| |
| public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference, |
| MethodRefKey extends MethodReference, AnnotationElement extends org.jf.dexlib2.iface.AnnotationElement, |
| EncodedValue> { |
| @Nonnull private final DexDataWriter writer; |
| @Nonnull private final StringSection<StringKey, ?> stringSection; |
| @Nonnull private final TypeSection<?, TypeKey, ?> typeSection; |
| @Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection; |
| @Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection; |
| @Nonnull private final AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection; |
| |
| public EncodedValueWriter( |
| @Nonnull DexDataWriter writer, |
| @Nonnull StringSection<StringKey, ?> stringSection, |
| @Nonnull TypeSection<?, TypeKey, ?> typeSection, |
| @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection, |
| @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection, |
| @Nonnull AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection) { |
| this.writer = writer; |
| this.stringSection = stringSection; |
| this.typeSection = typeSection; |
| this.fieldSection = fieldSection; |
| this.methodSection = methodSection; |
| this.annotationSection = annotationSection; |
| } |
| |
| protected abstract void writeEncodedValue(@Nonnull EncodedValue encodedValue) throws IOException; |
| |
| public void writeAnnotation(TypeKey annotationType, |
| Collection<? extends AnnotationElement> elements) throws IOException { |
| writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0); |
| writer.writeUleb128(typeSection.getItemIndex(annotationType)); |
| writer.writeUleb128(elements.size()); |
| |
| Collection<? extends AnnotationElement> sortedElements = Ordering.from(BaseAnnotationElement.BY_NAME) |
| .immutableSortedCopy(elements); |
| |
| for (AnnotationElement element: sortedElements) { |
| writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element))); |
| writeEncodedValue(annotationSection.getElementValue(element)); |
| } |
| } |
| |
| public void writeArray(Collection<? extends EncodedValue> elements) throws IOException { |
| writer.writeEncodedValueHeader(ValueType.ARRAY, 0); |
| writer.writeUleb128(elements.size()); |
| for (EncodedValue element: elements) { |
| writeEncodedValue(element); |
| } |
| } |
| |
| public void writeBoolean(boolean value) throws IOException { |
| writer.writeEncodedValueHeader(ValueType.BOOLEAN, value ? 1 : 0); |
| } |
| |
| public void writeByte(byte value) throws IOException { |
| writer.writeEncodedInt(ValueType.BYTE, value); |
| } |
| |
| public void writeChar(char value) throws IOException { |
| writer.writeEncodedUint(ValueType.CHAR, value); |
| } |
| |
| public void writeDouble(double value) throws IOException { |
| writer.writeEncodedDouble(ValueType.DOUBLE, value); |
| } |
| |
| public void writeEnum(@Nonnull FieldRefKey value) throws IOException { |
| writer.writeEncodedUint(ValueType.ENUM, fieldSection.getItemIndex(value)); |
| } |
| |
| public void writeField(@Nonnull FieldRefKey value) throws IOException { |
| writer.writeEncodedUint(ValueType.FIELD, fieldSection.getItemIndex(value)); |
| } |
| |
| public void writeFloat(float value) throws IOException { |
| writer.writeEncodedFloat(ValueType.FLOAT, value); |
| } |
| |
| public void writeInt(int value) throws IOException { |
| writer.writeEncodedInt(ValueType.INT, value); |
| } |
| |
| public void writeLong(long value) throws IOException { |
| writer.writeEncodedLong(ValueType.LONG, value); |
| } |
| |
| public void writeMethod(@Nonnull MethodRefKey value) throws IOException { |
| writer.writeEncodedUint(ValueType.METHOD, methodSection.getItemIndex(value)); |
| } |
| |
| public void writeNull() throws IOException { |
| writer.write(ValueType.NULL); |
| } |
| |
| public void writeShort(int value) throws IOException { |
| writer.writeEncodedInt(ValueType.SHORT, value); |
| } |
| |
| public void writeString(@Nonnull StringKey value) throws IOException { |
| writer.writeEncodedUint(ValueType.STRING, stringSection.getItemIndex(value)); |
| } |
| |
| public void writeType(@Nonnull TypeKey value) throws IOException { |
| writer.writeEncodedUint(ValueType.TYPE, typeSection.getItemIndex(value)); |
| } |
| } |