1 /*
2 * Copyright (c) 1995 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 */
14
15 #include "pmapi.h"
16 #include "impl.h"
17 #include <math.h>
18 #include <inttypes.h>
19
20 #ifndef ABS
21 #define ABS(a) ((a) < 0 ? -(a) : (a))
22 #endif
23
24 #if defined(HAVE_CONST_LONGLONG)
25 #define SIGN_64_MASK 0x8000000000000000LL
26 #else
27 #define SIGN_64_MASK 0x8000000000000000
28 #endif
29
30 /* pmAtomValue -> string, max length is 40 bytes */
31 const char *
32 pmAtomStr(const pmAtomValue *avp, int type)
33 {
34 int i;
35 static char buf[80];
36 pmAtomValue av;
37 int vlen;
38
39 /* avoid alignment problems ... avp may be unaligned! */
40 memcpy((void *)&av, (void *)avp, sizeof(av));
41
42 switch (type) {
43 case PM_TYPE_32:
44 snprintf(buf, sizeof(buf), "%d", av.l);
45 break;
46 case PM_TYPE_U32:
47 snprintf(buf, sizeof(buf), "%u", av.ul);
48 break;
49 case PM_TYPE_64:
50 snprintf(buf, sizeof(buf), "%"PRIi64, av.ll);
51 break;
52 case PM_TYPE_U64:
53 snprintf(buf, sizeof(buf), "%"PRIu64, av.ull);
54 break;
55 case PM_TYPE_FLOAT:
56 snprintf(buf, sizeof(buf), "%e", (double)av.f);
57 break;
58 case PM_TYPE_DOUBLE:
59 snprintf(buf, sizeof(buf), "%e", av.d);
60 break;
61 case PM_TYPE_STRING:
62 if (av.cp == NULL)
63 snprintf(buf, sizeof(buf), "<null>");
64 else {
65 i = (int)strlen(av.cp);
66 if (i < 38)
67 snprintf(buf, sizeof(buf), "\"%s\"", av.cp);
68 else
69 snprintf(buf, sizeof(buf), "\"%34.34s...\"", av.cp);
70 }
71 break;
72 case PM_TYPE_AGGREGATE:
73 case PM_TYPE_AGGREGATE_STATIC:
74 if (av.vbp == NULL) {
75 snprintf(buf, sizeof(buf), "<null>");
76 break;
77 }
78 vlen = av.vbp->vlen - PM_VAL_HDR_SIZE;
79 if (vlen == 0)
80 snprintf(buf, sizeof(buf), "[type=%s len=%d]", pmTypeStr(av.vbp->vtype), vlen);
81 else {
82 char *cp;
83 char *bp;
84 snprintf(buf, sizeof(buf), "[type=%s len=%d]", pmTypeStr(av.vbp->vtype), vlen);
85 cp = (char *)av.vbp->vbuf;
86 for (i = 0; i < vlen && i < 12; i++) {
87 bp = &buf[strlen(buf)];
88 if ((i % 4) == 0)
89 snprintf(bp, sizeof(buf) - (bp-buf), " %02x", *cp & 0xff);
90 else
91 snprintf(bp, sizeof(buf) - (bp-buf), "%02x", *cp & 0xff);
92 cp++;
93 }
94 if (vlen > 12) {
95 bp = &buf[strlen(buf)];
96 snprintf(bp, sizeof(buf) - (bp-buf), " ...");
97 }
98 }
99 break;
100 case PM_TYPE_EVENT:
101 {
102 /* have to assume alignment is OK in this case */
103 pmEventArray *eap = (pmEventArray *)avp->vbp;
104 if (eap->ea_nrecords == 1)
105 snprintf(buf, sizeof(buf), "[1 event record]");
106 else
107 snprintf(buf, sizeof(buf), "[%d event records]", eap->ea_nrecords);
108 }
109 break;
110 default:
111 snprintf(buf, sizeof(buf), "Error: unexpected type: %s", pmTypeStr(type));
112 }
113 return buf;
114 }
115
116 /*
117 * must be in agreement with ordinal values for PM_TYPE_* #defines
118 */
119 static char *typename[] = {
120 "32", "U32", "64", "U64", "FLOAT", "DOUBLE", "STRING", "AGGREGATE", "AGGREGATE_STATIC", "EVENT"
121 };
122
123 /* PM_TYPE_* -> string, max length is 20 bytes */
124 const char *
125 pmTypeStr(int type)
126 {
127 static char buf[30];
128 if (type >= 0 && type < sizeof(typename)/sizeof(typename[0]))
129 snprintf(buf, sizeof(buf), "%s", typename[type]);
130 else if (type == PM_TYPE_NOSUPPORT)
131 strcpy(buf, "Not Supported");
132 else if (type == PM_TYPE_UNKNOWN)
133 strcpy(buf, "Unknown");
134 else
135 snprintf(buf, sizeof(buf), "Illegal type=%d", type);
136
137 return buf;
138 }
139
140 /* scale+units -> string, max length is 60 bytes */
141 const char *
142 pmUnitsStr(const pmUnits *pu)
143 {
144 char *spacestr = NULL;
145 char *timestr = NULL;
146 char *countstr = NULL;
147 char *p;
148 char sbuf[20];
149 char tbuf[20];
150 char cbuf[20];
151 static char buf[60];
152
153 buf[0] = '\0';
154
155 if (pu->dimSpace) {
156 switch (pu->scaleSpace) {
157 case PM_SPACE_BYTE:
158 spacestr = "byte";
159 break;
160 case PM_SPACE_KBYTE:
161 spacestr = "Kbyte";
162 break;
163 case PM_SPACE_MBYTE:
164 spacestr = "Mbyte";
165 break;
166 case PM_SPACE_GBYTE:
167 spacestr = "Gbyte";
168 break;
169 case PM_SPACE_TBYTE:
170 spacestr = "Tbyte";
171 break;
172 case PM_SPACE_PBYTE:
173 spacestr = "Pbyte";
174 break;
175 case PM_SPACE_EBYTE:
176 spacestr = "Ebyte";
177 break;
178 default:
179 snprintf(sbuf, sizeof(sbuf), "space-%d", pu->scaleSpace);
180 spacestr = sbuf;
181 break;
182 }
183 }
184 if (pu->dimTime) {
185 switch (pu->scaleTime) {
186 case PM_TIME_NSEC:
187 timestr = "nanosec";
188 break;
189 case PM_TIME_USEC:
190 timestr = "microsec";
191 break;
192 case PM_TIME_MSEC:
193 timestr = "millisec";
194 break;
195 case PM_TIME_SEC:
196 timestr = "sec";
197 break;
198 case PM_TIME_MIN:
199 timestr = "min";
200 break;
201 case PM_TIME_HOUR:
202 timestr = "hour";
203 break;
204 default:
205 snprintf(tbuf, sizeof(tbuf), "time-%d", pu->scaleTime);
206 timestr = tbuf;
207 break;
208 }
209 }
210 if (pu->dimCount) {
211 switch (pu->scaleCount) {
212 case 0:
213 countstr = "count";
214 break;
215 case 1:
216 snprintf(cbuf, sizeof(cbuf), "count x 10");
217 countstr = cbuf;
218 break;
219 default:
220 snprintf(cbuf, sizeof(cbuf), "count x 10^%d", pu->scaleCount);
221 countstr = cbuf;
222 break;
223 }
224 }
225
226 p = buf;
227
228 if (pu->dimSpace > 0) {
229 if (pu->dimSpace == 1)
230 snprintf(p, sizeof(buf), "%s", spacestr);
231 else
232 snprintf(p, sizeof(buf), "%s^%d", spacestr, pu->dimSpace);
233 while (*p) p++;
234 *p++ = ' ';
235 }
236 if (pu->dimTime > 0) {
237 if (pu->dimTime == 1)
238 snprintf(p, sizeof(buf) - (p - buf), "%s", timestr);
239 else
240 snprintf(p, sizeof(buf) - (p - buf), "%s^%d", timestr, pu->dimTime);
241 while (*p) p++;
242 *p++ = ' ';
243 }
244 if (pu->dimCount > 0) {
245 if (pu->dimCount == 1)
246 snprintf(p, sizeof(buf) - (p - buf), "%s", countstr);
247 else
248 snprintf(p, sizeof(buf) - (p - buf), "%s^%d", countstr, pu->dimCount);
249 while (*p) p++;
250 *p++ = ' ';
251 }
252 if (pu->dimSpace < 0 || pu->dimTime < 0 || pu->dimCount < 0) {
253 *p++ = '/';
254 *p++ = ' ';
255 if (pu->dimSpace < 0) {
256 if (pu->dimSpace == -1)
257 snprintf(p, sizeof(buf) - (p - buf), "%s", spacestr);
258 else
259 snprintf(p, sizeof(buf) - (p - buf), "%s^%d", spacestr, -pu->dimSpace);
260 while (*p) p++;
261 *p++ = ' ';
262 }
263 if (pu->dimTime < 0) {
264 if (pu->dimTime == -1)
265 snprintf(p, sizeof(buf) - (p - buf), "%s", timestr);
266 else
267 snprintf(p, sizeof(buf) - (p - buf), "%s^%d", timestr, -pu->dimTime);
268 while (*p) p++;
269 *p++ = ' ';
270 }
271 if (pu->dimCount < 0) {
272 if (pu->dimCount == -1)
273 snprintf(p, sizeof(buf) - (p - buf), "%s", countstr);
274 else
275 snprintf(p, sizeof(buf) - (p - buf), "%s^%d", countstr, -pu->dimCount);
276 while (*p) p++;
277 *p++ = ' ';
278 }
279 }
280
281 if (buf[0] == '\0') {
282 /*
283 * dimension is all 0, but scale maybe specified ... small
284 * anomaly here as we would expect dimCount to be 1 not
285 * 0 for these cases, but support maintained for historical
286 * behaviour
287 */
288 if (pu->scaleCount == 1)
289 snprintf(buf, sizeof(buf), "x 10");
290 else if (pu->scaleCount != 0)
291 snprintf(buf, sizeof(buf), "x 10^%d", pu->scaleCount);
292 }
293 else {
294 p--;
295 *p = '\0';
296 }
297
298 return buf;
299 }
300
301 /* Scale conversion, based on value format, value type and scale */
302 int
303 pmConvScale(int type, const pmAtomValue *ival, const pmUnits *iunit,
304 pmAtomValue *oval, const pmUnits *ounit)
305 {
306 int sts;
307 int k;
308 __int64_t div, mult;
309 __int64_t d, m;
310
311 #ifdef PCP_DEBUG
312 if (pmDebug & DBG_TRACE_VALUE) {
313 fprintf(stderr, "pmConvScale: %s", pmAtomStr(ival, type));
314 fprintf(stderr, " [%s]", pmUnitsStr(iunit));
315 }
316 #endif
317
318 if (iunit->dimSpace != ounit->dimSpace ||
319 iunit->dimTime != ounit->dimTime ||
320 iunit->dimCount != ounit->dimCount) {
321 sts = PM_ERR_CONV;
322 goto bad;
323 }
324
325 div = mult = 1;
326
327 if (iunit->dimSpace) {
328 d = 1;
329 m = 1;
330 switch (iunit->scaleSpace) {
331 case PM_SPACE_BYTE:
332 d = 1024 * 1024;
333 break;
334 case PM_SPACE_KBYTE:
335 d = 1024;
336 break;
337 case PM_SPACE_MBYTE:
338 /* the canonical unit */
339 break;
340 case PM_SPACE_GBYTE:
341 m = 1024;
342 break;
343 case PM_SPACE_TBYTE:
344 m = 1024 * 1024;
345 break;
346 case PM_SPACE_PBYTE:
347 m = 1024 * 1024 * 1024;
348 break;
349 case PM_SPACE_EBYTE:
350 m = (__int64_t)1024 * 1024 * 1024 * 1024;
351 break;
352 default:
353 sts = PM_ERR_UNIT;
354 goto bad;
355 }
356 switch (ounit->scaleSpace) {
357 case PM_SPACE_BYTE:
358 m *= 1024 * 1024;
359 break;
360 case PM_SPACE_KBYTE:
361 m *= 1024;
362 break;
363 case PM_SPACE_MBYTE:
364 /* the canonical unit */
365 break;
366 case PM_SPACE_GBYTE:
367 d *= 1024;
368 break;
369 case PM_SPACE_TBYTE:
370 d *= 1024 * 1024;
371 break;
372 case PM_SPACE_PBYTE:
373 d *= 1024 * 1024 * 1024;
374 break;
375 case PM_SPACE_EBYTE:
376 d *= (__int64_t)1024 * 1024 * 1024 * 1024;
377 break;
378 default:
379 sts = PM_ERR_UNIT;
380 goto bad;
381 }
382 if (iunit->dimSpace > 0) {
383 for (k = 0; k < iunit->dimSpace; k++) {
384 div *= d;
385 mult *= m;
386 }
387 }
388 else {
389 for (k = iunit->dimSpace; k < 0; k++) {
390 mult *= d;
391 div *= m;
392 }
393 }
394 }
395
396 if (iunit->dimTime) {
397 d = 1;
398 m = 1;
399 switch (iunit->scaleTime) {
400 case PM_TIME_NSEC:
401 d = 1000000000;
402 break;
403 case PM_TIME_USEC:
404 d = 1000000;
405 break;
406 case PM_TIME_MSEC:
407 d = 1000;
408 break;
409 case PM_TIME_SEC:
410 /* the canonical unit */
411 break;
412 case PM_TIME_MIN:
413 m = 60;
414 break;
415 case PM_TIME_HOUR:
416 m = 3600;
417 break;
418 default:
419 sts = PM_ERR_UNIT;
420 goto bad;
421 }
422 switch (ounit->scaleTime) {
423 case PM_TIME_NSEC:
424 m *= 1000000000;
425 break;
426 case PM_TIME_USEC:
427 m *= 1000000;
428 break;
429 case PM_TIME_MSEC:
430 m *= 1000;
431 break;
432 case PM_TIME_SEC:
433 /* the canonical unit */
434 break;
435 case PM_TIME_MIN:
436 d *= 60;
437 break;
438 case PM_TIME_HOUR:
439 d *= 3600;
440 break;
441 default:
442 sts = PM_ERR_UNIT;
443 goto bad;
444 }
445 if (iunit->dimTime > 0) {
446 for (k = 0; k < iunit->dimTime; k++) {
447 div *= d;
448 mult *= m;
449 }
450 }
451 else {
452 for (k = iunit->dimTime; k < 0; k++) {
453 mult *= d;
454 div *= m;
455 }
456 }
457 }
458
459 if (iunit->dimCount ||
460 (iunit->dimSpace == 0 && iunit->dimTime == 0)) {
461 d = 1;
462 m = 1;
463 if (iunit->scaleCount < 0) {
464 for (k = iunit->scaleCount; k < 0; k++)
465 d *= 10;
466 }
467 else if (iunit->scaleCount > 0) {
468 for (k = 0; k < iunit->scaleCount; k++)
469 m *= 10;
470 }
471 if (ounit->scaleCount < 0) {
472 for (k = ounit->scaleCount; k < 0; k++)
473 m *= 10;
474 }
475 else if (ounit->scaleCount > 0) {
476 for (k = 0; k < ounit->scaleCount; k++)
477 d *= 10;
478 }
479 if (iunit->dimCount > 0) {
480 for (k = 0; k < iunit->dimCount; k++) {
481 div *= d;
482 mult *= m;
483 }
484 }
485 else if (iunit->dimCount < 0) {
486 for (k = iunit->dimCount; k < 0; k++) {
487 mult *= d;
488 div *= m;
489 }
490 }
491 else {
492 mult = m;
493 div = d;
494 }
495 }
496
497 if (mult % div == 0) {
498 mult /= div;
499 div = 1;
500 }
501
502 switch (type) {
503 case PM_TYPE_32:
504 oval->l = (__int32_t)((ival->l * mult + div/2) / div);
505 break;
506 case PM_TYPE_U32:
507 oval->ul = (__uint32_t)((ival->ul * mult + div/2) / div);
508 break;
509 case PM_TYPE_64:
510 oval->ll = (ival->ll * mult + div/2) / div;
511 break;
512 case PM_TYPE_U64:
513 oval->ull = (ival->ull * mult + div/2) / div;
514 break;
515 case PM_TYPE_FLOAT:
516 oval->f = ival->f * ((float)mult / (float)div);
517 break;
518 case PM_TYPE_DOUBLE:
519 oval->d = ival->d * ((double)mult / (double)div);
520 break;
521 default:
522 sts = PM_ERR_CONV;
523 goto bad;
524 }
525
526 #ifdef PCP_DEBUG
527 if (pmDebug & DBG_TRACE_VALUE) {
528 fprintf(stderr, " -> %s", pmAtomStr(oval, type));
529 fprintf(stderr, " [%s]\n", pmUnitsStr(ounit));
530 }
531 #endif
532 return 0;
533
534 bad:
535 #ifdef PCP_DEBUG
536 if (pmDebug & DBG_TRACE_VALUE) {
537 fprintf(stderr, " -> Error: %s", pmErrStr(sts));
538 fprintf(stderr, " [%s]\n", pmUnitsStr(ounit));
539 }
540 #endif
541 return sts;
542 }
543
544 /* Value extract from pmValue and type conversion */
545 int
546 pmExtractValue(int valfmt, const pmValue *ival, int itype,
547 pmAtomValue *oval, int otype)
548 {
549 pmAtomValue *ap;
550 pmAtomValue av;
551 int sts = 0;
552 int len;
553 const char *vp;
554 static char buf[80];
555
556 #ifdef PCP_DEBUG
557 if (pmDebug & DBG_TRACE_VALUE) {
558 fprintf(stderr, "pmExtractValue: ");
559 vp = "???";
560 }
561 #endif
562
563 oval->ll = 0;
564 if (valfmt == PM_VAL_INSITU) {
565 av.l = ival->value.lval;
566 #ifdef PCP_DEBUG
567 if (pmDebug & DBG_TRACE_VALUE)
568 vp = pmAtomStr(&av, itype);
569 #endif
570 switch (itype) {
571
572 case PM_TYPE_32:
573 case PM_TYPE_UNKNOWN:
574 switch (otype) {
575 case PM_TYPE_32:
576 oval->l = av.l;
577 break;
578 case PM_TYPE_U32:
579 if (av.l < 0)
580 sts = PM_ERR_SIGN;
581 else
582 oval->ul = (__uint32_t)av.l;
583 break;
584 case PM_TYPE_64:
585 oval->ll = (__int64_t)av.l;
586 break;
587 case PM_TYPE_U64:
588 if (av.l < 0)
589 sts = PM_ERR_SIGN;
590 else
591 oval->ull = (__uint64_t)av.l;
592 break;
593 case PM_TYPE_FLOAT:
594 oval->f = (float)av.l;
595 break;
596 case PM_TYPE_DOUBLE:
597 oval->d = (double)av.l;
598 break;
599 default:
600 sts = PM_ERR_CONV;
601 }
602 break;
603
604 case PM_TYPE_U32:
605 switch (otype) {
606 case PM_TYPE_32:
607 if (av.ul > 0x7fffffff)
608 sts = PM_ERR_TRUNC;
609 else
610 oval->l = (__int32_t)av.ul;
611 break;
612 case PM_TYPE_U32:
613 oval->ul = (__uint32_t)av.ul;
614 break;
615 case PM_TYPE_64:
616 oval->ll = (__int64_t)av.ul;
617 break;
618 case PM_TYPE_U64:
619 oval->ull = (__uint64_t)av.ul;
620 break;
621 case PM_TYPE_FLOAT:
622 oval->f = (float)av.ul;
623 break;
624 case PM_TYPE_DOUBLE:
625 oval->d = (double)av.ul;
626 break;
627 default:
628 sts = PM_ERR_CONV;
629 }
630 break;
631
632 /*
633 * Notes on conversion to FLOAT ... because of the limited
634 * precision of the mantissa, more than one integer value
635 * maps to the same floating point value ... hence the
636 * >= (float)max-int-value style of tests
637 */
638 case PM_TYPE_FLOAT: /* old style insitu encoding */
639 switch (otype) {
640 case PM_TYPE_32:
641 if ((float)ABS(av.f) >= (float)0x7fffffff)
642 sts = PM_ERR_TRUNC;
643 else
644 oval->l = (__int32_t)av.f;
645 break;
646 case PM_TYPE_U32:
647 if (av.f >= (float)((unsigned)0xffffffff))
648 sts = PM_ERR_TRUNC;
649 else if (av.f < 0)
650 sts = PM_ERR_SIGN;
651 else
652 oval->ul = (__uint32_t)av.f;
653 break;
654 case PM_TYPE_64:
655 #if defined(HAVE_CONST_LONGLONG)
656 if (av.f >= (float)0x7fffffffffffffffLL)
657 sts = PM_ERR_TRUNC;
658 #else
659 if (av.f >= (float)0x7fffffffffffffff)
660 sts = PM_ERR_TRUNC;
661 #endif
662 else
663 oval->ll = (__int64_t)av.f;
664 break;
665 case PM_TYPE_U64:
666 #if defined(HAVE_CONST_LONGLONG)
667 if (av.f >= (float)((__uint64_t)0xffffffffffffffffLL))
668 sts = PM_ERR_TRUNC;
669 #else
670 if (av.f >= (float)((__uint64_t)0xffffffffffffffff))
671 sts = PM_ERR_TRUNC;
672 #endif
673 else if (av.f < 0)
674 sts = PM_ERR_SIGN;
675 else
676 oval->ull = (__uint64_t)av.f;
677 break;
678 case PM_TYPE_FLOAT:
679 oval->f = av.f;
680 break;
681 case PM_TYPE_DOUBLE:
682 oval->d = (double)av.f;
683 break;
684 default:
685 sts = PM_ERR_CONV;
686 }
687 break;
688
689 case PM_TYPE_64:
690 case PM_TYPE_U64:
691 case PM_TYPE_DOUBLE:
692 case PM_TYPE_STRING:
693 case PM_TYPE_AGGREGATE:
694 case PM_TYPE_EVENT:
695 default:
696 sts = PM_ERR_CONV;
697 }
698 }
699 else if (valfmt == PM_VAL_DPTR || valfmt == PM_VAL_SPTR) {
700 __int64_t src;
701 __uint64_t usrc;
702 double dsrc;
703 float fsrc;
704 switch (itype) {
705
706 case PM_TYPE_64:
707 if (ival->value.pval->vlen != PM_VAL_HDR_SIZE + sizeof(__int64_t) ||
708 (ival->value.pval->vtype != PM_TYPE_64 &&
709 ival->value.pval->vtype != 0)) {
710 sts = PM_ERR_CONV;
711 break;
712 }
713 ap = (pmAtomValue *)&ival->value.pval->vbuf;
714 #ifdef PCP_DEBUG
715 if (pmDebug & DBG_TRACE_VALUE)
716 vp = pmAtomStr(ap, itype);
717 #endif
718 memcpy((void *)&src, (void *)ap, sizeof(src));
719 switch (otype) {
720 case PM_TYPE_32:
721 if (src > 0x7fffffff)
722 sts = PM_ERR_TRUNC;
723 else
724 oval->l = (__int32_t)src;
725 break;
726 case PM_TYPE_U32:
727 if (src > (unsigned)0xffffffff)
728 sts = PM_ERR_TRUNC;
729 else if (src < 0)
730 sts = PM_ERR_SIGN;
731 else
732 oval->ul = (__uint32_t)src;
733 break;
734 case PM_TYPE_64:
735 oval->ll = src;
736 break;
737 case PM_TYPE_U64:
738 if (src < 0)
739 sts = PM_ERR_SIGN;
740 else
741 oval->ull = (__uint64_t)src;
742 break;
743 case PM_TYPE_FLOAT:
744 oval->f = (float)src;
745 break;
746 case PM_TYPE_DOUBLE:
747 oval->d = (double)src;
748 break;
749 default:
750 sts = PM_ERR_CONV;
751 }
752 break;
753
754 case PM_TYPE_U64:
755 if (ival->value.pval->vlen != PM_VAL_HDR_SIZE + sizeof(__uint64_t) ||
756 (ival->value.pval->vtype != PM_TYPE_U64 &&
757 ival->value.pval->vtype != 0)) {
758 sts = PM_ERR_CONV;
759 break;
760 }
761 ap = (pmAtomValue *)&ival->value.pval->vbuf;
762 #ifdef PCP_DEBUG
763 if (pmDebug & DBG_TRACE_VALUE)
764 vp = pmAtomStr(ap, itype);
765 #endif
766 memcpy((void *)&usrc, (void *)ap, sizeof(usrc));
767 switch (otype) {
768 case PM_TYPE_32:
769 if (usrc > 0x7fffffff)
770 sts = PM_ERR_TRUNC;
771 else
772 oval->l = (__int32_t)usrc;
773 break;
774 case PM_TYPE_U32:
775 if (usrc > (unsigned)0xffffffff)
776 sts = PM_ERR_TRUNC;
777 else
778 oval->ul = (__uint32_t)usrc;
779 break;
780 case PM_TYPE_64:
781 #if defined(HAVE_CONST_LONGLONG)
782 if (usrc > (__int64_t)0x7fffffffffffffffLL)
783 sts = PM_ERR_TRUNC;
784 #else
785 if (usrc > (__int64_t)0x7fffffffffffffff)
786 sts = PM_ERR_TRUNC;
787 #endif
788 else
789 oval->ll = (__int64_t)usrc;
790 break;
791 case PM_TYPE_U64:
792 oval->ull = usrc;
793 break;
794 case PM_TYPE_FLOAT:
795 #if !defined(HAVE_CAST_U64_DOUBLE)
796 if (SIGN_64_MASK & usrc)
797 oval->f = (float)(__int64_t)(usrc & (~SIGN_64_MASK)) + (__uint64_t)SIGN_64_MASK;
798 else
799 oval->f = (float)(__int64_t)usrc;
800 #else
801 oval->f = (float)usrc;
802 #endif
803 break;
804 case PM_TYPE_DOUBLE:
805 #if !defined(HAVE_CAST_U64_DOUBLE)
806 if (SIGN_64_MASK & usrc)
807 oval->d = (double)(__int64_t)(usrc & (~SIGN_64_MASK)) + (__uint64_t)SIGN_64_MASK;
808 else
809 oval->d = (double)(__int64_t)usrc;
810 #else
811 oval->d = (double)usrc;
812 #endif
813 break;
814 default:
815 sts = PM_ERR_CONV;
816 }
817 break;
818
819 case PM_TYPE_DOUBLE:
820 if (ival->value.pval->vlen != PM_VAL_HDR_SIZE + sizeof(double) ||
821 (ival->value.pval->vtype != PM_TYPE_DOUBLE &&
822 ival->value.pval->vtype != 0)) {
823 sts = PM_ERR_CONV;
824 break;
825 }
826 ap = (pmAtomValue *)&ival->value.pval->vbuf;
827 #ifdef PCP_DEBUG
828 if (pmDebug & DBG_TRACE_VALUE)
829 vp = pmAtomStr(ap, itype);
830 #endif
831 memcpy((void *)&dsrc, (void *)ap, sizeof(dsrc));
832 switch (otype) {
833 case PM_TYPE_32:
834 if (ABS(dsrc) >= (double)0x7fffffff)
835 sts = PM_ERR_TRUNC;
836 else
837 oval->l = (__int32_t)dsrc;
838 break;
839 case PM_TYPE_U32:
840 if (dsrc >= (double)((unsigned)0xffffffff))
841 sts = PM_ERR_TRUNC;
842 else if (dsrc < 0)
843 sts = PM_ERR_SIGN;
844 else
845 oval->ul = (__uint32_t)dsrc;
846 break;
847 case PM_TYPE_64:
848 #if defined(HAVE_CONST_LONGLONG)
849 if (dsrc >= (double)0x7fffffffffffffffLL)
850 sts = PM_ERR_TRUNC;
851 #else
852 if (dsrc >= (double)0x7fffffffffffffff)
853 sts = PM_ERR_TRUNC;
854 #endif
855 else
856 oval->ll = (__int64_t)dsrc;
857 break;
858 case PM_TYPE_U64:
859 #if defined(HAVE_CONST_LONGLONG)
860 if (dsrc >= (double)((__uint64_t)0xffffffffffffffffLL))
861 sts = PM_ERR_TRUNC;
862 #else
863 if (dsrc >= (double)((__uint64_t)0xffffffffffffffff))
864 sts = PM_ERR_TRUNC;
865 #endif
866 else if (dsrc < 0)
867 sts = PM_ERR_SIGN;
868 else
869 oval->ull = (__uint64_t)dsrc;
870 break;
871 case PM_TYPE_FLOAT:
872 oval->f = (float)dsrc;
873 break;
874 case PM_TYPE_DOUBLE:
875 oval->d = dsrc;
876 break;
877 default:
878 sts = PM_ERR_CONV;
879 }
880 break;
881
882 case PM_TYPE_FLOAT: /* new style pmValueBlock encoding */
883 if (ival->value.pval->vlen != PM_VAL_HDR_SIZE + sizeof(float) ||
884 (ival->value.pval->vtype != PM_TYPE_FLOAT &&
885 ival->value.pval->vtype != 0)) {
886 sts = PM_ERR_CONV;
887 break;
888 }
889 ap = (pmAtomValue *)&ival->value.pval->vbuf;
890 #ifdef PCP_DEBUG
891 if (pmDebug & DBG_TRACE_VALUE)
892 vp = pmAtomStr(ap, itype);
893 #endif
894 memcpy((void *)&fsrc, (void *)ap, sizeof(fsrc));
895 switch (otype) {
896 case PM_TYPE_32:
897 if ((float)ABS(fsrc) >= (float)0x7fffffff)
898 sts = PM_ERR_TRUNC;
899 else
900 oval->l = (__int32_t)fsrc;
901 break;
902 case PM_TYPE_U32:
903 if (fsrc >= (float)((unsigned)0xffffffff))
904 sts = PM_ERR_TRUNC;
905 else if (fsrc < 0)
906 sts = PM_ERR_SIGN;
907 else
908 oval->ul = (__uint32_t)fsrc;
909 break;
910 case PM_TYPE_64:
911 #if defined(HAVE_CONST_LONGLONG)
912 if (fsrc >= (float)0x7fffffffffffffffLL)
913 sts = PM_ERR_TRUNC;
914 #else
915 if (fsrc >= (float)0x7fffffffffffffff)
916 sts = PM_ERR_TRUNC;
917 #endif
918 else
919 oval->ll = (__int64_t)fsrc;
920 break;
921 case PM_TYPE_U64:
922 #if defined(HAVE_CONST_LONGLONG)
923 if (fsrc >= (float)((__uint64_t)0xffffffffffffffffLL))
924 sts = PM_ERR_TRUNC;
925 #else
926 if (fsrc >= (float)((__uint64_t)0xffffffffffffffff))
927 sts = PM_ERR_TRUNC;
928 #endif
929 else if (fsrc < 0)
930 sts = PM_ERR_SIGN;
931 else
932 oval->ull = (__uint64_t)fsrc;
933 break;
934 case PM_TYPE_FLOAT:
935 oval->f = fsrc;
936 break;
937 case PM_TYPE_DOUBLE:
938 oval->d = (float)fsrc;
939 break;
940 default:
941 sts = PM_ERR_CONV;
942 }
943 break;
944
945 case PM_TYPE_STRING:
946 if (ival->value.pval->vtype != PM_TYPE_STRING &&
947 ival->value.pval->vtype != 0) {
948 sts = PM_ERR_CONV;
949 break;
950 }
951 len = ival->value.pval->vlen - PM_VAL_HDR_SIZE;
952 #ifdef PCP_DEBUG
953 if (pmDebug & DBG_TRACE_VALUE) {
|
Event array_null: |
Comparing an array to null is not useful: "ival->value.pval->vbuf == NULL". |
954 if (ival->value.pval->vbuf == NULL)
955 vp = "<null>";
956 else {
957 int i;
958 i = (int)strlen(ival->value.pval->vbuf);
959 if (i < 38)
960 snprintf(buf, sizeof(buf), "\"%s\"", ival->value.pval->vbuf);
961 else
962 snprintf(buf, sizeof(buf), "\"%34.34s...\"", ival->value.pval->vbuf);
963 vp = buf;
964 }
965 }
966 #endif
967 if (otype != PM_TYPE_STRING) {
968 sts = PM_ERR_CONV;
969 break;
970 }
971 if ((oval->cp = (char *)malloc(len + 1)) == NULL) {
972 __pmNoMem("pmExtractValue.string", len + 1, PM_FATAL_ERR);
973 }
974 memcpy(oval->cp, ival->value.pval->vbuf, len);
975 oval->cp[len] = '\0';
976 break;
977
978 case PM_TYPE_AGGREGATE:
979 if (ival->value.pval->vtype != PM_TYPE_AGGREGATE &&
980 ival->value.pval->vtype != 0) {
981 sts = PM_ERR_CONV;
982 break;
983 }
984 len = ival->value.pval->vlen;
985 #ifdef PCP_DEBUG
986 if (pmDebug & DBG_TRACE_VALUE) {
987 int vlen;
988 int i;
989 vlen = ival->value.pval->vlen - PM_VAL_HDR_SIZE;
990 if (vlen == 0)
991 snprintf(buf, sizeof(buf), "[len=%d]", vlen);
992 else {
993 char *cp;
994 char *bp;
995 snprintf(buf, sizeof(buf), "[len=%d]", vlen);
996 cp = (char *)ival->value.pval->vbuf;
997 for (i = 0; i < vlen && i < 12; i++) {
998 bp = &buf[strlen(buf)];
999 if ((i % 4) == 0)
1000 snprintf(bp, sizeof(buf) - (bp-buf), " %02x", *cp & 0xff);
1001 else
1002 snprintf(bp, sizeof(buf) - (bp-buf), "%02x", *cp & 0xff);
1003 cp++;
1004 }
1005 if (vlen > 12) {
1006 bp = &buf[strlen(buf)];
1007 snprintf(bp, sizeof(buf) - (bp-buf), " ...");
1008 }
1009 }
1010 vp = buf;
1011 }
1012 #endif
1013 if (otype != PM_TYPE_AGGREGATE) {
1014 sts = PM_ERR_CONV;
1015 break;
1016 }
1017 if ((oval->vbp = (pmValueBlock *)malloc(len)) == NULL) {
1018 __pmNoMem("pmExtractValue.aggr", len, PM_FATAL_ERR);
1019 }
1020 memcpy(oval->vbp, ival->value.pval, len);
1021 break;
1022
1023 case PM_TYPE_32:
1024 case PM_TYPE_U32:
1025 case PM_TYPE_EVENT:
1026 default:
1027 sts = PM_ERR_CONV;
1028 }
1029 }
1030 else
1031 sts = PM_ERR_CONV;
1032
1033 #ifdef PCP_DEBUG
1034 if (pmDebug & DBG_TRACE_VALUE) {
1035 fprintf(stderr, " %s", vp);
1036 fprintf(stderr, " [%s]", pmTypeStr(itype));
1037 if (sts == 0)
1038 fprintf(stderr, " -> %s", pmAtomStr(oval, otype));
1039 else
1040 fprintf(stderr, " -> Error: %s", pmErrStr(sts));
1041 fprintf(stderr, " [%s]\n", pmTypeStr(otype));
1042 }
1043 #endif
1044
1045 return sts;
1046 }