Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Break apart PackFile_unpack into more small functions

  • Loading branch information...
commit 8209940686a717a764115901e743582183156814 1 parent f8efe12
@aantn authored
Showing with 138 additions and 55 deletions.
  1. +31 −0 include/parrot/packfile.h
  2. +107 −55 src/packfile/api.c
View
31 include/parrot/packfile.h
@@ -713,6 +713,29 @@ void PackFile_funcs_register(SHIM_INTERP,
FUNC_MODIFIES(*pf);
PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+void PackFile_Header_read_uuid(PARROT_INTERP,
+ ARGMOD(PackFile_Header *self),
+ ARGIN(const opcode_t *packed),
+ size_t packed_size)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*self);
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+int PackFile_Header_unpack(PARROT_INTERP,
+ ARGMOD(PackFile_Header *self),
+ ARGIN(const opcode_t *packed),
+ size_t packed_size,
+ INTVAL pf_options)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*self);
+
+PARROT_EXPORT
void PackFile_Header_validate(PARROT_INTERP,
ARGIN(const PackFile_Header *self),
INTVAL pf_options)
@@ -955,6 +978,14 @@ void Parrot_trace_eprintf(ARGIN(const char *s), ...)
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_PackFile_funcs_register __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pf))
+#define ASSERT_ARGS_PackFile_Header_read_uuid __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self) \
+ , PARROT_ASSERT_ARG(packed))
+#define ASSERT_ARGS_PackFile_Header_unpack __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self) \
+ , PARROT_ASSERT_ARG(packed))
#define ASSERT_ARGS_PackFile_Header_validate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(self))
View
162 src/packfile/api.c
@@ -673,9 +673,6 @@ mark_const_subs(PARROT_INTERP)
}
-
-
-
/*
=item C<void PackFile_Header_validate(PARROT_INTERP, const PackFile_Header
@@ -737,6 +734,110 @@ PackFile_Header_validate(PARROT_INTERP, ARGIN(const PackFile_Header *self),
/*
+=item C<void PackFile_Header_read_uuid(PARROT_INTERP, PackFile_Header *self,
+const opcode_t *packed, size_t packed_size)>
+
+Reads a C<PackFile_Header>'s UUID from a block of memory and verifies that it is valid.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+void
+PackFile_Header_read_uuid(PARROT_INTERP, ARGMOD(PackFile_Header *self),
+ ARGIN(const opcode_t *packed), size_t packed_size)
+{
+ ASSERT_ARGS(PackFile_Header_read_uuid)
+
+ /* Check the UUID type is valid and, if needed, read a UUID. */
+ if (self->uuid_type == 0) {
+ /* No UUID; fine, nothing more to do. */
+ }
+ else if (self->uuid_type == 1) {
+ if (packed_size < (size_t) PACKFILE_HEADER_BYTES + self->uuid_size) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_Header_read_uuid: Buffer length %d is shorter than PACKFILE_HEADER_BYTES "
+ "+ uuid_size %d\n", packed_size, PACKFILE_HEADER_BYTES + self->uuid_size);
+ }
+
+ /* Read in the UUID. We'll put it in a NULL-terminated string, just in
+ * case people use it that way. */
+ self->uuid_data = mem_gc_allocate_n_typed(interp,
+ self->uuid_size + 1, unsigned char);
+
+ memcpy(self->uuid_data, packed + PACKFILE_HEADER_BYTES,
+ self->uuid_size);
+
+ /* NULL terminate */
+ self->uuid_data[self->uuid_size] = '\0';
+ }
+ else
+ /* Don't know this UUID type. */
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: Invalid UUID type %d\n", self->uuid_type);
+}
+
+
+/*
+
+=item C<int PackFile_Header_unpack(PARROT_INTERP, PackFile_Header *self, const
+opcode_t *packed, size_t packed_size, INTVAL pf_options)>
+
+Unpacks a C<PackFile_Header> from a block of memory and perform some validation
+to check that the head is correct.
+
+Returns size of unpacked header.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+int
+PackFile_Header_unpack(PARROT_INTERP, ARGMOD(PackFile_Header *self),
+ ARGIN(const opcode_t *packed), size_t packed_size,
+ INTVAL pf_options)
+{
+ ASSERT_ARGS(PackFile_Header_unpack)
+
+ /* Verify that the packfile isn't too small to contain a proper header */
+ if (packed_size < PACKFILE_HEADER_BYTES) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: Buffer length %d is shorter than PACKFILE_HEADER_BYTES %d.",
+ packed_size, PACKFILE_HEADER_BYTES);
+ }
+
+ /* Extract the header. */
+ memcpy(self, packed, PACKFILE_HEADER_BYTES);
+
+ /* Validate the header. */
+ PackFile_Header_validate(interp, self, pf_options);
+
+ /* Extract the header's UUID. */
+ PackFile_Header_read_uuid(interp, self, packed, packed_size)
+
+ /* Describe what was read for debugging. */
+ TRACE_PRINTF(("PackFile_Header_unpack: Wordsize %d.\n", self->wordsize));
+ TRACE_PRINTF(("PackFile_Header_unpack: Floattype %d (%s).\n",
+ self->floattype,
+ self->floattype == FLOATTYPE_8
+ ? FLOATTYPE_8_NAME
+ : self->floattype == FLOATTYPE_16
+ ? FLOATTYPE_16_NAME
+ : FLOATTYPE_12_NAME));
+ TRACE_PRINTF(("PackFile_Header_unpack: Byteorder %d (%sendian).\n",
+ self->byteorder, self->byteorder ? "big " : "little-"));
+
+ /* Return the number of bytes in the header */
+ return PACKFILE_HEADER_BYTES + self->uuid_size;
+}
+
+
+/*
+
=item C<opcode_t PackFile_unpack(PARROT_INTERP, PackFile *self, const opcode_t
*packed, size_t packed_size)>
@@ -765,64 +866,15 @@ PackFile_unpack(PARROT_INTERP, ARGMOD(PackFile *self),
PackFile * const pf = self;
#endif
- if (packed_size < PACKFILE_HEADER_BYTES) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Buffer length %d is shorter than PACKFILE_HEADER_BYTES %d.",
- packed_size, PACKFILE_HEADER_BYTES);
- }
-
self->src = packed;
self->size = packed_size;
- /* Extract the header. */
- memcpy(header, packed, PACKFILE_HEADER_BYTES);
-
- /* Validate the header. */
- PackFile_Header_validate(interp, self->header, self->options);
-
- /* Describe what was read for debugging. */
- TRACE_PRINTF(("PackFile_unpack: Wordsize %d.\n", header->wordsize));
- TRACE_PRINTF(("PackFile_unpack: Floattype %d (%s).\n",
- header->floattype,
- header->floattype == FLOATTYPE_8
- ? FLOATTYPE_8_NAME
- : header->floattype == FLOATTYPE_16
- ? FLOATTYPE_16_NAME
- : FLOATTYPE_12_NAME));
- TRACE_PRINTF(("PackFile_unpack: Byteorder %d (%sendian).\n",
- header->byteorder, header->byteorder ? "big " : "little-"));
-
- /* Check the UUID type is valid and, if needed, read a UUID. */
- if (header->uuid_type == 0) {
- /* No UUID; fine, nothing more to do. */
- }
- else if (header->uuid_type == 1) {
- if (packed_size < (size_t) PACKFILE_HEADER_BYTES + header->uuid_size) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Buffer length %d is shorter than PACKFILE_HEADER_BYTES "
- "+ uuid_size %d\n", packed_size, PACKFILE_HEADER_BYTES + header->uuid_size);
- }
-
-
- /* Read in the UUID. We'll put it in a NULL-terminated string, just in
- * case people use it that way. */
- header->uuid_data = mem_gc_allocate_n_typed(interp,
- header->uuid_size + 1, unsigned char);
-
- memcpy(header->uuid_data, packed + PACKFILE_HEADER_BYTES,
- header->uuid_size);
-
- /* NULL terminate */
- header->uuid_data[header->uuid_size] = '\0';
- }
- else
- /* Don't know this UUID type. */
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Invalid UUID type %d\n", header->uuid_type);
+ /* Unpack the header */
+ header_read_length = PackFile_Header_unpack(interp, self->header, packed,
+ packed_size, self->options);
/* Set cursor to position after what we've read, allowing for padding to a
* 16 byte boundary. */
- header_read_length = PACKFILE_HEADER_BYTES + header->uuid_size;
header_read_length += PAD_16_B(header_read_length);
cursor = packed + (header_read_length / sizeof (opcode_t));
TRACE_PRINTF(("PackFile_unpack: pad=%d\n",
Please sign in to comment.
Something went wrong with that request. Please try again.