2015-02-16 05:28:33 -08:00
|
|
|
package otto
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strconv"
|
|
|
|
"unicode/utf8"
|
|
|
|
)
|
|
|
|
|
|
|
|
type _stringObject interface {
|
|
|
|
Length() int
|
|
|
|
At(int) rune
|
|
|
|
String() string
|
|
|
|
}
|
|
|
|
|
|
|
|
type _stringASCII string
|
|
|
|
|
|
|
|
func (str _stringASCII) Length() int {
|
|
|
|
return len(str)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (str _stringASCII) At(at int) rune {
|
|
|
|
return rune(str[at])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (str _stringASCII) String() string {
|
|
|
|
return string(str)
|
|
|
|
}
|
|
|
|
|
|
|
|
type _stringWide struct {
|
|
|
|
string string
|
|
|
|
length int
|
|
|
|
runes []rune
|
|
|
|
}
|
|
|
|
|
|
|
|
func (str _stringWide) Length() int {
|
|
|
|
return str.length
|
|
|
|
}
|
|
|
|
|
|
|
|
func (str _stringWide) At(at int) rune {
|
|
|
|
if str.runes == nil {
|
|
|
|
str.runes = []rune(str.string)
|
|
|
|
}
|
|
|
|
return str.runes[at]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (str _stringWide) String() string {
|
|
|
|
return str.string
|
|
|
|
}
|
|
|
|
|
|
|
|
func _newStringObject(str string) _stringObject {
|
|
|
|
for i := 0; i < len(str); i++ {
|
|
|
|
if str[i] >= utf8.RuneSelf {
|
|
|
|
goto wide
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return _stringASCII(str)
|
|
|
|
|
|
|
|
wide:
|
|
|
|
return &_stringWide{
|
|
|
|
string: str,
|
|
|
|
length: utf8.RuneCountInString(str),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func stringAt(str _stringObject, index int) rune {
|
|
|
|
if 0 <= index && index < str.Length() {
|
|
|
|
return str.At(index)
|
|
|
|
}
|
|
|
|
return utf8.RuneError
|
|
|
|
}
|
|
|
|
|
|
|
|
func (runtime *_runtime) newStringObject(value Value) *_object {
|
2015-03-20 05:22:01 -07:00
|
|
|
str := _newStringObject(value.string())
|
2015-02-16 05:28:33 -08:00
|
|
|
|
|
|
|
self := runtime.newClassObject("String")
|
|
|
|
self.defineProperty("length", toValue_int(str.Length()), 0, false)
|
|
|
|
self.objectClass = _classString
|
|
|
|
self.value = str
|
|
|
|
return self
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *_object) stringValue() _stringObject {
|
|
|
|
if str, ok := self.value.(_stringObject); ok {
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func stringEnumerate(self *_object, all bool, each func(string) bool) {
|
|
|
|
if str := self.stringValue(); str != nil {
|
|
|
|
length := str.Length()
|
|
|
|
for index := 0; index < length; index++ {
|
|
|
|
if !each(strconv.FormatInt(int64(index), 10)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
objectEnumerate(self, all, each)
|
|
|
|
}
|
|
|
|
|
|
|
|
func stringGetOwnProperty(self *_object, name string) *_property {
|
|
|
|
if property := objectGetOwnProperty(self, name); property != nil {
|
|
|
|
return property
|
|
|
|
}
|
|
|
|
// TODO Test a string of length >= +int32 + 1?
|
|
|
|
if index := stringToArrayIndex(name); index >= 0 {
|
|
|
|
if chr := stringAt(self.stringValue(), int(index)); chr != utf8.RuneError {
|
|
|
|
return &_property{toValue_string(string(chr)), 0}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|