/*
*******************************************************************************
*
*   Copyright (C) 1997-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*/
/*===============================================================================
 *
 * File cmpshrta.cpp
 *
 * Modification History:
 *
 *  Date        Name        Description
 *  2/5/97      aliu        Added CompactIntArray streamIn and streamOut methods.
 *  3/4/97      aliu        Tuned performance of CompactIntArray constructor,
 * 05/07/97     helena      Added isBogus()
 *                          based on performance data indicating that this_obj was slow.
 * 07/15/98        erm            Synched with Java 1.2 CompactShortArray.java.
 * 07/30/98        erm            Added changes from 07/29/98 code review.
 * 11/01/99		weiv		Added getArray, getIndex and getCount based on Jitterbug 4
 *===============================================================================
 */
#include "ucmp16.h"
#include "cmemory.h"





#define arrayRegionMatches(source, sourceStart, target, targetStart, len) (uprv_memcmp(&source[sourceStart], &target[targetStart], len * sizeof(int16_t)) != 0)

/* internal constants*/
#define UCMP16_kMaxUnicode_int 65535
#define UCMP16_kUnicodeCount_int (UCMP16_kMaxUnicode_int + 1)
#define UCMP16_kBlockShift_int 7
#define UCMP16_kBlockCount_int (1 << UCMP16_kBlockShift_int)
#define UCMP16_kBlockBytes_int (UCMP16_kBlockCount_int * sizeof(int16_t))
#define UCMP16_kIndexShift_int (16 - UCMP16_kBlockShift_int)
#define UCMP16_kIndexCount_int (1 << UCMP16_kIndexShift_int)
#define UCMP16_kBlockMask_int (UCMP16_kBlockCount_int - 1)


static const int32_t UCMP16_kMaxUnicode = UCMP16_kMaxUnicode_int;
static const int32_t UCMP16_kUnicodeCount = UCMP16_kUnicodeCount_int;
static const int32_t UCMP16_kBlockShift = UCMP16_kBlockShift_int;
static const int32_t UCMP16_kBlockCount = UCMP16_kBlockCount_int;
static const int32_t UCMP16_kBlockBytes = UCMP16_kBlockBytes_int;
static const int32_t UCMP16_kIndexShift = UCMP16_kIndexShift_int;
static const int32_t UCMP16_kIndexCount = UCMP16_kIndexCount_int;
static const uint32_t UCMP16_kBlockMask = UCMP16_kBlockMask_int;

/**
 * Sets the array to the invalid memory state.
 */
static CompactShortArray* setToBogus(CompactShortArray* array);
static void touchBlock(CompactShortArray* this_obj,
               int32_t i,
               int16_t value);
static UBool blockTouched(const CompactShortArray* this_obj,
               int32_t i);


/* debug flags*/
/*=======================================================*/

int32_t ucmp16_getkUnicodeCount()
{return UCMP16_kUnicodeCount;}

int32_t ucmp16_getkBlockCount()
{return UCMP16_kBlockCount;}

CompactShortArray* ucmp16_open(int16_t defaultValue)
{
  int32_t i;
  CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
  if (this_obj == NULL) return NULL;
  
  this_obj->fStructSize = sizeof(CompactShortArray);
  this_obj->fCount = UCMP16_kUnicodeCount;
  this_obj->fCompact = FALSE; 
  this_obj->fBogus = FALSE;
  this_obj->fArray = NULL;
  this_obj->fAlias = FALSE;
  this_obj->fIndex = NULL;
  this_obj->fHashes = NULL; 
  this_obj->fIAmOwned = FALSE;
  this_obj->fDefaultValue = defaultValue;
  
  this_obj->fArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
  if (this_obj->fArray == NULL)
    {
      this_obj->fBogus = TRUE;
      return NULL;
    }
  
  this_obj->fIndex = (uint16_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(uint16_t));
  if (this_obj->fIndex == NULL)
    {
      uprv_free(this_obj->fArray);
      this_obj->fArray = NULL;
      
      this_obj->fBogus = TRUE;
      return NULL;
    }
  
  this_obj->kBlockShift = UCMP16_kBlockShift;
  this_obj->kBlockMask = UCMP16_kBlockMask;
  for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
    {
      this_obj->fArray[i] = defaultValue;
    }
  
  this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
  if (this_obj->fHashes == NULL)
    {
      uprv_free(this_obj->fArray);
      uprv_free(this_obj->fIndex);
      this_obj->fBogus = TRUE;
      return NULL;
    }
  
  for (i = 0; i < UCMP16_kIndexCount; i += 1)
    {
      this_obj->fIndex[i] = (uint16_t)(i << UCMP16_kBlockShift);
      this_obj->fHashes[i] = 0;
    }
  
  return this_obj;
}

