size_t keysz(size_t sz, const octet *ksz)
{
+ unsigned op = ksz[0]&KSZ_OPMASK;
+ unsigned wd = (ksz[0]&KSZ_16BIT) ? 2 : 1;
+ unsigned t, u, v;
+
+ ksz++;
+#define ARG(i) (wd == 1 ? ksz[i] : LOAD16(ksz + 2*i))
if (sz == 0)
- return (ksz[1]);
- else switch (ksz[0]) {
- case KSZ_ANY:
+ return (ARG(0));
+ else switch (op) {
+ case KSZ_ANY: return (sz);
+ case KSZ_RANGE:
+ t = ARG(1); u = ARG(2); v = ARG(3);
+ if (v) sz -= sz%v;
+ if (sz < t) return (0);
+ if (u && sz > u) return (u);
return (sz);
+ case KSZ_SET:
+ u = 0;
+ for (;;) {
+ t = ARG(0); ksz += wd; if (!t) break;
+ if (sz >= t && u < t) u = t;
+ }
+ return (u);
+ }
+#undef ARG
+
+ assert(((void)"bad key size table", 0));
+ return (0);
+}
+
+/* --- @keysz_pad@ --- *
+ *
+ * Arguments: @size_t sz@ = a proposed key size
+ * @const octet *ksz@ = pointer to key size table
+ *
+ * Returns: A key size, at least as large as @sz@, or zero if no such
+ * size is available.
+ */
+
+size_t keysz_pad(size_t sz, const octet *ksz)
+{
+ unsigned op = ksz[0]&KSZ_OPMASK;
+ unsigned wd = (ksz[0]&KSZ_16BIT) ? 2 : 1;
+ unsigned t, u, v;
+
+ ksz++;
+#define ARG(i) (wd == 1 ? ksz[i] : LOAD16(ksz + 2*i))
+ switch (op) {
+ case KSZ_ANY: return (sz);
case KSZ_RANGE:
- if (ksz[4])
- sz -= sz % ksz[4];
- if (sz < ksz[2])
- return (0);
- if (ksz[3] && sz > ksz[3])
- return (ksz[3]);
+ t = ARG(1); u = ARG(2); v = ARG(3);
+ if (v) { sz += v - 1; sz -= sz%v; }
+ if (u && sz > u) return (0);
+ if (sz < t) return (t);
return (sz);
- case KSZ_SET: {
- unsigned q = 0;
- for (ksz++; *ksz; ksz++) {
- if (sz >= *ksz && q < *ksz)
- q = *ksz;
+ case KSZ_SET:
+ u = 0;
+ for (;;) {
+ t = ARG(0); ksz += wd; if (!t) break;
+ if (sz <= t && (!u || u > t)) u = t;
}
- return (q);
- }
+ return (u);
}
+#undef ARG
assert(((void)"bad key size table", 0));
return (0);