Skip to content

Commit

Permalink
mapshape: msSHPReadAllocateBuffer() returns buffer
Browse files Browse the repository at this point in the history
This avoids lots of memory accesses, because the pointer is now in a
local variable.  Previously, the disassembly looked very clumsy,
because each occurrence of "psSHP->pabyRec" needed to reload the
register from RAM.
  • Loading branch information
MaxKellermann committed Oct 7, 2021
1 parent 359b160 commit dfc4559
Showing 1 changed file with 36 additions and 34 deletions.
70 changes: 36 additions & 34 deletions mapshape.c
Expand Up @@ -994,14 +994,14 @@ int msSHPWriteShape(SHPHandle psSHP, shapeObj *shape )
/*
** msSHPReadAllocateBuffer() - Ensure our record buffer is large enough.
*/
static int msSHPReadAllocateBuffer( SHPHandle psSHP, int hEntity, const char* pszCallingFunction)
static uchar *msSHPReadAllocateBuffer( SHPHandle psSHP, int hEntity, const char* pszCallingFunction)
{

int nEntitySize = msSHXReadSize(psSHP, hEntity);
if( nEntitySize < 0 || nEntitySize > INT_MAX - 8 ) {
msSetError(MS_MEMERR, "Out of memory. Cannot allocate %d bytes. Probably broken shapefile at feature %d",
pszCallingFunction, nEntitySize, hEntity);
return(MS_FAILURE);
return NULL;
}
nEntitySize += 8;
/* -------------------------------------------------------------------- */
Expand All @@ -1012,12 +1012,12 @@ static int msSHPReadAllocateBuffer( SHPHandle psSHP, int hEntity, const char* ps
if (pabyRec == NULL) {
msSetError(MS_MEMERR, "Out of memory. Cannot allocate %d bytes. Probably broken shapefile at feature %d",
pszCallingFunction, nEntitySize, hEntity);
return(MS_FAILURE);
return NULL;
}
psSHP->pabyRec = pabyRec;
psSHP->nBufSize = nEntitySize;
}
return MS_SUCCESS;
return psSHP->pabyRec;
}

/*
Expand Down Expand Up @@ -1054,7 +1054,8 @@ int msSHPReadPoint( SHPHandle psSHP, int hEntity, pointObj *point )
return(MS_FAILURE);
}

if (msSHPReadAllocateBuffer(psSHP, hEntity, "msSHPReadPoint()") == MS_FAILURE) {
uchar *pabyRec = msSHPReadAllocateBuffer(psSHP, hEntity, "msSHPReadPoint()");
if (pabyRec == NULL) {
return MS_FAILURE;
}

Expand All @@ -1065,14 +1066,14 @@ int msSHPReadPoint( SHPHandle psSHP, int hEntity, pointObj *point )
msSetError(MS_IOERR, "failed to seek offset", "msSHPReadPoint()");
return(MS_FAILURE);
}
if( 1 != VSIFReadL( psSHP->pabyRec, nEntitySize, 1, psSHP->fpSHP )) {
if( 1 != VSIFReadL( pabyRec, nEntitySize, 1, psSHP->fpSHP )) {
msSetError(MS_IOERR, "failed to fread record", "msSHPReadPoint()");
return(MS_FAILURE);
}


memcpy( &(point->x), psSHP->pabyRec + 12, 8 );
memcpy( &(point->y), psSHP->pabyRec + 20, 8 );
memcpy( &(point->x), pabyRec + 12, 8 );
memcpy( &(point->y), pabyRec + 20, 8 );

if( bBigEndian ) {
SwapWord( 8, &(point->x));
Expand Down Expand Up @@ -1237,7 +1238,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
return;
}

if (msSHPReadAllocateBuffer(psSHP, hEntity, "msSHPReadShape()") == MS_FAILURE) {
uchar *pabyRec = msSHPReadAllocateBuffer(psSHP, hEntity, "msSHPReadShape()");
if (pabyRec == NULL) {
shape->type = MS_SHAPE_NULL;
return;
}
Expand All @@ -1250,7 +1252,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
shape->type = MS_SHAPE_NULL;
return;
}
if( 1 != VSIFReadL( psSHP->pabyRec, nEntitySize, 1, psSHP->fpSHP )) {
if( 1 != VSIFReadL( pabyRec, nEntitySize, 1, psSHP->fpSHP )) {
msSetError(MS_IOERR, "failed to fread record", "msSHPReadPoint()");
shape->type = MS_SHAPE_NULL;
return;
Expand All @@ -1272,10 +1274,10 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
}

/* copy the bounding box */
memcpy( &shape->bounds.minx, psSHP->pabyRec + 8 + 4, 8 );
memcpy( &shape->bounds.miny, psSHP->pabyRec + 8 + 12, 8 );
memcpy( &shape->bounds.maxx, psSHP->pabyRec + 8 + 20, 8 );
memcpy( &shape->bounds.maxy, psSHP->pabyRec + 8 + 28, 8 );
memcpy( &shape->bounds.minx, pabyRec + 8 + 4, 8 );
memcpy( &shape->bounds.miny, pabyRec + 8 + 12, 8 );
memcpy( &shape->bounds.maxx, pabyRec + 8 + 20, 8 );
memcpy( &shape->bounds.maxy, pabyRec + 8 + 28, 8 );

