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

kjs

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