!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: canonstringdict.gs,v 1.10 2008-01-09 22:50:09 stever Exp $
!
!   CanonicalStringDictionary is the old (Gemstone 2G, Gemstone 6.0)
!				  class of AllSymbols
!   see newcanonstringdict.gs  for the Gemstone64  class of AllSymbols 
!
! Superclass Hierarchy:
!   CanonicalStringDictionary, StringKeyValueDictionary, 
!   KeyValueDictionary, AbstractDictionary, Collection, Object.
!
!=========================================================================

removeallmethods CanonicalStringDictionary
removeallclassmethods CanonicalStringDictionary

category: 'For Documentation Installation only'
classmethod: CanonicalStringDictionary
installDocumentation

| doc txt |
doc := GsClassDocumentation newForClass: self.

txt := (GsDocText new) details:
'A CanonicalStringDictionary is a StringKeyValueDictionary that provides
 protocol that is similar to Set in addition to its dictionary protocol.' .
doc documentClassWith: txt.
 
self description: doc.
%

category: 'Accessing the Class Format'
classmethod: CanonicalStringDictionary
firstPublicInstVar

^ 3
%

category: 'Hashing'
method: CanonicalStringDictionary
hashFunction: aKey

"The hash function performs an operation on the value of the
 key (aKey) and returns a value in the range 1..tableSize."

^(aKey hash \\  self tableSize) + 1
%

category: 'Private'
method: CanonicalStringDictionary
compareKey: key1 with: key2

"Returns whether key1 is equivalent to key2."

 key1 == key2 ifTrue:[ ^ true ].

 (key1 _isSymbol ~~ key2 _isSymbol) 
    ifTrue:[ ^ key1 asString = key2 asString ]
   ifFalse:[ ^ key1 = key2 ].
%

category: 'Updating'
method: CanonicalStringDictionary
addAssociation: anAssociation

"Add the argument anAssociation to the receiver."

^ super add: anAssociation
%

category: 'Updating'
method: CanonicalStringDictionary
addAll: aCollection

"Adds elements of aCollection to the receiver. Returns aCollection."

aCollection == self ifTrue:[ ^ aCollection ].
(aCollection isKindOf: AbstractDictionary) 
  ifTrue:[ ^ super addAll: aCollection].
aCollection do:[ :aString | self add: aString ].
^ aCollection
%

category: 'Updating'
method: CanonicalStringDictionary
remove: aString

"Removes aString if present in the receiver and returns the removed value.  If
 aString is not present, generates an error."

^ self removeKey: aString
%

category: 'Updating'
method: CanonicalStringDictionary
remove: aString ifAbsent: aBlock

"Removes aString if present in the receiver and returns the removed value.  If
 aString is not present, returns the result of evaluating the zero
 argument Block aBlock."

^ self removeKey: aString ifAbsent: aBlock
%

category: 'Updating'
method: CanonicalStringDictionary
add: aString

"Adds aString if it is not already present in the receiver, and returns
 either aString or the canonical string already present."

| aValue |
(aString isKindOf: String) ifTrue:[
  aValue := self at: aString otherwise: nil .
  aValue == nil ifTrue:[
    aString immediateInvariant .
    self at: aString put: aString .
    ^ aString
    ].
  ^ aValue
  ].
"assume aString is an Association."
^ super add: aString  
%

category: 'Accessing'
method: CanonicalStringDictionary
includes: aString

"Returns true if the receiver contains aString as a key, false otherwise."

| aValue |
aValue := self at: aString otherwise: nil .
^ aValue ~~ nil
%

category: 'Accessing'
method: CanonicalStringDictionary
includesValue: aString

"Returns true if the receiver contains aString as a key, false otherwise."

| aValue |
aValue := self at: aString otherwise: nil .
^ aValue ~~ nil
%

category: 'Accessing'
method: CanonicalStringDictionary
_validateGroupString: aString

| aValue |
aValue := self at: aString otherwise: nil .
aValue == nil ifTrue:[ 
  aString _error: #segErrBadGroup .
  ].
^ aValue
%

category: 'Repository Conversion'
method: CanonicalStringDictionary
_migrateSymbolSet: aSymbolSet

"Using the receiver as the canonicalization dictionary, migrate aSymbolSet
 to an IdentitySet of canonical Strings, and return the IdentitySet."

| newSet |

((aSymbolSet isKindOf: SymbolSet) _or: [aSymbolSet isKindOf: ObsoleteSymbolSet])
  ifTrue:[
  newSet := IdentitySet new .
  aSymbolSet do:[ :aSym | | aStr groupStr |
    aStr := String withAll: aSym .
    groupStr := self add: aStr .
    newSet add: groupStr .
    ].
  newSet assignToSegment: aSymbolSet segment .
  ^ newSet 
  ].

^ aSymbolSet
%
