Beispiel #1
0
static double lcd_to_double(const struct rs9lcd_packet *rs_packet, int type)
{
	double rawval = 0, multiplier = 1;
	uint8_t digit, raw_digit;
	gboolean dp_reached = FALSE;
	int i, end;

	/* end = 1: Don't parse last digit. end = 0: Parse all digits. */
	end = (type == READ_TEMP) ? 1 : 0;

	/* We have 4 digits, and we start from the most significant. */
	for (i = 3; i >= end; i--) {
		raw_digit = *(&(rs_packet->digit4) + i);
		digit = decode_digit(raw_digit);
		if (digit == 0xff) {
			rawval = NAN;
			break;
		}
		/*
		 * Digit 1 does not have a decimal point. Instead, the decimal
		 * point is used to indicate MAX, so we must avoid testing it.
		 */
		if ((i < 3) && (raw_digit & DP_MASK))
			dp_reached = TRUE;
		if (dp_reached)
			multiplier /= 10;
		rawval = rawval * 10 + digit;
	}
	rawval *= multiplier;
	if (rs_packet->info & INFO_NEG)
		rawval *= -1;

	/* See if we need to multiply our raw value by anything. */
	if (rs_packet->indicatrix1 & IND2_NANO)
		rawval *= 1E-9;
	else if (rs_packet->indicatrix2 & IND2_MICRO)
		rawval *= 1E-6;
	else if (rs_packet->indicatrix1 & IND1_MILI)
		rawval *= 1E-3;
	else if (rs_packet->indicatrix1 & IND1_KILO)
		rawval *= 1E3;
	else if (rs_packet->indicatrix1 & IND1_MEGA)
		rawval *= 1E6;

	return rawval;
}
Beispiel #2
0
enum punycode_status punycode_decode(
    punycode_uint input_length,
    const char input[],
    punycode_uint *output_length,
    punycode_uint output[],
    unsigned char case_flags[] )
{
    punycode_uint n, out, i, max_out, bias,
                  b, j, in, oldi, w, k, digit, t;

    /* Initialize the state: */

    n = initial_n;
    out = i = 0;
    max_out = *output_length;
    bias = initial_bias;

    /* Handle the basic code points:  Let b be the number of input code */
    /* points before the last delimiter, or 0 if there is none, then    */
    /* copy the first b code points to the output.                      */

    for (b = j = 0;  j < input_length;  ++j) if (delim(input[j])) b = j;
    if (b > max_out) return punycode_big_output;

    for (j = 0;  j < b;  ++j) {
        if (case_flags) case_flags[out] = flagged(input[j]);
        if (!basic(input[j])) return punycode_bad_input;
        output[out++] = input[j];
    }

    /* Main decoding loop:  Start just after the last delimiter if any  */
    /* basic code points were copied; start at the beginning otherwise. */

    for (in = b > 0 ? b + 1 : 0;  in < input_length;  ++out) {

        /* in is the index of the next character to be consumed, and */
        /* out is the number of code points in the output array.     */

        /* Decode a generalized variable-length integer into delta,  */
        /* which gets added to i.  The overflow checking is easier   */
        /* if we increase i as we go, then subtract off its starting */
        /* value at the end to obtain delta.                         */

        for (oldi = i, w = 1, k = base;  ;  k += base) {
            if (in >= input_length) return punycode_bad_input;
            digit = decode_digit(input[in++]);
            if (digit >= base) return punycode_bad_input;
            if (digit > (maxint - i) / w) return punycode_overflow;
            i += digit * w;
            t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */
                k >= bias + tmax ? tmax : k - bias;
            if (digit < t) break;
            if (w > maxint / (base - t)) return punycode_overflow;
            w *= (base - t);
        }

        bias = adapt(i - oldi, out + 1, oldi == 0);

        /* i was supposed to wrap around from out+1 to 0,   */
        /* incrementing n each time, so we'll fix that now: */

        if (i / (out + 1) > maxint - n) return punycode_overflow;
        n += i / (out + 1);
        i %= (out + 1);

        /* Insert n at position i of the output: */

        /* not needed for Punycode: */
        /* if (decode_digit(n) <= base) return punycode_invalid_input; */
        if (out >= max_out) return punycode_big_output;

        if (case_flags) {
            memmove(case_flags + i + 1, case_flags + i, out - i);
            /* Case of last character determines uppercase flag: */
            case_flags[i] = flagged(input[in - 1]);
        }

        memmove(output + i + 1, output + i, (out - i) * sizeof *output);
        output[i++] = n;
    }

    *output_length = out;
    return punycode_success;
}
Beispiel #3
0
int punycode_decode( unsigned int input_length,
                     const char input[],
                     unsigned int *output_length,
                     DWORD output[] )
{
  DWORD n, out, i, max_out, bias, b, j,
                 in, oldi, w, k, delta, digit, t;

  /* Initialize the state: */

  n = initial_n;
  out = i = 0;
  max_out = *output_length;
  bias = initial_bias;

  /* Handle the basic code points:  Let b be the number of input code */
  /* points before the last delimiter, or 0 if there is none, then    */
  /* copy the first b code points to the output.                      */

  for (b = j = 0;  j < input_length;  ++j) if (delim(input[j])) b = j;
  if (b > max_out) return XCODE_BAD_ARGUMENT_ERROR;

  for (j = 0;  j < b;  ++j) {
    if (!basic(input[j])) return XCODE_BAD_ARGUMENT_ERROR;
    output[out++] = input[j];
  }

  /* Main decoding loop:  Start just after the last delimiter if any  */
  /* basic code points were copied; start at the beginning otherwise. */

  for (in = b > 0 ? b + 1 : 0;  in < input_length;  ++out) {

    /* in is the index of the next character to be consumed, and */
    /* out is the number of code points in the output array.     */

    /* Decode a generalized variable-length integer into delta,  */
    /* which gets added to i.  The overflow checking is easier   */
    /* if we increase i as we go, then subtract off its starting */
    /* value at the end to obtain delta.                         */

    for (oldi = i, w = 1, k = base;  ;  k += base) {
      if (in >= input_length) return XCODE_BAD_ARGUMENT_ERROR;
      digit = decode_digit(input[in++]);
      if (digit >= base) return XCODE_BAD_ARGUMENT_ERROR;
      if (digit > (maxint - i) / w) return XCODE_BUFFER_OVERFLOW_ERROR;
      i += digit * w;
      t = k <= bias ? tmin : k - bias >= tmax ? tmax : k - bias;
      if (digit < t) break;
      if (w > maxint / (base - t)) return XCODE_BUFFER_OVERFLOW_ERROR;
      w *= (base - t);
    }

    /* Adapt the bias: */
    delta = oldi == 0 ? i / damp : (i - oldi) >> 1;
    delta += delta / (out + 1);
    for (bias = 0;  delta > cutoff;  bias += base) delta /= lobase;
    bias += (lobase + 1) * delta / (delta + skew);

    /* i was supposed to wrap around from out+1 to 0,   */
    /* incrementing n each time, so we'll fix that now: */

    if (i / (out + 1) > maxint - n) return XCODE_BUFFER_OVERFLOW_ERROR;
    n += i / (out + 1);
    i %= (out + 1);

    /* Insert n at position i of the output: */

    /* not needed for AMC-ACE-Z: */
    /* if (decode_digit(n) <= base) return amc_ace_invalid_input; */
    if (out >= max_out) return XCODE_BAD_ARGUMENT_ERROR;

    memmove(output + i + 1, output + i, (out - i) * sizeof *output);
    output[i++] = n;
  }

  *output_length = (unsigned int) out;
  return XCODE_SUCCESS;
}
Beispiel #4
0
/* Punycode decoder, RFC 3492 section 6.2. As with punycode_encode(),
 * read the RFC if you want to understand what this is actually doing.
 */
