1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2008, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexander Krivonogov ( algen )
11 *
12 ******************************************************************************/
13
14 define {
15 CP_ACP = 0
16 MB_PRECOMPOSED = 1
17 }
18
19 method buf buf.unicode( str src )
20 {
21 uint len = (MultiByteToWideChar( $CP_ACP, $MB_PRECOMPOSED, src.ptr(), *src, this.ptr(), 0 ) + 1)*2
22 this.expand( len )
23 MultiByteToWideChar( $CP_ACP, $MB_PRECOMPOSED, src.ptr(), *src, this.ptr(), len )
24 this[len-2] = 0
25 this[len-1] = 0
26 this.use = len
27 return this
28 }
29
30 method str str.fromunicode( uint src )
31 {
32 uint len = WideCharToMultiByte( $CP_ACP, 0, src, -1, this.ptr(), 0, 0, 0 )
33 this.reserve( len )
34 WideCharToMultiByte( $CP_ACP, 0, src, -1, this.ptr(), len, 0, 0 )
35 this.setlen( len - 1 )
36 return this
37 }
38
39 method VARIANT VARIANT.fromg( uint gtype, uint pval )
40 {
41 uint vt
42 long val
43 this.clear()
44 switch gtype
45 {
46 case ulong
47 {
48 vt = $VT_UI8
49 val = pval->ulong
50 }
51 case long
52 {
53 vt = $VT_I8
54 val = pval->long
55 }
56 case uint
57 {
58 vt = $VT_UI4
59 val = ulong( pval->uint )
60 }
61 case int
62 {
63 vt = $VT_I4
64 val = ulong( pval->uint )
65 }
66 case float
67 {
68 vt = $VT_R4
69 (&val)->float = pval->float
70 }
71 case double
72 {
73 vt = $VT_R8
74 val = pval->ulong
75 }
76 case str
77 {
78 vt = $VT_BSTR
79 buf ul
80 ul.unicode( pval->str )
81 val = ulong( SysAllocString( ul.ptr() ))
82 }
83 case oleobj
84 {
85 vt = $VT_DISPATCH | $VT_BYREF
86 val = ulong( &(pval->oleobj.ppv) )
87 }
88 case VARIANT
89 {
90 if (pval->VARIANT.vt & $VT_TYPEMASK) == $VT_ERROR && pval->VARIANT.val == 0x80020004L
91 {
92 val=ulong(pval->VARIANT.val)
93 vt =pval->VARIANT.vt
94 }
95 else
96 {
97 vt = pval->VARIANT.vt | $VT_BYREF
98 if pval->VARIANT.vt & $VT_BYREF
99 {
100 val = ulong(pval->VARIANT.val)
101 }
102 else
103 {
104 val = ulong(&pval->VARIANT.val)
105 }
106 }
107 }
108 }
109 this.vt = vt
110 this.val = val
111 return this
112 }
113
114 /*-----------------------------------------------------------------------------
115 * Id: variant_opeq F4
116 *
117 * Summary: Assign operation. #b(VARIANT = uint).
118 *
119 * Title: VARIANT = type
120 *
121 * Return: VARIANT( VT_UI4 ).
122 *
123 -----------------------------------------------------------------------------*/
124
125 operator VARIANT = (VARIANT left, uint right )
126 {
127 return left.fromg( uint, &right )
128 }
129
130 /*-----------------------------------------------------------------------------
131 * Id: variant_opeq_1 FC
132 *
133 * Summary: Assign operation: #b(VARIANT = int).
134 *
135 * Return: VARIANT( VT_I4 ).
136 *
137 -----------------------------------------------------------------------------*/
138
139 operator VARIANT = (VARIANT left, int right )
140 {
141 return left.fromg( int, &right )
142 }
143
144 /*-----------------------------------------------------------------------------
145 * Id: variant_opeq_2 FC
146 *
147 * Summary: Assign operation: #b(VARIANT = float).
148 *
149 * Return: VARIANT( VT_R4 ).
150 *
151 -----------------------------------------------------------------------------*/
152
153 operator VARIANT = (VARIANT left, float right )
154 {
155 return left.fromg( float, &right )
156 }
157
158 /*-----------------------------------------------------------------------------
159 * Id: variant_opeq_3 FC
160 *
161 * Summary: Assign operation: #b(VARIANT = double).
162 *
163 * Return: VARIANT( VT_R8 ).
164 *
165 -----------------------------------------------------------------------------*/
166
167 operator VARIANT = (VARIANT left, double right )
168 {
169 return left.fromg( double, &right )
170 }
171
172 /*-----------------------------------------------------------------------------
173 * Id: variant_opeq_4 FC
174 *
175 * Summary: Assign operation: #b(VARIANT = long).
176 *
177 * Return: VARIANT( VT_I8 ).
178 *
179 -----------------------------------------------------------------------------*/
180
181 operator VARIANT = (VARIANT left, long right )
182 {
183 return left.fromg( long, &right )
184 }
185
186 /*-----------------------------------------------------------------------------
187 * Id: variant_opeq_5 FC
188 *
189 * Summary: Assign operation: #b(VARIANT = ulong).
190 *
191 * Return: VARIANT( VT_UI8 ).
192 *
193 -----------------------------------------------------------------------------*/
194
195 operator VARIANT = (VARIANT left, ulong right )
196 {
197 return left.fromg( ulong, &right )
198 }
199
200 /*-----------------------------------------------------------------------------
201 * Id: variant_opeq_6 FC
202 *
203 * Summary: Assign operation: #b(VARIANT = str).
204 *
205 * Return: VARIANT( VT_BSTR ).
206 *
207 -----------------------------------------------------------------------------*/
208
209 operator VARIANT = (VARIANT left, str right )
210 {
211 return left.fromg( str, &right )
212 }
213
214 /*-----------------------------------------------------------------------------
215 * Id: variant_opeq_7 FC
216 *
217 * Summary: Assign operation: #b(VARIANT = VARIANT).
218 *
219 * Return: VARIANT.
220 *
221 -----------------------------------------------------------------------------*/
222
223 operator VARIANT = (VARIANT left, VARIANT right )
224 {
225 left.vt = right.vt
226 left.val = right.val
227 if !(left.vt & $VT_BYREF) && ((left.vt & $VT_TYPEMASK) == $VT_DISPATCH)
228 {
229 ((uint(left.val)->uint+4)->uint)->stdcall(uint(left.val))
230 }
231 return left
232 }
233
234 /*-----------------------------------------------------------------------------
235 * Id: type_opvar F4
236 *
237 * Summary: Conversion. #b[str(VARIANT)].
238 *
239 * Title: type( VARIANT )
240 *
241 * Return: The result #b(str) value.
242 *
243 -----------------------------------------------------------------------------*/
244
245 method str VARIANT.str <result>
246 {
247 uint pstr
248
249 if this.vt & $VT_BYREF : pstr = uint( this.val )->uint
250 else : pstr = uint( this.val )
251
252 switch this.vt & $VT_TYPEMASK
253 {
254 case $VT_BSTR
255 {
256 result.fromunicode( pstr )
257 }
258 }
259 }
260
261 /*-----------------------------------------------------------------------------
262 * Id: typevar_opeq F4
263 *
264 * Summary: Assign operation. #b[str = VARIANT( VT_BSTR )].
265 *
266 * Title: type = VARIANT
267 *
268 * Return: The result string.
269 *
270 -----------------------------------------------------------------------------*/
271
272 operator str = ( str left, VARIANT right )
273 {
274 return left = str( right )
275 }
276
277 /*-----------------------------------------------------------------------------
278 * Id: type_opvar_1 FC
279 *
280 * Summary: Conversion: #b[ulong(VARIANT)].
281 *
282 * Return: The result #b(ulong) value.
283 *
284 -----------------------------------------------------------------------------*/
285
286 method ulong VARIANT.ulong
287 {
288 ulong res
289 ulong val
290
291 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
292 else : val = this.val
293
294 switch this.vt & $VT_TYPEMASK
295 {
296 case $VT_I8
297 {
298 res = val
299 }
300 default : res = 0L
301 }
302 return res
303 }
304
305 /*-----------------------------------------------------------------------------
306 * Id: type_opvar_2 FC
307 *
308 * Summary: Conversion: #b[long(VARIANT)].
309 *
310 * Return: The result #b(long) value.
311 *
312 -----------------------------------------------------------------------------*/
313
314 method long VARIANT.long
315 {
316 long res
317 ulong val
318
319 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
320 else : val = this.val
321
322 switch this.vt & $VT_TYPEMASK
323 {
324 case $VT_I8
325 {
326 res = val
327 }
328 default : res = 0L
329 }
330 return res
331 }
332
333 /*-----------------------------------------------------------------------------
334 * Id: type_opvar_3 FC
335 *
336 * Summary: Conversion: #b[uint(VARIANT)].
337 *
338 * Return: The result #b(uint) value.
339 *
340 -----------------------------------------------------------------------------*/
341
342 method uint VARIANT.uint
343 {
344 uint res
345 ulong val
346
347 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
348 else : val = this.val
349
350 switch this.vt & $VT_TYPEMASK
351 {
352 case $VT_UI4, $VT_UI2, $VT_UI1, $VT_I4, $VT_I2, $VT_I1
353 {
354 res = uint( val )
355 }
356 case $VT_BOOL
357 {
358 if uint( val ) : res = 1
359 else : res = 0
360 }
361 default : res = 0
362 }
363 return res
364 }
365
366 /*-----------------------------------------------------------------------------
367 * Id: type_opvar_4 FC
368 *
369 * Summary: Conversion: #b[int(VARIANT)].
370 *
371 * Return: The result #b(int) value.
372 *
373 -----------------------------------------------------------------------------*/
374
375 method int VARIANT.int
376 {
377 uint res
378 ulong val
379
380 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
381 else : val = this.val
382
383 switch this.vt & $VT_TYPEMASK
384 {
385 case $VT_I4, $VT_UI4, $VT_UI2, $VT_UI1
386 {
387 res = int( val )
388 }
389 case $VT_I2
390 {
391 if uint( val ) & 0x8000
392 {
393 res = 0x80000000 & uint( val ) & 0x7FFF
394 }
395 else
396 {
397 res = int( val )
398 }
399 }
400 case $VT_I1
401 {
402 if uint( val ) & 0x80
403 {
404 res = 0x80000000 & uint( val ) & 0x7F
405 }
406 else
407 {
408 res = int( val )
409 }
410 }
411 case $VT_BOOL
412 {
413 if uint( val ) : res = 1
414 else : res = 0
415 }
416 default : res = 0
417 }
418 return res
419 }
420
421 /*-----------------------------------------------------------------------------
422 * Id: type_opvar_5 FC
423 *
424 * Summary: Conversion: #b[float(VARIANT)].
425 *
426 * Return: The result #b(float) value.
427 *
428 -----------------------------------------------------------------------------*/
429
430 method float VARIANT.float
431 {
432 float res
433 ulong val
434
435 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
436 else : val = this.val
437
438 switch this.vt & $VT_TYPEMASK
439 {
440 case $VT_R4
441 {
442 res = (&val)->float
443 }
444 default : res = 0f
445 }
446 return res
447 }
448
449 /*-----------------------------------------------------------------------------
450 * Id: type_opvar_6 FC
451 *
452 * Summary: Conversion: #b[double(VARIANT)].
453 *
454 * Return: The result #b(double) value.
455 *
456 -----------------------------------------------------------------------------*/
457
458 method double VARIANT.double
459 {
460 double res
461 ulong val
462
463 if this.vt & $VT_BYREF : val = uint( this.val )->ulong
464 else : val = this.val
465
466 switch this.vt & $VT_TYPEMASK
467 {
468 case $VT_R8
469 {
470 res = (&val)->double
471 }
472 default : res = 0d
473 }
474 return res
475 }
476
477 /*-----------------------------------------------------------------------------
478 * Id: variant_isnull F3
479 *
480 * Summary: Enables to define whether or not a variable is NULL. This method
481 enables you to define whether or not a variable is NULL - the
482 VARIANT( VT_NULL ) type.
483 *
484 * Return: The method returns 1, if the VARIANT variable is of the VT_NULL
485 type, otherwise, it returns zero.
486 *
487 -----------------------------------------------------------------------------*/
488
489 method uint VARIANT.isnull()
490 {
491 if (this.vt & $VT_TYPEMASK) == $VT_NULL : return 1
492 return 0
493 }
494
495 /*-----------------------------------------------------------------------------
496 * Id: variant_ismissing F3
497 *
498 * Summary: Checks if the variant is "missing" (optional) parameter of the
499 method.
500 *
501 * Return: The method returns 1, if the VARIANT variable is "missing".
502 *
503 -----------------------------------------------------------------------------*/
504
505 method uint VARIANT.ismissing()
506 {
507 if (this.vt & $VT_TYPEMASK) == $VT_ERROR && this.val == 0x80020004L : return 1
508 return 0
509 }
510
511 /*-----------------------------------------------------------------------------
512 ** Id: variant_setmissing F3
513 *
514 * Summary: Sets the "missing" variant. The method sets the variant variable
515 as "missing" (optional) parameter.
516 *
517 -----------------------------------------------------------------------------*/
518
519 method VARIANT.setmissing()
520 {
521 this.clear()
522 this.vt = $VT_ERROR
523 this.val = 0x80020004L
524 }
525