if( bBigEndian ) {
SwapWord( 8, &shape->bounds.minx);
Expand All @@ -1284,8 +1286,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
SwapWord( 8, &shape->bounds.maxy);
}

memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
memcpy( &nPoints, pabyRec + 40 + 8, 4 );
memcpy( &nParts, pabyRec + 36 + 8, 4 );

if( bBigEndian ) {
nPoints = SWAP_FOUR_BYTES(nPoints);
Expand Down Expand Up @@ -1332,7 +1334,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
return;
}

memcpy( psSHP->panParts, psSHP->pabyRec + 44 + 8, 4 * nParts );
memcpy( psSHP->panParts, pabyRec + 44 + 8, 4 * nParts );
if( bBigEndian ) {
for( i = 0; i < nParts; i++ ) {
*(psSHP->panParts+i) = SWAP_FOUR_BYTES(*(psSHP->panParts+i));
Expand Down Expand Up @@ -1379,8 +1381,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )

/* nOffset = 44 + 8 + 4*nParts; */
for( j = 0; j < shape->line[i].numpoints; j++ ) {
memcpy(&(shape->line[i].point[j].x), psSHP->pabyRec + 44 + 4*nParts + 8 + k * 16, 8 );
memcpy(&(shape->line[i].point[j].y), psSHP->pabyRec + 44 + 4*nParts + 8 + k * 16 + 8, 8 );
memcpy(&(shape->line[i].point[j].x), pabyRec + 44 + 4*nParts + 8 + k * 16, 8 );
memcpy(&(shape->line[i].point[j].y), pabyRec + 44 + 4*nParts + 8 + k * 16 + 8, 8 );

if( bBigEndian ) {
SwapWord( 8, &(shape->line[i].point[j].x) );
Expand All @@ -1394,7 +1396,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
if (psSHP->nShapeType == SHP_POLYGONZ || psSHP->nShapeType == SHP_ARCZ) {
const int nOffset = 44 + 8 + (4*nParts) + (16*nPoints) ;
if( nEntitySize >= nOffset + 16 + 8*nPoints ) {
memcpy(&(shape->line[i].point[j].z), psSHP->pabyRec + nOffset + 16 + k*8, 8 );
memcpy(&(shape->line[i].point[j].z), pabyRec + nOffset + 16 + k*8, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[i].point[j].z) );
}
}
Expand All @@ -1406,7 +1408,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
if (psSHP->nShapeType == SHP_POLYGONM || psSHP->nShapeType == SHP_ARCM) {
const int nOffset = 44 + 8 + (4*nParts) + (16*nPoints) ;
if( nEntitySize >= nOffset + 16 + 8*nPoints ) {
memcpy(&(shape->line[i].point[j].m), psSHP->pabyRec + nOffset + 16 + k*8, 8 );
memcpy(&(shape->line[i].point[j].m), pabyRec + nOffset + 16 + k*8, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[i].point[j].m) );
}
}
Expand Down Expand Up @@ -1438,10 +1440,10 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
}

