26 #include "interpreter.h"
27 #include "operations.h"
29 #include "regexp_object.h"
30 #include "string_object.h"
31 #include "error_object.h"
33 #include "string_object.lut.h"
38 #ifdef HAVE_SYS_TYPES_H
39 #include <sys/types.h>
41 #ifdef HAVE_SYS_BITYPES_H
42 #include <sys/bitypes.h>
49 const ClassInfo StringInstanceImp::info = {
"String", 0, 0, 0};
51 StringInstanceImp::StringInstanceImp(ObjectImp *proto)
54 setInternalValue(
String(
""));
57 StringInstanceImp::StringInstanceImp(ObjectImp *proto,
const UString &
string)
60 setInternalValue(
String(
string));
65 if (propertyName == lengthPropertyName)
66 return Number(internalValue().toString(exec).size());
69 const unsigned index = propertyName.toArrayIndex(&ok);
71 const UString s = internalValue().toString(exec);
72 const unsigned length = s.
size();
74 const UChar c = s[index];
79 return ObjectImp::get(exec, propertyName);
84 if (propertyName == lengthPropertyName)
86 ObjectImp::put(exec, propertyName, value, attr);
91 if (propertyName == lengthPropertyName)
95 unsigned index = propertyName.toULong(&ok);
96 if (ok && index < (
unsigned)internalValue().toString(exec).size())
99 return ObjectImp::hasProperty(exec, propertyName);
104 if (propertyName == lengthPropertyName)
108 unsigned index = propertyName.toULong(&ok);
109 if (ok && index < (
unsigned)internalValue().toString(exec).size())
112 return ObjectImp::deleteProperty(exec, propertyName);
117 ReferenceList properties = ObjectImp::propList(exec,recursive);
119 UString str = internalValue().toString(exec);
120 for (
int i = 0; i < str.
size(); i++)
121 if (!ObjectImp::hasProperty(exec,Identifier::from(i)))
128 const ClassInfo StringPrototypeImp::info = {
"String", &StringInstanceImp::info, &stringTable, 0};
170 StringPrototypeImp::StringPrototypeImp(
ExecState * ,
171 ObjectPrototypeImp *objProto)
172 : StringInstanceImp(objProto)
176 putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum);
182 return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );
187 StringProtoFuncImp::StringProtoFuncImp(
ExecState *exec,
int i,
int len)
189 static_cast<
FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
193 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
196 bool StringProtoFuncImp::implementsCall()
const
202 static inline int localeCompare(
const UString &a,
const UString &b)
205 return compare(a, b);
214 if (
id == ToString ||
id == ValueOf) {
215 KJS_CHECK_THIS( StringInstanceImp, thisObj );
239 if (pos < 0 || pos >= len)
247 if (pos < 0 || pos >= len)
257 for ( ; it != args.
end() ; ++it) {
258 s += it->dispatchToString(exec);
265 if (a1.
type() == UndefinedType)
275 if (a1.
type() == UndefinedType || KJS::isNaN(d))
288 RegExp *reg, *tmpReg = 0;
290 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info))
292 imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
301 reg = tmpReg =
new RegExp(a0.
toString(exec), RegExp::None);
303 if (!reg->isValid()) {
306 "Invalid regular expression");
307 exec->setException(err);
310 RegExpObjectImp* regExpObj =
static_cast<RegExpObjectImp*
>(exec->interpreter()->
builtinRegExp().imp());
311 int **ovector = regExpObj->registerRegexp(reg, s);
312 reg->prepareMatch(s);
313 UString mstr = reg->match(s, -1, &pos, ovector);
319 }
else if ((reg->flags() & RegExp::Global) == 0) {
321 regExpObj->setSubPatterns(reg->subPatterns());
322 result = regExpObj->arrayOfMatches(exec,mstr);
330 mstr = reg->match(s, pos, &pos, ovector);
340 if (a0.
type() == ObjectType && a0.
toObject(exec).inherits(&RegExpImp::info)) {
341 RegExpImp* imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
342 RegExp *reg = imp->regExp();
344 Value tmp = imp->get(exec,
"global");
345 if (tmp.
type() != UndefinedType && tmp.
toBoolean(exec) ==
true)
360 reg->prepareMatch(s);
362 int **ovector = regExpObj->registerRegexp( reg, s );
363 UString mstr = reg->match(s, lastIndex, &pos, ovector);
364 regExpObj->setSubPatterns(reg->subPatterns());
377 for (
int i = 0; (i = rstr.
find(
UString(
"$"), i)) != -1; i++) {
378 if (i+1<rstr.
size() && rstr[i+1] ==
'$') {
384 if (ok && pos <= (
unsigned)reg->subPatterns()) {
386 + s.
substr((*ovector)[2*pos],
387 (*ovector)[2*pos+1]-(*ovector)[2*pos])
389 i += (*ovector)[2*pos+1]-(*ovector)[2*pos] - 1;
397 for (
unsigned int sub = 1; sub <= reg->subPatterns() ; ++sub )
399 (*ovector)[2*sub+1]-(*ovector)[2*sub]) ) );
408 if (pos != lastIndex)
409 out += s.
substr(lastIndex, pos - lastIndex);
414 lastIndex = pos + len;
418 if (lastIndex == 0 && out.
size() == 0)
421 out += s.
substr(lastIndex, s.
size() - lastIndex);
443 int begin = args[0].toUInt32(exec);
445 if (args[1].type() != UndefinedType) {
446 end = args[1].toInteger(exec);
448 int from = begin < 0 ? len + begin : begin;
449 int to = end < 0 ? len + end : end;
450 if (to > from && to > 0 && from < len) {
468 uint32_t limit = (a1.
type() != UndefinedType) ? a1.
toUInt32(exec) : 0xFFFFFFFFU;
471 RegExp reg(obj0.
get(exec,
"source").
toString(exec));
473 if (s.
isEmpty() && !reg.match(s, 0).isNull()) {
476 res.
put(exec, lengthPropertyName,
Number(0), DontDelete|ReadOnly|DontEnum);
480 while (static_cast<uint32_t>(i) != limit && pos < s.
size()) {
484 UString mstr = reg.match(s, pos, &mpos, &ovector);
485 delete [] ovector; ovector = 0L;
489 if (mpos != p0 || !mstr.
isEmpty()) {
491 p0 = mpos + mstr.
size();
501 put(exec,lengthPropertyName,
Number(0));
504 while (static_cast<uint32_t>(i) != limit && i < s.
size()-1)
508 while (static_cast<uint32_t>(i) != limit && (pos = s.
find(u2, p0)) >= 0) {
510 p0 = pos + u2.
size();
516 if (static_cast<uint32_t>(i) != limit)
518 res.
put(exec,lengthPropertyName,
Number(i));
528 d = maxInt(len + n, 0);
529 if (a1.
type() == UndefinedType)
532 d2 = minInt(maxInt(m, 0), len - d);
539 if (KJS::isNaN(start))
551 if (a1.
type() == UndefinedType)
558 result =
String(s.
substr((
int)start, (
int)end-(
int)start));
562 case ToLocaleLowerCase:
563 for (i = 0; i < len; i++)
564 s[i] = s[i].toLower();
568 case ToLocaleUpperCase:
569 for (i = 0; i < len; i++)
570 s[i] = s[i].toUpper();
575 #ifndef KJS_PURE_ECMA
577 result =
String(
"<big>" + s +
"</big>");
580 result =
String(
"<small>" + s +
"</small>");
583 result =
String(
"<blink>" + s +
"</blink>");
586 result =
String(
"<b>" + s +
"</b>");
589 result =
String(
"<tt>" + s +
"</tt>");
592 result =
String(
"<i>" + s +
"</i>");
595 result =
String(
"<strike>" + s +
"</strike>");
598 result =
String(
"<sub>" + s +
"</sub>");
601 result =
String(
"<sup>" + s +
"</sup>");
604 result =
String(
"<font color=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
607 result =
String(
"<font size=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
610 result =
String(
"<a name=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
613 result =
String(
"<a href=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
623 StringObjectImp::StringObjectImp(
ExecState *exec,
625 StringPrototypeImp *stringProto)
630 putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);
632 putDirect(
"fromCharCode",
new StringObjectFuncImp(exec,funcProto), DontEnum);
635 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
639 bool StringObjectImp::implementsConstruct()
const
648 if (args.
size() == 0)
649 return Object(
new StringInstanceImp(proto));
650 return Object(
new StringInstanceImp(proto, args.
begin()->dispatchToString(exec)));
653 bool StringObjectImp::implementsCall()
const
676 putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);
679 bool StringObjectFuncImp::implementsCall()
const
691 while (it != args.
end()) {
692 unsigned short u = it->toUInt16(exec);
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents...
UString substr(int pos=0, int len=-1) const
Type type() const
Returns the type of value.
Base class for all function objects.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Represents an primitive Number value.
void append(const Value &val)
Append an object to the end of the list.
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
int find(const UString &f, int pos=0) const
Represents an primitive Null value.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
static Object create(ExecState *exec, ErrorType errtype=GeneralError, const char *message=0, int lineno=-1, int sourceId=-1)
Factory method for error objects.
The initial value of Function.prototype (and thus all objects created with the Function constructor) ...
double toNumber(ExecState *exec) const
Performs the ToNumber type conversion operation on this value (ECMA 9.3)
unsigned char high() const
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
ListIterator begin() const
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
bool implementsCall() const
Whether or not the object implements the call() method.
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
unsigned char low() const
Represents an primitive String value.
Defines a Javascript reference.
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
Value internalValue() const
Returns the internal value of the object.
static const List & empty()
Returns a pointer to a static instance of an empty list.
int rfind(const UString &f, int pos) const
A list of Reference objects.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
Object builtinArray() const
Returns the builtin "Array" object.
Value call(ExecState *exec, Object &thisObj, const List &args)
Calls this object as if it is a function.
int toInteger(ExecState *exec) const
Performs the ToInteger type conversion operation on this value (ECMA 9.4)
Object builtinStringPrototype() const
Returns the builtin "String.prototype" object.
bool isValid() const
Returns whether or not this is a valid value.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
Represents the current state of script execution.
Represents an Identifier for a Javascript object.
Iterator for KJS::List objects.