summaryrefslogtreecommitdiff
path: root/libstore/decode.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-04-01 22:27:37 +0000
committerMiles Bader <miles@gnu.org>1996-04-01 22:27:37 +0000
commit2b4f7e7596b8c9e3985e3e24ce457da4d66476d0 (patch)
treee29a23dbff87d965c3bbe8795f30afae852298f8 /libstore/decode.c
parent3f886f691b2e31da9e23ff28b29a0f2fb02d818d (diff)
Formerly decode.c.~3~
Diffstat (limited to 'libstore/decode.c')
-rw-r--r--libstore/decode.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/libstore/decode.c b/libstore/decode.c
index a809bf48..a6ef9e5e 100644
--- a/libstore/decode.c
+++ b/libstore/decode.c
@@ -24,13 +24,84 @@
#include "store.h"
+/* Decodes the standard leaf device encoding that's common to various builtin
+ formats. */
+error_t
+store_default_leaf_decode (struct store_enc *enc, struct store **store)
+{
+ char *misc;
+ error_t err;
+ int type, flags;
+ mach_port_t port;
+ size_t block_size, num_runs, name_len, misc_len;
+
+ /* Make sure there are enough encoded ints and ports. */
+ if (enc->cur_int + 6 > enc->ints_len || enc->cur_port + 1 > enc->ports_len)
+ return EINVAL;
+
+ /* Read encoded ints. */
+ type = enc->ints[enc->cur_int++];
+ flags = enc->ints[enc->cur_int++];
+ block_size = enc->ints[enc->cur_int++];
+ num_runs = enc->ints[enc->cur_int++];
+ name_len = enc->ints[enc->cur_int++];
+ misc_len = enc->ints[enc->cur_int++];
+
+ /* Make sure there are enough encoded offsets and data. */
+ if (enc->cur_offset + num_runs * 2 > enc->offsets_len
+ || enc->cur_data + name_len + misc_len > enc->data_len)
+ return EINVAL;
+
+ if (ports->data[ports->cur_data + name_len - 1] != '\0')
+ return EINVAL; /* Name not terminated. */
+
+ misc = malloc (misc_len);
+ if (! misc)
+ return ENOMEM;
+
+ /* Read encoded ports (be careful to deallocate this if we barf). */
+ port = enc->ports[enc->cur_port++];
+
+ switch (type)
+ {
+ case STORAGE_DEVICE:
+ err =
+ _store_device_create (port, block_size,
+ ports->offsets + ports->curr_offset, num_runs,
+ store);
+ break;
+ case STORAGE_FILE:
+ err =
+ _store_file_create (port, block_size,
+ ports->offsets + ports->curr_offset, num_runs,
+ store);
+ break;
+ default:
+ err = EINVAL;
+ }
+
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), port);
+ free (misc);
+ }
+ else
+ {
+ (*store)->flags = flags;
+ (*store)->misc = misc;
+ (*store)->misc_len = misc_len;
+ }
+
+ return err;
+}
+
/* Decode ENC, either returning a new store in STORE, or an error. If
nothing else is to be done with ENC, its contents may then be freed using
store_enc_dealloc. */
error_t
store_decode (struct store_enc *enc, struct store **store)
{
- if (enc->cur_ints >= enc->ints_len)
+ if (enc->cur_int >= enc->ints_len)
/* The first int should always be the type. */
return EINVAL;