/* copy the bounding box */
memcpy( &shape->bounds.minx, psSHP->pabyRec + 8 + 4, 8 );
memcpy( &shape->bounds.miny, psSHP->pabyRec + 8 + 12, 8 );
memcpy( &shape->bounds.maxx, psSHP->pabyRec + 8 + 20, 8 );
memcpy( &shape->bounds.maxy, psSHP->pabyRec + 8 + 28, 8 );
memcpy( &shape->bounds.minx, pabyRec + 8 + 4, 8 );
memcpy( &shape->bounds.miny, pabyRec + 8 + 12, 8 );
memcpy( &shape->bounds.maxx, pabyRec + 8 + 20, 8 );
memcpy( &shape->bounds.maxy, pabyRec + 8 + 28, 8 );

if( bBigEndian ) {
SwapWord( 8, &shape->bounds.minx);
Expand All @@ -1450,7 +1452,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
SwapWord( 8, &shape->bounds.maxy);
}

memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
memcpy( &nPoints, pabyRec + 44, 4 );
if( bBigEndian ) nPoints = SWAP_FOUR_BYTES(nPoints);

/* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -1498,8 +1500,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
}

for( i = 0; i < nPoints; i++ ) {
memcpy(&(shape->line[0].point[i].x), psSHP->pabyRec + 48 + 16 * i, 8 );
memcpy(&(shape->line[0].point[i].y), psSHP->pabyRec + 48 + 16 * i + 8, 8 );
memcpy(&(shape->line[0].point[i].x), pabyRec + 48 + 16 * i, 8 );
memcpy(&(shape->line[0].point[i].y), pabyRec + 48 + 16 * i + 8, 8 );

if( bBigEndian ) {
SwapWord( 8, &(shape->line[0].point[i].x) );
Expand All @@ -1512,7 +1514,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
shape->line[0].point[i].z = 0; /* initialize */
if (psSHP->nShapeType == SHP_MULTIPOINTZ) {
const int nOffset = 48 + 16*nPoints;
memcpy(&(shape->line[0].point[i].z), psSHP->pabyRec + nOffset + 16 + i*8, 8 );
memcpy(&(shape->line[0].point[i].z), pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[0].point[i].z));
}

Expand All @@ -1522,7 +1524,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
shape->line[0].point[i].m = 0; /* initialize */
if (psSHP->nShapeType == SHP_MULTIPOINTM) {
const int nOffset = 48 + 16*nPoints;
memcpy(&(shape->line[0].point[i].m), psSHP->pabyRec + nOffset + 16 + i*8, 8 );
memcpy(&(shape->line[0].point[i].m), pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[0].point[i].m));
}
}
Expand Down Expand Up @@ -1553,8 +1555,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
shape->line[0].numpoints = 1;
shape->line[0].point = (pointObj *) msSmallMalloc(sizeof(pointObj));

memcpy( &(shape->line[0].point[0].x), psSHP->pabyRec + 12, 8 );
memcpy( &(shape->line[0].point[0].y), psSHP->pabyRec + 20, 8 );
memcpy( &(shape->line[0].point[0].x), pabyRec + 12, 8 );
memcpy( &(shape->line[0].point[0].y), pabyRec + 20, 8 );

if( bBigEndian ) {
SwapWord( 8, &(shape->line[0].point[0].x));
Expand All @@ -1568,7 +1570,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
if (psSHP->nShapeType == SHP_POINTZ) {
const int nOffset = 20 + 8;
if( nEntitySize >= nOffset + 8 ) {
memcpy(&(shape->line[0].point[0].z), psSHP->pabyRec + nOffset, 8 );
memcpy(&(shape->line[0].point[0].z), pabyRec + nOffset, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[0].point[0].z));
}
}
Expand All @@ -1580,7 +1582,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape )
if (psSHP->nShapeType == SHP_POINTM) {
const int nOffset = 20 + 8;
if( nEntitySize >= nOffset + 8 ) {
memcpy(&(shape->line[0].point[0].m), psSHP->pabyRec + nOffset, 8 );
memcpy(&(shape->line[0].point[0].m), pabyRec + nOffset, 8 );
if( bBigEndian ) SwapWord( 8, &(shape->line[0].point[0].m));
}
}
Expand Down

0 comments on commit dfc4559

Please sign in to comment.