• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kjs
 

kjs

  • kjs
string_object.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  * This file is part of the KDE libraries
4  * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
5  * Copyright (C) 2003 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22 
23 #include "value.h"
24 #include "object.h"
25 #include "types.h"
26 #include "interpreter.h"
27 #include "operations.h"
28 #include "regexp.h"
29 #include "regexp_object.h"
30 #include "string_object.h"
31 #include "error_object.h"
32 #include <stdio.h>
33 #include "string_object.lut.h"
34 
35 #ifdef HAVE_STDINT_H
36 #include <stdint.h>
37 #endif
38 #ifdef HAVE_SYS_TYPES_H
39 #include <sys/types.h>
40 #endif
41 #ifdef HAVE_SYS_BITYPES_H
42 #include <sys/bitypes.h> /* For uintXX_t on Tru64 */
43 #endif
44 
45 using namespace KJS;
46 
47 // ------------------------------ StringInstanceImp ----------------------------
48 
49 const ClassInfo StringInstanceImp::info = {"String", 0, 0, 0};
50 
51 StringInstanceImp::StringInstanceImp(ObjectImp *proto)
52  : ObjectImp(proto)
53 {
54  setInternalValue(String(""));
55 }
56 
57 StringInstanceImp::StringInstanceImp(ObjectImp *proto, const UString &string)
58  : ObjectImp(proto)
59 {
60  setInternalValue(String(string));
61 }
62 
63 Value StringInstanceImp::get(ExecState *exec, const Identifier &propertyName) const
64 {
65  if (propertyName == lengthPropertyName)
66  return Number(internalValue().toString(exec).size());
67 
68  bool ok;
69  const unsigned index = propertyName.toArrayIndex(&ok);
70  if (ok) {
71  const UString s = internalValue().toString(exec);
72  const unsigned length = s.size();
73  if (index < length) {
74  const UChar c = s[index];
75  return String(UString(&c, 1));
76  }
77  }
78 
79  return ObjectImp::get(exec, propertyName);
80 }
81 
82 void StringInstanceImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
83 {
84  if (propertyName == lengthPropertyName)
85  return;
86  ObjectImp::put(exec, propertyName, value, attr);
87 }
88 
89 bool StringInstanceImp::hasProperty(ExecState *exec, const Identifier &propertyName) const
90 {
91  if (propertyName == lengthPropertyName)
92  return true;
93 
94  bool ok;
95  unsigned index = propertyName.toULong(&ok);
96  if (ok && index < (unsigned)internalValue().toString(exec).size())
97  return true;
98 
99  return ObjectImp::hasProperty(exec, propertyName);
100 }
101 
102 bool StringInstanceImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
103 {
104  if (propertyName == lengthPropertyName)
105  return false;
106 
107  bool ok;
108  unsigned index = propertyName.toULong(&ok);
109  if (ok && index < (unsigned)internalValue().toString(exec).size())
110  return false;
111 
112  return ObjectImp::deleteProperty(exec, propertyName);
113 }
114 
115 ReferenceList StringInstanceImp::propList(ExecState *exec, bool recursive)
116 {
117  ReferenceList properties = ObjectImp::propList(exec,recursive);
118 
119  UString str = internalValue().toString(exec);
120  for (int i = 0; i < str.size(); i++)
121  if (!ObjectImp::hasProperty(exec,Identifier::from(i)))
122  properties.append(Reference(this, i));
123 
124  return properties;
125 }
126 
127 // ------------------------------ StringPrototypeImp ---------------------------
128 const ClassInfo StringPrototypeImp::info = {"String", &StringInstanceImp::info, &stringTable, 0};
129 /* Source for string_object.lut.h
130 @begin stringTable 28
131  toString StringProtoFuncImp::ToString DontEnum|Function 0
132  valueOf StringProtoFuncImp::ValueOf DontEnum|Function 0
133  charAt StringProtoFuncImp::CharAt DontEnum|Function 1
134  charCodeAt StringProtoFuncImp::CharCodeAt DontEnum|Function 1
135  concat StringProtoFuncImp::Concat DontEnum|Function 1
136  indexOf StringProtoFuncImp::IndexOf DontEnum|Function 1
137  lastIndexOf StringProtoFuncImp::LastIndexOf DontEnum|Function 1
138  match StringProtoFuncImp::Match DontEnum|Function 1
139  replace StringProtoFuncImp::Replace DontEnum|Function 2
140  search StringProtoFuncImp::Search DontEnum|Function 1
141  slice StringProtoFuncImp::Slice DontEnum|Function 2
142  split StringProtoFuncImp::Split DontEnum|Function 2
143  substr StringProtoFuncImp::Substr DontEnum|Function 2
144  substring StringProtoFuncImp::Substring DontEnum|Function 2
145  toLowerCase StringProtoFuncImp::ToLowerCase DontEnum|Function 0
146  toUpperCase StringProtoFuncImp::ToUpperCase DontEnum|Function 0
147  toLocaleLowerCase StringProtoFuncImp::ToLocaleLowerCase DontEnum|Function 0
148  toLocaleUpperCase StringProtoFuncImp::ToLocaleUpperCase DontEnum|Function 0
149  localeCompare StringProtoFuncImp::LocaleCompare DontEnum|Function 1
150 #
151 # Under here: html extension, should only exist if KJS_PURE_ECMA is not defined
152 # I guess we need to generate two hashtables in the .lut.h file, and use #ifdef
153 # to select the right one... TODO. #####
154  big StringProtoFuncImp::Big DontEnum|Function 0
155  small StringProtoFuncImp::Small DontEnum|Function 0
156  blink StringProtoFuncImp::Blink DontEnum|Function 0
157  bold StringProtoFuncImp::Bold DontEnum|Function 0
158  fixed StringProtoFuncImp::Fixed DontEnum|Function 0
159  italics StringProtoFuncImp::Italics DontEnum|Function 0
160  strike StringProtoFuncImp::Strike DontEnum|Function 0
161  sub StringProtoFuncImp::Sub DontEnum|Function 0
162  sup StringProtoFuncImp::Sup DontEnum|Function 0
163  fontcolor StringProtoFuncImp::Fontcolor DontEnum|Function 1
164  fontsize StringProtoFuncImp::Fontsize DontEnum|Function 1
165  anchor StringProtoFuncImp::Anchor DontEnum|Function 1
166  link StringProtoFuncImp::Link DontEnum|Function 1
167 @end
168 */
169 // ECMA 15.5.4
170 StringPrototypeImp::StringPrototypeImp(ExecState * /*exec*/,
171  ObjectPrototypeImp *objProto)
172  : StringInstanceImp(objProto)
173 {
174  Value protect(this);
175  // The constructor will be added later, after StringObjectImp has been built
176  putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum);
177 
178 }
179 
180 Value StringPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
181 {
182  return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );
183 }
184 
185 // ------------------------------ StringProtoFuncImp ---------------------------
186 
187 StringProtoFuncImp::StringProtoFuncImp(ExecState *exec, int i, int len)
188  : InternalFunctionImp(
189  static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
190  ), id(i)
191 {
192  Value protect(this);
193  putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
194 }
195 
196 bool StringProtoFuncImp::implementsCall() const
197 {
198  return true;
199 }
200 
201 // ### use as fallback only. implement locale aware version.
202 static inline int localeCompare(const UString &a, const UString &b)
203 {
204  // ### other browsers have more detailed return values than -1, 0 and 1
205  return compare(a, b);
206 }
207 
208 // ECMA 15.5.4.2 - 15.5.4.20
209 Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
210 {
211  Value result;
212 
213  // toString and valueOf are no generic functions.
214  if (id == ToString || id == ValueOf) {
215  KJS_CHECK_THIS( StringInstanceImp, thisObj );
216 
217  return String(thisObj.internalValue().toString(exec));
218  }
219 
220  int n, m;
221  UString u2, u3;
222  double dpos;
223  int pos, p0, i;
224  double d = 0.0;
225 
226  UString s = thisObj.toString(exec);
227 
228  int len = s.size();
229  Value a0 = args[0];
230  Value a1 = args[1];
231 
232  switch (id) {
233  case ToString:
234  case ValueOf:
235  // handled above
236  break;
237  case CharAt:
238  pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec);
239  if (pos < 0 || pos >= len)
240  s = "";
241  else
242  s = s.substr(pos, 1);
243  result = String(s);
244  break;
245  case CharCodeAt:
246  pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec);
247  if (pos < 0 || pos >= len)
248  d = NaN;
249  else {
250  UChar c = s[pos];
251  d = (c.high() << 8) + c.low();
252  }
253  result = Number(d);
254  break;
255  case Concat: {
256  ListIterator it = args.begin();
257  for ( ; it != args.end() ; ++it) {
258  s += it->dispatchToString(exec);
259  }
260  result = String(s);
261  break;
262  }
263  case IndexOf:
264  u2 = a0.toString(exec);
265  if (a1.type() == UndefinedType)
266  pos = 0;
267  else
268  pos = a1.toInteger(exec);
269  d = s.find(u2, pos);
270  result = Number(d);
271  break;
272  case LastIndexOf:
273  u2 = a0.toString(exec);
274  d = a1.toNumber(exec);
275  if (a1.type() == UndefinedType || KJS::isNaN(d))
276  dpos = len;
277  else {
278  dpos = d;
279  if (dpos < 0)
280  dpos = 0;
281  else if (dpos > len)
282  dpos = len;
283  }
284  result = Number(s.rfind(u2, int(dpos)));
285  break;
286  case Match:
287  case Search: {
288  RegExp *reg, *tmpReg = 0;
289  RegExpImp *imp = 0;
290  if (a0.isA(ObjectType) && a0.toObject(exec).inherits(&RegExpImp::info))
291  {
292  imp = static_cast<RegExpImp *>( a0.toObject(exec).imp() );
293  reg = imp->regExp();
294  }
295  else
296  { /*
297  * ECMA 15.5.4.12 String.prototype.search (regexp)
298  * If regexp is not an object whose [[Class]] property is "RegExp", it is
299  * replaced with the result of the expression new RegExp(regexp).
300  */
301  reg = tmpReg = new RegExp(a0.toString(exec), RegExp::None);
302  }
303  if (!reg->isValid()) {
304  delete tmpReg;
305  Object err = Error::create(exec, SyntaxError,
306  "Invalid regular expression");
307  exec->setException(err);
308  return err;
309  }
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);
314  if (id == Search) {
315  result = Number(pos);
316  } else { // Match
317  if (mstr.isNull()) {
318  result = Null(); // no match
319  } else if ((reg->flags() & RegExp::Global) == 0) {
320  // case without 'g' flag is handled like RegExp.prototype.exec
321  regExpObj->setSubPatterns(reg->subPatterns());
322  result = regExpObj->arrayOfMatches(exec,mstr);
323  } else {
324  // return array of matches
325  List list;
326  while (pos >= 0) {
327  list.append(String(mstr));
328  pos += mstr.isEmpty() ? 1 : mstr.size();
329  delete [] *ovector;
330  mstr = reg->match(s, pos, &pos, ovector);
331  }
332  result = exec->lexicalInterpreter()->builtinArray().construct(exec, list);
333  }
334  }
335  reg->doneMatch();
336  delete tmpReg;
337  break;
338  }
339  case Replace:
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();
343  bool global = false;
344  Value tmp = imp->get(exec,"global");
345  if (tmp.type() != UndefinedType && tmp.toBoolean(exec) == true)
346  global = true;
347 
348  RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
349  int lastIndex = 0;
350  Object o1;
351  // Test if 2nd arg is a function (new in JS 1.3)
352  if ( a1.type() == ObjectType && a1.toObject(exec).implementsCall() )
353  o1 = a1.toObject(exec);
354  else
355  u3 = a1.toString(exec); // 2nd arg is the replacement string
356 
357  UString out;
358 
359  // This is either a loop (if global is set) or a one-way (if not).
360  reg->prepareMatch(s);
361  do {
362  int **ovector = regExpObj->registerRegexp( reg, s );
363  UString mstr = reg->match(s, lastIndex, &pos, ovector);
364  regExpObj->setSubPatterns(reg->subPatterns());
365  if (pos == -1)
366  break;
367 
368  len = mstr.size();
369 
370  UString rstr;
371  // Prepare replacement
372  if (!o1.isValid())
373  {
374  rstr = u3;
375  bool ok;
376  // check if u3 matches $1 or $2 etc
377  for (int i = 0; (i = rstr.find(UString("$"), i)) != -1; i++) {
378  if (i+1<rstr.size() && rstr[i+1] == '$') { // "$$" -> "$"
379  rstr = rstr.substr(0,i) + "$" + rstr.substr(i+2);
380  continue;
381  }
382  // Assume number part is one char exactly
383  unsigned long pos = rstr.substr(i+1,1).toULong(&ok, false /* tolerate empty string */);
384  if (ok && pos <= (unsigned)reg->subPatterns()) {
385  rstr = rstr.substr(0,i)
386  + s.substr((*ovector)[2*pos],
387  (*ovector)[2*pos+1]-(*ovector)[2*pos])
388  + rstr.substr(i+2);
389  i += (*ovector)[2*pos+1]-(*ovector)[2*pos] - 1; // -1 offsets i++
390  }
391  }
392  } else // 2nd arg is a function call. Spec from http://devedge.netscape.com/library/manuals/2000/javascript/1.5/reference/string.html#1194258
393  {
394  List l;
395  l.append(String(mstr)); // First arg: complete matched substring
396  // Then the submatch strings
397  for ( unsigned int sub = 1; sub <= reg->subPatterns() ; ++sub )
398  l.append( String( s.substr((*ovector)[2*sub],
399  (*ovector)[2*sub+1]-(*ovector)[2*sub]) ) );
400  l.append(Number(pos)); // The offset within the string where the match occurred
401  l.append(String(s)); // Last arg: the string itself. Can't see the difference with the 1st arg!
402  Object thisObj = exec->interpreter()->globalObject();
403  rstr = o1.call( exec, thisObj, l ).toString(exec);
404  }
405 
406  // Append the stuff we skipped over to get to the match --
407  // that would be [lastIndex, pos) of the original..
408  if (pos != lastIndex)
409  out += s.substr(lastIndex, pos - lastIndex);
410 
411  // Append the replacement..
412  out += rstr;
413 
414  lastIndex = pos + len; // Skip over the matched stuff...
415  } while (global);
416 
417  // Append the rest of the string to the output...
418  if (lastIndex == 0 && out.size() == 0) // Don't copy stuff if nothing changed
419  out = s;
420  else
421  out += s.substr(lastIndex, s.size() - lastIndex);
422 
423  reg->doneMatch();
424 
425  result = String(out);
426  } else { // First arg is a string
427  u2 = a0.toString(exec);
428  pos = s.find(u2);
429  len = u2.size();
430  // Do the replacement
431  if (pos == -1)
432  result = String(s);
433  else {
434  u3 = s.substr(0, pos) + a1.toString(exec) +
435  s.substr(pos + len);
436  result = String(u3);
437  }
438  }
439  break;
440  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366 or 15.5.4.13
441  {
442  // The arg processing is very much like ArrayProtoFunc::Slice
443  int begin = args[0].toUInt32(exec);
444  int end = len;
445  if (args[1].type() != UndefinedType) {
446  end = args[1].toInteger(exec);
447  }
448  int from = begin < 0 ? len + begin : begin;
449  int to = end < 0 ? len + end : end;
450  if (to > from && to > 0 && from < len) {
451  if (from < 0) {
452  from = 0;
453  }
454  if (to > len) {
455  to = len;
456  }
457  result = String(s.substr(from, to - from));
458  } else {
459  result = String("");
460  }
461  break;
462  }
463  case Split: {
464  Object constructor = exec->lexicalInterpreter()->builtinArray();
465  Object res = Object::dynamicCast(constructor.construct(exec,List::empty()));
466  result = res;
467  i = p0 = 0;
468  uint32_t limit = (a1.type() != UndefinedType) ? a1.toUInt32(exec) : 0xFFFFFFFFU;
469  if (a0.type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) {
470  Object obj0 = Object::dynamicCast(a0);
471  RegExp reg(obj0.get(exec,"source").toString(exec));
472  reg.prepareMatch(s);
473  if (s.isEmpty() && !reg.match(s, 0).isNull()) {
474  // empty string matched by regexp -> empty array
475  reg.doneMatch();
476  res.put(exec, lengthPropertyName, Number(0), DontDelete|ReadOnly|DontEnum);
477  break;
478  }
479  pos = 0;
480  while (static_cast<uint32_t>(i) != limit && pos < s.size()) {
481  // TODO: back references
482  int mpos;
483  int *ovector = 0L;
484  UString mstr = reg.match(s, pos, &mpos, &ovector);
485  delete [] ovector; ovector = 0L;
486  if (mpos < 0)
487  break;
488  pos = mpos + (mstr.isEmpty() ? 1 : mstr.size());
489  if (mpos != p0 || !mstr.isEmpty()) {
490  res.put(exec,i, String(s.substr(p0, mpos-p0)));
491  p0 = mpos + mstr.size();
492  i++;
493  }
494  }
495  reg.doneMatch();
496  } else {
497  u2 = a0.toString(exec);
498  if (u2.isEmpty()) {
499  if (s.isEmpty()) {
500  // empty separator matches empty string -> empty array
501  put(exec,lengthPropertyName, Number(0));
502  break;
503  } else {
504  while (static_cast<uint32_t>(i) != limit && i < s.size()-1)
505  res.put(exec,i++, String(s.substr(p0++, 1)));
506  }
507  } else {
508  while (static_cast<uint32_t>(i) != limit && (pos = s.find(u2, p0)) >= 0) {
509  res.put(exec,i, String(s.substr(p0, pos-p0)));
510  p0 = pos + u2.size();
511  i++;
512  }
513  }
514  }
515  // add remaining string, if any
516  if (static_cast<uint32_t>(i) != limit)
517  res.put(exec,i++, String(s.substr(p0)));
518  res.put(exec,lengthPropertyName, Number(i));
519  }
520  break;
521  case Substr: {
522  n = a0.toInteger(exec);
523  m = a1.toInteger(exec);
524  int d, d2;
525  if (n >= 0)
526  d = n;
527  else
528  d = maxInt(len + n, 0);
529  if (a1.type() == UndefinedType)
530  d2 = len - d;
531  else
532  d2 = minInt(maxInt(m, 0), len - d);
533  result = String(s.substr(d, d2));
534  break;
535  }
536  case Substring: {
537  double start = a0.toNumber(exec);
538  double end = a1.toNumber(exec);
539  if (KJS::isNaN(start))
540  start = 0;
541  if (KJS::isNaN(end))
542  end = 0;
543  if (start < 0)
544  start = 0;
545  if (end < 0)
546  end = 0;
547  if (start > len)
548  start = len;
549  if (end > len)
550  end = len;
551  if (a1.type() == UndefinedType)
552  end = len;
553  if (start > end) {
554  double temp = end;
555  end = start;
556  start = temp;
557  }
558  result = String(s.substr((int)start, (int)end-(int)start));
559  }
560  break;
561  case ToLowerCase:
562  case ToLocaleLowerCase: // FIXME: To get this 100% right we need to detect Turkish and change I to lowercase i without a dot.
563  for (i = 0; i < len; i++)
564  s[i] = s[i].toLower();
565  result = String(s);
566  break;
567  case ToUpperCase:
568  case ToLocaleUpperCase: // FIXME: To get this 100% right we need to detect Turkish and change i to uppercase I with a dot.
569  for (i = 0; i < len; i++)
570  s[i] = s[i].toUpper();
571  result = String(s);
572  break;
573  case LocaleCompare:
574  return Number(localeCompare(s, a0.toString(exec)));
575 #ifndef KJS_PURE_ECMA
576  case Big:
577  result = String("<big>" + s + "</big>");
578  break;
579  case Small:
580  result = String("<small>" + s + "</small>");
581  break;
582  case Blink:
583  result = String("<blink>" + s + "</blink>");
584  break;
585  case Bold:
586  result = String("<b>" + s + "</b>");
587  break;
588  case Fixed:
589  result = String("<tt>" + s + "</tt>");
590  break;
591  case Italics:
592  result = String("<i>" + s + "</i>");
593  break;
594  case Strike:
595  result = String("<strike>" + s + "</strike>");
596  break;
597  case Sub:
598  result = String("<sub>" + s + "</sub>");
599  break;
600  case Sup:
601  result = String("<sup>" + s + "</sup>");
602  break;
603  case Fontcolor:
604  result = String("<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
605  break;
606  case Fontsize:
607  result = String("<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
608  break;
609  case Anchor:
610  result = String("<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
611  break;
612  case Link:
613  result = String("<a href=\"" + a0.toString(exec) + "\">" + s + "</a>");
614  break;
615 #endif
616  }
617 
618  return result;
619 }
620 
621 // ------------------------------ StringObjectImp ------------------------------
622 
623 StringObjectImp::StringObjectImp(ExecState *exec,
624  FunctionPrototypeImp *funcProto,
625  StringPrototypeImp *stringProto)
626  : InternalFunctionImp(funcProto)
627 {
628  Value protect(this);
629  // ECMA 15.5.3.1 String.prototype
630  putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);
631 
632  putDirect("fromCharCode", new StringObjectFuncImp(exec,funcProto), DontEnum);
633 
634  // no. of arguments for constructor
635  putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
636 }
637 
638 
639 bool StringObjectImp::implementsConstruct() const
640 {
641  return true;
642 }
643 
644 // ECMA 15.5.2
645 Object StringObjectImp::construct(ExecState *exec, const List &args)
646 {
647  ObjectImp *proto = exec->lexicalInterpreter()->builtinStringPrototype().imp();
648  if (args.size() == 0)
649  return Object(new StringInstanceImp(proto));
650  return Object(new StringInstanceImp(proto, args.begin()->dispatchToString(exec)));
651 }
652 
653 bool StringObjectImp::implementsCall() const
654 {
655  return true;
656 }
657 
658 // ECMA 15.5.1
659 Value StringObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
660 {
661  if (args.isEmpty())
662  return String("");
663  else {
664  Value v = args[0];
665  return String(v.toString(exec));
666  }
667 }
668 
669 // ------------------------------ StringObjectFuncImp --------------------------
670 
671 // ECMA 15.5.3.2 fromCharCode()
672 StringObjectFuncImp::StringObjectFuncImp(ExecState* /*exec*/, FunctionPrototypeImp *funcProto)
673  : InternalFunctionImp(funcProto)
674 {
675  Value protect(this);
676  putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum);
677 }
678 
679 bool StringObjectFuncImp::implementsCall() const
680 {
681  return true;
682 }
683 
684 Value StringObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
685 {
686  UString s;
687  if (args.size()) {
688  UChar *buf = new UChar[args.size()];
689  UChar *p = buf;
690  ListIterator it = args.begin();
691  while (it != args.end()) {
692  unsigned short u = it->toUInt16(exec);
693  *p++ = UChar(u);
694  it++;
695  }
696  s = UString(buf, args.size(), false);
697  } else
698  s = "";
699 
700  return String(s);
701 }
KJS::Value
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents...
Definition: value.h:168
KJS::UString::substr
UString substr(int pos=0, int len=-1) const
Definition: ustring.cpp:869
KJS::Value::type
Type type() const
Returns the type of value.
Definition: value.h:196
KJS::InternalFunctionImp
Base class for all function objects.
Definition: function.h:41
KJS::Object::get
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Definition: object.h:664
KJS::UString::size
int size() const
Definition: ustring.h:360
KJS::Object::construct
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
Definition: object.h:697
KJS::Number
Represents an primitive Number value.
Definition: value.h:368
KJS::List::append
void append(const Value &val)
Append an object to the end of the list.
Definition: list.h:66
KJS::Interpreter::globalObject
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
Definition: interpreter.cpp:129
KJS::Value::toBoolean
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
Definition: value.h:217
KJS::UString::find
int find(const UString &f, int pos=0) const
Definition: ustring.cpp:799
KJS::Null
Represents an primitive Null value.
Definition: value.h:295
KJS::ExecState::lexicalInterpreter
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Definition: interpreter.cpp:395
KJS::Error::create
static Object create(ExecState *exec, ErrorType errtype=GeneralError, const char *message=0, int lineno=-1, int sourceId=-1)
Factory method for error objects.
Definition: object.cpp:504
KJS::FunctionPrototypeImp
The initial value of Function.prototype (and thus all objects created with the Function constructor) ...
Definition: function_object.h:35
KJS::Value::toNumber
double toNumber(ExecState *exec) const
Performs the ToNumber type conversion operation on this value (ECMA 9.3)
Definition: value.h:222
KJS::Object
Represents an Object.
Definition: object.h:82
KJS::UChar::high
unsigned char high() const
Definition: ustring.h:74
KJS::Value::toUInt32
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
Definition: value.h:237
KJS::List::begin
ListIterator begin() const
Definition: list.h:186
KJS::Value::toObject
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
Definition: object.h:359
KJS::Object::implementsCall
bool implementsCall() const
Whether or not the object implements the call() method.
Definition: object.h:700
KJS::Value::isA
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Definition: value.h:204
KJS::UChar::low
unsigned char low() const
Definition: ustring.h:78
KJS::UString
Unicode string class.
Definition: ustring.h:190
KJS::UChar
Unicode character.
Definition: ustring.h:52
KJS::String
Represents an primitive String value.
Definition: value.h:341
KJS::Reference
Defines a Javascript reference.
Definition: reference.h:35
KJS::Object::dynamicCast
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
Definition: object.cpp:46
KJS::UString::isNull
bool isNull() const
Definition: ustring.h:344
KJS
Definition: array_instance.h:28
KJS::Object::internalValue
Value internalValue() const
Returns the internal value of the object.
Definition: object.h:718
KJS::List::size
int size() const
Definition: list.h:90
KJS::List::empty
static const List & empty()
Returns a pointer to a static instance of an empty list.
Definition: list.cpp:322
KJS::List::end
ListIterator end() const
Definition: list.h:187
KJS::UString::rfind
int rfind(const UString &f, int pos) const
Definition: ustring.cpp:833
KJS::ReferenceList
A list of Reference objects.
Definition: reference_list.h:54
KJS::Object::put
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Definition: object.h:670
KJS::List
Native list type.
Definition: list.h:48
KJS::Value::toString
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
Definition: value.h:247
KJS::ClassInfo
Class Information.
Definition: object.h:59
KJS::Interpreter::builtinArray
Object builtinArray() const
Returns the builtin "Array" object.
Definition: interpreter.cpp:184
KJS::Object::call
Value call(ExecState *exec, Object &thisObj, const List &args)
Calls this object as if it is a function.
Definition: object.cpp:54
KJS::Value::toInteger
int toInteger(ExecState *exec) const
Performs the ToInteger type conversion operation on this value (ECMA 9.4)
Definition: value.h:227
KJS::List::isEmpty
bool isEmpty() const
Definition: list.h:86
KJS::Interpreter::builtinStringPrototype
Object builtinStringPrototype() const
Returns the builtin "String.prototype" object.
Definition: interpreter.cpp:239
KJS::Value::isValid
bool isValid() const
Returns whether or not this is a valid value.
Definition: value.h:182
KJS::Interpreter::builtinRegExp
Object builtinRegExp() const
Returns the builtin "RegExp" object.
Definition: interpreter.cpp:209
KStdAccel::end
const KShortcut & end()
KJS::UString::isEmpty
bool isEmpty() const
Definition: ustring.h:348
KJS::UString::toULong
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
Definition: ustring.cpp:686
KJS::ExecState
Represents the current state of script execution.
Definition: interpreter.h:439
KJS::Identifier
Represents an Identifier for a Javascript object.
Definition: identifier.h:32
KJS::ListIterator
Iterator for KJS::List objects.
Definition: list.h:138

kjs

Skip menu "kjs"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kjs

Skip menu "kjs"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kjs by doxygen 1.8.8
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |