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);