/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.jack.dx.dex.file;

import com.android.jack.dx.rop.cst.CstString;
import com.android.jack.dx.util.AnnotatedOutput;
import com.android.jack.dx.util.ByteArray;
import com.android.jack.dx.util.Hex;
import com.android.jack.dx.util.Leb128Utils;

/**
 * Representation of string data for a particular string, in a Dalvik file.
 */
public final class StringDataItem extends OffsettedItem {
  /** {@code non-null;} the string value */
  private final CstString value;

  /**
   * Constructs an instance.
   *
   * @param value {@code non-null;} the string value
   */
  public StringDataItem(CstString value) {
    super(1, writeSize(value));

    this.value = value;
  }

  /**
   * Gets the write size for a given value.
   *
   * @param value {@code non-null;} the string value
   * @return {@code >= 2}; the write size, in bytes
   */
  private static int writeSize(CstString value) {
    int utf16Size = value.getUtf16Size();

    // The +1 is for the '\0' termination byte.
    return Leb128Utils.unsignedLeb128Size(utf16Size) + value.getUtf8Size() + 1;
  }

  /** {@inheritDoc} */
  @Override
  public ItemType itemType() {
    return ItemType.TYPE_STRING_DATA_ITEM;
  }

  /** {@inheritDoc} */
  @Override
  public void addContents(DexFile file) {
    // Nothing to do here.
  }

  /** {@inheritDoc} */
  @Override
  public void writeTo0(DexFile file, AnnotatedOutput out) {
    ByteArray bytes = value.getBytes();
    int utf16Size = value.getUtf16Size();

    if (out.annotates()) {
      out.annotate(Leb128Utils.unsignedLeb128Size(utf16Size), "utf16_size: " + Hex.u4(utf16Size));
      out.annotate(bytes.size() + 1, value.toQuoted());
    }

    out.writeUleb128(utf16Size);
    out.write(bytes);
    out.writeByte(0);
  }

  /** {@inheritDoc} */
  @Override
  public String toHuman() {
    return value.toQuoted();
  }

  /** {@inheritDoc} */
  @Override
  protected int compareTo0(OffsettedItem other) {
    StringDataItem otherData = (StringDataItem) other;

    return value.compareTo(otherData.value);
  }
}