void ucmp16_initBogus(CompactShortArray *this_obj)
{
  if (this_obj == NULL) return;
  this_obj->fStructSize = sizeof(CompactShortArray);
  this_obj->fCount = UCMP16_kUnicodeCount;
  this_obj->fCompact = FALSE; 
  this_obj->fBogus = TRUE;
  this_obj->fArray = NULL;
  this_obj->fAlias = FALSE;
  this_obj->fIndex = NULL;
  this_obj->fHashes = NULL; 
  this_obj->fIAmOwned = TRUE;
  this_obj->fDefaultValue = 0;
}  

void ucmp16_init(CompactShortArray *this_obj, int16_t defaultValue)
{
  int32_t i;

  this_obj->fStructSize = sizeof(CompactShortArray);
  this_obj->fCount = UCMP16_kUnicodeCount;
  this_obj->fCompact = FALSE; 
  this_obj->fBogus = FALSE;
  this_obj->fArray = NULL;
  this_obj->fAlias = FALSE;
  this_obj->fIndex = NULL;
  this_obj->fHashes = NULL; 
  this_obj->fIAmOwned = TRUE;
  this_obj->fDefaultValue = defaultValue;
  
  this_obj->fArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
  if (this_obj->fArray == NULL)
    {
      this_obj->fBogus = TRUE;
      return;
    }
  
  this_obj->fIndex = (uint16_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(uint16_t));
  if (this_obj->fIndex == NULL)
    {
      uprv_free(this_obj->fArray);
      this_obj->fArray = NULL;
      
      this_obj->fBogus = TRUE;
      return;
    }
  
  this_obj->kBlockShift = UCMP16_kBlockShift;
  this_obj->kBlockMask = UCMP16_kBlockMask;
  for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
    {
      this_obj->fArray[i] = defaultValue;
    }
  
  this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
  if (this_obj->fHashes == NULL)
    {
      uprv_free(this_obj->fArray);
      uprv_free(this_obj->fIndex);
      this_obj->fBogus = TRUE;
      return;
    }
  
  for (i = 0; i < UCMP16_kIndexCount; i += 1)
    {
      this_obj->fIndex[i] = (uint16_t)(i << UCMP16_kBlockShift);
      this_obj->fHashes[i] = 0;
    }
}

CompactShortArray* ucmp16_openAdopt(uint16_t *indexArray,
                    int16_t *newValues, 
                    int32_t count,
                    int16_t defaultValue)
{
  CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
  if (this_obj == NULL) return NULL;
  this_obj->fHashes = NULL;
  this_obj->fCount = count; 
  this_obj->fDefaultValue = defaultValue;
  this_obj->fBogus = FALSE;
  this_obj->fArray = newValues;
  this_obj->fIndex = indexArray;
  this_obj->fCompact = count < UCMP16_kUnicodeCount;
  this_obj->fStructSize = sizeof(CompactShortArray);
  this_obj->kBlockShift = UCMP16_kBlockShift;
  this_obj->kBlockMask = UCMP16_kBlockMask;
  this_obj->fAlias = FALSE;
  this_obj->fIAmOwned = FALSE;

  return this_obj;
}


CompactShortArray* ucmp16_openAdoptWithBlockShift(uint16_t *indexArray,
                          int16_t *newValues,
                          int32_t count,
                          int16_t defaultValue,
                          int32_t blockShift)
{
  CompactShortArray* this_obj = ucmp16_openAdopt(indexArray,
                         newValues,
                         count,
                         defaultValue);
  if (this_obj == NULL) return NULL;
  
  this_obj->kBlockShift  = blockShift;
  this_obj->kBlockMask = (uint32_t) (((uint32_t)1 << (uint32_t)blockShift) - (uint32_t)1);
  
  return this_obj;
}


CompactShortArray* ucmp16_openAlias(uint16_t *indexArray,
                    int16_t *newValues, 
                    int32_t count,
                    int16_t defaultValue)
{
  CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
  if (this_obj == NULL) return NULL;
  this_obj->fHashes = NULL;
  this_obj->fCount = count; 
  this_obj->fDefaultValue = defaultValue;
  this_obj->fBogus = FALSE;
  this_obj->fArray = newValues;
  this_obj->fIndex = indexArray;
  this_obj->fCompact = count < UCMP16_kUnicodeCount;
  this_obj->fStructSize = sizeof(CompactShortArray);
  this_obj->kBlockShift = UCMP16_kBlockShift;
  this_obj->kBlockMask = UCMP16_kBlockMask;
  this_obj->fAlias = TRUE;
  this_obj->fIAmOwned = FALSE;

  return this_obj;
}

