001package com.streamconverter.command.impl.charcode;
002
003import com.streamconverter.command.AbstractStreamCommand;
004import java.io.IOException;
005import java.io.InputStream;
006import java.io.InputStreamReader;
007import java.io.OutputStream;
008import java.io.OutputStreamWriter;
009import java.nio.charset.Charset;
010import java.util.Objects;
011
012/**
013 * Converts the character encoding of a stream from one encoding to another.
014 *
015 * <p>This class extends the AbstractStreamCommand and implements the conversion of character
016 * encodings.
017 */
018// BEGIN CharacterConvertCommand.java
019public class CharacterConvertCommand extends AbstractStreamCommand {
020  private String from;
021  private String to;
022
023  /**
024   * Constructor to initialize the character encodings for conversion.
025   *
026   * @param from The source character encoding.
027   * @param to The target character encoding.
028   * @throws IllegalArgumentException if the specified character encodings are not supported.
029   */
030  public CharacterConvertCommand(String from, String to) {
031    Objects.requireNonNull(from);
032    Objects.requireNonNull(to);
033    if (Charset.isSupported(from) == false) {
034      throw new IllegalArgumentException("変換元文字コードがサポートされていません");
035    }
036    if (Charset.isSupported(to) == false) {
037      throw new IllegalArgumentException("変換先文字コードがサポートされていません");
038    }
039    this.from = from;
040    this.to = to;
041  }
042
043  /**
044   * Executes the character encoding conversion on the provided input stream and writes the result
045   * to the output stream.
046   *
047   * @param inputStream The input stream to read data from.
048   * @param outputStream The output stream to write data to.
049   * @throws IOException If an I/O error occurs during the execution of the command.
050   */
051  @Override
052  public void executeInternal(InputStream inputStream, OutputStream outputStream)
053      throws IOException {
054    Objects.requireNonNull(inputStream);
055    Objects.requireNonNull(outputStream);
056
057    // 省メモリストリーミング文字コード変換
058    try (InputStreamReader reader = new InputStreamReader(inputStream, this.from);
059        OutputStreamWriter writer = new OutputStreamWriter(outputStream, this.to); ) {
060
061      // transferTo()は大容量データでメモリを大量消費するため、
062      // 固定サイズバッファでストリーミング処理を実装
063      char[] buffer = new char[8192]; // 8KB char buffer (16KB memory)
064      int charsRead;
065
066      while ((charsRead = reader.read(buffer)) != -1) {
067        writer.write(buffer, 0, charsRead);
068        writer.flush(); // 即座に出力してメモリを解放
069      }
070    }
071  }
072}