(uc2ul, _uc2ul): Macros removed.
authorroland <roland>
Fri, 10 Mar 1995 18:53:01 +0000 (18:53 +0000)
committerroland <roland>
Fri, 10 Mar 1995 18:53:01 +0000 (18:53 +0000)
(decode): New inline function; decode signed 32-bit integers, and
sign-extend properly when long is longer than 32 bits.
(__tzfile_read): Changed all uses of uc2ul to decode.
Decode the transition times properly when sizeof (time_t) > 4.

time/tzfile.c

index 8ee4896..9ff24df 100644 (file)
@@ -54,10 +54,26 @@ static char *zone_names = NULL;
 static size_t num_leaps;
 static struct leap *leaps = NULL;
 
-#define        uc2ul(x)        _uc2ul((unsigned char *) (x))
-#define        _uc2ul(x)                                                             \
-  ((x)[3] + ((x)[2] << CHAR_BIT) + ((x)[1] << (2 * CHAR_BIT)) +                      \
-   ((x)[0] << (3 * CHAR_BIT)))
+#include <endian.h>
+
+/* Decode the four bytes at PTR as a signed integer in network byte order.  */
+static inline int
+decode (const void *ptr)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return *(const int *) ptr;
+#else
+  const unsigned char *p = ptr;
+  int result = 0;
+
+  result = (result << 8) | *p++;
+  result = (result << 8) | *p++;
+  result = (result << 8) | *p++;
+  result = (result << 8) | *p++;
+
+  return result;
+#endif
+}
 
 void
 DEFUN(__tzfile_read, (file), CONST char *file)
@@ -107,12 +123,12 @@ DEFUN(__tzfile_read, (file), CONST char *file)
   if (fread((PTR) &tzhead, sizeof(tzhead), 1, f) != 1)
     goto lose;
 
-  num_transitions = (size_t) uc2ul(tzhead.tzh_timecnt);
-  num_types = (size_t) uc2ul (tzhead.tzh_typecnt);
-  chars = (size_t) uc2ul (tzhead.tzh_charcnt);
-  num_leaps = (size_t) uc2ul (tzhead.tzh_leapcnt);
-  num_isstd = (size_t) uc2ul (tzhead.tzh_ttisstdcnt);
-  num_isgmt = (size_t) uc2ul (tzhead.tzh_ttisgmtcnt);
+  num_transitions = (size_t) decode (tzhead.tzh_timecnt);
+  num_types = (size_t) decode (tzhead.tzh_typecnt);
+  chars = (size_t) decode (tzhead.tzh_charcnt);
+  num_leaps = (size_t) decode (tzhead.tzh_leapcnt);
+  num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
+  num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
 
   if (num_transitions > 0)
     {
@@ -142,13 +158,20 @@ DEFUN(__tzfile_read, (file), CONST char *file)
        goto lose;
     }
 
-  if (fread((PTR) transitions, sizeof(time_t),
-           num_transitions, f) != num_transitions ||
+  if (fread((PTR) transitions, 4, num_transitions, f) != num_transitions ||
       fread((PTR) type_idxs, 1, num_transitions, f) != num_transitions)
     goto lose;
 
-  for (i = 0; i < num_transitions; ++i)
-    transitions[i] = uc2ul (&transitions[i]);
+  if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4)
+    {
+      /* Decode the transition times, stored as 4-byte integers in
+        network (big-endian) byte order.  We work from the end of
+        the array so as not to clobber the next element to be
+        processed when sizeof (time_t) > 4.  */
+      i = num_transitions;
+      while (num_transitions-- > 0)
+       transitions[i] = decode ((char *) transitions + i*4);
+    }
 
   for (i = 0; i < num_types; ++i)
     {
@@ -157,7 +180,7 @@ DEFUN(__tzfile_read, (file), CONST char *file)
          fread((PTR) &types[i].isdst, 1, 1, f) != 1 ||
          fread((PTR) &types[i].idx, 1, 1, f) != 1)
        goto lose;
-      types[i].offset = (long int) uc2ul(x);
+      types[i].offset = (long int) decode (x);
     }
 
   if (fread((PTR) zone_names, 1, chars, f) != chars)
@@ -168,10 +191,10 @@ DEFUN(__tzfile_read, (file), CONST char *file)
       unsigned char x[4];
       if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x))
        goto lose;
-      leaps[i].transition = (time_t) uc2ul(x);
+      leaps[i].transition = (time_t) decode (x);
       if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x))
        goto lose;
-      leaps[i].change = (long int) uc2ul(x);
+      leaps[i].change = (long int) decode (x);
     }
 
   for (i = 0; i < num_isstd; ++i)