jscript: Added String constructor object.
[wine] / dlls / jscript / string.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20
21 #include "wine/debug.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
24
25 typedef struct {
26     DispatchEx dispex;
27 } StringInstance;
28
29 static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
30 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
31 static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
32 static const WCHAR anchorW[] = {'a','n','c','h','o','r',0};
33 static const WCHAR bigW[] = {'b','i','g',0};
34 static const WCHAR blinkW[] = {'b','l','i','n','k',0};
35 static const WCHAR boldW[] = {'b','o','l','d',0};
36 static const WCHAR charAtW[] = {'c','h','a','r','A','t',0};
37 static const WCHAR charCodeAtW[] = {'c','h','a','r','C','o','d','e','A','t',0};
38 static const WCHAR concatW[] = {'c','o','n','c','a','t',0};
39 static const WCHAR fixedW[] = {'f','i','x','e','d',0};
40 static const WCHAR fontcolorW[] = {'f','o','n','t','c','o','l','o','r',0};
41 static const WCHAR fontsizeW[] = {'f','o','n','t','s','i','z','e',0};
42 static const WCHAR indexOfW[] = {'i','n','d','e','x','O','f',0};
43 static const WCHAR italicsW[] = {'i','t','a','l','i','c','s',0};
44 static const WCHAR lastIndexOfW[] = {'l','a','s','t','I','n','d','e','x','O','f',0};
45 static const WCHAR linkW[] = {'l','i','n','k',0};
46 static const WCHAR matchW[] = {'m','a','t','c','h',0};
47 static const WCHAR replaceW[] = {'r','e','p','l','a','c','e',0};
48 static const WCHAR searchW[] = {'s','e','a','r','c','h',0};
49 static const WCHAR sliceW[] = {'s','l','i','c','e',0};
50 static const WCHAR smallW[] = {'s','m','a','l','l',0};
51 static const WCHAR splitW[] = {'s','p','l','i','t',0};
52 static const WCHAR strikeW[] = {'s','t','r','i','k','e',0};
53 static const WCHAR subW[] = {'s','u','b',0};
54 static const WCHAR substringW[] = {'s','u','b','s','t','r','i','n','g',0};
55 static const WCHAR substrW[] = {'s','u','b','s','t','r',0};
56 static const WCHAR supW[] = {'s','u','p',0};
57 static const WCHAR toLowerCaseW[] = {'t','o','L','o','w','e','r','C','a','s','e',0};
58 static const WCHAR toUpperCaseW[] = {'t','o','U','p','p','e','r','C','a','s','e',0};
59 static const WCHAR toLocaleLowerCaseW[] = {'t','o','L','o','c','a','l','e','L','o','w','e','r','C','a','s','e',0};
60 static const WCHAR toLocaleUpperCaseW[] = {'t','o','L','o','c','a','l','e','U','p','p','e','r','C','a','s','e',0};
61 static const WCHAR localeCompareW[] = {'l','o','c','a','l','e','C','o','m','p','a','r','e',0};
62 static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
63 static const WCHAR propertyIsEnumerableW[] =
64     {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
65 static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
66
67 static void String_destructor(DispatchEx *dispex)
68 {
69     FIXME("\n");
70 }
71
72 static HRESULT String_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
73         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
74 {
75     FIXME("\n");
76     return E_NOTIMPL;
77 }
78
79 static HRESULT String_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
80         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
81 {
82     FIXME("\n");
83     return E_NOTIMPL;
84 }
85
86 static HRESULT String_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
87         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
88 {
89     FIXME("\n");
90     return E_NOTIMPL;
91 }
92
93 static HRESULT String_anchor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
94         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
95 {
96     FIXME("\n");
97     return E_NOTIMPL;
98 }
99
100 static HRESULT String_big(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
101         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
102 {
103     FIXME("\n");
104     return E_NOTIMPL;
105 }
106
107 static HRESULT String_blink(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
108         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
109 {
110     FIXME("\n");
111     return E_NOTIMPL;
112 }
113
114 static HRESULT String_bold(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
115         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
116 {
117     FIXME("\n");
118     return E_NOTIMPL;
119 }
120
121 static HRESULT String_charAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
122         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
123 {
124     FIXME("\n");
125     return E_NOTIMPL;
126 }
127
128 static HRESULT String_charCodeAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
129         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
130 {
131     FIXME("\n");
132     return E_NOTIMPL;
133 }
134
135 static HRESULT String_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
136         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
137 {
138     FIXME("\n");
139     return E_NOTIMPL;
140 }
141
142 static HRESULT String_fixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
143         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
144 {
145     FIXME("\n");
146     return E_NOTIMPL;
147 }
148
149 static HRESULT String_fontcolor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
150         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
151 {
152     FIXME("\n");
153     return E_NOTIMPL;
154 }
155
156 static HRESULT String_fontsize(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
157         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
158 {
159     FIXME("\n");
160     return E_NOTIMPL;
161 }
162
163 static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
164         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
165 {
166     FIXME("\n");
167     return E_NOTIMPL;
168 }
169
170 static HRESULT String_italics(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
171         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
172 {
173     FIXME("\n");
174     return E_NOTIMPL;
175 }
176
177 static HRESULT String_lastIndexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
178         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
179 {
180     FIXME("\n");
181     return E_NOTIMPL;
182 }
183
184 static HRESULT String_link(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
185         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
186 {
187     FIXME("\n");
188     return E_NOTIMPL;
189 }
190
191 static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
192         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
193 {
194     FIXME("\n");
195     return E_NOTIMPL;
196 }
197
198 static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
199         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
200 {
201     FIXME("\n");
202     return E_NOTIMPL;
203 }
204
205 static HRESULT String_search(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
206         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
207 {
208     FIXME("\n");
209     return E_NOTIMPL;
210 }
211
212 static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
213         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
214 {
215     FIXME("\n");
216     return E_NOTIMPL;
217 }
218
219 static HRESULT String_small(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
220         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
221 {
222     FIXME("\n");
223     return E_NOTIMPL;
224 }
225
226 static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
227         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
228 {
229     FIXME("\n");
230     return E_NOTIMPL;
231 }
232
233 static HRESULT String_strike(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
234         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
235 {
236     FIXME("\n");
237     return E_NOTIMPL;
238 }
239
240 static HRESULT String_sub(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
241         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
242 {
243     FIXME("\n");
244     return E_NOTIMPL;
245 }
246
247 static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
248         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
249 {
250     FIXME("\n");
251     return E_NOTIMPL;
252 }
253
254 static HRESULT String_substr(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
255         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
256 {
257     FIXME("\n");
258     return E_NOTIMPL;
259 }
260
261 static HRESULT String_sup(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
262         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
263 {
264     FIXME("\n");
265     return E_NOTIMPL;
266 }
267
268 static HRESULT String_toLowerCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
269         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
270 {
271     FIXME("\n");
272     return E_NOTIMPL;
273 }
274
275 static HRESULT String_toUpperCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
276         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
277 {
278     FIXME("\n");
279     return E_NOTIMPL;
280 }
281
282 static HRESULT String_toLocaleLowerCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
283         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
284 {
285     FIXME("\n");
286     return E_NOTIMPL;
287 }
288
289 static HRESULT String_toLocaleUpperCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
290         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
291 {
292     FIXME("\n");
293     return E_NOTIMPL;
294 }
295
296 static HRESULT String_localeCompare(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
297         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
298 {
299     FIXME("\n");
300     return E_NOTIMPL;
301 }
302
303 static HRESULT String_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
304         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
305 {
306     FIXME("\n");
307     return E_NOTIMPL;
308 }
309
310 static HRESULT String_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
311         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
312 {
313     FIXME("\n");
314     return E_NOTIMPL;
315 }
316
317 static HRESULT String_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
318         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
319 {
320     FIXME("\n");
321     return E_NOTIMPL;
322 }
323
324 static HRESULT String_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
325         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
326 {
327     FIXME("\n");
328     return E_NOTIMPL;
329 }
330
331 static const builtin_prop_t String_props[] = {
332     {anchorW,                String_anchor,                PROPF_METHOD},
333     {bigW,                   String_big,                   PROPF_METHOD},
334     {blinkW,                 String_blink,                 PROPF_METHOD},
335     {boldW,                  String_bold,                  PROPF_METHOD},
336     {charAtW,                String_charAt,                PROPF_METHOD},
337     {charCodeAtW,            String_charCodeAt,            PROPF_METHOD},
338     {concatW,                String_concat,                PROPF_METHOD},
339     {fixedW,                 String_fixed,                 PROPF_METHOD},
340     {fontcolorW,             String_fontcolor,             PROPF_METHOD},
341     {fontsizeW,              String_fontsize,              PROPF_METHOD},
342     {hasOwnPropertyW,        String_hasOwnProperty,        PROPF_METHOD},
343     {indexOfW,               String_indexOf,               PROPF_METHOD},
344     {isPrototypeOfW,         String_isPrototypeOf,         PROPF_METHOD},
345     {italicsW,               String_italics,               PROPF_METHOD},
346     {lastIndexOfW,           String_lastIndexOf,           PROPF_METHOD},
347     {lengthW,                String_length,                0},
348     {linkW,                  String_link,                  PROPF_METHOD},
349     {localeCompareW,         String_localeCompare,         PROPF_METHOD},
350     {matchW,                 String_match,                 PROPF_METHOD},
351     {propertyIsEnumerableW,  String_propertyIsEnumerable,  PROPF_METHOD},
352     {replaceW,               String_replace,               PROPF_METHOD},
353     {searchW,                String_search,                PROPF_METHOD},
354     {sliceW,                 String_slice,                 PROPF_METHOD},
355     {smallW,                 String_small,                 PROPF_METHOD},
356     {splitW,                 String_split,                 PROPF_METHOD},
357     {strikeW,                String_strike,                PROPF_METHOD},
358     {substringW,             String_substring,             PROPF_METHOD},
359     {substrW,                String_substr,                PROPF_METHOD},
360     {subW,                   String_sub,                   PROPF_METHOD},
361     {supW,                   String_sup,                   PROPF_METHOD},
362     {toLocaleLowerCaseW,     String_toLocaleLowerCase,     PROPF_METHOD},
363     {toLocaleUpperCaseW,     String_toLocaleUpperCase,     PROPF_METHOD},
364     {toLowerCaseW,           String_toLowerCase,           PROPF_METHOD},
365     {toStringW,              String_toString,              PROPF_METHOD},
366     {toUpperCaseW,           String_toUpperCase,           PROPF_METHOD},
367     {valueOfW,               String_valueOf,               PROPF_METHOD}
368 };
369
370 static const builtin_info_t String_info = {
371     JSCLASS_STRING,
372     {NULL, String_value, 0},
373     sizeof(String_props)/sizeof(*String_props),
374     String_props,
375     String_destructor,
376     NULL
377 };
378
379 static HRESULT StringConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
380         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
381 {
382     FIXME("\n");
383     return E_NOTIMPL;
384 }
385
386 static HRESULT string_alloc(script_ctx_t *ctx, BOOL use_constr, StringInstance **ret)
387 {
388     StringInstance *string;
389     HRESULT hres;
390
391     string = heap_alloc_zero(sizeof(StringInstance));
392     if(!string)
393         return E_OUTOFMEMORY;
394
395     if(use_constr)
396         hres = init_dispex_from_constr(&string->dispex, ctx, &String_info, ctx->string_constr);
397     else
398         hres = init_dispex(&string->dispex, ctx, &String_info, NULL);
399     if(FAILED(hres)) {
400         heap_free(string);
401         return hres;
402     }
403
404     *ret = string;
405     return S_OK;
406 }
407
408 HRESULT create_string_constr(script_ctx_t *ctx, DispatchEx **ret)
409 {
410     StringInstance *string;
411     HRESULT hres;
412
413     hres = string_alloc(ctx, FALSE, &string);
414     if(FAILED(hres))
415         return hres;
416
417     hres = create_builtin_function(ctx, StringConstr_value, PROPF_CONSTR, &string->dispex, ret);
418
419     jsdisp_release(&string->dispex);
420     return hres;
421 }