aboutsummaryrefslogtreecommitdiff
path: root/src/pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pack.c')
-rw-r--r--src/pack.c178
1 files changed, 177 insertions, 1 deletions
diff --git a/src/pack.c b/src/pack.c
index 701d82a..b71823a 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -22,6 +22,8 @@
22#include <ctype.h> 22#include <ctype.h>
23#include <inttypes.h> 23#include <inttypes.h>
24#include <limits.h> 24#include <limits.h>
25#include <arpa/inet.h>
26#include <errno.h>
25#include "pack.h" 27#include "pack.h"
26 28
27/* Data format specification is a simplified form of Perl pack() template. 29/* Data format specification is a simplified form of Perl pack() template.
@@ -47,6 +49,14 @@
47 i A signed integer value. 49 i A signed integer value.
48 I A unsigned integer value. 50 I A unsigned integer value.
49 51
52 n An unsigned short (16-bit) in "network" (big-endian) order.
53 N An unsigned long (32-bit) in "network" (big-endian) order.
54 v An unsigned short (16-bit) in "VAX" (little-endian) order.
55 V An unsigned long (32-bit) in "VAX" (little-endian) order.
56
57 f A single-precision float in native format.
58 d A double-precision float in native format.
59
50 x A null byte (a.k.a ASCII NUL, "\000", chr(0)) 60 x A null byte (a.k.a ASCII NUL, "\000", chr(0))
51 X Back up a byte. 61 X Back up a byte.
52 @ Null-fill or truncate to absolute position, counted from the 62 @ Null-fill or truncate to absolute position, counted from the
@@ -328,6 +338,166 @@ I_unpacker(struct packenv *env, int rep)
328 env->buf_pos += sizeof(unsigned); 338 env->buf_pos += sizeof(unsigned);
329} 339}
330 340
341/* n - An unsigned short (16-bit) in "network" (big-endian) order. */
342static void
343n_packer(struct packenv *env, int rep)
344{
345 if (env->buf_base) {
346 char *arg = packenv_get(env);
347 if (arg) {
348 uintmax_t x;
349 if (getunum(arg, UINT16_MAX, &x) == 0) {
350 uint16_t v = htons((uint16_t) x);
351 memcpy(env->buf_base + env->buf_pos,
352 &v, sizeof(v));
353 }
354 }
355 }
356 env->buf_pos += sizeof(uint16_t);
357}
358
359static void
360n_unpacker(struct packenv *env, int rep)
361{
362 uint16_t v = ntohs(*(uint16_t *)(env->buf_base + env->buf_pos));
363 printunum(env->fp, v);
364 env->buf_pos += sizeof(uint16_t);
365}
366
367/* N - An unsigned long (32-bit) in "network" (big-endian) order. */
368static void
369N_packer(struct packenv *env, int rep)
370{
371 if (env->buf_base) {
372 char *arg = packenv_get(env);
373 if (arg) {
374 uintmax_t x;
375 if (getunum(arg, UINT32_MAX, &x) == 0) {
376 uint32_t v = htonl((uint32_t) x);
377 memcpy(env->buf_base + env->buf_pos,
378 &v, sizeof(v));
379 }
380 }
381 }
382 env->buf_pos += sizeof(uint32_t);
383}
384
385static void
386N_unpacker(struct packenv *env, int rep)
387{
388 uint32_t v = ntohl(*(uint32_t *)(env->buf_base + env->buf_pos));
389 printunum(env->fp, v);
390 env->buf_pos += sizeof(uint32_t);
391}
392
393/* v - An unsigned short (16-bit) in "VAX" (little-endian) order. */
394static void
395v_packer(struct packenv *env, int rep)
396{
397 if (env->buf_base) {
398 char *arg = packenv_get(env);
399 if (arg) {
400 uintmax_t x;
401 if (getunum(arg, UINT16_MAX, &x) == 0) {
402 uint16_t v = ntohs((uint16_t) x);
403 memcpy(env->buf_base + env->buf_pos,
404 &v, sizeof(v));
405 }
406 }
407 }
408 env->buf_pos += sizeof(uint16_t);
409}
410
411static void
412v_unpacker(struct packenv *env, int rep)
413{
414 uint16_t v = htons(*(uint16_t *)(env->buf_base + env->buf_pos));
415 printunum(env->fp, v);
416 env->buf_pos += sizeof(uint16_t);
417}
418
419/* V - An unsigned long (32-bit) in "VAX" (little-endian) order. */
420static void
421V_packer(struct packenv *env, int rep)
422{
423 if (env->buf_base) {
424 char *arg = packenv_get(env);
425 if (arg) {
426 uintmax_t x;
427 if (getunum(arg, UINT32_MAX, &x) == 0) {
428 uint32_t v = ntohl((uint32_t) x);
429 memcpy(env->buf_base + env->buf_pos,
430 &v, sizeof(v));
431 }
432 }
433 }
434 env->buf_pos += sizeof(uint32_t);
435}
436
437static void
438V_unpacker(struct packenv *env, int rep)
439{
440 uint32_t v = htonl(*(uint32_t *)(env->buf_base + env->buf_pos));
441 printunum(env->fp, v);
442 env->buf_pos += sizeof(uint32_t);
443}
444
445/* f - A single-precision float in native format. */
446static void
447f_packer(struct packenv *env, int rep)
448{
449 if (env->buf_base) {
450 char *arg = packenv_get(env);
451 if (arg) {
452 float v;
453 char *p;
454
455 errno = 0;
456 v = strtof(arg, &p);
457 if (*p == 0 && errno == 0)
458 memcpy(env->buf_base + env->buf_pos,
459 &v, sizeof(v));
460 }
461 }
462 env->buf_pos += sizeof(float);
463}
464
465static void
466f_unpacker(struct packenv *env, int rep)
467{
468 float v = *(float *)(env->buf_base + env->buf_pos);
469 fprintf(env->fp, "%f", v); /* FIXME: Format? */
470 env->buf_pos += sizeof(uint32_t);
471}
472
473/* d - A double-precision float in native format. */
474static void
475d_packer(struct packenv *env, int rep)
476{
477 if (env->buf_base) {
478 char *arg = packenv_get(env);
479 if (arg) {
480 double v;
481 char *p;
482
483 errno = 0;
484 v = strtod(arg, &p);
485 if (*p == 0 && errno == 0)
486 memcpy(env->buf_base + env->buf_pos,
487 &v, sizeof(v));
488 }
489 }
490 env->buf_pos += sizeof(double);
491}
492
493static void
494d_unpacker(struct packenv *env, int rep)
495{
496 double v = *(double *)(env->buf_base + env->buf_pos);
497 fprintf(env->fp, "%g", v); /* FIXME: Format? */
498 env->buf_pos += sizeof(double);
499}
500
331static void 501static void
332x_packer(struct packenv *env, int rep) 502x_packer(struct packenv *env, int rep)
333{ 503{
@@ -393,7 +563,13 @@ static struct packspec packspec[] = {
393 { 'Q', 0, Q_packer, Q_unpacker }, 563 { 'Q', 0, Q_packer, Q_unpacker },
394 { 'i', 0, i_packer, i_unpacker }, 564 { 'i', 0, i_packer, i_unpacker },
395 { 'I', 0, I_packer, I_unpacker }, 565 { 'I', 0, I_packer, I_unpacker },
396 /* FIXME: n N v V f d */ 566 { 'n', 0, n_packer, n_unpacker },
567 { 'N', 0, N_packer, N_unpacker },
568 { 'v', 0, v_packer, v_unpacker },
569 { 'V', 0, V_packer, V_unpacker },
570 { 'f', 0, f_packer, f_unpacker },
571 { 'd', 0, d_packer, d_unpacker },
572
397 { 'x', 0, x_packer, x_unpacker }, 573 { 'x', 0, x_packer, x_unpacker },
398 { 'X', 0, X_packer, X_packer }, 574 { 'X', 0, X_packer, X_packer },
399 { '@', F_REP, at_packer, at_unpacker }, 575 { '@', F_REP, at_packer, at_unpacker },

Return to:

Send suggestions and report system problems to the System administrator.