1 : //==============================================================================
2 : // File <$/src/cpp/dev/idlc/int_value.cpp>
3 : // This file is part of YaOrb : Yet Another Object Request Broker,
4 : // Copyright (c) 2000-2003, 2006, Marc Alff.
5 : //
6 : // This program is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU General Public License
8 : // as published by the Free Software Foundation; either version 2
9 : // of the License, or (at your option) any later version.
10 : //
11 : // This program 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
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; 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 <stdio.h>
23 : #include <iostream>
24 :
25 : #include "src/cpp/prod/tool/DEVELOPMENT.h"
26 : #include "src/cpp/prod/tool/Assert.h"
27 :
28 : #include "src/cpp/dev/idlc/int_value.h"
29 : #include "src/cpp/dev/idlc/yyutils.h"
30 : #include "src/cpp/dev/idlc/bit_arith.h"
31 : #include "src/cpp/dev/idlc/arith.h"
32 :
33 : // do NOT use limits.h !
34 :
35 : typedef uint64_t BigInt_t ;
36 :
37 : struct IDLIntTypeInfo_s
38 : {
39 : enum IDLIntType_e _type ;
40 : const char * _printName ;
41 : bool _signed ;
42 : BigInt_t _neg_minimum ; /* warning : the sign is reversed ! */
43 : BigInt_t _maximum ;
44 : int _size ;
45 : int _indice ;
46 : } ;
47 :
48 : typedef void (*convertFn)(IDLIntValue*) ;
49 :
50 207 : static void nop(IDLIntValue*)
51 : {}
52 :
53 : // Matrix, line 0 : S16_to_XXX
54 :
55 3 : static void S16_to_U16(IDLIntValue* v)
56 : {
57 3 : uint16_t v2 = v->GetS16() ;
58 3 : v->PutU16(v2) ;
59 : }
60 :
61 2 : static void S16_to_S32(IDLIntValue* v)
62 : {
63 2 : int32_t v2 = v->GetS16() ;
64 2 : v->PutS32(v2) ;
65 : }
66 :
67 1 : static void S16_to_U32(IDLIntValue* v)
68 : {
69 1 : uint32_t v2 = v->GetS16() ;
70 1 : v->PutU32(v2) ;
71 : }
72 :
73 2 : static void S16_to_S64(IDLIntValue* v)
74 : {
75 2 : int64_t v2 = v->GetS16() ;
76 2 : v->PutS64(v2) ;
77 : }
78 :
79 1 : static void S16_to_U64(IDLIntValue* v)
80 : {
81 1 : uint64_t v2 = v->GetS16() ;
82 1 : v->PutU64(v2) ;
83 : }
84 :
85 : // Matrix, line 1 : U16_to_XXX
86 :
87 1 : static void U16_to_S16(IDLIntValue* v)
88 : {
89 1 : int16_t v2 = v->GetU16() ;
90 1 : v->PutS16(v2) ;
91 : }
92 :
93 2 : static void U16_to_S32(IDLIntValue* v)
94 : {
95 2 : int32_t v2 = v->GetU16() ;
96 2 : v->PutS32(v2) ;
97 : }
98 :
99 2 : static void U16_to_U32(IDLIntValue* v)
100 : {
101 2 : uint32_t v2 = v->GetU16() ;
102 2 : v->PutU32(v2) ;
103 : }
104 :
105 2 : static void U16_to_S64(IDLIntValue* v)
106 : {
107 2 : int64_t v2 = v->GetU16() ;
108 2 : v->PutS64(v2) ;
109 : }
110 :
111 2 : static void U16_to_U64(IDLIntValue* v)
112 : {
113 2 : uint64_t v2 = v->GetU16() ;
114 2 : v->PutU64(v2) ;
115 : }
116 :
117 : // Matrix, line 2 : S32_to_XXX
118 :
119 2 : static void S32_to_S16(IDLIntValue* v)
120 : {
121 2 : int16_t v2 = v->GetS32() ;
122 2 : v->PutS16(v2) ;
123 : }
124 :
125 2 : static void S32_to_U16(IDLIntValue* v)
126 : {
127 2 : uint16_t v2 = v->GetS32() ;
128 2 : v->PutU16(v2) ;
129 : }
130 :
131 3 : static void S32_to_U32(IDLIntValue* v)
132 : {
133 3 : uint32_t v2 = v->GetS32() ;
134 3 : v->PutU32(v2) ;
135 : }
136 :
137 6 : static void S32_to_S64(IDLIntValue* v)
138 : {
139 6 : int64_t v2 = v->GetS32() ;
140 6 : v->PutS64(v2) ;
141 : }
142 :
143 3 : static void S32_to_U64(IDLIntValue* v)
144 : {
145 3 : uint64_t v2 = v->GetS32() ;
146 3 : v->PutU64(v2) ;
147 : }
148 :
149 : // Matrix, line 3 : U32_to_XXX
150 :
151 1 : static void U32_to_S16(IDLIntValue* v)
152 : {
153 1 : int16_t v2 = v->GetU32() ;
154 1 : v->PutS16(v2) ;
155 : }
156 :
157 2 : static void U32_to_U16(IDLIntValue* v)
158 : {
159 2 : uint16_t v2 = v->GetU32() ;
160 2 : v->PutU16(v2) ;
161 : }
162 :
163 3 : static void U32_to_S32(IDLIntValue* v)
164 : {
165 3 : int32_t v2 = v->GetU32() ;
166 3 : v->PutS32(v2) ;
167 : }
168 :
169 4 : static void U32_to_S64(IDLIntValue* v)
170 : {
171 4 : int64_t v2 = v->GetU32() ;
172 4 : v->PutS64(v2) ;
173 : }
174 :
175 4 : static void U32_to_U64(IDLIntValue* v)
176 : {
177 4 : uint64_t v2 = v->GetU32() ;
178 4 : v->PutU64(v2) ;
179 : }
180 :
181 : // Matrix, line 4 : S64_to_XXX
182 :
183 2 : static void S64_to_S16(IDLIntValue* v)
184 : {
185 2 : int16_t v2 = v->GetS64() ;
186 2 : v->PutS16(v2) ;
187 : }
188 :
189 2 : static void S64_to_U16(IDLIntValue* v)
190 : {
191 2 : uint16_t v2 = v->GetS64() ;
192 2 : v->PutU16(v2) ;
193 : }
194 :
195 6 : static void S64_to_S32(IDLIntValue* v)
196 : {
197 6 : int32_t v2 = v->GetS64() ;
198 6 : v->PutS32(v2) ;
199 : }
200 :
201 4 : static void S64_to_U32(IDLIntValue* v)
202 : {
203 4 : uint32_t v2 = v->GetS64() ;
204 4 : v->PutU32(v2) ;
205 : }
206 :
207 5 : static void S64_to_U64(IDLIntValue* v)
208 : {
209 5 : uint64_t v2 = v->GetS64() ;
210 5 : v->PutU64(v2) ;
211 : }
212 :
213 : // Matrix, line 5 : U16_to_XXX
214 :
215 157 : static void U64_to_S16(IDLIntValue* v)
216 : {
217 157 : int16_t v2 = v->GetU64() ;
218 157 : v->PutS16(v2) ;
219 : }
220 :
221 49 : static void U64_to_U16(IDLIntValue* v)
222 : {
223 49 : uint16_t v2 = v->GetU64() ;
224 49 : v->PutU16(v2) ;
225 : }
226 :
227 71 : static void U64_to_S32(IDLIntValue* v)
228 : {
229 71 : int32_t v2 = v->GetU64() ;
230 71 : v->PutS32(v2) ;
231 : }
232 :
233 67 : static void U64_to_U32(IDLIntValue* v)
234 : {
235 67 : uint32_t v2 = v->GetU64() ;
236 67 : v->PutU32(v2) ;
237 : }
238 :
239 76 : static void U64_to_S64(IDLIntValue* v)
240 : {
241 76 : int64_t v2 = v->GetU64() ;
242 76 : v->PutS64(v2) ;
243 : }
244 :
245 : static convertFn convertMatrix[6][6] =
246 : {
247 : {nop , S16_to_U16, S16_to_S32, S16_to_U32, S16_to_S64, S16_to_U64},
248 : {U16_to_S16, nop , U16_to_S32, U16_to_U32, U16_to_S64, U16_to_U64},
249 : {S32_to_S16, S32_to_U16, nop , S32_to_U32, S32_to_S64, S32_to_U64},
250 : {U32_to_S16, U32_to_U16, U32_to_S32, nop , U32_to_S64, U32_to_U64},
251 : {S64_to_S16, S64_to_U16, S64_to_S32, S64_to_U32, nop , S64_to_U64},
252 : {U64_to_S16, U64_to_U16, U64_to_S32, U64_to_U32, U64_to_S64, nop }
253 : } ;
254 :
255 : // Can not be const because of FixGCCBug
256 : static struct IDLIntTypeInfo_s types[] =
257 : {
258 : /* _type , _printName ,_signed,
259 : _neg_minimum , _maximum , _size , _indice */
260 :
261 : { idl_signed_short , "idl short" , true ,
262 : 0x0000000000008000 , 0x0000000000007FFF , 16 , 0 },
263 : { idl_unsigned_short , "idl unsigned short" , false ,
264 : 0 , 0x000000000000FFFF , 16 , 1 },
265 : { idl_signed_long , "idl long" , true ,
266 : 0x0000000080000000 , 0x000000007FFFFFFF , 32 , 2 },
267 : { idl_unsigned_long , "idl unsigned long" , false ,
268 : 0 , 0x00000000FFFFFFFF , 32 , 3 },
269 : { idl_signed_long_long , "idl long long" , true ,
270 : 0 , 0 , 64 , 4 },
271 : { idl_unsigned_long_long, "idl unsigned long long", false ,
272 : 0 , 0 , 64 , 5 }
273 :
274 : // FIXME (in fact FIX GCC 2.7.2.3)
275 : // GCC Compile-Time Bug prevents to use long long immediate values,
276 : // event if long long are well supported at run-time.
277 : // { idl_signed_long_long , "idl long long" , true ,
278 : // 0x8000000000000000 , 0x7FFFFFFFFFFFFFFF , 64 , 4 },
279 : // { idl_unsigned_long_long, "idl unsigned long long", false ,
280 : // 0 , 0xFFFFFFFFFFFFFFFF , 64 , 5 }
281 : } ;
282 :
283 63 : void FixGCCBug(void)
284 : {
285 : volatile uint64_t value ;
286 : uint64_t *hackPtr ;
287 :
288 : // 0x7FFFFFFFFFFFFFFF is not understood by GCC at compile-time
289 63 : value = 0x7FFFFFFF ;
290 63 : value <<= 32 ;
291 63 : value += 0xFFFFFFFF ;
292 :
293 : hackPtr = & types[4]._maximum ;
294 :
295 63 : *hackPtr = value ;
296 :
297 : // 0x8000000000000000 is not understood by GCC at compile-time
298 63 : value = 0x80000000 ;
299 63 : value <<= 32 ;
300 :
301 : hackPtr = & types[4]._neg_minimum ;
302 :
303 63 : *hackPtr = value ;
304 :
305 : // 0xFFFFFFFFFFFFFFFF is not understood by GCC at compile-time
306 63 : value = 0xFFFFFFFF ;
307 63 : value <<= 32 ;
308 63 : value += 0xFFFFFFFF ;
309 :
310 : hackPtr = & types[5]._maximum ;
311 :
312 63 : *hackPtr = value ;
313 : }
314 :
315 2749 : static const struct IDLIntTypeInfo_s *findInfo(IDLIntType_e type)
316 : {
317 : const struct IDLIntTypeInfo_s *cursor = & types[0] ;
318 :
319 : for ( ; ; )
320 : {
321 6458 : if (cursor->_type == type)
322 : {
323 : return cursor ;
324 : }
325 : cursor ++ ;
326 : }
327 : }
328 :
329 63 : static IDLIntType global_S16_type(idl_signed_short) ;
330 63 : static IDLIntType global_S32_type(idl_signed_long) ;
331 63 : static IDLIntType global_S64_type(idl_signed_long_long) ;
332 63 : static IDLIntType global_U16_type(idl_unsigned_short) ;
333 63 : static IDLIntType global_U32_type(idl_unsigned_long) ;
334 63 : static IDLIntType global_U64_type(idl_unsigned_long_long) ;
335 :
336 20 : IDLType* IDLIntValue::GetValueType(void) const
337 : {
338 : IDLType *result = NULL ;
339 :
340 20 : switch(_type)
341 : {
342 : case idl_signed_short :
343 : {
344 : result = & global_S16_type ;
345 6 : break ;
346 : }
347 : case idl_signed_long :
348 : {
349 : result = & global_S32_type ;
350 0 : break ;
351 : }
352 : case idl_signed_long_long :
353 : {
354 : result = & global_S64_type ;
355 0 : break ;
356 : }
357 : case idl_unsigned_short :
358 : {
359 : result = & global_U16_type ;
360 0 : break ;
361 : }
362 : case idl_unsigned_long :
363 : {
364 : result = & global_U32_type ;
365 : break ;
366 : }
367 : case idl_unsigned_long_long :
368 : {
369 : result = & global_U64_type ;
370 : break ;
371 : }
372 : }
373 :
374 : return result ;
375 : }
376 :
377 : // IDLIntValue
378 :
379 731 : IDLIntValue::IDLIntValue()
380 : : IDLValue(idl_intType),
381 : _type(idl_signed_short),
382 : _value_u16(0),
383 : _value_s16(0),
384 : _value_u32(0),
385 : _value_s32(0),
386 : _value_u64(0),
387 731 : _value_s64(0)
388 : {
389 : }
390 :
391 1001 : IDLIntValue::IDLIntValue(const IDLIntValue& v)
392 : : IDLValue(v),
393 : _type(v._type),
394 : _value_u16(v._value_u16),
395 : _value_s16(v._value_s16),
396 : _value_u32(v._value_u32),
397 : _value_s32(v._value_s32),
398 : _value_u64(v._value_u64),
399 1001 : _value_s64(v._value_s64)
400 : {
401 : }
402 :
403 0 : IDLIntValue& IDLIntValue::operator=(const IDLIntValue& v)
404 : {
405 0 : _type = v._type ;
406 :
407 0 : _value_u16 = v._value_u16 ;
408 0 : _value_s16 = v._value_s16 ;
409 0 : _value_u32 = v._value_u32 ;
410 0 : _value_s32 = v._value_s32 ;
411 0 : _value_u64 = v._value_u64 ;
412 0 : _value_s64 = v._value_s64 ;
413 :
414 : return *this ;
415 : }
416 :
417 1617 : IDLIntValue::~IDLIntValue()
418 1617 : {}
419 :
420 20 : IDLIntType_e IDLIntValue::GetType(void)
421 : {
422 : return _type ;
423 : }
424 :
425 1001 : IDLValue *IDLIntValue::copy(void)
426 : {
427 1001 : return new IDLIntValue(*this) ;
428 : }
429 :
430 79 : void IDLIntValue::PutU16(uint16_t v)
431 : {
432 79 : _type = idl_unsigned_short ;
433 79 : _value_u16 = v ;
434 : }
435 :
436 209 : void IDLIntValue::PutS16(int16_t v)
437 : {
438 209 : _type = idl_signed_short ;
439 209 : _value_s16 = v ;
440 : }
441 :
442 98 : void IDLIntValue::PutU32(uint32_t v)
443 : {
444 98 : _type = idl_unsigned_long ;
445 98 : _value_u32 = v ;
446 : }
447 :
448 131 : void IDLIntValue::PutS32(int32_t v)
449 : {
450 131 : _type = idl_signed_long ;
451 131 : _value_s32 = v ;
452 : }
453 :
454 550 : void IDLIntValue::PutU64(uint64_t v)
455 : {
456 550 : _type = idl_unsigned_long_long ;
457 550 : _value_u64 = v ;
458 : }
459 :
460 139 : void IDLIntValue::PutS64(int64_t v)
461 : {
462 139 : _type = idl_signed_long_long ;
463 139 : _value_s64 = v ;
464 : }
465 :
466 9 : uint16_t IDLIntValue::GetU16(void)
467 : {
468 : ASSERT(_type == idl_unsigned_short) ;
469 : return _value_u16 ;
470 : }
471 :
472 15 : int16_t IDLIntValue::GetS16(void)
473 : {
474 : ASSERT (_type == idl_signed_short) ;
475 : return _value_s16 ;
476 : }
477 :
478 28 : uint32_t IDLIntValue::GetU32(void)
479 : {
480 : ASSERT (_type == idl_unsigned_long) ;
481 : return _value_u32 ;
482 : }
483 :
484 16 : int32_t IDLIntValue::GetS32(void)
485 : {
486 : ASSERT (_type == idl_signed_long) ;
487 : return _value_s32 ;
488 : }
489 :
490 467 : uint64_t IDLIntValue::GetU64(void)
491 : {
492 : ASSERT (_type == idl_unsigned_long_long) ;
493 : return _value_u64 ;
494 : }
495 :
496 19 : int64_t IDLIntValue::GetS64(void)
497 : {
498 : ASSERT (_type == idl_signed_long_long) ;
499 : return _value_s64 ;
500 : }
501 :
502 598 : void IDLIntValue::print(std::ostream &str) const
503 : {
504 598 : if (IsError())
505 : {
506 105 : switch (_type)
507 : {
508 : case idl_unsigned_short :
509 6 : { str << "U16 = <error>" ; break ; }
510 : case idl_signed_short :
511 17 : { str << "S16 = <error>" ; break ; }
512 : case idl_unsigned_long :
513 11 : { str << "U32 = <error>" ; break ; }
514 : case idl_signed_long :
515 15 : { str << "S32 = <error>" ; break ; }
516 : case idl_unsigned_long_long :
517 30 : { str << "U64 = <error>" ; break ; }
518 : case idl_signed_long_long :
519 26 : { str << "S64 = <error>" ; break ; }
520 : } ;
521 : }
522 : else
523 : {
524 493 : switch (_type)
525 : {
526 : case idl_unsigned_short :
527 55 : { str << "U16 = " << _value_u16 ; break ; }
528 : case idl_signed_short :
529 78 : { str << "S16 = " << _value_s16 ; break ; }
530 : case idl_unsigned_long :
531 67 : { str << "U32 = " << _value_u32 ; break ; }
532 : case idl_signed_long :
533 91 : { str << "S32 = " << _value_s32 ; break ; }
534 : case idl_unsigned_long_long :
535 90 : { str << "U64 = " << _value_u64 ; break ; }
536 : case idl_signed_long_long :
537 112 : { str << "S64 = " << _value_s64 ; break ; }
538 : } ;
539 : }
540 : }
541 :
542 : bool IDLIntValue::checkForSign(const IDLIntTypeInfo_s *me,
543 743 : const IDLIntTypeInfo_s *convert)
544 : {
545 : /* No sign change, OK */
546 743 : if ((me->_signed) == (convert->_signed))
547 : {
548 : return true ;
549 : }
550 :
551 : /* Target type is signed, so OK */
552 364 : if (convert->_signed)
553 : {
554 : return true ;
555 : }
556 :
557 : /* This value is signed, and the target type is not */
558 : /* See if the actual value is positive (OK) or negative (KO) */
559 :
560 : bool result = false ;
561 :
562 30 : switch (_type)
563 : {
564 : case idl_signed_short :
565 : {
566 : result = ((_value_s16 >= 0) ? true : false) ;
567 6 : break ;
568 : }
569 : case idl_signed_long :
570 : {
571 : result = ((_value_s32 >= 0) ? true : false) ;
572 9 : break ;
573 : }
574 : case idl_signed_long_long :
575 : {
576 : result = ((_value_s64 >= 0) ? true : false) ;
577 : break ;
578 : }
579 :
580 : // Technical note :
581 : // The default is to please the compiler, but is not used.
582 : // No code is in the default, to avoid gcov complaints.
583 : // Should this return, the result will be false.
584 :
585 : default : {}
586 : }
587 :
588 : return result ;
589 : }
590 :
591 : bool IDLIntValue::checkForSize(const IDLIntTypeInfo_s *me,
592 742 : const IDLIntTypeInfo_s *convert)
593 : {
594 : /* Convert is bigger, OK */
595 742 : if ( (me->_maximum <= convert->_maximum)
596 : && (me->_neg_minimum <= convert->_neg_minimum))
597 : return true ;
598 :
599 : uint64_t max = convert->_maximum ;
600 : uint64_t neg_min = convert->_neg_minimum ;
601 509 : int64_t min = -neg_min; // safe
602 :
603 : /* Must convert to a smaller int : see the real value */
604 :
605 : /*
606 : * unsigned values
607 : * ===============
608 : *
609 : * ------------------- 0 ---------------- MAX ------------------
610 : * U1, safe in uint64_t
611 : * U2, if U1 fails
612 : * N/A
613 : *
614 : * signed values
615 : * =============
616 : *
617 : * ------- MIN -------------- 0 ---------------- MAX -----------
618 : * S1, safe in int64_t
619 : * S2, safe in __sXX
620 : * S3, safe in __uXX
621 : * S4
622 : */
623 :
624 509 : switch (_type)
625 : {
626 : case idl_unsigned_short :
627 : {
628 : // Note (U1)
629 2 : if (_value_u16 > max)
630 : return false ;
631 :
632 : // Note (U2)
633 : return true ;
634 : }
635 : case idl_signed_short :
636 : {
637 : // Note (S1)
638 5 : if (_value_s16 < min)
639 : return false ;
640 :
641 : // Note (S2)
642 5 : if (_value_s16 <= 0)
643 : return true ;
644 :
645 : // Note (S3)
646 : uint16_t tmp = _value_s16 ;
647 4 : if (tmp <= max)
648 : return true ;
649 :
650 : // Note (S4)
651 : return false ;
652 : }
653 : case idl_unsigned_long :
654 : {
655 : // Note (U1)
656 12 : if (_value_u32 > max)
657 : return false ;
658 :
659 : // Note (U2)
660 : return true ;
661 : }
662 : case idl_signed_long :
663 : {
664 : // Note (S1)
665 15 : if (_value_s32 < min)
666 : return false ;
667 :
668 : // Note (S2)
669 13 : if (_value_s32 <= 0)
670 : return true ;
671 :
672 : // Note (S3)
673 : uint32_t tmp = _value_s32 ;
674 12 : if (tmp <= max)
675 : return true ;
676 :
677 : // Note (S4)
678 : return false ;
679 : }
680 : case idl_unsigned_long_long :
681 : {
682 : // Note (U1)
683 440 : if (_value_u64 > max)
684 : return false ;
685 :
686 : // Note (U2)
687 : return true ;
688 : }
689 : case idl_signed_long_long :
690 : {
691 : // Note (S1)
692 35 : if (_value_s64 < min)
693 : return false ;
694 :
695 : // Note (S2)
696 29 : if (_value_s64 <= 0)
697 : return true ;
698 :
699 : // Note (S3)
700 : uint64_t tmp = _value_s64 ;
701 25 : if (tmp <= max)
702 : return true ;
703 :
704 : // Note (S4)
705 : return false ;
706 : }
707 : default :
708 : ASSERT(false) ;
709 : return false ;
710 : } ;
711 : }
712 :
713 747 : void IDLIntValue::convert(IDLType *type)
714 : {
715 : ASSERT(type != NULL) ;
716 :
717 : const struct IDLIntTypeInfo_s *myInfo = NULL ;
718 : const struct IDLIntTypeInfo_s *convertInfo = NULL ;
719 :
720 747 : myInfo = findInfo(_type) ;
721 :
722 747 : type = IDLType::ResolveAlias(type) ;
723 :
724 747 : if (type->isA() == idl_intType)
725 : {
726 : IDLIntType *type2 = (IDLIntType*) type ;
727 743 : convertInfo = findInfo(type2->GetType()) ;
728 : }
729 :
730 747 : if ((myInfo != NULL) && (convertInfo != NULL))
731 : {
732 743 : bool signOK = checkForSign(myInfo, convertInfo) ;
733 :
734 743 : if (signOK == false)
735 : {
736 1 : IDLCompileError("can't cast because of sign") ;
737 1 : errLog << "The value is : " ;
738 1 : print(errLog) ;
739 1 : errLog << ", trying to cast into : " ;
740 1 : type->print(errLog) ;
741 : errLog << std::endl ;
742 1 : SetError() ;
743 : }
744 : else
745 : {
746 742 : bool sizeOK = checkForSize(myInfo, convertInfo) ;
747 :
748 742 : if (sizeOK == false)
749 : {
750 48 : IDLCompileError("can't cast because of size") ;
751 48 : errLog << "The value is : " ;
752 48 : print(errLog) ;
753 48 : errLog << ", trying to cast into : " ;
754 48 : type->print(errLog) ;
755 : errLog << std::endl ;
756 48 : SetError() ;
757 : }
758 : else
759 : {
760 : int lign = myInfo->_indice ;
761 : int column = convertInfo->_indice ;
762 : convertFn fct = convertMatrix[lign][column] ;
763 :
764 : ASSERT (fct != NULL) ;
765 694 : (*fct) (this) ;
766 : }
767 : }
768 : }
769 : else
770 : {
771 : // No need to generate more messages if
772 : // either _type or type is already in error.
773 :
774 4 : if ( (this->isA() != idl_errorType)
775 : && (type->isA() != idl_errorType) )
776 : {
777 4 : typeConvertionError(type) ;
778 : }
779 : }
780 : }
781 :
782 24 : IDLValue* IDLIntValue::computeAdd(const IDLValue *v)
783 : {
784 24 : IDLIntValue *result = new IDLIntValue() ;
785 : IDLIntValue *v2 = NULL ;
786 : bool overflow = false ;
787 :
788 : ASSERT(v->isA() == idl_intType) ;
789 24 : v2 = (IDLIntValue*) v ;
790 : ASSERT(v2->GetType() == _type) ;
791 :
792 24 : switch (_type)
793 : {
794 : case idl_unsigned_short :
795 : {
796 : uint16_t r ;
797 3 : overflow = add_u16(_value_u16, v2->_value_u16, & r) ;
798 3 : result->PutU16(r) ;
799 3 : break ;
800 : }
801 : case idl_signed_short :
802 : {
803 : int16_t r ;
804 5 : overflow = add_s16(_value_s16, v2->_value_s16, & r) ;
805 5 : result->PutS16(r) ;
806 5 : break ;
807 : }
808 : case idl_unsigned_long :
809 : {
810 : uint32_t r ;
811 3 : overflow = add_u32(_value_u32, v2->_value_u32, & r) ;
812 3 : result->PutU32(r) ;
813 3 : break ;
814 : }
815 : case idl_signed_long :
816 : {
817 : int32_t r ;
818 5 : overflow = add_s32(_value_s32, v2->_value_s32, & r) ;
819 5 : result->PutS32(r) ;
820 5 : break ;
821 : }
822 : case idl_unsigned_long_long :
823 : {
824 : uint64_t r ;
825 3 : overflow = add_u64(_value_u64, v2->_value_u64, & r) ;
826 3 : result->PutU64(r) ;
827 3 : break ;
828 : }
829 : case idl_signed_long_long :
830 : {
831 : int64_t r ;
832 5 : overflow = add_s64(_value_s64, v2->_value_s64, & r) ;
833 5 : result->PutS64(r) ;
834 : break ;
835 : }
836 : default :
837 : ASSERT(false) ;
838 : }
839 :
840 24 : if (overflow)
841 : {
842 9 : overflowError("+", v) ;
843 9 : result->SetError() ;
844 : }
845 : return result ;
846 : }
847 :
848 24 : IDLValue* IDLIntValue::computeSub(const IDLValue *v)
849 : {
850 24 : IDLIntValue *result = new IDLIntValue() ;
851 : IDLIntValue *v2 = NULL ;
852 : bool overflow = false ;
853 :
854 : ASSERT(v->isA() == idl_intType) ;
855 24 : v2 = (IDLIntValue*) v ;
856 : ASSERT(v2->GetType() == _type) ;
857 :
858 24 : switch (_type)
859 : {
860 : case idl_unsigned_short :
861 : {
862 : uint16_t r ;
863 3 : overflow = sub_u16(_value_u16, v2->_value_u16, & r) ;
864 3 : result->PutU16(r) ;
865 3 : break ;
866 : }
867 : case idl_signed_short :
868 : {
869 : int16_t r ;
870 5 : overflow = sub_s16(_value_s16, v2->_value_s16, & r) ;
871 5 : result->PutS16(r) ;
872 5 : break ;
873 : }
874 : case idl_unsigned_long :
875 : {
876 : uint32_t r ;
877 3 : overflow = sub_u32(_value_u32, v2->_value_u32, & r) ;
878 3 : result->PutU32(r) ;
879 3 : break ;
880 : }
881 : case idl_signed_long :
882 : {
883 : int32_t r ;
884 5 : overflow = sub_s32(_value_s32, v2->_value_s32, & r) ;
885 5 : result->PutS32(r) ;
886 5 : break ;
887 : }
888 : case idl_unsigned_long_long :
889 : {
890 : uint64_t r ;
891 3 : overflow = sub_u64(_value_u64, v2->_value_u64, & r) ;
892 3 : result->PutU64(r) ;
893 3 : break ;
894 : }
895 : case idl_signed_long_long :
896 : {
897 : int64_t r ;
898 5 : overflow = sub_s64(_value_s64, v2->_value_s64, & r) ;
899 5 : result->PutS64(r) ;
900 : break ;
901 : }
902 : default :
903 : ASSERT(false) ;
904 : }
905 :
906 24 : if (overflow)
907 : {
908 9 : overflowError("-", v) ;
909 9 : result->SetError() ;
910 : }
911 : return result ;
912 : }
913 :
914 6 : IDLValue* IDLIntValue::computeMul(const IDLValue *v)
915 : {
916 6 : IDLIntValue *result = new IDLIntValue() ;
917 : IDLIntValue *v2 = NULL ;
918 : bool overflow = false ;
919 :
920 : ASSERT(v->isA() == idl_intType) ;
921 6 : v2 = (IDLIntValue*) v ;
922 : ASSERT(v2->GetType() == _type) ;
923 :
924 6 : switch (_type)
925 : {
926 : case idl_unsigned_short :
927 : {
928 : uint16_t r ;
929 1 : overflow = mul_u16(_value_u16, v2->_value_u16, & r) ;
930 1 : result->PutU16(r) ;
931 1 : break ;
932 : }
933 : case idl_signed_short :
934 : {
935 : int16_t r ;
936 1 : overflow = mul_s16(_value_s16, v2->_value_s16, & r) ;
937 1 : result->PutS16(r) ;
938 1 : break ;
939 : }
940 : case idl_unsigned_long :
941 : {
942 : uint32_t r ;
943 1 : overflow = mul_u32(_value_u32, v2->_value_u32, & r) ;
944 1 : result->PutU32(r) ;
945 1 : break ;
946 : }
947 : case idl_signed_long :
948 : {
949 : int32_t r ;
950 1 : overflow = mul_s32(_value_s32, v2->_value_s32, & r) ;
951 1 : result->PutS32(r) ;
952 1 : break ;
953 : }
954 : case idl_unsigned_long_long :
955 : {
956 : uint64_t r ;
957 1 : overflow = mul_u64(_value_u64, v2->_value_u64, & r) ;
958 1 : result->PutU64(r) ;
959 1 : break ;
960 : }
961 : case idl_signed_long_long :
962 : {
963 : int64_t r ;
964 1 : overflow = mul_s64(_value_s64, v2->_value_s64, & r) ;
965 1 : result->PutS64(r) ;
966 : break ;
967 : }
968 : default :
969 : ASSERT(false) ;
970 : }
971 :
972 6 : if (overflow)
973 : {
974 0 : overflowError("*", v) ;
975 0 : result->SetError() ;
976 : }
977 : return result ;
978 : }
979 :
980 6 : IDLValue* IDLIntValue::computeDiv(const IDLValue *v)
981 : {
982 6 : IDLIntValue *result = new IDLIntValue() ;
983 : IDLIntValue *v2 = NULL ;
984 : bool overflow = false ;
985 :
986 : ASSERT(v->isA() == idl_intType) ;
987 6 : v2 = (IDLIntValue*) v ;
988 : ASSERT(v2->GetType() == _type) ;
989 :
990 6 : switch (_type)
991 : {
992 : case idl_unsigned_short :
993 : {
994 : uint16_t r ;
995 1 : overflow = div_u16(_value_u16, v2->_value_u16, & r) ;
996 1 : result->PutU16(r) ;
997 1 : break ;
998 : }
999 : case idl_signed_short :
1000 : {
1001 : int16_t r ;
1002 1 : overflow = div_s16(_value_s16, v2->_value_s16, & r) ;
1003 1 : result->PutS16(r) ;
1004 1 : break ;
1005 : }
1006 : case idl_unsigned_long :
1007 : {
1008 : uint32_t r ;
1009 1 : overflow = div_u32(_value_u32, v2->_value_u32, & r) ;
1010 1 : result->PutU32(r) ;
1011 1 : break ;
1012 : }
1013 : case idl_signed_long :
1014 : {
1015 : int32_t r ;
1016 1 : overflow = div_s32(_value_s32, v2->_value_s32, & r) ;
1017 1 : result->PutS32(r) ;
1018 1 : break ;
1019 : }
1020 : case idl_unsigned_long_long :
1021 : {
1022 : uint64_t r ;
1023 1 : overflow = div_u64(_value_u64, v2->_value_u64, & r) ;
1024 1 : result->PutU64(r) ;
1025 1 : break ;
1026 : }
1027 : case idl_signed_long_long :
1028 : {
1029 : int64_t r ;
1030 1 : overflow = div_s64(_value_s64, v2->_value_s64, & r) ;
1031 1 : result->PutS64(r) ;
1032 : break ;
1033 : }
1034 : default :
1035 : ASSERT(false) ;
1036 : }
1037 :
1038 6 : if (overflow)
1039 : {
1040 0 : overflowError("/", v) ;
1041 0 : result->SetError() ;
1042 : }
1043 : return result ;
1044 : }
1045 :
1046 57 : IDLValue* IDLIntValue::computeShl(const IDLValue *v)
1047 : {
1048 57 : IDLIntValue *result = new IDLIntValue() ;
1049 : IDLIntValue *v2 = NULL ;
1050 : bool overflow = false ;
1051 :
1052 : ASSERT(v->isA() == idl_intType) ;
1053 57 : v2 = (IDLIntValue*) v ;
1054 : ASSERT(v2->GetType() == _type) ;
1055 :
1056 57 : switch (_type)
1057 : {
1058 : case idl_unsigned_short :
1059 : {
1060 : uint16_t r ;
1061 7 : overflow = shl_u16(_value_u16, v2->_value_u16, & r) ;
1062 7 : result->PutU16(r) ;
1063 7 : break ;
1064 : }
1065 : case idl_signed_short :
1066 : {
1067 : int16_t r ;
1068 12 : overflow = shl_s16(_value_s16, v2->_value_s16, & r) ;
1069 12 : result->PutS16(r) ;
1070 12 : break ;
1071 : }
1072 : case idl_unsigned_long :
1073 : {
1074 : uint32_t r ;
1075 7 : overflow = shl_u32(_value_u32, v2->_value_u32, & r) ;
1076 7 : result->PutU32(r) ;
1077 7 : break ;
1078 : }
1079 : case idl_signed_long :
1080 : {
1081 : int32_t r ;
1082 12 : overflow = shl_s32(_value_s32, v2->_value_s32, & r) ;
1083 12 : result->PutS32(r) ;
1084 12 : break ;
1085 : }
1086 : case idl_unsigned_long_long :
1087 : {
1088 : uint64_t r ;
1089 7 : overflow = shl_u64(_value_u64, v2->_value_u64, & r) ;
1090 7 : result->PutU64(r) ;
1091 7 : break ;
1092 : }
1093 : case idl_signed_long_long :
1094 : {
1095 : int64_t r ;
1096 12 : overflow = shl_s64(_value_s64, v2->_value_s64, & r) ;
1097 12 : result->PutS64(r) ;
1098 : break ;
1099 : }
1100 : default :
1101 : ASSERT(false) ;
1102 : }
1103 :
1104 57 : if (overflow)
1105 : {
1106 27 : overflowError("<<", v) ;
1107 27 : result->SetError() ;
1108 : }
1109 : return result ;
1110 : }
1111 :
1112 6 : IDLValue* IDLIntValue::computeShr(const IDLValue *v)
1113 : {
1114 6 : IDLIntValue *result = new IDLIntValue() ;
1115 : IDLIntValue *v2 = NULL ;
1116 : bool overflow = false ;
1117 :
1118 : ASSERT(v->isA() == idl_intType) ;
1119 6 : v2 = (IDLIntValue*) v ;
1120 : ASSERT(v2->GetType() == _type) ;
1121 :
1122 6 : switch (_type)
1123 : {
1124 : case idl_unsigned_short :
1125 : {
1126 : uint16_t r ;
1127 1 : overflow = shr_u16(_value_u16, v2->_value_u16, & r) ;
1128 1 : result->PutU16(r) ;
1129 1 : break ;
1130 : }
1131 : case idl_signed_short :
1132 : {
1133 : int16_t r ;
1134 1 : overflow = shr_s16(_value_s16, v2->_value_s16, & r) ;
1135 1 : result->PutS16(r) ;
1136 1 : break ;
1137 : }
1138 : case idl_unsigned_long :
1139 : {
1140 : uint32_t r ;
1141 1 : overflow = shr_u32(_value_u32, v2->_value_u32, & r) ;
1142 1 : result->PutU32(r) ;
1143 1 : break ;
1144 : }
1145 : case idl_signed_long :
1146 : {
1147 : int32_t r ;
1148 1 : overflow = shr_s32(_value_s32, v2->_value_s32, & r) ;
1149 1 : result->PutS32(r) ;
1150 1 : break ;
1151 : }
1152 : case idl_unsigned_long_long :
1153 : {
1154 : uint64_t r ;
1155 1 : overflow = shr_u64(_value_u64, v2->_value_u64, & r) ;
1156 1 : result->PutU64(r) ;
1157 1 : break ;
1158 : }
1159 : case idl_signed_long_long :
1160 : {
1161 : int64_t r ;
1162 1 : overflow = shr_s64(_value_s64, v2->_value_s64, & r) ;
1163 1 : result->PutS64(r) ;
1164 : break ;
1165 : }
1166 : default :
1167 : ASSERT(false) ;
1168 : }
1169 :
1170 6 : if (overflow)
1171 : {
1172 0 : overflowError(">>", v) ;
1173 0 : result->SetError() ;
1174 : }
1175 : return result ;
1176 : }
1177 :
1178 6 : IDLValue* IDLIntValue::computeMod(const IDLValue *v)
1179 : {
1180 6 : IDLIntValue *result = new IDLIntValue() ;
1181 : IDLIntValue *v2 = NULL ;
1182 : bool overflow = false ;
1183 :
1184 : ASSERT(v->isA() == idl_intType) ;
1185 6 : v2 = (IDLIntValue*) v ;
1186 : ASSERT(v2->GetType() == _type) ;
1187 :
1188 6 : switch (_type)
1189 : {
1190 : case idl_unsigned_short :
1191 : {
1192 : uint16_t r ;
1193 1 : overflow = mod_u16(_value_u16, v2->_value_u16, & r) ;
1194 1 : result->PutU16(r) ;
1195 1 : break ;
1196 : }
1197 : case idl_signed_short :
1198 : {
1199 : int16_t r ;
1200 1 : overflow = mod_s16(_value_s16, v2->_value_s16, & r) ;
1201 1 : result->PutS16(r) ;
1202 1 : break ;
1203 : }
1204 : case idl_unsigned_long :
1205 : {
1206 : uint32_t r ;
1207 1 : overflow = mod_u32(_value_u32, v2->_value_u32, & r) ;
1208 1 : result->PutU32(r) ;
1209 1 : break ;
1210 : }
1211 : case idl_signed_long :
1212 : {
1213 : int32_t r ;
1214 1 : overflow = mod_s32(_value_s32, v2->_value_s32, & r) ;
1215 1 : result->PutS32(r) ;
1216 1 : break ;
1217 : }
1218 : case idl_unsigned_long_long :
1219 : {
1220 : uint64_t r ;
1221 1 : overflow = mod_u64(_value_u64, v2->_value_u64, & r) ;
1222 1 : result->PutU64(r) ;
1223 1 : break ;
1224 : }
1225 : case idl_signed_long_long :
1226 : {
1227 : int64_t r ;
1228 1 : overflow = mod_s64(_value_s64, v2->_value_s64, & r) ;
1229 1 : result->PutS64(r) ;
1230 : break ;
1231 : }
1232 : default :
1233 : ASSERT(false) ;
1234 : }
1235 :
1236 6 : if (overflow)
1237 : {
1238 0 : overflowError("%", v) ;
1239 0 : result->SetError() ;
1240 : }
1241 : return result ;
1242 : }
1243 :
1244 6 : IDLValue* IDLIntValue::computeOr(const IDLValue *v)
1245 : {
1246 6 : IDLIntValue *result = new IDLIntValue() ;
1247 : IDLIntValue *v2 = NULL ;
1248 :
1249 : ASSERT(v->isA() == idl_intType) ;
1250 6 : v2 = (IDLIntValue*) v ;
1251 : ASSERT(v2->GetType() == _type) ;
1252 :
1253 6 : switch (_type)
1254 : {
1255 : case idl_unsigned_short :
1256 : {
1257 : uint16_t r ;
1258 1 : or_u16(_value_u16, v2->_value_u16, & r) ;
1259 1 : result->PutU16(r) ;
1260 1 : break ;
1261 : }
1262 : case idl_signed_short :
1263 : {
1264 : int16_t r ;
1265 1 : or_s16(_value_s16, v2->_value_s16, & r) ;
1266 1 : result->PutS16(r) ;
1267 1 : break ;
1268 : }
1269 : case idl_unsigned_long :
1270 : {
1271 : uint32_t r ;
1272 1 : or_u32(_value_u32, v2->_value_u32, & r) ;
1273 1 : result->PutU32(r) ;
1274 1 : break ;
1275 : }
1276 : case idl_signed_long :
1277 : {
1278 : int32_t r ;
1279 1 : or_s32(_value_s32, v2->_value_s32, & r) ;
1280 1 : result->PutS32(r) ;
1281 1 : break ;
1282 : }
1283 : case idl_unsigned_long_long :
1284 : {
1285 : uint64_t r ;
1286 1 : or_u64(_value_u64, v2->_value_u64, & r) ;
1287 1 : result->PutU64(r) ;
1288 1 : break ;
1289 : }
1290 : case idl_signed_long_long :
1291 : {
1292 : int64_t r ;
1293 1 : or_s64(_value_s64, v2->_value_s64, & r) ;
1294 1 : result->PutS64(r) ;
1295 : break ;
1296 : }
1297 : default :
1298 : ASSERT(false) ;
1299 : }
1300 :
1301 : return result ;
1302 : }
1303 :
1304 6 : IDLValue* IDLIntValue::computeXor(const IDLValue *v)
1305 : {
1306 6 : IDLIntValue *result = new IDLIntValue() ;
1307 : IDLIntValue *v2 = NULL ;
1308 :
1309 : ASSERT(v->isA() == idl_intType) ;
1310 6 : v2 = (IDLIntValue*) v ;
1311 : ASSERT(v2->GetType() == _type) ;
1312 :
1313 6 : switch (_type)
1314 : {
1315 : case idl_unsigned_short :
1316 : {
1317 : uint16_t r ;
1318 1 : xor_u16(_value_u16, v2->_value_u16, & r) ;
1319 1 : result->PutU16(r) ;
1320 1 : break ;
1321 : }
1322 : case idl_signed_short :
1323 : {
1324 : int16_t r ;
1325 1 : xor_s16(_value_s16, v2->_value_s16, & r) ;
1326 1 : result->PutS16(r) ;
1327 1 : break ;
1328 : }
1329 : case idl_unsigned_long :
1330 : {
1331 : uint32_t r ;
1332 1 : xor_u32(_value_u32, v2->_value_u32, & r) ;
1333 1 : result->PutU32(r) ;
1334 1 : break ;
1335 : }
1336 : case idl_signed_long :
1337 : {
1338 : int32_t r ;
1339 1 : xor_s32(_value_s32, v2->_value_s32, & r) ;
1340 1 : result->PutS32(r) ;
1341 1 : break ;
1342 : }
1343 : case idl_unsigned_long_long :
1344 : {
1345 : uint64_t r ;
1346 1 : xor_u64(_value_u64, v2->_value_u64, & r) ;
1347 1 : result->PutU64(r) ;
1348 1 : break ;
1349 : }
1350 : case idl_signed_long_long :
1351 : {
1352 : int64_t r ;
1353 1 : xor_s64(_value_s64, v2->_value_s64, & r) ;
1354 1 : result->PutS64(r) ;
1355 : break ;
1356 : }
1357 : default :
1358 : ASSERT(false) ;
1359 : }
1360 :
1361 : return result ;
1362 : }
1363 :
1364 6 : IDLValue* IDLIntValue::computeAnd(const IDLValue *v)
1365 : {
1366 6 : IDLIntValue *result = new IDLIntValue() ;
1367 : IDLIntValue *v2 = NULL ;
1368 :
1369 : ASSERT(v->isA() == idl_intType) ;
1370 6 : v2 = (IDLIntValue*) v ;
1371 : ASSERT(v2->GetType() == _type) ;
1372 :
1373 6 : switch (_type)
1374 : {
1375 : case idl_unsigned_short :
1376 : {
1377 : uint16_t r ;
1378 1 : and_u16(_value_u16, v2->_value_u16, & r) ;
1379 1 : result->PutU16(r) ;
1380 1 : break ;
1381 : }
1382 : case idl_signed_short :
1383 : {
1384 : int16_t r ;
1385 1 : and_s16(_value_s16, v2->_value_s16, & r) ;
1386 1 : result->PutS16(r) ;
1387 1 : break ;
1388 : }
1389 : case idl_unsigned_long :
1390 : {
1391 : uint32_t r ;
1392 1 : and_u32(_value_u32, v2->_value_u32, & r) ;
1393 1 : result->PutU32(r) ;
1394 1 : break ;
1395 : }
1396 : case idl_signed_long :
1397 : {
1398 : int32_t r ;
1399 1 : and_s32(_value_s32, v2->_value_s32, & r) ;
1400 1 : result->PutS32(r) ;
1401 1 : break ;
1402 : }
1403 : case idl_unsigned_long_long :
1404 : {
1405 : uint64_t r ;
1406 1 : and_u64(_value_u64, v2->_value_u64, & r) ;
1407 1 : result->PutU64(r) ;
1408 1 : break ;
1409 : }
1410 : case idl_signed_long_long :
1411 : {
1412 : int64_t r ;
1413 1 : and_s64(_value_s64, v2->_value_s64, & r) ;
1414 1 : result->PutS64(r) ;
1415 : break ;
1416 : }
1417 : default :
1418 : ASSERT(false) ;
1419 : }
1420 :
1421 : return result ;
1422 : }
1423 :
1424 64 : IDLValue* IDLIntValue::computeMinus(void)
1425 : {
1426 64 : IDLIntValue *result = new IDLIntValue() ;
1427 : bool overflow = false ;
1428 :
1429 64 : switch (_type)
1430 : {
1431 : case idl_unsigned_short :
1432 : {
1433 3 : if (_value_u16 == 0)
1434 : {
1435 1 : result->PutU16(0) ;
1436 : }
1437 : else
1438 : {
1439 : overflow = true ;
1440 : }
1441 : break ;
1442 : }
1443 : case idl_signed_short :
1444 : {
1445 : int16_t r = - _value_s16 ;
1446 17 : result->PutS16(r) ;
1447 17 : break ;
1448 : }
1449 : case idl_unsigned_long :
1450 : {
1451 3 : if (_value_u32 == 0)
1452 : {
1453 1 : result->PutU32(0) ;
1454 : }
1455 : else
1456 : {
1457 : overflow = true ;
1458 : }
1459 : break ;
1460 : }
1461 : case idl_signed_long :
1462 : {
1463 : int32_t r = - _value_s32 ;
1464 18 : result->PutS32(r) ;
1465 18 : break ;
1466 : }
1467 : case idl_unsigned_long_long :
1468 : {
1469 3 : if (_value_u64 == 0)
1470 : {
1471 1 : result->PutU64(0) ;
1472 : }
1473 : else
1474 : {
1475 : overflow = true ;
1476 : }
1477 : break ;
1478 : }
1479 : case idl_signed_long_long :
1480 : {
1481 : int64_t r = - _value_s64 ;
1482 20 : result->PutS64(r) ;
1483 : break ;
1484 : }
1485 : default :
1486 : ASSERT(false) ;
1487 : }
1488 :
1489 : if (overflow)
1490 : {
1491 6 : overflowError("-") ;
1492 6 : result->SetError() ;
1493 : }
1494 : return result ;
1495 : }
1496 :
1497 6 : IDLValue* IDLIntValue::computeNeg(void)
1498 : {
1499 6 : NON_DEV("computeNeg") ;
1500 6 : return new IDLIntValue() ;
1501 63 : }
1502 63 :
|