/************************************************************************/ /* */ /* Standard record version control. This routine returns the address */ /* of a structure containing the desired record information. This can */ /* either be the address of the raw memory image of the disk record */ /* that was read in, or a memory-allocated structure filled in element */ /* by element, depending on whether or not the disk format and the */ /* structure definitions match. Either way, byte flipping is performed */ /* as necessary by the architecture-dependent macros cp_xxxx() defined */ /* in bytflp.h */ /* */ /* Inputs: version Version number of disk image */ /* address Memory address of disk image */ /* */ /* Output: size number of bytes read from input */ /* address */ /* Return value Address of filled app structure */ /* */ /* Created April 3 2017 JPB */ /* */ /************************************************************************/ #include #include #include #include "bytflp.h" #include "type_222.h" #include "mk4_dfio.h" #include "mk4_util.h" struct type_222 * addr_222_impl (short version, void *address, int *size, int truncate_data) { int setstr_hash; int control_hash; int setstr_len; int cf_len; int setstr_pad; int cf_pad; int full_size; int i; struct type_222 *t222; struct type_222_v0 *t222_v0; if (version != T222_VERSION) { msg ("Type 222 records not yet supported by version control", 2); return (NULL); } if (version == 0) { if(truncate_data) { //just read enough to get the size and skip over the data //cast the void ptr t222_v0 = (struct type_222_v0*)address; //collect the structure data through bytflp.h routines cp_int(setstr_len, t222_v0->setstring_length); cp_int(cf_len, t222_v0->cf_length); //NOTE: making the assumption that we need alignment on 8-byte boundaries //on some machines this may not be the case, and the word size might //be 16, 32, etc. //round up to get the next multiple of 8, then add 8 bytes //done for aligned allocation and extra space for null termination int setstr_pad = (( setstr_len + 7 ) & ~7) + 8; int cf_pad = ( (cf_len + 7 ) & ~7) + 8; //now allocate and configure the return struct //There is some extra space allocated here, due to double counting //of the first 8 bytes of the char array in both sizeof and //in their padded lengths, but ~8 wasted bytes is not a big deal full_size = sizeof(struct type_222) + setstr_pad + cf_pad; t222 = (struct type_222*) malloc ( full_size ); /* Note input bytes so we can maintain */ /* pointer in file image */ *size = full_size; return (NULL); } else { //cast the void ptr t222_v0 = (struct type_222_v0*)address; //collect the structure data through bytflp.h routines cp_int(setstr_len, t222_v0->setstring_length); cp_int(cf_len, t222_v0->cf_length); //NOTE: making the assumption that we need alignment on 8-byte boundaries //on some machines this may not be the case, and the word size might //be 16, 32, etc. //round up to get the next multiple of 8, then add 8 bytes //done for aligned allocation and extra space for null termination int setstr_pad = (( setstr_len + 7 ) & ~7) + 8; int cf_pad = ( (cf_len + 7 ) & ~7) + 8; //now allocate and configure the return struct //There is some extra space allocated here, due to double counting //of the first 8 bytes of the char array in both sizeof and //in their padded lengths, but ~8 wasted bytes is not a big deal full_size = sizeof(struct type_222) + setstr_pad + cf_pad; t222 = (struct type_222*) malloc ( full_size ); /* Note input bytes so we can maintain */ /* pointer in file image */ *size = full_size; msg ("Allocated memory block %d", -1, t222); //fill in the data strncpy(t222->record_id, "222", 3); strncpy(t222->version_no, "00", 2); cp_short(t222->padded, t222_v0->padded); cp_uint(t222->setstring_hash, t222_v0->setstring_hash); cp_uint(t222->control_hash, t222_v0->control_hash); cp_int(t222->setstring_length, t222_v0->setstring_length); cp_int(t222->cf_length, t222_v0->cf_length); //copy in the set string contents (if any) memcpy(t222->control_contents, t222_v0->control_contents, setstr_len); //null out the trailing values for(i=setstr_len; icontrol_contents)[i] = '\0';} //for now we don't bother with compression (cf file size ~5k or less), //but this might be needed in the future if control files become //very complex memcpy( &( (t222->control_contents)[setstr_pad] ), &( (t222_v0->control_contents)[setstr_pad] ), cf_len); //null out the trailing values for(i = setstr_pad + cf_len; icontrol_contents)[i] = '\0';} return (t222); } } else { msg ("Unrecognized type 222 record version number %d", 2, version); return (NULL); } } struct type_222 * addr_222 (short version, void *address, int *size) { return addr_222_impl(version, address, size, 0); } struct type_222 * addr_222_dummy (short version, void *address, int *size) { return addr_222_impl(version, address, size, 1); }