void ConvertObsolete (ushort OldIndex) { uchar *TypeString; TENTRY *OldEntry; int i; uchar type; converttypefcn * pTypeFcn; CV_typ_t forward; OldEntry = GetTypeEntry (OldIndex, &forward); DASSERT(!OldEntry->flags.IsNewFormat); TypeString = OldEntry->TypeString; // get the string type = TypeString[3]; for (pTypeFcn = C6ConvertTypeFcn, i = 0; i < C6CONVERTTYPECNT; i++, pTypeFcn++) { if (pTypeFcn->oldtyp == type) { break; } } if (i != C6CONVERTTYPECNT) { pTypeFcn->pfcn (OldEntry); } else { // unexpected C6 type - convert to a nil type // sps - 12/2/92 Warn (WARN_BADTYP, FormatMod (pCurMod), NULL); C6CnvtNilType (OldEntry); } }
int LES_TypeData::GetTypeEntrySlow(const LES_uint hash) const { /* This is horribly slow - need hash lookup table */ const int numTypes = m_numTypes; for (int i = 0; i < numTypes; i++) { const LES_TypeEntry* const typeEntryPtr = GetTypeEntry(i); if (typeEntryPtr->m_hash == hash) { return i; } } return -1; }
LOCAL void C6CnvtArgList (ushort usArgList, ushort usCount) { uchar * pchTypeStr; uchar * pchTypeStrBase; // The base of the original type string plfArgList plf; ushort usNTotal; // New length of symbol including length field ushort usNewLength; // New paded length excluding length field. ushort usfInTmp; // True if string stored in temporary buffer uchar * pchDest; ushort i; uchar * pchDestBase; TENTRY *OldEntry; CV_typ_t forward; OldEntry = GetTypeEntry ((CV_typ_t)(usArgList - 512), &forward); if (OldEntry->flags.IsNewFormat) { return; } OldEntry->flags.IsNewFormat = TRUE; pchTypeStr = OldEntry->TypeString; // get the string pchTypeStrBase = pchTypeStr; DASSERT((pchTypeStr[3] == OLF_LIST) || (pchTypeStr[3] == OLF_ARGLIST) || ((usCount != 0) && (pchTypeStr[3] == OLF_NIL))); // calculate new length usNTotal = LNGTHSZ + offsetof (lfArgList, arg) + (sizeof(CV_typ_t) * usCount); usNewLength = usNTotal - LNGTHSZ; // Get some memory to put the result in if (usNewLength + LNGTHSZ <= LENGTH (pchTypeStr) + 3) { // Get some scratch memory so we don't wipe out the memory we are // are attempting to rewrite. usfInTmp = TRUE; pchDest = GetScratchString (usNewLength + LNGTHSZ); } else { usfInTmp = FALSE; pchDest = Alloc (usNewLength + LNGTHSZ); } pchDestBase = pchDest; pchTypeStr += 4; // Skip to the arguments; *((ushort*)pchDest)++ = usNewLength; plf = (plfArgList) pchDest; plf->leaf = LF_ARGLIST; plf->count = usCount; // Loop through copying the indexes from the old to the new. for (i = 0; i < usCount; i++) { plf->arg[i] = getindex (pchTypeStr); } pchDest = (uchar *) &(plf->arg[i]); if (usfInTmp) { // Copy the new string over the old one memcpy (OldEntry->TypeString, pchDestBase, usNewLength + LNGTHSZ); DASSERT(pchDest == pchDestBase + usNewLength + LNGTHSZ); } else { FreeAllocStrings (OldEntry); OldEntry->flags.IsMalloced = TRUE; OldEntry->TypeString = pchDestBase; DASSERT(pchDest == OldEntry->TypeString + usNewLength + LNGTHSZ); } }
LOCAL ushort MergeLists (ushort tList, ushort nList, ushort Count) { uchar *TypeIndexString, *NameOffsetString; uchar *ScratchString; // temporary work uchar *ScratchSave; uchar *OffsetStart; ushort Length; ushort FinalLength; int i; CV_fldattr_t mattrib = {0}; TENTRY *TypeEntry, *NameEntry; CV_typ_t forward; mattrib.access = CV_public; // public access field TypeEntry = GetTypeEntry ((CV_typ_t)(tList - 512), &forward); NameEntry = GetTypeEntry ((CV_typ_t)(nList - 512), &forward); // Get the two strings to walk TypeIndexString = TypeEntry->TypeString; NameOffsetString = NameEntry->TypeString; // Calculate the longest possible result // We are intentionally wasting memory to avoid walking the list // two times. Length = LNGTHSZ // Size of length field + MAXPAD // So we can align the start + offsetof (lfFieldList, data) // Field leaf size + (LENGTH (NameOffsetString) - 1) // Variable length data size + (Count // Number of fields times * (offsetof (lfMember, offset) // Size LF_MEMBER structure plus + MAXPAD // Maximum number of pad bytes per field + MAXC6NUMERICGROWTH)); // Maximum possible growth of numeric field TypeIndexString += 4; // skip to indices NameOffsetString += 4; // skip to names ScratchString = GetScratchString (Length); // get a scratch string //M00SPEED This logic could be moved to GetScratchSize // This garantees we can do padding when running with any malloc version while((ulong)ScratchString & MAXPAD) { // Make sure buffer starts on a four byte boundry ScratchString++; } ScratchSave = ScratchString; // Start building new C7 field list ScratchString += LNGTHSZ; // Skip Length (fill in later with exact size) *((ushort *)ScratchString)++ = LF_FIELDLIST; for (; Count > 0; Count --) { DASSERT(*NameOffsetString == OLF_NAME); DASSERT(*TypeIndexString == OLF_INDEX); NameOffsetString ++; // skip OLF_NAME *((ushort *)ScratchString)++ = LF_MEMBER; *((ushort *)ScratchString)++ = getindex (TypeIndexString); *((CV_fldattr_t *)ScratchString)++ = mattrib; // Temporarily skip over the string OffsetStart = NameOffsetString + *NameOffsetString + 1; ConvertNumeric (&OffsetStart, &ScratchString); // copy over the name for (i = *NameOffsetString + 1; i; i --) { *ScratchString ++ = *NameOffsetString ++; } // update the name offset string NameOffsetString = OffsetStart; // Pad the new leaf if ((ulong)ScratchString & MAXPAD) { *ScratchString = (uchar)(0xF0 + MAXPAD + 1 - ((ulong)ScratchString & MAXPAD)); while((ulong)(++ScratchString) & MAXPAD) { *ScratchString = 0; } } } TypeIndexString = TypeEntry->TypeString; NameOffsetString = NameEntry->TypeString; FinalLength = ScratchString - ScratchSave; DASSERT(FinalLength <= Length); *((ushort *)(ScratchSave)) = FinalLength - LNGTHSZ; // Allocate memory and copy the type string into it TypeIndexString = AllocNewStr (TypeEntry, FinalLength); TypeEntry->flags.IsNewFormat = TRUE; memcpy (TypeIndexString, ScratchSave, FinalLength); return (tList); }