/*=======================================================*/
 
void ucmp16_close(CompactShortArray* this_obj)
{
  if(this_obj != NULL) {
    if(!this_obj->fAlias) {
      if(this_obj->fArray != NULL) {
        uprv_free(this_obj->fArray);
      }
      if(this_obj->fIndex != NULL) {
        uprv_free(this_obj->fIndex);
      }
    }
    if(this_obj->fHashes != NULL) {
      uprv_free(this_obj->fHashes);
    }
    if(!this_obj->fIAmOwned)
      {
        uprv_free(this_obj);
      }
  }
}

CompactShortArray* setToBogus(CompactShortArray* this_obj)
{
  if(this_obj != NULL) {
    if(!this_obj->fAlias) {
      uprv_free(this_obj->fArray);
      this_obj->fArray = NULL;
  
      uprv_free(this_obj->fIndex);
      this_obj->fIndex = NULL;
    }
    uprv_free(this_obj->fHashes);
    this_obj->fHashes = NULL;

    this_obj->fCount = 0;
    this_obj->fCompact = FALSE;
    this_obj->fBogus = TRUE;
  }
  
  return this_obj;
}


void ucmp16_expand(CompactShortArray* this_obj)
{
  if (this_obj->fCompact)
    {
      int32_t i;
      int16_t *tempArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));


      if (tempArray == NULL)
      {
       this_obj->fBogus = TRUE;
        return;
      }

      this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
      if (this_obj->fHashes == NULL)
      {
         this_obj->fBogus = TRUE;
         return;
      }
      
      for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
    {
      tempArray[i] = ucmp16_get(this_obj, (UChar)i);  /* HSYS : How expand?*/
        }
      
      for (i = 0; i < (1 << (16 - this_obj->kBlockShift)); i += 1)
    {
      this_obj->fIndex[i] = (uint16_t)(i<<this_obj->kBlockShift);
        }
      
      uprv_free(this_obj->fArray);
      this_obj->fArray = tempArray;
      this_obj->fCompact = FALSE;
    }
}

void ucmp16_set(CompactShortArray* this_obj,
        UChar c,
        int16_t value)
{
  if (this_obj->fCompact)
    {
      ucmp16_expand(this_obj);
      if (this_obj->fBogus) return;
    }
  
  this_obj->fArray[(int32_t)c] = value;
  
  if (value != this_obj->fDefaultValue)
    {
      touchBlock(this_obj, c >> this_obj->kBlockShift, value);
    }
}


void ucmp16_setRange(CompactShortArray* this_obj, 
             UChar start,
             UChar end,
             int16_t value)
{
  int32_t i;
  if (this_obj->fCompact)
    {
      ucmp16_expand(this_obj);
      if (this_obj->fBogus)  return;
    }
  if (value != this_obj->fDefaultValue)
    {
      for (i = start; i <= end; i += 1)
    {
       this_obj->fArray[i] = value;
      touchBlock(this_obj, i >> this_obj->kBlockShift, value);
    }
    }
  else
    {
      for (i = start; i <= end; i += 1)      this_obj->fArray[i] = value;
    }
}


