25 #include "interpreter.h"
26 #include "operations.h"
28 #include "regexp_object.h"
29 #include "string_object.h"
30 #include "error_object.h"
32 #include "string_object.lut.h"
37 #ifdef HAVE_SYS_TYPES_H
38 #include <sys/types.h>
40 #ifdef HAVE_SYS_BITYPES_H
41 #include <sys/bitypes.h>
48 const ClassInfo StringInstanceImp::info = {
"String", 0, 0, 0};
50 StringInstanceImp::StringInstanceImp(ObjectImp *proto)
53 setInternalValue(
String(
""));
56 StringInstanceImp::StringInstanceImp(ObjectImp *proto,
const UString &
string)
59 setInternalValue(
String(
string));
64 if (propertyName == lengthPropertyName)
65 return Number(internalValue().toString(exec).size());
68 const unsigned index = propertyName.toArrayIndex(&ok);
70 const UString s = internalValue().toString(exec);
71 const unsigned length = s.
size();
73 const UChar c = s[index];
78 return ObjectImp::get(exec, propertyName);
83 if (propertyName == lengthPropertyName)
85 ObjectImp::put(exec, propertyName, value, attr);
90 if (propertyName == lengthPropertyName)
94 unsigned index = propertyName.toULong(&ok);
95 if (ok && index < (
unsigned)internalValue().toString(exec).size())
98 return ObjectImp::hasProperty(exec, propertyName);
103 if (propertyName == lengthPropertyName)
107 unsigned index = propertyName.toULong(&ok);
108 if (ok && index < (
unsigned)internalValue().toString(exec).size())
111 return ObjectImp::deleteProperty(exec, propertyName);
116 ReferenceList properties = ObjectImp::propList(exec,recursive);
118 UString str = internalValue().toString(exec);
119 for (
int i = 0; i < str.
size(); i++)
120 if (!ObjectImp::hasProperty(exec,Identifier::from(i)))
127 const ClassInfo StringPrototypeImp::info = {
"String", &StringInstanceImp::info, &stringTable, 0};
169 StringPrototypeImp::StringPrototypeImp(
ExecState * ,
170 ObjectPrototypeImp *objProto)
171 : StringInstanceImp(objProto)
175 putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum);
181 return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable,
this );
186 StringProtoFuncImp::StringProtoFuncImp(
ExecState *exec,
int i,
int len)
188 static_cast<
FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
192 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
195 bool StringProtoFuncImp::implementsCall()
const
201 static inline int localeCompare(
const UString &a,
const UString &b)
204 return compare(a, b);
213 if (
id == ToString ||
id == ValueOf) {
214 KJS_CHECK_THIS( StringInstanceImp, thisObj );
238 if (pos < 0 || pos >= len)
246 if (pos < 0 || pos >= len)
256 for ( ; it != args.
end() ; ++it) {
257 s += it->dispatchToString(exec);
264 if (a1.
type() == UndefinedType)
274 if (a1.
type() == UndefinedType || KJS::isNaN(d))
287 RegExp *reg, *tmpReg = 0;
289 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info))
291 imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
300 reg = tmpReg =
new RegExp(a0.
toString(exec), RegExp::None);
302 if (!reg->isValid()) {
304 Object err = Error::create(exec, SyntaxError,
305 "Invalid regular expression");
306 exec->setException(err);
309 RegExpObjectImp* regExpObj =
static_cast<RegExpObjectImp*
>(exec->interpreter()->
builtinRegExp().imp());
310 int **ovector = regExpObj->registerRegexp(reg, s);
311 reg->prepareMatch(s);
312 UString mstr = reg->match(s, -1, &pos, ovector);
318 }
else if ((reg->flags() & RegExp::Global) == 0) {
320 regExpObj->setSubPatterns(reg->subPatterns());
321 result = regExpObj->arrayOfMatches(exec,mstr);
329 mstr = reg->match(s, pos, &pos, ovector);
339 if (a0.
type() == ObjectType && a0.
toObject(exec).inherits(&RegExpImp::info)) {
340 RegExpImp* imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
341 RegExp *reg = imp->regExp();
343 Value tmp = imp->get(exec,
"global");
344 if (tmp.
type() != UndefinedType && tmp.
toBoolean(exec) ==
true)
359 reg->prepareMatch(s);
361 int **ovector = regExpObj->registerRegexp( reg, s );
362 UString mstr = reg->match(s, lastIndex, &pos, ovector);
363 regExpObj->setSubPatterns(reg->subPatterns());
376 for (
int i = 0; (i = rstr.
find(
UString(
"$"), i)) != -1; i++) {
377 if (i+1<rstr.
size() && rstr[i+1] ==
'$') {
383 if (ok && pos <= (
unsigned)reg->subPatterns()) {
385 + s.
substr((*ovector)[2*pos],
386 (*ovector)[2*pos+1]-(*ovector)[2*pos])
388 i += (*ovector)[2*pos+1]-(*ovector)[2*pos] - 1;
396 for (
unsigned int sub = 1; sub <= reg->subPatterns() ; ++sub )
398 (*ovector)[2*sub+1]-(*ovector)[2*sub]) ) );
407 if (pos != lastIndex)
408 out += s.
substr(lastIndex, pos - lastIndex);
413 lastIndex = pos + len;
417 if (lastIndex == 0 && out.
size() == 0)
420 out += s.
substr(lastIndex, s.
size() - lastIndex);
442 int begin = args[0].toUInt32(exec);
444 if (args[1].type() != UndefinedType) {
445 end = args[1].toInteger(exec);
447 int from = begin < 0 ? len + begin : begin;
449 if (to > from && to > 0 && from < len) {
464 Object res = Object::dynamicCast(constructor.
construct(exec,List::empty()));
467 uint32_t limit = (a1.
type() != UndefinedType) ? a1.
toUInt32(exec) : 0xFFFFFFFFU;
468 if (a0.
type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) {
469 Object obj0 = Object::dynamicCast(a0);
470 RegExp reg(obj0.
get(exec,
"source").
toString(exec));
472 if (s.
isEmpty() && !reg.match(s, 0).isNull()) {
475 res.
put(exec, lengthPropertyName,
Number(0), DontDelete|ReadOnly|DontEnum);
479 while (
static_cast<uint32_t
>(i) != limit && pos < s.
size()) {
483 UString mstr = reg.match(s, pos, &mpos, &ovector);
484 delete [] ovector; ovector = 0L;
488 if (mpos != p0 || !mstr.
isEmpty()) {
490 p0 = mpos + mstr.
size();
500 put(exec,lengthPropertyName,
Number(0));
503 while (
static_cast<uint32_t
>(i) != limit && i < s.
size()-1)
507 while (
static_cast<uint32_t
>(i) != limit && (pos = s.
find(u2, p0)) >= 0) {
509 p0 = pos + u2.
size();
515 if (
static_cast<uint32_t
>(i) != limit)
517 res.
put(exec,lengthPropertyName,
Number(i));
527 d = maxInt(len + n, 0);
528 if (a1.
type() == UndefinedType)
531 d2 = minInt(maxInt(m, 0), len - d);
538 if (KJS::isNaN(start))
550 if (a1.
type() == UndefinedType)
557 result =
String(s.
substr((
int)start, (
int)end-(
int)start));
561 case ToLocaleLowerCase:
562 for (i = 0; i < len; i++)
563 s[i] = s[i].toLower();
567 case ToLocaleUpperCase:
568 for (i = 0; i < len; i++)
569 s[i] = s[i].toUpper();
576 #ifndef KJS_PURE_ECMA
578 result =
String(
"<big>" + s +
"</big>");
581 result =
String(
"<small>" + s +
"</small>");
584 result =
String(
"<blink>" + s +
"</blink>");
587 result =
String(
"<b>" + s +
"</b>");
590 result =
String(
"<tt>" + s +
"</tt>");
593 result =
String(
"<i>" + s +
"</i>");
596 result =
String(
"<strike>" + s +
"</strike>");
599 result =
String(
"<sub>" + s +
"</sub>");
602 result =
String(
"<sup>" + s +
"</sup>");
605 result =
String(
"<font color=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
608 result =
String(
"<font size=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
611 result =
String(
"<a name=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
614 result =
String(
"<a href=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
624 StringObjectImp::StringObjectImp(
ExecState *exec,
626 StringPrototypeImp *stringProto)
631 putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);
633 putDirect(
"fromCharCode",
new StringObjectFuncImp(exec,funcProto), DontEnum);
636 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
640 bool StringObjectImp::implementsConstruct()
const
649 if (args.
size() == 0)
650 return Object(
new StringInstanceImp(proto));
651 return Object(
new StringInstanceImp(proto, args.
begin()->dispatchToString(exec)));
654 bool StringObjectImp::implementsCall()
const
677 putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);
680 bool StringObjectFuncImp::implementsCall()
const
692 while (it != args.
end()) {
693 unsigned short u = it->toUInt16(exec);
Represents the current state of script execution.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
The initial value of Function.prototype (and thus all objects created with the Function constructor)
Represents an Identifier for a Javascript object.
Base class for all function objects.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
Object builtinArray() const
Returns the builtin "Array" object.
Object builtinStringPrototype() const
Returns the builtin "String.prototype" object.
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
Iterator for KJS::List objects.
void append(const Value &val)
Append an object to the end of the list.
ListIterator begin() const
Represents an primitive Null value.
Represents an primitive Number value.
bool implementsCall() const
Whether or not the object implements the call() method.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Value internalValue() const
Returns the internal value of the object.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Value call(ExecState *exec, Object &thisObj, const List &args)
Calls this object as if it is a function.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
A list of Reference objects.
Defines a Javascript reference.
Represents an primitive String value.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
int find(const UString &f, int pos=0) const
int rfind(const UString &f, int pos) const
UString substr(int pos=0, int len=-1) const
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents.
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
int toInteger(ExecState *exec) const
Performs the ToInteger type conversion operation on this value (ECMA 9.4)
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
bool isValid() const
Returns whether or not this is a valid value.
Type type() const
Returns the type of value.
double toNumber(ExecState *exec) const
Performs the ToNumber type conversion operation on this value (ECMA 9.3)
const TDEShortcut & end()
unsigned char low() const
unsigned char high() const