1
0
mirror of https://github.com/robertkrimen/otto synced 2025-09-28 18:45:22 +08:00
otto/type_array.go
2012-10-05 18:47:53 -07:00

151 lines
3.0 KiB
Go

package otto
import (
"strconv"
)
func (runtime *_runtime) newArrayObject(valueArray []Value) *_object {
self := runtime.newObject()
self.Class = "Array"
self._propertyStash = newArrayStash(valueArray, self._propertyStash)
return self
}
// _arrayStash
type _arrayStash struct {
valueArray []Value
_stash
}
func newArrayStash(valueArray []Value, stash _stash) *_arrayStash {
self := &_arrayStash{
valueArray,
stash,
}
return self
}
func (self *_arrayStash) CanWrite(name string) bool {
// length
if name == "length" {
return true
}
// .0, .1, .2, ...
index := stringToArrayIndex(name)
if index >= 0 {
return true
}
return self._stash.CanWrite(name)
}
func (self *_arrayStash) CanRead(name string) bool {
// length
if name == "length" {
return true
}
// .0, .1, .2, ...
index := stringToArrayIndex(name)
if index >= 0 {
return index < int64(len(self.valueArray)) && self.valueArray[index]._valueType != valueEmpty
}
return self._stash.CanRead(name)
}
func (self *_arrayStash) Read(name string) Value {
// length
if name == "length" {
return toValue(len(self.valueArray))
}
// .0, .1, .2, ...
index := stringToArrayIndex(name)
if index >= 0 {
if index < int64(len(self.valueArray)) {
value := self.valueArray[index]
if value._valueType != valueEmpty {
return value
}
}
return UndefinedValue()
}
return self._stash.Read(name)
}
func (self *_arrayStash) Write(name string, value Value) {
// length
if name == "length" {
value := uint(toUI32(value))
length := uint(len(self.valueArray))
if value > length {
valueArray := make([]Value, value)
copy(valueArray, self.valueArray)
self.valueArray = valueArray
} else if value < length {
self.valueArray = self.valueArray[:value]
}
return
}
// .0, .1, .2, ...
index := stringToArrayIndex(name)
if index >= 0 {
// May be able to do tricky stuff here
// with checking cap() after len(), but not
// sure if worth it
if index < int64(len(self.valueArray)) {
self.valueArray[index] = value
return
}
valueArray := make([]Value, index + 1)
copy(valueArray, self.valueArray)
valueArray[index] = value
self.valueArray = valueArray
return
}
self._stash.Write(name, value)
}
func (self *_arrayStash) property(name string) *_property {
// length
if name == "length" {
return &_property{
toValue(len(self.valueArray)),
propertyModeWrite, // +Write -Enumerate -Configure
}
}
// .0, .1, .2, ...
index := stringToArrayIndex(name)
if index >= 0 {
value := UndefinedValue()
if index < int64(len(self.valueArray)) {
value = self.valueArray[index]
}
return &_property{
Value: value,
Mode: propertyModeWriteEnumerateConfigure, // +Write +Enumerate +Configure
}
}
return self._stash.property(name)
}
func (self *_arrayStash) Enumerate(each func(string)) {
// .0, .1, .2, ...
for index, _ := range self.valueArray {
if self.valueArray[index]._valueType == valueEmpty {
continue // A sparse array
}
name := strconv.FormatInt(int64(index), 10)
each(name)
}
self._stash.Enumerate(each)
}