// Path: src/main/java/com/xiaomi/infra/galaxy/fds/android/exception/GalaxyFDSClientException.java
// public class GalaxyFDSClientException extends Exception {
// 
//   public GalaxyFDSClientException() {}
// 
//   public GalaxyFDSClientException(String message) {
//     super(message);
//   }
// 
//   public GalaxyFDSClientException(Throwable cause) {
//     super(cause);
//   }
// 
//   public GalaxyFDSClientException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: src/main/java/com/xiaomi/infra/galaxy/fds/android/model/FDSObject.java
// public class FDSObject implements Closeable {
// 
//   /**
//    * The name of the object
//    */
//   private final String objectName;
// 
//   /**
//    * The name of the bucket in which this object is contained
//    */
//   private final String bucketName;
// 
//   /**
//    * The metadata stored by Galaxy FDS for this object
//    */
//   private ObjectMetadata metadata;
// 
//   /**
//    * The stream containing the contents of this object from FDS
//    */
//   private InputStream objectContent;
// 
//   public FDSObject(String bucketName, String objectName) {
//     this.bucketName = bucketName;
//     this.objectName = objectName;
//   }
// 
//   /**
//    * Gets the name of the object
//    *
//    * @return The name of the object
//    */
//   public String getObjectName() {
//     return objectName;
//   }
// 
//   /**
//    * Gets the name of the bucket in which this object is contained.
//    *
//    * @return The name of the bucket in which this object is contained.
//    */
//   public String getBucketName() {
//     return bucketName;
//   }
// 
//   /**
//    * Gets the metadata stored by Galaxy FDS for this object. The
//    * {@link ObjectMetadata} object includes any custom user metadata supplied by
//    * the caller when the object was uploaded, as well as HTTP metadata such as
//    * content length and content type.
//    *
//    * @return The metadata stored by Galaxy FDS for this object.
//    * @see FDSObject#getObjectContent()
//    */
//   public ObjectMetadata getObjectMetadata() {
//     return metadata;
//   }
// 
//   /**
//    * Sets the object metadata for this object in memory.
//    * <p/>
//    * <b>NOTE:</b> This does not update the object metadata stored in Galaxy
//    * FDS, but only updates this object in local memory.
//    *
//    * @param metadata The new metadata to set for this object in memory.
//    */
//   public void setObjectMetadata(ObjectMetadata metadata) {
//     this.metadata = metadata;
//   }
// 
//   /**
//    * Gets an input stream containing the contents of this object. Callers should
//    * close this input stream as soon as possible, because the object contents
//    * aren't buffered in memory and stream directly from Galaxy FDS.
//    *
//    * @return An input stream containing the contents of this object.
//    * @see FDSObject#setObjectContent(InputStream)
//    */
//   public InputStream getObjectContent() {
//     return objectContent;
//   }
// 
//   /**
//    * Sets the input stream containing this object's contents.
//    *
//    * @param objectContent The input stream containing this object's contents.
//    * @see FDSObject#getObjectContent()
//    */
//   public void setObjectContent(InputStream objectContent) {
//     this.objectContent = objectContent;
//   }
// 
//   /**
//    * Releases any underlying system resources. If the resources are already
//    * released then invoking this method has no effect.
//    */
//   @Override
//   public void close() {
//     if (objectContent != null) {
//       try {
//         objectContent.close();
//       } catch (IOException e) {
//         // ignored
//       }
//     }
//   }
// }


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import android.webkit.MimeTypeMap;
import com.xiaomi.infra.galaxy.fds.android.exception.GalaxyFDSClientException;
import com.xiaomi.infra.galaxy.fds.android.model.FDSObject;
package com.xiaomi.infra.galaxy.fds.android.util;




public class Util {
  private static final int BUFFER_SIZE = 4096;

