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

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
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kjs by doxygen 1.9.1
This website is maintained by Timothy Pearson.