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> 45 const ClassInfo StringInstanceImp::info = {
"String", 0, 0, 0};
47 StringInstanceImp::StringInstanceImp(ObjectImp *proto)
50 setInternalValue(
String(
""));
53 StringInstanceImp::StringInstanceImp(ObjectImp *proto,
const UString &
string)
56 setInternalValue(
String(
string));
61 if (propertyName == lengthPropertyName)
62 return Number(internalValue().toString(exec).size());
65 const unsigned index = propertyName.toArrayIndex(&ok);
67 const UString s = internalValue().toString(exec);
68 const unsigned length = s.
size();
70 const UChar c = s[index];
75 return ObjectImp::get(exec, propertyName);
80 if (propertyName == lengthPropertyName)
82 ObjectImp::put(exec, propertyName, value, attr);
87 if (propertyName == lengthPropertyName)
91 unsigned index = propertyName.toULong(&ok);
92 if (ok && index < (
unsigned)internalValue().toString(exec).size())
95 return ObjectImp::hasProperty(exec, propertyName);
100 if (propertyName == lengthPropertyName)
104 unsigned index = propertyName.toULong(&ok);
105 if (ok && index < (
unsigned)internalValue().toString(exec).size())
108 return ObjectImp::deleteProperty(exec, propertyName);
113 ReferenceList properties = ObjectImp::propList(exec,recursive);
115 UString str = internalValue().toString(exec);
116 for (
int i = 0; i < str.
size(); i++)
117 if (!ObjectImp::hasProperty(exec,Identifier::from(i)))
124 const ClassInfo StringPrototypeImp::info = {
"String", &StringInstanceImp::info, &stringTable, 0};
166 StringPrototypeImp::StringPrototypeImp(
ExecState * ,
167 ObjectPrototypeImp *objProto)
168 : StringInstanceImp(objProto)
172 putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum);
178 return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );
183 StringProtoFuncImp::StringProtoFuncImp(
ExecState *exec,
int i,
int len)
185 static_cast<
FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
189 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
192 bool StringProtoFuncImp::implementsCall()
const 198 static inline int localeCompare(
const UString &a,
const UString &b)
201 return compare(a, b);
210 if (
id == ToString ||
id == ValueOf) {
211 KJS_CHECK_THIS( StringInstanceImp, thisObj );
235 if (pos < 0 || pos >= len)
243 if (pos < 0 || pos >= len)
253 for ( ; it != args.
end() ; ++it) {
254 s += it->dispatchToString(exec);
261 if (a1.
type() == UndefinedType)
271 if (a1.
type() == UndefinedType || KJS::isNaN(d))
284 RegExp *reg, *tmpReg = 0;
286 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info))
288 imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
297 reg = tmpReg =
new RegExp(a0.
toString(exec), RegExp::None);
299 if (!reg->isValid()) {
302 "Invalid regular expression");
303 exec->setException(err);
306 RegExpObjectImp* regExpObj =
static_cast<RegExpObjectImp*
>(exec->interpreter()->
builtinRegExp().imp());
307 int **ovector = regExpObj->registerRegexp(reg, s);
308 reg->prepareMatch(s);
309 UString mstr = reg->match(s, -1, &pos, ovector);
315 }
else if ((reg->flags() & RegExp::Global) == 0) {
317 regExpObj->setSubPatterns(reg->subPatterns());
318 result = regExpObj->arrayOfMatches(exec,mstr);
326 mstr = reg->match(s, pos, &pos, ovector);
336 if (a0.
type() == ObjectType && a0.
toObject(exec).inherits(&RegExpImp::info)) {
337 RegExpImp* imp =
static_cast<RegExpImp *
>( a0.
toObject(exec).imp() );
338 RegExp *reg = imp->regExp();
340 Value tmp = imp->get(exec,
"global");
341 if (tmp.
type() != UndefinedType && tmp.
toBoolean(exec) ==
true)
356 reg->prepareMatch(s);
358 int **ovector = regExpObj->registerRegexp( reg, s );
359 UString mstr = reg->match(s, lastIndex, &pos, ovector);
360 regExpObj->setSubPatterns(reg->subPatterns());
373 for (
int i = 0; (i = rstr.
find(
UString(
"$"), i)) != -1; i++) {
374 if (i+1<rstr.
size() && rstr[i+1] ==
'$') {
380 if (ok && pos <= (
unsigned)reg->subPatterns()) {
382 + s.
substr((*ovector)[2*pos],
383 (*ovector)[2*pos+1]-(*ovector)[2*pos])
385 i += (*ovector)[2*pos+1]-(*ovector)[2*pos] - 1;
393 for (
unsigned int sub = 1; sub <= reg->subPatterns() ; ++sub )
395 (*ovector)[2*sub+1]-(*ovector)[2*sub]) ) );
404 if (pos != lastIndex)
405 out += s.
substr(lastIndex, pos - lastIndex);
410 lastIndex = pos + len;
414 if (lastIndex == 0 && out.
size() == 0)
417 out += s.
substr(lastIndex, s.
size() - lastIndex);
439 int begin = args[0].toUInt32(exec);
441 if (args[1].type() != UndefinedType) {
442 end = args[1].toInteger(exec);
444 int from = begin < 0 ? len + begin : begin;
445 int to = end < 0 ? len + end : end;
446 if (to > from && to > 0 && from < len) {
464 uint32_t limit = (a1.
type() != UndefinedType) ? a1.
toUInt32(exec) : 0xFFFFFFFFU;
467 RegExp reg(obj0.
get(exec,
"source").
toString(exec));
469 if (s.
isEmpty() && !reg.match(s, 0).isNull()) {
472 res.
put(exec, lengthPropertyName,
Number(0), DontDelete|ReadOnly|DontEnum);
476 while (static_cast<uint32_t>(i) != limit && pos < s.
size()) {
480 UString mstr = reg.match(s, pos, &mpos, &ovector);
481 delete [] ovector; ovector = 0L;
485 if (mpos != p0 || !mstr.
isEmpty()) {
487 p0 = mpos + mstr.
size();
497 put(exec,lengthPropertyName,
Number(0));
500 while (static_cast<uint32_t>(i) != limit && i < s.
size()-1)
504 while (static_cast<uint32_t>(i) != limit && (pos = s.
find(u2, p0)) >= 0) {
506 p0 = pos + u2.
size();
512 if (static_cast<uint32_t>(i) != limit)
514 res.
put(exec,lengthPropertyName,
Number(i));
524 d = maxInt(len + n, 0);
525 if (a1.
type() == UndefinedType)
528 d2 = minInt(maxInt(m, 0), len - d);
535 if (KJS::isNaN(start))
547 if (a1.
type() == UndefinedType)
554 result =
String(s.
substr((
int)start, (
int)end-(
int)start));
558 case ToLocaleLowerCase:
559 for (i = 0; i < len; i++)
560 s[i] = s[i].toLower();
564 case ToLocaleUpperCase:
565 for (i = 0; i < len; i++)
566 s[i] = s[i].toUpper();
573 #ifndef KJS_PURE_ECMA 575 result =
String(
"<big>" + s +
"</big>");
578 result =
String(
"<small>" + s +
"</small>");
581 result =
String(
"<blink>" + s +
"</blink>");
584 result =
String(
"<b>" + s +
"</b>");
587 result =
String(
"<tt>" + s +
"</tt>");
590 result =
String(
"<i>" + s +
"</i>");
593 result =
String(
"<strike>" + s +
"</strike>");
596 result =
String(
"<sub>" + s +
"</sub>");
599 result =
String(
"<sup>" + s +
"</sup>");
602 result =
String(
"<font color=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
605 result =
String(
"<font size=\"" + a0.
toString(exec) +
"\">" + s +
"</font>");
608 result =
String(
"<a name=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
611 result =
String(
"<a href=\"" + a0.
toString(exec) +
"\">" + s +
"</a>");
621 StringObjectImp::StringObjectImp(
ExecState *exec,
623 StringPrototypeImp *stringProto)
628 putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);
630 putDirect(
"fromCharCode",
new StringObjectFuncImp(exec,funcProto), DontEnum);
633 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
637 bool StringObjectImp::implementsConstruct()
const 646 if (args.
size() == 0)
647 return Object(
new StringInstanceImp(proto));
648 return Object(
new StringInstanceImp(proto, args.
begin()->dispatchToString(exec)));
651 bool StringObjectImp::implementsCall()
const 674 putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);
677 bool StringObjectFuncImp::implementsCall()
const 689 while (it != args.
end()) {
690 unsigned short u = it->toUInt16(exec);
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)
double toNumber(ExecState *exec) const
Performs the ToNumber type conversion operation on this value (ECMA 9.3)
Base class for all function objects.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
UString substr(int pos=0, int len=-1) const
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Represents an primitive Number value.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
unsigned char high() const
void append(const Value &val)
Append an object to the end of the list.
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
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Type type() const
Returns the type of value.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Represents an primitive Null value.
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) ...
Object builtinArray() const
Returns the builtin "Array" object.
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
const TDEShortcut & end()
Object builtinStringPrototype() const
Returns the builtin "String.prototype" object.
int toInteger(ExecState *exec) const
Performs the ToInteger type conversion operation on this value (ECMA 9.4)
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.
bool implementsCall() const
Whether or not the object implements the call() method.
int rfind(const UString &f, int pos) const
static const List & empty()
Returns a pointer to a static instance of an empty list.
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
bool isValid() const
Returns whether or not this is a valid value.
A list of Reference objects.
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
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.
unsigned char low() const
ListIterator begin() const
Represents the current state of script execution.
Represents an Identifier for a Javascript object.
Iterator for KJS::List objects.