summaryrefslogtreecommitdiff
path: root/src/libpcp/src/endian.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpcp/src/endian.c')
-rw-r--r--src/libpcp/src/endian.c361
1 files changed, 361 insertions, 0 deletions
diff --git a/src/libpcp/src/endian.c b/src/libpcp/src/endian.c
new file mode 100644
index 0000000..a5782b6
--- /dev/null
+++ b/src/libpcp/src/endian.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2013-2014 Red Hat.
+ * Copyright (c) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+
+/*
+ * Bit field typedefs for endian translations to support little endian
+ * hosts.
+ *
+ * For a typedef __X_foo, the big endian version will be "foo" or
+ * The only structures that appear here are ones that
+ * (a) may be encoded within a PDU, and/or
+ * (b) may appear in a PCP archive
+ */
+
+#include "pmapi.h"
+#include "impl.h"
+#include "internal.h"
+
+#ifndef __htonpmUnits
+pmUnits
+__htonpmUnits(pmUnits units)
+{
+ unsigned int x;
+
+ x = htonl(*(unsigned int *)&units);
+ units = *(pmUnits *)&x;
+
+ return units;
+}
+#endif
+
+#ifndef __ntohpmUnits
+pmUnits
+__ntohpmUnits(pmUnits units)
+{
+ unsigned int x;
+
+ x = ntohl(*(unsigned int *)&units);
+ units = *(pmUnits *)&x;
+
+ return units;
+}
+#endif
+
+#ifndef __htonpmValueBlock
+static void
+htonEventArray(pmValueBlock * const vb, int highres)
+{
+ size_t size;
+ char *base;
+ int r; /* records */
+ int p; /* parameters in a record ... */
+ int nrecords;
+ int nparams;
+ int vtype;
+ int vlen;
+ __uint32_t *tp; /* points to int holding vtype/vlen */
+
+ /* ea_type and ea_len handled via *ip below */
+ if (highres) {
+ pmHighResEventArray *hreap = (pmHighResEventArray *)vb;
+ base = (char *)&hreap->ea_record[0];
+ nrecords = hreap->ea_nrecords;
+ hreap->ea_nrecords = htonl(nrecords);
+ }
+ else {
+ pmEventArray *eap = (pmEventArray *)vb;
+ base = (char *)&eap->ea_record[0];
+ nrecords = eap->ea_nrecords;
+ eap->ea_nrecords = htonl(nrecords);
+ }
+
+ /* walk packed event record array */
+ for (r = 0; r < nrecords; r++) {
+ if (highres) {
+ pmHighResEventRecord *hrerp = (pmHighResEventRecord *)base;
+ size = sizeof(hrerp->er_timestamp) + sizeof(hrerp->er_flags) +
+ sizeof(hrerp->er_nparams);
+ if (hrerp->er_flags & PM_EVENT_FLAG_MISSED)
+ nparams = 0;
+ else
+ nparams = hrerp->er_nparams;
+ hrerp->er_nparams = htonl(nparams);
+ hrerp->er_flags = htonl(hrerp->er_flags);
+ hrerp->er_timestamp.tv_sec = htonl(hrerp->er_timestamp.tv_sec);
+ hrerp->er_timestamp.tv_nsec = htonl(hrerp->er_timestamp.tv_nsec);
+ }
+ else {
+ pmEventRecord *erp = (pmEventRecord *)base;
+ size = sizeof(erp->er_timestamp) + sizeof(erp->er_flags) +
+ sizeof(erp->er_nparams);
+ if (erp->er_flags & PM_EVENT_FLAG_MISSED)
+ nparams = 0;
+ else
+ nparams = erp->er_nparams;
+ erp->er_nparams = htonl(erp->er_nparams);
+ erp->er_flags = htonl(erp->er_flags);
+ erp->er_timestamp.tv_sec = htonl(erp->er_timestamp.tv_sec);
+ erp->er_timestamp.tv_usec = htonl(erp->er_timestamp.tv_usec);
+ }
+ base += size;
+
+ for (p = 0; p < nparams; p++) {
+ pmEventParameter *epp = (pmEventParameter *)base;
+
+ epp->ep_pmid = __htonpmID(epp->ep_pmid);
+ vtype = epp->ep_type;
+ vlen = epp->ep_len;
+ tp = (__uint32_t *)&epp->ep_pmid;
+ tp++; /* now points to ep_type/ep_len */
+ *tp = htonl(*tp);
+ tp++; /* now points to vbuf */
+ /* convert the types we're able to ... */
+ switch (vtype) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ *tp = htonl(*tp);
+ break;
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ __htonll((void *)tp);
+ break;
+ case PM_TYPE_DOUBLE:
+ __htond((void *)tp);
+ break;
+ case PM_TYPE_FLOAT:
+ __htonf((void *)tp);
+ break;
+ }
+ base += sizeof(epp->ep_pmid) + PM_PDU_SIZE_BYTES(vlen);
+ }
+ }
+}
+
+void
+__htonpmValueBlock(pmValueBlock * const vb)
+{
+ unsigned int *ip = (unsigned int *)vb;
+
+ if (vb->vtype == PM_TYPE_U64 || vb->vtype == PM_TYPE_64)
+ __htonll(vb->vbuf);
+ else if (vb->vtype == PM_TYPE_DOUBLE)
+ __htond(vb->vbuf);
+ else if (vb->vtype == PM_TYPE_FLOAT)
+ __htonf(vb->vbuf);
+ else if (vb->vtype == PM_TYPE_EVENT)
+ htonEventArray(vb, 0);
+ else if (vb->vtype == PM_TYPE_HIGHRES_EVENT)
+ htonEventArray(vb, 1);
+
+ *ip = htonl(*ip); /* vtype/vlen */
+}
+#endif
+
+#ifndef __ntohpmValueBlock
+static void
+ntohEventArray(pmValueBlock * const vb, int highres)
+{
+ char *base;
+ int r; /* records */
+ int p; /* parameters in a record ... */
+ int nrecords;
+ int nparams;
+
+ /* ea_type and ea_len handled via *ip above */
+ if (highres) {
+ pmHighResEventArray *hreap = (pmHighResEventArray *)vb;
+ base = (char *)&hreap->ea_record[0];
+ nrecords = hreap->ea_nrecords = ntohl(hreap->ea_nrecords);
+ }
+ else {
+ pmEventArray *eap = (pmEventArray *)vb;
+ base = (char *)&eap->ea_record[0];
+ nrecords = eap->ea_nrecords = ntohl(eap->ea_nrecords);
+ }
+
+ /* walk packed event record array */
+ for (r = 0; r < nrecords; r++) {
+ unsigned int flags;
+ size_t size;
+
+ if (highres) {
+ pmHighResEventRecord *hrerp = (pmHighResEventRecord *)base;
+ size = sizeof(hrerp->er_timestamp) + sizeof(hrerp->er_flags) +
+ sizeof(hrerp->er_nparams);
+ hrerp->er_timestamp.tv_sec = ntohl(hrerp->er_timestamp.tv_sec);
+ hrerp->er_timestamp.tv_nsec = ntohl(hrerp->er_timestamp.tv_nsec);
+ nparams = hrerp->er_nparams = ntohl(hrerp->er_nparams);
+ flags = hrerp->er_flags = ntohl(hrerp->er_flags);
+ }
+ else {
+ pmEventRecord *erp = (pmEventRecord *)base;
+ size = sizeof(erp->er_timestamp) + sizeof(erp->er_flags) +
+ sizeof(erp->er_nparams);
+ erp->er_timestamp.tv_sec = ntohl(erp->er_timestamp.tv_sec);
+ erp->er_timestamp.tv_usec = ntohl(erp->er_timestamp.tv_usec);
+ nparams = erp->er_nparams = ntohl(erp->er_nparams);
+ flags = erp->er_flags = ntohl(erp->er_flags);
+ }
+
+ if (flags & PM_EVENT_FLAG_MISSED)
+ nparams = 0;
+
+ base += size;
+ for (p = 0; p < nparams; p++) {
+ __uint32_t *tp; /* points to int holding vtype/vlen */
+ pmEventParameter *epp = (pmEventParameter *)base;
+
+ epp->ep_pmid = __ntohpmID(epp->ep_pmid);
+ tp = (__uint32_t *)&epp->ep_pmid;
+ tp++; /* now points to ep_type/ep_len */
+ *tp = ntohl(*tp);
+ tp++; /* now points to vbuf */
+ /* convert the types we're able to ... */
+ switch (epp->ep_type) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ *tp = ntohl(*tp);
+ break;
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ __ntohll((void *)tp);
+ break;
+ case PM_TYPE_DOUBLE:
+ __ntohd((void *)tp);
+ break;
+ case PM_TYPE_FLOAT:
+ __ntohf((void *)tp);
+ break;
+ }
+ base += sizeof(epp->ep_pmid) + PM_PDU_SIZE_BYTES(epp->ep_len);
+ }
+ }
+}
+
+void
+__ntohpmValueBlock(pmValueBlock * const vb)
+{
+ unsigned int *ip = (unsigned int *)vb;
+
+ /* Swab the first word, which contain vtype and vlen */
+ *ip = ntohl(*ip);
+
+ switch (vb->vtype) {
+ case PM_TYPE_U64:
+ case PM_TYPE_64:
+ __ntohll(vb->vbuf);
+ break;
+
+ case PM_TYPE_DOUBLE:
+ __ntohd(vb->vbuf);
+ break;
+
+ case PM_TYPE_FLOAT:
+ __ntohf(vb->vbuf);
+ break;
+
+ case PM_TYPE_EVENT:
+ ntohEventArray(vb, 0);
+ break;
+
+ case PM_TYPE_HIGHRES_EVENT:
+ ntohEventArray(vb, 1);
+ break;
+ }
+}
+#endif
+
+#ifndef __htonpmPDUInfo
+__pmPDUInfo
+__htonpmPDUInfo(__pmPDUInfo info)
+{
+ unsigned int x;
+
+ x = htonl(*(unsigned int *)&info);
+ info = *(__pmPDUInfo *)&x;
+
+ return info;
+}
+#endif
+
+#ifndef __ntohpmPDUInfo
+__pmPDUInfo
+__ntohpmPDUInfo(__pmPDUInfo info)
+{
+ unsigned int x;
+
+ x = ntohl(*(unsigned int *)&info);
+ info = *(__pmPDUInfo *)&x;
+
+ return info;
+}
+#endif
+
+#ifndef __htonpmCred
+__pmCred
+__htonpmCred(__pmCred cred)
+{
+ unsigned int x;
+
+ x = htonl(*(unsigned int *)&cred);
+ cred = *(__pmCred *)&x;
+
+ return cred;
+}
+#endif
+
+#ifndef __ntohpmCred
+__pmCred
+__ntohpmCred(__pmCred cred)
+{
+ unsigned int x;
+
+ x = ntohl(*(unsigned int *)&cred);
+ cred = *(__pmCred *)&x;
+
+ return cred;
+}
+#endif
+
+
+#ifndef __htonf
+void
+__htonf(char *p)
+{
+ char c;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ c = p[i];
+ p[i] = p[3-i];
+ p[3-i] = c;
+ }
+}
+#endif
+
+#ifndef __htonll
+void
+__htonll(char *p)
+{
+ char c;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ c = p[i];
+ p[i] = p[7-i];
+ p[7-i] = c;
+ }
+}
+#endif