/* gnu_java_nio_charset_iconv_IconvDecoder.c --
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

#include <config.h>
#include <jcl.h>

#include <stdio.h>
#include <assert.h>
#include <errno.h>

#if defined(HAVE_ICONV)
#include <iconv.h>
#endif

#include "gnu_java_nio_charset_iconv_IconvDecoder.h"

static void createRawData (JNIEnv * env, jobject obj, void *ptr);
static void *getData (JNIEnv * env, jobject obj);

static jfieldID infid = NULL;
static jfieldID outfid = NULL;

/* Union used for type punning. */
union char_union
{
  jbyte **jb;
  jchar **jc;
  char **c;
};

JNIEXPORT void JNICALL
Java_gnu_java_nio_charset_iconv_IconvDecoder_openIconv (JNIEnv * env,
							jobject obj,
							jstring jname)
{
#if defined(HAVE_ICONV)
  iconv_t iconv_object;
  jclass cls;

  const char *name = JCL_jstring_to_cstring (env, jname);
  if (name == NULL)
    return;

  /* Cache fieldIDs for use in decode function. */
  if (infid == NULL || outfid == NULL)
    {
      cls = (*env)->GetObjectClass (env, obj);
      infid = (*env)->GetFieldID (env, cls, "inremaining", "I");
      assert (infid != 0);
      outfid = (*env)->GetFieldID (env, cls, "outremaining", "I");
      assert (outfid != 0);
    }

  /* to java from "name", native java format depends on endianness */
#ifdef WORDS_BIGENDIAN
  iconv_object = iconv_open ("UTF-16BE", name);
#else
  iconv_object = iconv_open ("UTF-16LE", name);
#endif

  JCL_free_cstring (env, jname, name);
  if ((long) iconv_object == -1L)
    {
      JCL_ThrowException (env, "java/lang/IllegalArgumentException",
			  "Charset not available");
      return;
    }
  createRawData (env, obj, (void *) iconv_object);
#else
  JCL_ThrowException (env, "java/lang/IllegalArgumentException",
		      "iconv not available");
#endif
}

JNIEXPORT jint JNICALL
Java_gnu_java_nio_charset_iconv_IconvDecoder_decode (JNIEnv * env,
						     jobject obj,
						     jbyteArray inArr,
						     jcharArray outArr,
						     jint posIn, jint remIn,
						     jint posOut, jint remOut)
{
#if defined(HAVE_ICONV)
  iconv_t iconv_object = getData (env, obj);
  size_t retval;
  union char_union in, out;
  jbyte *input, *inputcopy;
  jchar *output, *outputcopy;
  size_t lenIn = (size_t) remIn;
  size_t lenOut = (size_t) remOut * 2;

  inputcopy = input = (*env)->GetByteArrayElements (env, inArr, 0);
  outputcopy = output = (*env)->GetCharArrayElements (env, outArr, 0);

  input += posIn;
  output += posOut;

  in.jb = &input;
  out.jc = &output;
  retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn,
		  out.c, &lenOut);

  /* XXX: Do we need to relase the input array? It's not modified. */
  (*env)->ReleaseByteArrayElements (env, inArr, inputcopy, 0);
  (*env)->ReleaseCharArrayElements (env, outArr, outputcopy, 0);

  if (retval == (size_t) (-1))
    {
      if (errno == EILSEQ)
	retval = 1;
      else
	retval = 0;
    }
  else
    retval = 0;

  (*env)->SetIntField (env, obj, infid, (jint) lenIn);
  (*env)->SetIntField (env, obj, outfid, (jint) (lenOut >> 1));

  return (jint) retval;
#else
  return -1;
#endif
}

JNIEXPORT void JNICALL
Java_gnu_java_nio_charset_iconv_IconvDecoder_closeIconv (JNIEnv * env,
							 jobject obj)
{
#if defined(HAVE_ICONV)
  iconv_t iconv_object;
  iconv_object = getData (env, obj);
  iconv_close (iconv_object);
#endif
}


static void
createRawData (JNIEnv * env, jobject obj, void *ptr)
{
  jclass cls;
  jobject data;
  jfieldID data_fid;

  cls = (*env)->GetObjectClass (env, obj);
  data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
  assert (data_fid != 0);

  data = JCL_NewRawDataObject(env, ptr);

  (*env)->SetObjectField (env, obj, data_fid, data);
}

static void *
getData (JNIEnv * env, jobject obj)
{
  jclass cls;
  jfieldID data_fid;
  jobject data;

  cls = (*env)->GetObjectClass (env, obj);
  data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
  assert (data_fid != 0);
  data = (*env)->GetObjectField (env, obj, data_fid);

  return JCL_GetRawData(env, data);
}
