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()) {
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;
448 int to = end < 0 ? len + end : end;
449 if (to > from && to > 0 && from < len) {
467 uint32_t limit = (a1.
type() != UndefinedType) ? a1.
toUInt32(exec) : 0xFFFFFFFFU;
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);