1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 ** This file is part of the QtScript module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the either Technology Preview License Agreement or the
13 ** Beta Release License Agreement.
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at http://www.qtsoftware.com/contact.
40 ****************************************************************************/
42 #include "qscriptecmastring_p.h"
46 #include "qscriptengine_p.h"
47 #include "qscriptvalueimpl_p.h"
48 #include "qscriptcontext_p.h"
49 #include "qscriptmember_p.h"
50 #include "qscriptobject_p.h"
51 #include "qscriptclassdata_p.h"
53 #include <QtCore/QStringList>
54 #include <QtCore/QtDebug>
55 #include <QtCore/qnumeric.h>
61 namespace QScript
{ namespace Ecma
{
63 class StringClassData
: public QScriptClassData
65 QScriptClassInfo
*m_classInfo
;
68 StringClassData(QScriptClassInfo
*classInfo
);
69 virtual ~StringClassData();
71 inline QScriptClassInfo
*classInfo() const
72 { return m_classInfo
; }
74 virtual bool resolve(const QScriptValueImpl
&object
,
75 QScriptNameIdImpl
*nameId
,
76 QScript::Member
*member
, QScriptValueImpl
*base
,
77 QScript::AccessMode access
);
78 virtual bool get(const QScriptValueImpl
&object
, const Member
&member
,
79 QScriptValueImpl
*out_value
);
80 virtual bool put(QScriptValueImpl
*object
, const Member
&member
,
81 const QScriptValueImpl
&value
);
82 virtual QScriptClassDataIterator
*newIterator(const QScriptValueImpl
&object
);
85 class StringClassDataIterator
: public QScriptClassDataIterator
88 StringClassDataIterator(int length
);
89 virtual ~StringClassDataIterator();
91 virtual bool hasNext() const;
92 virtual void next(QScript::Member
*member
);
94 virtual bool hasPrevious() const;
95 virtual void previous(QScript::Member
*member
);
97 virtual void toFront();
98 virtual void toBack();
105 StringClassData::StringClassData(QScriptClassInfo
*classInfo
):
106 m_classInfo(classInfo
)
110 StringClassData::~StringClassData()
114 bool StringClassData::resolve(const QScriptValueImpl
&object
,
115 QScriptNameIdImpl
*nameId
,
116 QScript::Member
*member
,
117 QScriptValueImpl
*base
,
118 QScript::AccessMode
/*access*/)
120 if (object
.classInfo() != classInfo())
123 QScriptEnginePrivate
*eng
= object
.engine();
125 if (nameId
== eng
->idTable()->id_length
) {
126 member
->native(nameId
, /*id=*/ 0,
127 QScriptValue::Undeletable
128 | QScriptValue::ReadOnly
129 | QScriptValue::SkipInEnumeration
);
135 int index
= nameId
->s
.toInt(&ok
);
136 if (!ok
|| (index
< 0))
139 QScriptNameIdImpl
*ref
= object
.internalValue().stringValue();
140 if (index
>= ref
->s
.length())
143 member
->native(nameId
, index
, QScriptValue::Undeletable
| QScriptValue::ReadOnly
);
147 bool StringClassData::get(const QScriptValueImpl
&object
,
148 const QScript::Member
&member
,
149 QScriptValueImpl
*result
)
151 Q_ASSERT(member
.isValid());
153 if (object
.classInfo() != classInfo())
156 QScriptEnginePrivate
*eng
= object
.engine();
157 if (! member
.isNativeProperty())
160 QScriptNameIdImpl
*ref
= object
.internalValue().stringValue();
161 int len
= ref
->s
.length();
163 if (member
.nameId() == eng
->idTable()->id_length
)
164 *result
= QScriptValueImpl(len
);
166 else if (member
.id() >= 0 && member
.id() < len
)
167 eng
->newString(result
, ref
->s
.at(member
.id()));
170 *result
= eng
->undefinedValue();
175 bool StringClassData::put(QScriptValueImpl
*, const Member
&,
176 const QScriptValueImpl
&)
178 // writes to string elements are ignored
182 QScriptClassDataIterator
*StringClassData::newIterator(const QScriptValueImpl
&object
)
184 QScriptNameIdImpl
*id
= object
.internalValue().stringValue();
185 return new StringClassDataIterator(id
->s
.length());
188 StringClassDataIterator::StringClassDataIterator(int length
)
194 StringClassDataIterator::~StringClassDataIterator()
198 bool StringClassDataIterator::hasNext() const
200 return m_pos
< m_length
;
203 void StringClassDataIterator::next(QScript::Member
*member
)
205 member
->native(/*nameId=*/ 0, m_pos
, QScriptValue::Undeletable
| QScriptValue::ReadOnly
);
209 bool StringClassDataIterator::hasPrevious() const
211 return (m_pos
- 1) >= 0;
214 void StringClassDataIterator::previous(QScript::Member
*member
)
217 member
->native(/*nameId=*/ 0, m_pos
, QScriptValue::Undeletable
| QScriptValue::ReadOnly
);
220 void StringClassDataIterator::toFront()
225 void StringClassDataIterator::toBack()
232 String::String(QScriptEnginePrivate
*eng
):
233 Core(eng
, QLatin1String("String"), QScriptClassInfo::StringType
)
235 classInfo()->setData(new StringClassData(classInfo()));
237 newString(&publicPrototype
, QString());
239 eng
->newConstructor(&ctor
, this, publicPrototype
);
241 addPrototypeFunction(QLatin1String("toString"), method_toString
, 0);
242 addPrototypeFunction(QLatin1String("valueOf"), method_valueOf
, 0);
243 addPrototypeFunction(QLatin1String("charAt"), method_charAt
, 1);
244 addPrototypeFunction(QLatin1String("charCodeAt"), method_charCodeAt
, 1);
245 addPrototypeFunction(QLatin1String("concat"), method_concat
, 1);
246 addPrototypeFunction(QLatin1String("indexOf"), method_indexOf
, 1);
247 addPrototypeFunction(QLatin1String("lastIndexOf"), method_lastIndexOf
, 1);
248 addPrototypeFunction(QLatin1String("localeCompare"), method_localeCompare
, 1);
249 addPrototypeFunction(QLatin1String("match"), method_match
, 1);
250 addPrototypeFunction(QLatin1String("replace"), method_replace
, 2);
251 addPrototypeFunction(QLatin1String("search"), method_search
, 1);
252 addPrototypeFunction(QLatin1String("slice"), method_slice
, 2);
253 addPrototypeFunction(QLatin1String("split"), method_split
, 2);
254 addPrototypeFunction(QLatin1String("substr"), method_substr
, 2);
255 addPrototypeFunction(QLatin1String("substring"), method_substring
, 2);
256 addPrototypeFunction(QLatin1String("toLowerCase"), method_toLowerCase
, 0);
257 addPrototypeFunction(QLatin1String("toLocaleLowerCase"), method_toLocaleLowerCase
, 0);
258 addPrototypeFunction(QLatin1String("toUpperCase"), method_toUpperCase
, 0);
259 addPrototypeFunction(QLatin1String("toLocaleUpperCase"), method_toLocaleUpperCase
, 0);
261 addConstructorFunction(QLatin1String("fromCharCode"), method_fromCharCode
, 1);
268 void String::execute(QScriptContextPrivate
*context
)
270 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
271 engine()->notifyFunctionEntry(context
);
275 if (context
->argumentCount() > 0)
276 value
= context
->argument(0).toString();
278 QScriptValueImpl
str(engine(), value
);
279 if (!context
->isCalledAsConstructor()) {
280 context
->setReturnValue(str
);
282 QScriptValueImpl
&obj
= context
->m_thisObject
;
283 obj
.setClassInfo(classInfo());
284 obj
.setInternalValue(str
);
285 obj
.setPrototype(publicPrototype
);
286 context
->setReturnValue(obj
);
288 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
289 engine()->notifyFunctionExit(context
);
293 void String::newString(QScriptValueImpl
*result
, const QString
&value
)
295 engine()->newObject(result
, publicPrototype
, classInfo());
296 result
->setInternalValue(QScriptValueImpl(engine(), value
));
299 QScriptValueImpl
String::method_toString(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*classInfo
)
301 QScriptValueImpl self
= context
->thisObject();
302 if (self
.classInfo() != classInfo
) {
303 return context
->throwError(QScriptContext::TypeError
, QLatin1String("String.prototype.toString"));
305 return (self
.internalValue());
308 QScriptValueImpl
String::method_valueOf(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*classInfo
)
310 QScriptValueImpl self
= context
->thisObject();
311 if (self
.classInfo() != classInfo
) {
312 return throwThisObjectTypeError(
313 context
, QLatin1String("String.prototype.valueOf"));
315 return (self
.internalValue());
318 QScriptValueImpl
String::method_charAt(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
320 QString str
= context
->thisObject().toString();
323 if (context
->argumentCount() > 0)
324 pos
= int (context
->argument(0).toInteger());
327 if (pos
>= 0 && pos
< str
.length())
328 result
+= str
.at(pos
);
330 return (QScriptValueImpl(eng
, result
));
333 QScriptValueImpl
String::method_charCodeAt(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*)
335 QString str
= context
->thisObject().toString();
338 if (context
->argumentCount() > 0)
339 pos
= int (context
->argument(0).toInteger());
341 qsreal result
= qSNaN();
343 if (pos
>= 0 && pos
< str
.length())
344 result
= str
.at(pos
).unicode();
346 return (QScriptValueImpl(result
));
349 QScriptValueImpl
String::method_concat(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
351 QString value
= context
->thisObject().toString();
353 for (int i
= 0; i
< context
->argumentCount(); ++i
)
354 value
+= context
->argument(i
).toString();
356 return (QScriptValueImpl(eng
, value
));
359 QScriptValueImpl
String::method_indexOf(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*)
361 QString value
= context
->thisObject().toString();
363 QString searchString
= context
->argument(0).toString();
366 if (context
->argumentCount() > 1)
367 pos
= int (context
->argument(1).toInteger());
370 if (! value
.isEmpty())
371 index
= value
.indexOf(searchString
, qMin(qMax(pos
, 0), value
.length()));
373 return (QScriptValueImpl(index
));
376 QScriptValueImpl
String::method_lastIndexOf(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*)
378 QString value
= context
->thisObject().toString();
380 QString searchString
= context
->argument(0).toString();
382 qsreal position
= context
->argument(1).toNumber();
383 if (qIsNaN(position
))
386 position
= QScriptEnginePrivate::toInteger(position
);
388 int pos
= QScriptEnginePrivate::toInt32(qMin(qMax(position
, 0.0), qsreal(value
.length())));
389 if (!searchString
.isEmpty() && pos
== value
.length())
391 int index
= value
.lastIndexOf(searchString
, pos
);
392 return (QScriptValueImpl(index
));
395 QScriptValueImpl
String::method_localeCompare(QScriptContextPrivate
*context
, QScriptEnginePrivate
*, QScriptClassInfo
*)
397 QString value
= context
->thisObject().toString();
398 QString that
= context
->argument(0).toString();
399 return QScriptValueImpl(QString::localeAwareCompare(value
, that
));
402 QScriptValueImpl
String::method_match(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
404 QScriptValueImpl pattern
= context
->argument(0);
406 if (! eng
->regexpConstructor
->get(pattern
))
407 eng
->regexpConstructor
->newRegExp(&pattern
, context
->argument(0).toString(), /*flags=*/0);
409 QScriptValueImpl rx_exec
= pattern
.property(QLatin1String("exec"), QScriptValue::ResolvePrototype
);
410 if (! (rx_exec
.isValid() && rx_exec
.isFunction())) {
411 return context
->throwError(QScriptContext::TypeError
,
412 QLatin1String("String.prototype.match"));
415 QScriptValueImplList args
;
416 args
<< context
->thisObject();
418 QScriptValueImpl global
= pattern
.property(QLatin1String("global"));
419 if (! (global
.isValid() && global
.toBoolean()))
420 return (rx_exec
.call(pattern
, args
));
422 QScript::Array
result(eng
);
424 QScriptNameIdImpl
*lastIndexId
= eng
->nameId(QLatin1String("lastIndex"));
425 QScriptNameIdImpl
*zeroId
= eng
->nameId(QLatin1String("0"));
427 pattern
.setProperty(lastIndexId
, QScriptValueImpl(0));
430 qsreal lastIndex
= pattern
.property(lastIndexId
).toNumber();
431 QScriptValueImpl r
= rx_exec
.call(pattern
, args
);
434 qsreal newLastIndex
= pattern
.property(lastIndexId
).toNumber();
435 if (newLastIndex
== lastIndex
)
436 pattern
.setProperty(lastIndexId
, QScriptValueImpl(lastIndex
+ 1));
437 result
.assign(n
++, r
.property(zeroId
));
440 return (eng
->newArray(result
));
443 QScriptValueImpl
String::method_replace(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
445 QString input
= context
->thisObject().toString();
446 QScriptValueImpl searchValue
= context
->argument(0);
447 QScriptValueImpl replaceValue
= context
->argument(1);
450 if (searchValue
.classInfo() == eng
->regexpConstructor
->classInfo()) {
451 // searchValue is a RegExp
452 QScriptValueImpl rx_exec
= searchValue
.property(QLatin1String("exec"), QScriptValue::ResolvePrototype
);
453 if (!rx_exec
.isFunction()) {
454 return context
->throwError(QScriptContext::TypeError
,
455 QLatin1String("String.prototype.replace"));
457 QVector
<QScriptValueImpl
> occurrences
;
458 QScriptValueImpl global
= searchValue
.property(QLatin1String("global"));
459 QScriptValueImplList args
;
460 args
<< QScriptValueImpl(eng
, input
);
461 if (!global
.toBoolean()) {
462 QScriptValueImpl r
= rx_exec
.call(searchValue
, args
);
464 occurrences
.append(r
);
466 QScriptNameIdImpl
*lastIndexId
= eng
->nameId(QLatin1String("lastIndex"));
467 searchValue
.setProperty(lastIndexId
, QScriptValueImpl(0));
469 qsreal lastIndex
= searchValue
.property(lastIndexId
).toNumber();
470 QScriptValueImpl r
= rx_exec
.call(searchValue
, args
);
473 qsreal newLastIndex
= searchValue
.property(lastIndexId
).toNumber();
474 if (newLastIndex
== lastIndex
)
475 searchValue
.setProperty(lastIndexId
, QScriptValueImpl(lastIndex
+ 1));
476 occurrences
.append(r
);
480 if (replaceValue
.isFunction()) {
481 QScriptNameIdImpl
*indexId
= eng
->nameId(QLatin1String("index"));
482 QScriptNameIdImpl
*lengthId
= eng
->nameId(QLatin1String("length"));
483 for (int i
= 0; i
< occurrences
.count(); ++i
) {
484 QScriptValueImpl needle
= occurrences
.at(i
);
485 int index
= int (needle
.property(indexId
).toInteger());
486 uint length
= eng
->toUint32(needle
.property(lengthId
).toNumber());
487 output
+= input
.mid(pos
, index
- pos
);
489 for (uint j
= 0; j
< length
; ++j
)
490 args
<< needle
.property(j
);
491 args
<< QScriptValueImpl(index
);
492 args
<< QScriptValueImpl(eng
, input
);
493 QScriptValueImpl ret
= replaceValue
.call(eng
->nullValue(), args
);
494 output
+= ret
.toString();
495 pos
= index
+ args
[0].toString().length();
498 // use string representation of replaceValue
499 const QString replaceString
= replaceValue
.toString();
500 const QLatin1Char dollar
= QLatin1Char('$');
501 QScriptNameIdImpl
*indexId
= eng
->nameId(QLatin1String("index"));
502 QScriptNameIdImpl
*zeroId
= eng
->nameId(QLatin1String("0"));
503 for (int i
= 0; i
< occurrences
.count(); ++i
) {
504 QScriptValueImpl needle
= occurrences
.at(i
);
505 int index
= int (needle
.property(indexId
).toInteger());
506 output
+= input
.mid(pos
, index
- pos
);
508 while (j
< replaceString
.length()) {
509 const QChar c
= replaceString
.at(j
++);
510 if ((c
== dollar
) && (j
< replaceString
.length())) {
511 const QChar nc
= replaceString
.at(j
);
514 } else if (nc
== QLatin1Char('`')) {
516 output
+= input
.left(index
);
518 } else if (nc
== QLatin1Char('\'')) {
520 output
+= input
.mid(index
+ needle
.property(zeroId
).toString().length());
522 } else if (nc
.isDigit()) {
524 int cap
= nc
.toLatin1() - '0';
525 if ((j
< replaceString
.length()) && replaceString
.at(j
).isDigit()) {
527 cap
= replaceString
.at(j
++).toLatin1() - '0';
529 output
+= needle
.property(QScriptValueImpl(cap
).toString()).toString();
535 pos
= index
+ needle
.property(zeroId
).toString().length();
538 output
+= input
.mid(pos
);
540 // use string representation of searchValue
541 const QString searchString
= searchValue
.toString();
543 if (replaceValue
.isFunction()) {
544 int index
= input
.indexOf(searchString
, pos
);
546 output
+= input
.mid(pos
, index
- pos
);
547 QScriptValueImplList args
;
548 args
<< QScriptValueImpl(eng
, searchString
);
549 args
<< QScriptValueImpl(index
);
550 args
<< QScriptValueImpl(eng
, input
);
551 QScriptValueImpl ret
= replaceValue
.call(eng
->nullValue(), args
);
552 output
+= ret
.toString();
553 pos
= index
+ searchString
.length();
556 // use string representation of replaceValue
557 const QString replaceString
= replaceValue
.toString();
558 const QLatin1Char dollar
= QLatin1Char('$');
559 int index
= input
.indexOf(searchString
, pos
);
561 output
+= input
.mid(pos
, index
- pos
);
563 while (j
< replaceString
.length()) {
564 const QChar c
= replaceString
.at(j
++);
565 if ((c
== dollar
) && (j
< replaceString
.length())) {
566 const QChar nc
= replaceString
.at(j
);
569 } else if (nc
== QLatin1Char('`')) {
570 output
+= input
.left(index
);
573 } else if (nc
== QLatin1Char('\'')) {
574 output
+= input
.mid(index
+ searchString
.length());
581 pos
= index
+ searchString
.length();
584 output
+= input
.mid(pos
);
586 return QScriptValueImpl(eng
, output
);
589 QScriptValueImpl
String::method_search(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
591 QScriptValueImpl pattern
= context
->argument(0);
593 Ecma::RegExp::Instance
*rx_data
= 0;
594 if (0 == (rx_data
= eng
->regexpConstructor
->get(pattern
))) {
595 eng
->regexpConstructor
->newRegExp(&pattern
, context
->argument(0).toString(), /*flags=*/0);
596 rx_data
= eng
->regexpConstructor
->get(pattern
);
599 QString value
= context
->thisObject().toString();
601 return (QScriptValueImpl(value
.indexOf(rx_data
->value
)));
603 return eng
->nullValue();
607 QScriptValueImpl
String::method_slice(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
609 QString text
= context
->thisObject().toString();
610 int length
= text
.length();
612 int start
= int (context
->argument(0).toInteger());
613 int end
= context
->argument(1).isUndefined()
614 ? length
: int (context
->argument(1).toInteger());
617 start
= qMax(length
+ start
, 0);
619 start
= qMin(start
, length
);
622 end
= qMax(length
+ end
, 0);
624 end
= qMin(end
, length
);
626 int count
= qMax(0, end
- start
);
627 return (QScriptValueImpl(eng
, text
.mid(start
, count
)));
630 QScriptValueImpl
String::method_split(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
632 QScriptValueImpl l
= context
->argument(1);
633 quint32 lim
= l
.isUndefined() ? UINT_MAX
: QScriptEnginePrivate::toUint32(l
.toNumber());
636 return eng
->newArray();
638 QString S
= context
->thisObject().toString();
639 QScriptValueImpl separator
= context
->argument(0);
641 QScript::Array
A(eng
);
642 // the argumentCount() check is for compatibility with spidermonkey;
643 // it is not according to ECMA-262
644 if (separator
.isUndefined() && (context
->argumentCount() == 0)) {
645 A
.assign(0, QScriptValueImpl(eng
, S
));
649 if (Ecma::RegExp::Instance
*rx
= eng
->regexpConstructor
->get(separator
)) {
650 matches
= S
.split(rx
->value
, rx
->value
.pattern().isEmpty()
651 ? QString::SkipEmptyParts
: QString::KeepEmptyParts
);
653 #endif // QT_NO_REGEXP
655 QString sep
= separator
.toString();
656 matches
= S
.split(sep
, sep
.isEmpty()
657 ? QString::SkipEmptyParts
: QString::KeepEmptyParts
);
659 uint count
= qMin(lim
, uint(matches
.count()));
660 for (uint i
= 0; i
< count
; ++i
)
661 A
.assign(i
, QScriptValueImpl(eng
, matches
.at(i
)));
664 return eng
->newArray(A
);
667 QScriptValueImpl
String::method_substr(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
669 QString value
= context
->thisObject().toString();
672 if (context
->argumentCount() > 0)
673 start
= context
->argument(0).toInteger();
675 qsreal length
= +qInf();
676 if (context
->argumentCount() > 1)
677 length
= context
->argument(1).toInteger();
679 qsreal count
= value
.length();
681 start
= qMax(count
+ start
, 0.0);
683 length
= qMin(qMax(length
, 0.0), count
- start
);
685 qint32 x
= QScriptEnginePrivate::toInt32(start
);
686 qint32 y
= QScriptEnginePrivate::toInt32(length
);
687 return QScriptValueImpl(eng
, value
.mid(x
, y
));
690 QScriptValueImpl
String::method_substring(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
692 QString value
= context
->thisObject().toString();
693 int length
= value
.length();
698 if (context
->argumentCount() > 0)
699 start
= context
->argument(0).toInteger();
701 if (context
->argumentCount() > 1)
702 end
= context
->argument(1).toInteger();
704 if (qIsNaN(start
) || start
< 0)
707 if (qIsNaN(end
) || end
< 0)
722 qint32 x
= QScriptEnginePrivate::toInt32(start
);
723 qint32 y
= QScriptEnginePrivate::toInt32(end
- start
);
725 return (QScriptValueImpl(eng
, value
.mid(x
, y
)));
728 QScriptValueImpl
String::method_toLowerCase(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
730 QString value
= context
->thisObject().toString();
731 return (QScriptValueImpl(eng
, value
.toLower()));
734 QScriptValueImpl
String::method_toLocaleLowerCase(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*classInfo
)
736 return method_toLowerCase(context
, eng
, classInfo
); // ### check me
739 QScriptValueImpl
String::method_toUpperCase(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
741 QString value
= context
->thisObject().toString();
742 return (QScriptValueImpl(eng
, value
.toUpper()));
745 QScriptValueImpl
String::method_toLocaleUpperCase(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*classInfo
)
747 return method_toUpperCase(context
, eng
, classInfo
); // ### check me
750 QScriptValueImpl
String::method_fromCharCode(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
753 for (int i
= 0; i
< context
->argumentCount(); ++i
) {
754 QChar
c(context
->argument(i
).toUInt16());
757 return (QScriptValueImpl(eng
, str
));
762 QScriptValueImpl
String::method_ext_arg(QScriptContextPrivate
*context
, QScriptEnginePrivate
*eng
, QScriptClassInfo
*)
764 QString value
= context
->thisObject().toString();
765 QScriptValueImpl arg
= context
->argument(0);
768 result
= value
.arg(arg
.toString());
769 else if (arg
.isNumber())
770 result
= value
.arg(arg
.toNumber());
771 return QScriptValueImpl(eng
, result
);
774 } } // namespace QScript::Ecma
778 #endif // QT_NO_SCRIPT