Re: bitfields with ASCII pfiles

From: Glover, Rick I. (RickGlover@PaulHastings.COM)
Date: 07/13/01


> From: David Hamilton [mailto:gdave44@HOTMAIL.COM]
> Has anyone converted to bitfields while using ASCII pfiles. There are a
> number of Incompatible types in assignment that i'm not sure how to handle.
>
> Any insight would be greatly appreciated.

I haven't, but maybe some insight will help.  There are basically two routines
that you'll need.  One to convert the struct to a string of ascii and the other
to convert the string of ascii into a struct.  I implemented bitfields and
needed to do this for OLC.  I think the routines were in a patch that I put out
a while ago, but I may have modified them since then.  If anyone has a
correction to these, I'm open to it.  bit0 is initialized in my code as binary
10000000.  An example of how to uses these are:

tmpptr = struct2ascii((char *)&AFF_FLAGS(ch), sizeof(AFF_FLAGS(ch)));
  and
ascii2struct((char *)&AFF_FLAGS(ch), sizeof(AFF_FLAGS(ch)), string)


char *struct2ascii(char *address, int length)
{
  int i, a, letter, cnt;
  ubyte bitmask;
  char str[MAX_STRING_LENGTH], *ptr;

  ptr = str;
  for (i = 0, cnt = 0; i < length * 8; i++) {
    a = i / 8;
    bitmask = (bit0 == 1 ? bit0 << (i % 8) : bit0 >> (i % 8));
    if (!(i % 26) && i)
      *(ptr + cnt++) = '|';
    if (address[a] & bitmask) {
      letter = i - (26 * (i / 26));
      *(ptr + cnt++) = 'a' + letter;
    }
  }
  *(ptr + cnt) = '\0';

  return (str_dup(str));
}

void ascii2struct(char *address, int length, char *flag)
{
  long flags = 0, tmp;
  int a, b, add, bitnr;
  bool is_number = FALSE;
  register char *p;

  for (a = 0; a < length; a++)
    address[a] = 0;

  add = 0;
  for (p = flag; *p; p++) {
    if (*p == '|')
      add += 26;
    else if (islower(*p)) {
      bitnr = (*p - 'a') + add;
      if ((a = bitnr / 8) < length)
        address[a] |= (bit0 == 1 ? bit0 << (bitnr % 8) : bit0 >> (bitnr %
8));
      else
        log("SYSERR: bit is outside of range in ascii2struct() in utils.c");
    } else if (isupper(*p)) {
      bitnr = (26 + (*p - 'A')) + add;
      if ((a = bitnr / 8) < length)
        address[a] |= (bit0 == 1 ? bit0 << (bitnr % 8) : bit0 >> (bitnr %
8));
      else
        log("SYSERR: bit is outside of range in ascii2struct() in utils.c");
    } else if (isdigit(*p)) {
      is_number = TRUE;
      break;
    } else
      break;
  }
  if (is_number) {
    flags = atol(flag);
    for (a = 0; ((unsigned int)a < sizeof(flags)) && (a < length); a++) {
      tmp = (flags >> (a * 8));
      if (bit0 == 1)
        address[a] = (char)tmp;
      else {
        /* shift bits in reverse order */
        for (address[a] = b = 0; b < 8; b++) {
          address[a] = address[a] << 1;
          if (tmp & 1)
            address[a] |= 1;
          tmp = tmp >> 1;
        }
      }
    }
  }
}

Rick
(sorry for the autotext below that I don't have any control over)

"paulhastings.com" made the following annotations on 07/13/01 02:23:02
------------------------------------------------------------------------------

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/06/01 PST