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; }
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; }
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; }
/* 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; }
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++; }