/* Write a constant expression in binary form to a buffer.  */
int
gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
			size_t buffer_size)
{
  if (source == NULL)
    return 0;

  if (source->expr_type == EXPR_ARRAY)
    return encode_array (source, buffer, buffer_size);

  gcc_assert (source->expr_type == EXPR_CONSTANT
	      || source->expr_type == EXPR_STRUCTURE
	      || source->expr_type == EXPR_SUBSTRING);

  /* If we already have a target-memory representation, we use that rather 
     than recreating one.  */
  if (source->representation.string)
    {
      memcpy (buffer, source->representation.string,
	      source->representation.length);
      return source->representation.length;
    }

  switch (source->ts.type)
    {
    case BT_INTEGER:
      return encode_integer (source->ts.kind, source->value.integer, buffer,
			     buffer_size);
    case BT_REAL:
      return encode_float (source->ts.kind, source->value.real, buffer,
			   buffer_size);
    case BT_COMPLEX:
      return encode_complex (source->ts.kind, source->value.complex.r,
			     source->value.complex.i, buffer, buffer_size);
    case BT_LOGICAL:
      return encode_logical (source->ts.kind, source->value.logical, buffer,
			     buffer_size);
    case BT_CHARACTER:
      if (source->expr_type == EXPR_CONSTANT || source->ref == NULL)
	return encode_character (source->value.character.length,
			         source->value.character.string, buffer,
			         buffer_size);
      else
	{
	  int start, end;

	  gcc_assert (source->expr_type == EXPR_SUBSTRING);
	  gfc_extract_int (source->ref->u.ss.start, &start);
	  gfc_extract_int (source->ref->u.ss.end, &end);
	  return encode_character (MAX(end - start + 1, 0),
				   &source->value.character.string[start-1],
				   buffer, buffer_size);
	}
    case BT_DERIVED:
      return encode_derived (source, buffer, buffer_size);
    default:
      gfc_internal_error ("Invalid expression in gfc_target_encode_expr.");
      return 0;
    }
}
Example #2
0
// static
std::string LLURI::escape(
	const std::string& str,
	const std::string& allowed,
	bool is_allowed_sorted)
{
	// *NOTE: This size determination feels like a good value to
	// me. If someone wante to come up with a more precise heuristic
	// with some data to back up the assertion that 'sort is good'
	// then feel free to change this test a bit.
	if(!is_allowed_sorted && (str.size() > 2 * allowed.size()))
	{
		// if it's already sorted, or if the url is quite long, we
		// want to optimize this process.
		std::string sorted_allowed(allowed);
		std::sort(sorted_allowed.begin(), sorted_allowed.end());
		return escape(str, sorted_allowed, true);
	}

	std::ostringstream ostr;
	std::string::const_iterator it = str.begin();
	std::string::const_iterator end = str.end();
	std::string::value_type c;
	if(is_allowed_sorted)
	{
		std::string::const_iterator allowed_begin(allowed.begin());
		std::string::const_iterator allowed_end(allowed.end());
		for(; it != end; ++it)
		{
			c = *it;
			if(std::binary_search(allowed_begin, allowed_end, c))
			{
				ostr << c;
			}
			else
			{
				encode_character(ostr, c);
			}
		}
	}
	else
	{
		for(; it != end; ++it)
		{
			c = *it;
			if(allowed.find(c) == std::string::npos)
			{
				encode_character(ostr, c);
			}
			else
			{
				ostr << c;
			}
		}
	}
	return ostr.str();
}