  private static final ThreadLocal<SimpleDateFormat> DATE_FOPMAT =
      new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
          SimpleDateFormat format = new SimpleDateFormat(
              "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
          format.setTimeZone(TimeZone.getTimeZone("GMT"));
          return format;
        }
      };

  /**
   * Download an object to the specified file
   *
   * @param object          The FDS object contains a reference to an
   *                        InputStream contains the object's data
   * @param destinationFile The file to store the object's data
   * @param isAppend          If append to the end of the file or overwrite it
   * @throws GalaxyFDSClientException
   */
  public static void downloadObjectToFile(FDSObject object,
      File destinationFile, boolean isAppend) throws GalaxyFDSClientException {
    // attempt to create the parent if it doesn't exist
    File parentDirectory = destinationFile.getParentFile();
    if (!isAppend && parentDirectory != null && !parentDirectory.exists() ) {
      parentDirectory.mkdirs();
    }

    int bytesRead = 0;
// Path: src/main/java/com/xiaomi/infra/galaxy/fds/android/exception/GalaxyFDSClientException.java
// public class GalaxyFDSClientException extends Exception {
// 
//   public GalaxyFDSClientException() {}
// 
//   public GalaxyFDSClientException(String message) {
//     super(message);
//   }
// 
//   public GalaxyFDSClientException(Throwable cause) {
//     super(cause);
//   }
// 
//   public GalaxyFDSClientException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: src/main/java/com/xiaomi/infra/galaxy/fds/android/model/FDSObject.java
// public class FDSObject implements Closeable {
// 
//   /**
//    * The name of the object
//    */
//   private final String objectName;
// 
//   /**
//    * The name of the bucket in which this object is contained
//    */
//   private final String bucketName;
// 
//   /**
//    * The metadata stored by Galaxy FDS for this object
//    */
//   private ObjectMetadata metadata;
// 
//   /**
//    * The stream containing the contents of this object from FDS
//    */
//   private InputStream objectContent;
// 
//   public FDSObject(String bucketName, String objectName) {
//     this.bucketName = bucketName;
//     this.objectName = objectName;
//   }
// 
//   /**
//    * Gets the name of the object
//    *
//    * @return The name of the object
//    */
//   public String getObjectName() {
//     return objectName;
//   }
// 
//   /**
//    * Gets the name of the bucket in which this object is contained.
//    *
//    * @return The name of the bucket in which this object is contained.
//    */
//   public String getBucketName() {
//     return bucketName;
//   }
// 
//   /**
//    * Gets the metadata stored by Galaxy FDS for this object. The
//    * {@link ObjectMetadata} object includes any custom user metadata supplied by
//    * the caller when the object was uploaded, as well as HTTP metadata such as
//    * content length and content type.
//    *
//    * @return The metadata stored by Galaxy FDS for this object.
//    * @see FDSObject#getObjectContent()
//    */
//   public ObjectMetadata getObjectMetadata() {
//     return metadata;
//   }
// 
//   /**
//    * Sets the object metadata for this object in memory.
//    * <p/>
//    * <b>NOTE:</b> This does not update the object metadata stored in Galaxy
//    * FDS, but only updates this object in local memory.
//    *
//    * @param metadata The new metadata to set for this object in memory.
//    */
//   public void setObjectMetadata(ObjectMetadata metadata) {
//     this.metadata = metadata;
//   }
// 
//   /**
//    * Gets an input stream containing the contents of this object. Callers should
//    * close this input stream as soon as possible, because the object contents
//    * aren't buffered in memory and stream directly from Galaxy FDS.
//    *
//    * @return An input stream containing the contents of this object.
//    * @see FDSObject#setObjectContent(InputStream)
//    */
//   public InputStream getObjectContent() {
//     return objectContent;
//   }
// 
//   /**
//    * Sets the input stream containing this object's contents.
//    *
//    * @param objectContent The input stream containing this object's contents.
//    * @see FDSObject#getObjectContent()
//    */
//   public void setObjectContent(InputStream objectContent) {
//     this.objectContent = objectContent;
//   }
// 
//   /**
//    * Releases any underlying system resources. If the resources are already
//    * released then invoking this method has no effect.
//    */
//   @Override
//   public void close() {
//     if (objectContent != null) {
//       try {
//         objectContent.close();
//       } catch (IOException e) {
//         // ignored
//       }
//     }
//   }
// }


// Path: src/main/java/com/xiaomi/infra/galaxy/fds/android/util/Util.java
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import android.webkit.MimeTypeMap;
import com.xiaomi.infra.galaxy.fds.android.exception.GalaxyFDSClientException;
import com.xiaomi.infra.galaxy.fds.android.model.FDSObject;

package com.xiaomi.infra.galaxy.fds.android.util;




public class Util {
  private static final int BUFFER_SIZE = 4096;

  private static final ThreadLocal<SimpleDateFormat> DATE_FOPMAT =
      new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
          SimpleDateFormat format = new SimpleDateFormat(
              "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
          format.setTimeZone(TimeZone.getTimeZone("GMT"));
          return format;
        }
      };

  /**
   * Download an object to the specified file
   *
   * @param object          The FDS object contains a reference to an
   *                        InputStream contains the object's data
   * @param destinationFile The file to store the object's data
   * @param isAppend          If append to the end of the file or overwrite it
   * @throws GalaxyFDSClientException
   */
  public static void downloadObjectToFile(FDSObject object,
      File destinationFile, boolean isAppend) throws GalaxyFDSClientException {
    // attempt to create the parent if it doesn't exist
    File parentDirectory = destinationFile.getParentFile();
    if (!isAppend && parentDirectory != null && !parentDirectory.exists() ) {
      parentDirectory.mkdirs();
    }

    int bytesRead = 0;
    byte[] buffer = new byte[BUFFER_SIZE];