#// for bash ver3

#// bashlib is provided under 3-clause BSD license.
#// Copyright (C) 2011 Sofrware Design Gallery "Sage Plaisir 21" All Rights Reserved.


 
#//*********************************************************************
#// <<< [SetAttr_func] >>> 
#//*********************************************************************
function  SetAttr_func()
{
  local  self="$1"
  local  AttrName="$2"
  local  Value="$3"

  eval  ${self}__${AttrName}="'$Value'"


  #// make attribute key list
  #// *___First -> *__<Attr>__Next -> *__<LastAttr>__Next <--> *___Last
  local  next
  eval  next='$'${self}__${AttrName}__Next
  if [ "$next" == "" ];then
    local  old_last
    eval  old_last='$'${self}___Last
    if [ "$old_last" == "" ];then  old_last=${self}___First  ;fi
    eval  $old_last=${self}__${AttrName}__Next
    eval  ${self}__${AttrName}__Next=${self}___Last
    eval  ${self}___Last=${self}__${AttrName}__Next
    eval  ${self}='$(( $'"${self}"' + 1 ))'
  fi
}


 
#//*********************************************************************
#// <<< [Attr_func] >>> 
#//*********************************************************************
function  Attr_func()
{
  local  self="$1"
  local  AttrName="$2"

  eval  g_Ret='$'"${self}__${AttrName}"
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getLength_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getLength_method()
{
  eval  g_Ret='$'"${self}"
  if [ "$g_Ret" == "" ];then  g_Ret=0  ;fi
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getKeys_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getKeys_method()
{
  local  self="$1"
  if [ "$self" == "" ];then  Error_func  "no object name"  ;fi
  local  key_offset
  local  minus
  local  next
  local  list_count=0
  local  self_count

  key_offset=$(( ${#self} + 2 ))
  minus=$(( $key_offset + 6 ))

  eval  next='$'${self}___First
  if [ x"$next" == x""  -o  x"$next" == x"${self}___Last" ];then  g_Ret="" ; return  ;fi

  g_Ret="${next:$key_offset:$(( ${#next} - $minus ))}"
  eval  next='$'$next
  list_count=1
  while [ "$next" != "${self}___Last" ];do
    g_Ret="$g_Ret ${next:$key_offset:$(( ${#next} - $minus ))}"
    eval  next='$'$next
    list_count=$(( $list_count + 1 ))
  done ; done_func $?

  eval  self_count='$'$self
  if [ "$list_count" != "$self_count" ];then
    local  str

    str="AssociativeArrayClass のオブジェクト $self が壊れています。 "
    str="${str}AssociativeArrayClass.destroy_method を呼び忘れた可能性があります。"
    str="${str}\$declare_associative_array（疑似連想配列の宣言）をしている場所より前のいくつかの場所から、"
    str="${str}AssociativeArrayClass.getKeys_method  $self を呼び出して、destroy_method を呼び出す場所を探してください。${LF}"
    str="${str}list_count=$list_count, self_count=$self_count"
    Error_func  "$str"
  fi
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getItems_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getItems_method()
{
  local  self="$1"
  if [ "$self" == "" ];then  Error_func  "no object name"  ;fi
  local  keys ; AssociativeArrayClass.getKeys_method  $self ; keys=( $g_Ret )
  local  key

  g_Ret=""
  for key  in "${keys[@]}" ;do
    eval  g_Ret='"$g_Ret $'"${self}__$key"'"'
  done ; done_func $?
  StringClass.substring_method  "$g_Ret"  1
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.clear_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.clear_method()
{
  AssociativeArrayClass.destroy_method  "$1"
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.destroy_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.destroy_method()
{
  local  self="$1"
  local  keys ; AssociativeArrayClass.getKeys_method  $self ; keys=( $g_Ret )
  local  key

  for key  in "${keys[@]}" ;do
    unset  ${self}__${key}
    unset  ${self}__${key}__Next
  done ; done_func $?
  unset  ${self}___First
  unset  ${self}___Last
  unset  $self
}


 
#//*********************************************************************
#// <<< [CopyArray_func] >>> 
#//*********************************************************************
function  CopyArray_func()
{
  local  DstArray__="$1"
  local  SrcArray__="$2"
  local  first__
  local  key__
  local  keys__

  local  locals__="DstArray__ SrcArray__ first__ key__ keys__"
  CheckOutParamIsConflictToLocal_func  "$DstArray__"   $locals__
  CheckOutParamIsConflictToLocal_func  "$SrcArray__"   $locals__

  eval  first__='"$'${SrcArray__}___First'"'

  if [ "$first__" != "" ];then
    CopyAssociativeArray_func  "$@"
  else
    ArrayClass.clear_method  $DstArray__
    eval  keys__=( '"${!'"$SrcArray__"'[@]}"' )
    for key__  in "${keys__[@]}" ;do
      eval  $DstArray__'[$key__]'='${'$SrcArray__'[$key__]}'
    done ; done_func $?
  fi
}


 
#//*********************************************************************
#// <<< [CopyAssociativeArray_func] >>> 
#//*********************************************************************
function  CopyAssociativeArray_func()
{
  local  DstArray__="$1"
  local  SrcArray__="$2"
  local  key__
  local  keys__
  local  locals__="DstArray__ SrcArray__ key__ keys__ value__"
  CheckOutParamIsConflictToLocal_func  "$DstArray__"   $locals__
  CheckOutParamIsConflictToLocal_func  "$SrcArray__"   $locals__

  AssociativeArrayClass.destroy_method  $DstArray__

  AssociativeArrayClass.getKeys_method  $SrcArray__
  eval  keys__=( "${g_Ret[@]}" )

  for key__  in "${keys__[@]}" ;do
    eval  SetAttr_func  $DstArray__  "$key__"  '$'${SrcArray__}__${key__}
  done ; done_func $?
}


 
