static unsigned8
read_icr (struct hw *me,
	  struct mn103int *controller,
	  unsigned_word base)
{
  unsigned_word offset;
  struct mn103int_group *group = decode_group (me, controller, base, &offset);
  unsigned8 val = 0;
  switch (group->type)
    {

    case NMI_GROUP:
      switch (offset)
	{
	case 0:
	  val = INSERT_ID (group->request);
	  HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x",
		     group->gid, val));
	  break;
	default:
	  break;
	}
      break;

    case LEVEL_GROUP:
      switch (offset)
	{
	case 0:
	  val = (INSERT_IR (group->request)
		 | INSERT_ID (group->request & group->enable));
	  HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x",
		     group->gid, val));
	  break;
	case 1:
	  val = (INSERT_LV (group->level)
		 | INSERT_IE (group->enable));
	  HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x",
		     group->gid, val));
	  break;
	}
      break;

    default:
      break;

    }

  return val;
}
예제 #2
0
파일: message.cpp 프로젝트: capitalk/fix8
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode(const f8String& from, const unsigned offset)
{
	unsigned s_offset(offset), result;
	const unsigned fsize(from.size());
	const char *dptr(from.data());
	char tag[MAX_FLD_LENGTH], val[MAX_FLD_LENGTH];

	for (unsigned pos(_pos.size()); s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
	{
		const unsigned tv(fast_atoi<unsigned>(tag));
		const BaseEntry *be(_ctx._be.find_ptr(tv));
#if defined PERMIT_CUSTOM_FIELDS
		if (!be && (!_ctx._ube || (be = _ctx._ube->find_ptr(tv)) == 0))
#else
		if (!be)
#endif
			throw InvalidField(tv);
		Presence::const_iterator itr(_fp.get_presence().end());
		if (!_fp.has(tv, itr))
			break;
		s_offset += result;
		if (_fp.get(tv, itr, FieldTrait::present))
		{
			if (!_fp.get(tv, itr, FieldTrait::automatic))
				throw DuplicateField(tv);
		}
		else
		{
			add_field(tv, itr, ++pos, be->_create(val, be->_rlm, -1), false);
			if (_fp.is_group(tv, itr))
				s_offset = decode_group(tv, from, s_offset);
		}
	}

	const unsigned short missing(_fp.find_missing());
	if (missing)
	{
		const BaseEntry& tbe(_ctx._be.find_ref(missing));
		ostringstream ostr;
		ostr << tbe._name << " (" << missing << ')';
		throw MissingMandatoryField(ostr.str());
	}

	return s_offset;
}
예제 #3
0
static InternetAddress *
decode_address (const char **in)
{
	const char *inptr, *start, *word, *comment = NULL;
	InternetAddress *addr = NULL;
	gboolean has_lwsp = FALSE;
	gboolean is_word;
	GString *name;
	
	decode_lwsp (in);
	start = inptr = *in;
	
	name = g_string_new ("");
	
	/* Both groups and mailboxes can begin with a phrase (denoting
	 * the display name for the address). Collect all of the
	 * tokens that make up this name phrase.
	 */
	while (*inptr) {
		if ((word = decode_word (&inptr))) {
			g_string_append_len (name, word, (size_t) (inptr - word));
			
		check_lwsp:
			word = inptr;
			skip_lwsp (&inptr);
			
			/* is the next token a word token? */
			is_word = *inptr == '"' || is_atom (*inptr);
			
			if (inptr > word && is_word) {
				g_string_append_c (name, ' ');
				has_lwsp = TRUE;
			}
			
			if (is_word)
				continue;
		}
		
		/* specials    =  "(" / ")" / "<" / ">" / "@"  ; Must be in quoted-
		 *             /  "," / ";" / ":" / "\" / <">  ;  string, to use
		 *             /  "." / "[" / "]"              ;  within a word.
		 */
		if (*inptr == ':') {
			/* rfc2822 group */
			inptr++;
			addr = decode_group (&inptr);
			decode_lwsp (&inptr);
			if (*inptr != ';')
				w(g_warning ("Invalid group spec, missing closing ';': %.*s",
					     inptr - start, start));
			else
				inptr++;
			break;
		} else if (*inptr == '<') {
			/* rfc2822 angle-addr */
			inptr++;
			
			/* check for obsolete routing... */
			if (*inptr != '@' || decode_route (&inptr)) {
				/* rfc2822 addr-spec */
				addr = decode_addrspec (&inptr);
			}
			
			decode_lwsp (&inptr);
			if (*inptr != '>') {
				w(g_warning ("Invalid rfc2822 angle-addr, missing closing '>': %.*s",
					     inptr - start, start));
				
				while (*inptr && *inptr != '>' && *inptr != ',')
					inptr++;
				
				if (*inptr == '>')
					inptr++;
			} else {
				inptr++;
			}
			
			/* if comment is non-NULL, we can check for a comment containing a name */
			comment = inptr;
			break;
		} else if (*inptr == '(') {
			/* beginning of a comment, use decode_lwsp() to skip past it */
			decode_lwsp (&inptr);
		} else if (*inptr && strchr ("@,;", *inptr)) {
			if (name->len == 0) {
				if (*inptr == '@') {
					GString *domain;
					
					w(g_warning ("Unexpected address: %s: skipping.", start));
					
					/* skip over @domain? */
					inptr++;
					domain = g_string_new ("");
					decode_domain (&inptr, domain);
					g_string_free (domain, TRUE);
				} else {
					/* empty address */
				}
				break;
			} else if (has_lwsp) {
				/* assume this is just an unquoted special that we should
				   treat as part of the name */
				w(g_warning ("Unquoted '%c' in address name: %s: ignoring.", *inptr, start));
				g_string_append_c (name, *inptr);
				inptr++;
				
				goto check_lwsp;
			}
			
		addrspec:
			/* what we thought was a name was actually an addrspec? */
			g_string_truncate (name, 0);
			inptr = start;
			
			addr = decode_addrspec (&inptr);
			
			/* if comment is non-NULL, we can check for a comment containing a name */
			comment = inptr;
			break;
		} else if (*inptr == '.') {
			/* This would normally signify that we are
			 * decoding the local-part of an addr-spec,
			 * but sadly, it is common for broken mailers
			 * to forget to quote/encode .'s in the name
			 * phrase. */
			g_string_append_c (name, *inptr);
			inptr++;
			
			goto check_lwsp;
		} else if (*inptr) {
			/* Technically, these are all invalid tokens
			 * but in the interest of being liberal in
			 * what we accept, we'll ignore them. */
			w(g_warning ("Unexpected char '%c' in address: %s: ignoring.", *inptr, start));
			g_string_append_c (name, *inptr);
			inptr++;
			
			goto check_lwsp;
		} else {
			goto addrspec;
		}
	}
	
	/* Note: will also skip over any comments */
	decode_lwsp (&inptr);
	
	if (name->len == 0 && comment && inptr > comment) {
		/* missing a name, look for a trailing comment */
		if ((comment = memchr (comment, '(', inptr - comment))) {
			const char *cend;
			
			/* find the end of the comment */
			cend = inptr - 1;
			while (cend > comment && is_lwsp (*cend))
				cend--;
			
			if (*cend == ')')
				cend--;
			
			g_string_append_len (name, comment + 1, (size_t) (cend - comment));
		}
	}
	
	if (addr && name->len > 0)
		_internet_address_decode_name (addr, name);
	
	g_string_free (name, TRUE);
	
	*in = inptr;
	
	return addr;
}
static void
write_icr (struct hw *me,
	   struct mn103int *controller,
	   unsigned_word base,
	   unsigned8 val)
{
  unsigned_word offset;
  struct mn103int_group *group = decode_group (me, controller, base, &offset);
  switch (group->type)
    {

    case NMI_GROUP:
      switch (offset)
	{
	case 0:
	  HW_TRACE ((me, "write-icr group=%d:0 nmi 0x%02x",
		     group->gid, val));
	  group->request &= ~EXTRACT_ID (val);
	  break;
	  /* Special backdoor access to SYSEF flag from CPU.  See
             interp.c:program_interrupt(). */
	case 3:
	  HW_TRACE ((me, "write-icr-special group=%d:0 nmi 0x%02x",
		     group->gid, val));
	  group->request |= EXTRACT_ID (val);
	default:
	  break;
	}
      break;

    case LEVEL_GROUP:
      switch (offset)
	{
	case 0: /* request/detect */
	  /* Clear any ID bits and then set them according to IR */
	  HW_TRACE ((me, "write-icr group=%d:0 level 0x%02x %x:%x:%x",
		     group->gid, val,
		     group->request, EXTRACT_IR (val), EXTRACT_ID (val)));
	  group->request =
	    ((EXTRACT_IR (val) & EXTRACT_ID (val))
	     | (EXTRACT_IR (val) & group->request)
	     | (~EXTRACT_IR (val) & ~EXTRACT_ID (val) & group->request));
	  break;
	case 1: /* level/enable */
	  HW_TRACE ((me, "write-icr group=%d:1 level 0x%02x",
		     group->gid, val));
	  group->level = EXTRACT_LV (val);
	  group->enable = EXTRACT_IE (val);
	  break;
	default:
	  /* ignore */
	  break;
	}
      push_interrupt_level (me, controller);
      break;

    default:
      break;

    }
}