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
45const ClassInfo StringInstanceImp::info = {
"String", 0, 0, 0};
47StringInstanceImp::StringInstanceImp(ObjectImp *proto)
50 setInternalValue(
String(
""));
53StringInstanceImp::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];
71 return String(UString(&c, 1));
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)))
118 properties.append(Reference(
this, i));
124const ClassInfo StringPrototypeImp::info = {
"String", &StringInstanceImp::info, &stringTable, 0};
166StringPrototypeImp::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 );
183StringProtoFuncImp::StringProtoFuncImp(
ExecState *exec,
int i,
int len)
185 static_cast<
FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
189 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
192bool StringProtoFuncImp::implementsCall()
const
198static 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)
252 ListIterator it = args.
begin();
253 for ( ; it != args.
end() ; ++it) {
254 s += it->dispatchToString(exec);
261 if (a1.
type() == UndefinedType)
271 if (a1.
type() == UndefinedType || KJS::isNaN(d))
280 result = Number(s.
rfind(u2,
int(dpos)));
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);
311 result = Number(pos);
315 }
else if ((reg->flags() & RegExp::Global) == 0) {
317 regExpObj->setSubPatterns(reg->subPatterns());
318 result = regExpObj->arrayOfMatches(exec,mstr);
323 list.
append(String(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)
344 RegExpObjectImp* regExpObj =
static_cast<RegExpObjectImp*
>(exec->
lexicalInterpreter()->builtinRegExp().imp());
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);
421 result = String(out);
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;
446 if (to > from && to > 0 && from < len) {
453 result = String(s.
substr(from, to - from));
464 uint32_t limit = (a1.
type() != UndefinedType) ? a1.
toUInt32(exec) : 0xFFFFFFFFU;
467 RegExp reg(obj0.
get(exec,
"source").
toString(exec));
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()) {
486 res.
put(exec,i, String(s.
substr(p0, mpos-p0)));
487 p0 = mpos + mstr.
size();
497 put(exec,lengthPropertyName, Number(0));
500 while (
static_cast<uint32_t
>(i) != limit && i < s.
size()-1)
501 res.
put(exec,i++, String(s.
substr(p0++, 1)));
504 while (
static_cast<uint32_t
>(i) != limit && (pos = s.
find(u2, p0)) >= 0) {
505 res.
put(exec,i, String(s.
substr(p0, pos-p0)));
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);
529 result = String(s.
substr(d, d2));
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();
571 return Number(localeCompare(s, a0.
toString(exec)));
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>");
621StringObjectImp::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);
637bool StringObjectImp::implementsConstruct()
const
646 if (args.
size() == 0)
647 return Object(
new StringInstanceImp(proto));
648 return Object(
new StringInstanceImp(proto, args.
begin()->dispatchToString(exec)));
651bool StringObjectImp::implementsCall()
const
674 putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);
677bool StringObjectFuncImp::implementsCall()
const
686 UChar *buf =
new UChar[args.
size()];
688 ListIterator it = args.
begin();
689 while (it != args.
end()) {
690 unsigned short u = it->toUInt16(exec);
694 s = UString(buf, args.
size(),
false);
static Object create(ExecState *exec, ErrorType errtype=GeneralError, const char *message=0, int lineno=-1, int sourceId=-1)
Factory method for error objects.
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 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...
void append(const Value &val)
Append an object to the end of the list.
ListIterator begin() const
static const List & empty()
Returns a pointer to a static instance of an empty list.
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.
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
A list of Reference objects.
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