static gboolean
punycode_decode (const gchar *input,
                 gsize        input_length,
                 GString     *output)
{
  GArray *output_chars;
  gunichar n;
  guint i, bias;
  guint oldi, w, k, digit, t;
  const gchar *split;

  n = PUNYCODE_INITIAL_N;
  i = 0;
  bias = PUNYCODE_INITIAL_BIAS;

  split = input + input_length - 1;
  while (split > input && *split != '-')
    split--;
  if (split > input)
    {
      output_chars = g_array_sized_new (FALSE, FALSE, sizeof (gunichar),
					split - input);
      input_length -= (split - input) + 1;
      while (input < split)
	{
	  gunichar ch = (gunichar)*input++;
	  if (!PUNYCODE_IS_BASIC (ch))
	    goto fail;
	  g_array_append_val (output_chars, ch);
	}
      input++;
    }
  else
    output_chars = g_array_new (FALSE, FALSE, sizeof (gunichar));

  while (input_length)
    {
      oldi = i;
      w = 1;
      for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE)
	{
	  if (!input_length--)
	    goto fail;
	  digit = decode_digit (*input++);
	  if (digit >= PUNYCODE_BASE)
	    goto fail;
	  if (digit > (G_MAXUINT - i) / w)
	    goto fail;
	  i += digit * w;
	  if (k <= bias)
	    t = PUNYCODE_TMIN;
	  else if (k >= bias + PUNYCODE_TMAX)
	    t = PUNYCODE_TMAX;
	  else
	    t = k - bias;
	  if (digit < t)
	    break;
	  if (w > G_MAXUINT / (PUNYCODE_BASE - t))
	    goto fail;
	  w *= (PUNYCODE_BASE - t);
	}

      bias = adapt (i - oldi, output_chars->len + 1, oldi == 0);

      if (i / (output_chars->len + 1) > G_MAXUINT - n)
	goto fail;
      n += i / (output_chars->len + 1);
      i %= (output_chars->len + 1);

      g_array_insert_val (output_chars, i++, n);
    }

  for (i = 0; i < output_chars->len; i++)
    g_string_append_unichar (output, g_array_index (output_chars, gunichar, i));
  g_array_free (output_chars, TRUE);
  return TRUE;

 fail:
  g_array_free (output_chars, TRUE);
  return FALSE;
}
Beispiel #5
0
static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog2 analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	struct dev_context *devc;
	long factor, ivalue;
	uint8_t digits[4];
	gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto;
	gboolean is_hold, is_max, is_min, is_relative, minus;
	float fvalue;

	devc = sdi->priv;

	digits[0] = decode_digit(data[12]);
	digits[1] = decode_digit(data[11]);
	digits[2] = decode_digit(data[10]);
	digits[3] = decode_digit(data[9]);

	if (digits[0] == 0x0f && digits[1] == 0x00 && digits[2] == 0x0a &&
			digits[3] == 0x0f)
		/* The "over limit" (OL) display comes through like this */
		ivalue = -1;
	else if (digits[0] > 9 || digits[1] > 9 || digits[2] > 9 || digits[3] > 9)
		/* An invalid digit in any position denotes no value. */
		ivalue = -2;
	else {
		ivalue = digits[0] * 1000;
		ivalue += digits[1] * 100;
		ivalue += digits[2] * 10;
		ivalue += digits[3];
	}

	/* Decimal point position */
	factor = 0;
	switch (data[7] >> 4) {
	case 0x00:
		factor = 0;
		break;
	case 0x02:
		factor = 1;
		break;
	case 0x04:
		factor = 2;
		break;
	case 0x08:
		factor = 3;
		break;
	default:
		sr_err("Unknown decimal point byte: 0x%.2x.", data[7]);
		break;
	}

	/* Minus flag */
	minus = data[2] & 0x01;

	/* Mode detail symbols on the right side of the digits */
	is_duty = is_continuity = is_diode = FALSE;
	switch (data[4]) {
	case 0x00:
		/* None. */
		break;
	case 0x01:
		/* Micro */
		factor += 6;
		break;
	case 0x02:
		/* Milli */
		factor += 3;
		break;
	case 0x04:
		/* Kilo */
		ivalue *= 1000;
		break;
	case 0x08:
		/* Mega */
		ivalue *= 1000000;
		break;
	case 0x10:
		/* Continuity shows up as Ohm + this bit */
		is_continuity = TRUE;
		break;
	case 0x20:
		/* Diode tester is Volt + this bit */
		is_diode = TRUE;
		break;
	case 0x40:
		is_duty = TRUE;
		break;
	case 0x80:
		/* Never seen */
		sr_dbg("Unknown mode right detail: 0x%.2x.", data[4]);
		break;
	default:
		sr_dbg("Unknown/invalid mode right detail: 0x%.2x.", data[4]);
		break;
	}

	/* Scale flags on the right, continued */
	is_max = is_min = FALSE;
	if (data[5] & 0x04)
		is_max = TRUE;
	if (data[5] & 0x08)
		is_min = TRUE;
	if (data[5] & 0x40)
		/* Nano */
		factor += 9;

	/* Mode detail symbols on the left side of the digits */
	is_auto = is_dc = is_ac = is_hold = is_relative = FALSE;
	if (data[6] & 0x04)
		is_auto = TRUE;
	if (data[6] & 0x08)
		is_dc = TRUE;
	if (data[6] & 0x10)
		is_ac = TRUE;
	if (data[6] & 0x20)
		is_relative = TRUE;
	if (data[6] & 0x40)
		is_hold = TRUE;

	fvalue = (float)ivalue / pow(10, factor);
	if (minus)
		fvalue = -fvalue;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 4);

	/* Measurement mode */
	meaning.channels = sdi->channels;
	meaning.mq = 0;
	switch (data[3]) {
	case 0x00:
		if (is_duty) {
			meaning.mq = SR_MQ_DUTY_CYCLE;
			meaning.unit = SR_UNIT_PERCENTAGE;
		} else
			sr_dbg("Unknown measurement mode: %.2x.", data[3]);
		break;
	case 0x01:
		if (is_diode) {
			meaning.mq = SR_MQ_VOLTAGE;
			meaning.unit = SR_UNIT_VOLT;
			meaning.mqflags |= SR_MQFLAG_DIODE;
			if (ivalue < 0)
				fvalue = NAN;
		} else {
			if (ivalue < 0)
				break;
			meaning.mq = SR_MQ_VOLTAGE;
			meaning.unit = SR_UNIT_VOLT;
			if (is_ac)
				meaning.mqflags |= SR_MQFLAG_AC;
			if (is_dc)
				meaning.mqflags |= SR_MQFLAG_DC;
		}
		break;
	case 0x02:
		meaning.mq = SR_MQ_CURRENT;
		meaning.unit = SR_UNIT_AMPERE;
		if (is_ac)
			meaning.mqflags |= SR_MQFLAG_AC;
		if (is_dc)
			meaning.mqflags |= SR_MQFLAG_DC;
		break;
	case 0x04:
		if (is_continuity) {
			meaning.mq = SR_MQ_CONTINUITY;
			meaning.unit = SR_UNIT_BOOLEAN;
			fvalue = ivalue < 0 ? 0.0 : 1.0;
		} else {
			meaning.mq = SR_MQ_RESISTANCE;
			meaning.unit = SR_UNIT_OHM;
			if (ivalue < 0)
				fvalue = INFINITY;
		}
		break;
	case 0x08:
		/* Never seen */
		sr_dbg("Unknown measurement mode: 0x%.2x.", data[3]);
		break;
	case 0x10:
		meaning.mq = SR_MQ_FREQUENCY;
		meaning.unit = SR_UNIT_HERTZ;
		break;
	case 0x20:
		meaning.mq = SR_MQ_CAPACITANCE;
		meaning.unit = SR_UNIT_FARAD;
		break;
	case 0x40:
		meaning.mq = SR_MQ_TEMPERATURE;
		meaning.unit = SR_UNIT_CELSIUS;
		break;
	case 0x80:
		meaning.mq = SR_MQ_TEMPERATURE;
		meaning.unit = SR_UNIT_FAHRENHEIT;
		break;
	default:
		sr_dbg("Unknown/invalid measurement mode: 0x%.2x.", data[3]);
		break;
	}
	if (meaning.mq == 0)
		return;

	if (is_auto)
		meaning.mqflags |= SR_MQFLAG_AUTORANGE;
	if (is_hold)
		meaning.mqflags |= SR_MQFLAG_HOLD;
	if (is_max)
		meaning.mqflags |= SR_MQFLAG_MAX;
	if (is_min)
		meaning.mqflags |= SR_MQFLAG_MIN;
	if (is_relative)
		meaning.mqflags |= SR_MQFLAG_RELATIVE;

	analog.data = &fvalue;
	analog.num_samples = 1;

	packet.type = SR_DF_ANALOG2;
	packet.payload = &analog;
	sr_session_send(devc->cb_data, &packet);

	devc->num_samples++;
}