!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: jisstring.gs,v 1.6 2008-01-09 22:50:12 stever Exp $
!
!=========================================================================

expectvalue %String
run
  JapaneseString _newKernelByteSubclass: 'JISString'
    classVars: #()
    poolDictionaries: #[]
    inDictionary: Globals
    instancesInvariant: false
    reservedOop: 769
%

removeallmethods JISString
removeallclassmethods JISString

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

| doc txt |
doc := GsClassDocumentation newForClass: self.
txt := (GsDocText new) details:
'JISString represents Japanese strings containing JISCharacters.  Each
 Character in a JISString occupies two bytes.'.
doc documentClassWith: txt.

self description: doc.
%

category: 'Concatenating'
method: JISString
, aCharOrCharColl

"Returns a new instance of the receiver's class that contains the elements of
 the receiver followed by the elements of aCharOrCharColl.

 Note: Creating a new instance and copying the receiver take time.  If you can
 safely modify the receiver, it is faster to use the addAll: method."

^JISString new addAll: self;
               addAll: aCharOrCharColl;
 	       yourself
%

category: 'Accessing'
method: JISString
at: anIndex

"Returns the JISCharacter at anIndex."

| highByte lowByte offset |

offset := anIndex * 2 .
lowByte := self _basicAt: offset .
highByte := self _basicAt: offset - 1 .
 ^ JISCharacter withValue: highByte * 256 + lowByte
%

category: 'Accessing'
method: JISString
size

"Returns the size of the receiver in Characters."

^ self _basicSize // 2
%

category: 'Updating'
method: JISString
at: anIndex put: aCharacter

"Stores aCharacter at the specified location."

| offset val highByte lowByte |
offset := anIndex * 2 .
val := aCharacter asJISCharacter jisValue .
highByte := val // 256 .
lowByte :=  val \\ 256 .
self _basicAt: offset - 1 put: highByte .
self _basicAt: offset     put: lowByte .
^ aCharacter
%

category: 'Updating'
method: JISString
size: anInteger

"Changes the size of the receiver to anInteger.

 If anInteger is less than the current size of the receiver, the receiver is
 shrunk accordingly.  If anInteger is greater than the current size of the
 receiver, the receiver is extended and new elements are initialized to nil."

^ self _basicSize: anInteger * 2
%

category: 'Formatting'
method: JISString
asJISString

"Returns the receiver."

"This reimplementation from JapaneseString is crucial!"

^self
%

category: 'Converting'
method: JISString
asSymbolKind

"Returns a copy of the receiver as an instance of class Symbol."

^ self asSymbol

%

category: 'Searching'
method: JISString
indexOf: aCharacter startingAt: startIndex

"Returns the index of the first occurrence of aCharacter in the receiver,
 not preceding startIndex.  If the receiver does not contain aCharacter,
 this returns zero."

startIndex to: self size do:[:j|
  (self at:j ) == aCharacter ifTrue:[ ^ j ].
  ].
^ 0
%

category: 'Adding'
method: JISString
add: aCharOrCharCollection

"Appends aCharOrCharCollection to the receiver.  The argument
 aCharOrCharCollection must be a CharacterCollection or a kind of
 AbstractCharacter."

(aCharOrCharCollection isKindOf: Collection) ifTrue:[
 ^ self addAll: aCharOrCharCollection; yourself
 ].
self at: (self size + 1) put: aCharOrCharCollection
%

category: 'Adding'
method: JISString
addAll: aCharOrCharCollection

"Equivalent to add: aCharOrCharCollection."

| idx |

(aCharOrCharCollection isKindOf: Collection) ifTrue:[
  idx := self size . 
  aCharOrCharCollection do:[ :aChar |
    idx := idx + 1 .
    self at: idx put: aChar .
    ].
  ^ self
  ].
^ self at: (self size + 1) put: aCharOrCharCollection
%

category: 'Adding'
method: JISString
addLast: aCharOrCharCollection

"Equivalent to add: aCharOrCharCollection."

^ self add: aCharOrCharCollection
%

category: 'Adding'
method: JISString
insertAll: aCharOrCharCollection at: anIndex

"Inserts aCharOrCharCollection at the specified index."

<primitive: 241>

anIndex _validateClass: SmallInteger.
(anIndex > (self size + 1))
ifTrue:[ ^ self _errorIndexOutOfRange: anIndex]
ifFalse:[ ^ super insertAll: aCharOrCharCollection at: anIndex]
%

category: 'Converting'
method: JISString
asSymbol

"Returns the receiver as a DoubleByteSymbol."

^ (DoubleByteString withAll: self) asSymbol
%

category: 'Formatting'
method: JISString
printString

"Returns a JISString whose contents are a displayable representation of the
 receiver."

| ws str |

str := JISString new.
ws := PrintStream printingOn: str.
self printOn: ws.
^str
%

category: 'Indexing Support'
method: JISString
_isValidPathTermName

"Returns true if the receiver is a valid term in a path expression."

^ (Symbol withAll: self) _isValidPathTermName
%

! category: 'Comparing'
! method: String
! = aCharCollection
! 
! "Returns true if corresponding Characters in the
!  receiver and argument are equal.  Returns false otherwise."
! 
!  "Uses the same primitive as String>>= , which tests for equal size of
!   receiver and argument and equal 8-bit value in each byte of receiver and
!   argument."
! 
! <primitive: 27>
! 
! "fail if argument is not a kind of String; let the argument's method handle
!  this operation"
! (aCharCollection isKindOf: CharacterCollection)
!    ifTrue: [^aCharCollection = self]
!    ifFalse: [^false]
! %

