From 3448749de67974c30bc62d86c2d986d27d526f0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 Nov 2018 11:56:18 +0100 Subject: [PATCH] - replaced a few temporary allocations with TArray and added a few convenience loader functions for this. Amazingly with today's optimizers this creates code which is just as good as doing it all manually with the added benefit of being safer. --- src/files.h | 8 ++++++++ src/p_setup.cpp | 26 +++++++------------------- src/p_setup.h | 7 +++++++ src/p_udmf.cpp | 6 +----- src/p_usdf.cpp | 5 +---- src/parsecontext.cpp | 8 ++------ src/sc_man.h | 4 ++++ src/tarray.h | 10 +++++----- src/w_wad.cpp | 24 ++++++++++++++++++++++++ src/w_wad.h | 1 + 10 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/files.h b/src/files.h index 4b281438f..ea24cff20 100644 --- a/src/files.h +++ b/src/files.h @@ -184,6 +184,14 @@ public: return mReader->Read(buffer, (long)len); } + TArray Read(size_t len) + { + TArray buffer((int)len, true); + Size length = mReader->Read(&buffer[0], (long)len); + buffer.Clamp((int)length); + return buffer; + } + TArray Read() { TArray buffer(mReader->Length, true); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 15cbb0b54..8f456c024 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1691,15 +1691,10 @@ uint16_t MakeSkill(int flags) void P_LoadThings (MapData * map) { - int lumplen = map->Size(ML_THINGS); - int numthings = lumplen / sizeof(mapthing_t); - - char *mtp; mapthing_t *mt; - - mtp = new char[lumplen]; - map->Read(ML_THINGS, mtp); - mt = (mapthing_t*)mtp; + auto mtp = map->Read(ML_THINGS); + int numthings = mtp.Size() / sizeof(mapthing_t); + mt = (mapthing_t*)mtp.Data(); MapThingsConverted.Resize(numthings); FMapThing *mti = &MapThingsConverted[0]; @@ -1767,7 +1762,6 @@ void P_LoadThings (MapData * map) if (flags & BTF_NOTSINGLE) mti[i].flags &= ~MTF_SINGLE; } } - delete [] mtp; } //=========================================================================== @@ -2109,29 +2103,24 @@ void P_LoadLineDefs (MapData * map) { int i, skipped; line_t *ld; - int lumplen = map->Size(ML_LINEDEFS); - char * mldf; maplinedef_t *mld; - int numlines = lumplen / sizeof(maplinedef_t); + auto mldf = map->Read(ML_LINEDEFS); + int numlines = mldf.Size() / sizeof(maplinedef_t); linemap.Resize(numlines); - mldf = new char[lumplen]; - map->Read(ML_LINEDEFS, mldf); - // [RH] Count the number of sidedef references. This is the number of // sidedefs we need. The actual number in the SIDEDEFS lump might be less. // Lines with 0 length are also removed. for (skipped = sidecount = i = 0; i < numlines; ) { - mld = ((maplinedef_t*)mldf) + i; + mld = ((maplinedef_t*)mldf.Data()) + i; unsigned v1 = LittleShort(mld->v1); unsigned v2 = LittleShort(mld->v2); if (v1 >= level.vertexes.Size() || v2 >= level.vertexes.Size()) { - delete [] mldf; I_Error ("Line %d has invalid vertices: %d and/or %d.\nThe map only contains %u vertices.", i+skipped, v1, v2, level.vertexes.Size()); } else if (v1 == v2 || @@ -2164,7 +2153,7 @@ void P_LoadLineDefs (MapData * map) P_AllocateSideDefs (map, sidecount); - mld = (maplinedef_t *)mldf; + mld = (maplinedef_t *)mldf.Data(); ld = &level.lines[0]; for (i = 0; i < numlines; i++, mld++, ld++) { @@ -2203,7 +2192,6 @@ void P_LoadLineDefs (MapData * map) if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags2 & LEVEL2_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; } - delete[] mldf; } //=========================================================================== diff --git a/src/p_setup.h b/src/p_setup.h index 1f773e951..dd3a1e1e3 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -104,6 +104,13 @@ public: } } + TArray Read(unsigned lumpindex) + { + TArray buffer(Size(lumpindex), true); + Read(lumpindex, buffer.Data(), (int)buffer.Size()); + return buffer; + } + uint32_t Size(unsigned int lumpindex) { if (lumpindexSize(ML_TEXTMAP)]; - isTranslated = true; isExtended = false; floordrop = false; - map->Read(ML_TEXTMAP, buffer); - sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), buffer, map->Size(ML_TEXTMAP)); - delete [] buffer; + sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), map->Read(ML_TEXTMAP)); sc.SetCMode(true); if (sc.CheckString("namespace")) { diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index 4838d4b8d..f24cd5d7b 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -473,10 +473,7 @@ class USDFParser : public UDMFParserBase public: bool Parse(int lumpnum, FileReader &lump, int lumplen) { - char *buffer = new char[lumplen]; - lump.Read(buffer, lumplen); - sc.OpenMem(Wads.GetLumpFullName(lumpnum), buffer, lumplen); - delete [] buffer; + sc.OpenMem(Wads.GetLumpFullName(lumpnum), lump.Read(lumplen)); sc.SetCMode(true); // Namespace must be the first field because everything else depends on it. if (sc.CheckString("namespace")) diff --git a/src/parsecontext.cpp b/src/parsecontext.cpp index cdc28c15a..9631c4b49 100644 --- a/src/parsecontext.cpp +++ b/src/parsecontext.cpp @@ -323,15 +323,12 @@ void FParseContext::ParseLump(const char *lumpname) } // Read the lump into a buffer and add a 0-terminator - int lumplen = Wads.LumpLength(lumpno); - char *lumpdata = new char[lumplen+1]; - Wads.ReadLump(lumpno, lumpdata); - lumpdata[lumplen] = 0; + auto lumpdata = Wads.ReadLumpIntoArray(lumpno, 1); SourceLine = 0; SourceFile = lumpname; - char *sourcep = lumpdata; + char *sourcep = (char*)lumpdata.Data(); while ( (tokentype = GetToken(sourcep, &token)) ) { // It is much easier to handle include statements outside the main parser. @@ -349,7 +346,6 @@ void FParseContext::ParseLump(const char *lumpname) Parse(pParser, tokentype, token, this); } } - delete [] lumpdata; SourceLine = SavedSourceLine; SourceFile = SavedSourceFile; } diff --git a/src/sc_man.h b/src/sc_man.h index 9c4f34a22..57ab6ec52 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -21,6 +21,10 @@ public: void Open(const char *lumpname); bool OpenFile(const char *filename); void OpenMem(const char *name, const char *buffer, int size); + void OpenMem(const char *name, TArray &buffer) + { + OpenMem(name, (const char*)buffer.Data(), buffer.Size()); + } void OpenString(const char *name, FString buffer); void OpenLumpNum(int lump); void Close(); diff --git a/src/tarray.h b/src/tarray.h index 8543637cd..77fc2fa5c 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -157,12 +157,12 @@ public: Count = 0; Array = NULL; } - TArray (int max, bool reserve = false) + TArray (size_t max, bool reserve = false) { - Most = max; - Count = reserve? max : 0; + Most = (unsigned)max; + Count = (unsigned)(reserve? max : 0); Array = (T *)M_Malloc (sizeof(T)*max); - if (reserve) + if (reserve && Count > 0) { ConstructEmpty(0, Count - 1); } @@ -436,7 +436,7 @@ public: Grow (amount); unsigned int place = Count; Count += amount; - ConstructEmpty(place, Count - 1); + if (Count > 0) ConstructEmpty(place, Count - 1); return place; } unsigned int Size () const diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 9c474ceb8..177a8b802 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1281,6 +1281,30 @@ void FWadCollection::ReadLump (int lump, void *dest) } } +//========================================================================== +// +// W_ReadLump +// +// Loads the lump into a TArray and returns it. +// +//========================================================================== + +TArray FWadCollection::ReadLumpIntoArray(int lump, int pad) +{ + auto lumpr = OpenLumpReader(lump); + auto size = lumpr.GetLength(); + TArray data(size + pad); + auto numread = lumpr.Read(data.Data(), size); + + if (numread != size) + { + I_Error("W_ReadLump: only read %ld of %ld on lump %i\n", + numread, size, lump); + } + if (pad > 0) memset(&data[size], 0, pad); + return data; +} + //========================================================================== // // ReadLump - variant 2 diff --git a/src/w_wad.h b/src/w_wad.h index dca4bd8fe..a7009d65e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -148,6 +148,7 @@ public: void ReadLump (int lump, void *dest); + TArray ReadLumpIntoArray(int lump, int pad = 0); // reads lump into a writable buffer and optionally adds some padding at the end. (FMemLump isn't writable!) FMemLump ReadLump (int lump); FMemLump ReadLump (const char *name) { return ReadLump (GetNumForName (name)); }