/*=======================================================*/
void ucmp16_compact(CompactShortArray* this_obj)
{
  if (!this_obj->fCompact)
    {
      int32_t limitCompacted = 0;
      int32_t i, iBlockStart;
      int16_t iUntouched = -1;
      
      for (i = 0, iBlockStart = 0; i < (1 << (16 - this_obj->kBlockShift)); i += 1, iBlockStart += (1 << this_obj->kBlockShift))
    {
      UBool touched = blockTouched(this_obj, i);
      
      this_obj->fIndex[i] = 0xFFFF;
      
      if (!touched && iUntouched != -1)
        {
          /* If no values in this_obj block were set, we can just set its
           * index to be the same as some other block with no values
           * set, assuming we've seen one yet.
           */
          this_obj->fIndex[i] = iUntouched;
            }
      else
        {
          int32_t j, jBlockStart;
          
          for (j = 0, jBlockStart = 0;
           j < limitCompacted;
           j += 1, jBlockStart += (1 << this_obj->kBlockShift))
        {
          if (this_obj->fHashes[i] == this_obj->fHashes[j] &&
              arrayRegionMatches(this_obj->fArray,
                     iBlockStart,
                     this_obj->fArray, 
                     jBlockStart,
                     (1 << this_obj->kBlockShift)))
            {
              this_obj->fIndex[i] = (int16_t)jBlockStart;
                    }
                }
          
                /* TODO: verify this_obj is correct*/
          if (this_obj->fIndex[i] == 0xFFFF)
        {
          /* we didn't match, so copy & update*/
          uprv_memcpy(&(this_obj->fArray[jBlockStart]), 
                 &(this_obj->fArray[iBlockStart]),
                 (1 << this_obj->kBlockShift)*sizeof(int16_t));
          
          this_obj->fIndex[i] = (int16_t)jBlockStart;
          this_obj->fHashes[j] = this_obj->fHashes[i];
          limitCompacted += 1;
          
          if (!touched)
            {
              /* If this_obj is the first untouched block we've seen,*/
              /* remember its index.*/
              iUntouched = (int16_t)jBlockStart;
                    }
                }
            }
        }

        /* we are done compacting, so now make the array shorter*/
      {
    int32_t newSize = limitCompacted * (1 << this_obj->kBlockShift);
    int16_t *result = (int16_t*) uprv_malloc(sizeof(int16_t) * newSize);
    
    uprv_memcpy(result, this_obj->fArray, newSize * sizeof(int16_t));

    uprv_free(this_obj->fArray);
    this_obj->fArray = result;
    this_obj->fCount = newSize;
    uprv_free(this_obj->fHashes);
    this_obj->fHashes = NULL;

    this_obj->fCompact = TRUE;
      }
    }
}

/**
 * Query whether a specified block was "touched", i.e. had a value set.
 * Untouched blocks can be skipped when compacting the array
 */

int16_t ucmp16_getDefaultValue(const CompactShortArray* this_obj)
{
  return this_obj->fDefaultValue;
}


void touchBlock(CompactShortArray* this_obj,
        int32_t i,
        int16_t value)
{
  this_obj->fHashes[i] = (this_obj->fHashes[i] + (value << 1)) | 1;
}

UBool blockTouched(const CompactShortArray* this_obj, int32_t i)
{
  return (this_obj->fHashes[i] != 0);
}

uint32_t ucmp16_getCount(const CompactShortArray* this_obj)
{
    return this_obj->fCount;
}

const int16_t* ucmp16_getArray(const CompactShortArray* this_obj)
{
    return this_obj->fArray;
}

const uint16_t* ucmp16_getIndex(const CompactShortArray* this_obj)
{
    return this_obj->fIndex;
}


/* We use sizeof(*array), etc so that this code can be as portable as 
   possible between the ucmpX_ family.  Check lines marked 'SIZE'.
*/

U_CAPI  void U_EXPORT2 ucmp16_initFromData(CompactShortArray *this_obj, const uint8_t **source, UErrorCode *status)
{
  uint32_t i;
  const uint8_t *oldSource = *source;

  if(U_FAILURE(*status))
    return;

 this_obj->fArray = NULL;
 this_obj->fIndex = NULL; 
 this_obj->fBogus = FALSE;
 this_obj->fStructSize = sizeof(CompactShortArray);
 this_obj->fCompact = TRUE;
 this_obj->fAlias = TRUE;
 this_obj->fIAmOwned = TRUE;
 this_obj->fHashes = NULL;
 this_obj->fDefaultValue = 0x0000; /* not used */
  
 i = * ((const uint32_t*) *source);
 (*source) += 4;

 if(i != ICU_UCMP16_VERSION)
 {
   *status = U_INVALID_FORMAT_ERROR;
   return;
 }
  
 this_obj->fCount = * ((const uint32_t*)*source);
 (*source) += 4;

 this_obj->kBlockShift = * ((const uint32_t*)*source);
 (*source) += 4;

 this_obj->kBlockMask = * ((const uint32_t*)*source);
 (*source) += 4;

 this_obj->fIndex = (uint16_t*) *source;
 (*source) += sizeof(this_obj->fIndex[0])*UCMP16_kIndexCount;

 this_obj->fArray = (int16_t*) *source;
 (*source) += sizeof(this_obj->fArray[0])*this_obj->fCount;

 /* eat up padding */
 while((*source-(oldSource))%4)
    (*source)++;
}


