summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/common/misc/sg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/common/misc/sg.cpp')
-rw-r--r--src/VBox/Runtime/common/misc/sg.cpp58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/VBox/Runtime/common/misc/sg.cpp b/src/VBox/Runtime/common/misc/sg.cpp
index fe089b81..2866722d 100644
--- a/src/VBox/Runtime/common/misc/sg.cpp
+++ b/src/VBox/Runtime/common/misc/sg.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -31,6 +31,7 @@
#include <iprt/sg.h>
#include <iprt/string.h>
#include <iprt/assert.h>
+#include <iprt/asm.h>
static void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData)
@@ -46,7 +47,7 @@ static void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData)
return NULL;
}
- AssertReleaseMsg( pSgBuf->cbSegLeft <= 5 * _1M
+ AssertReleaseMsg( pSgBuf->cbSegLeft <= 32 * _1M
&& (uintptr_t)pSgBuf->pvSegCur >= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg
&& (uintptr_t)pSgBuf->pvSegCur + pSgBuf->cbSegLeft <= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg + pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg,
("pSgBuf->idxSeg=%d pSgBuf->cSegs=%d pSgBuf->pvSegCur=%p pSgBuf->cbSegLeft=%zd pSgBuf->paSegs[%d].pvSeg=%p pSgBuf->paSegs[%d].cbSeg=%zd\n",
@@ -314,7 +315,7 @@ RTDECL(size_t) RTSgBufCopyToBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy)
}
-RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy)
+RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, const void *pvBuf, size_t cbCopy)
{
AssertPtrReturn(pSgBuf, 0);
AssertPtrReturn(pvBuf, 0);
@@ -332,7 +333,7 @@ RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy)
memcpy(pvDst, pvBuf, cbThisCopy);
cbLeft -= cbThisCopy;
- pvBuf = (void *)((uintptr_t)pvBuf + cbThisCopy);
+ pvBuf = (const void *)((uintptr_t)pvBuf + cbThisCopy);
}
return cbCopy - cbLeft;
@@ -421,3 +422,52 @@ RTDECL(size_t) RTSgBufSegArrayCreate(PRTSGBUF pSgBuf, PRTSGSEG paSeg, unsigned *
return cb;
}
+RTDECL(bool) RTSgBufIsZero(PRTSGBUF pSgBuf, size_t cbCheck)
+{
+ bool fIsZero = true;
+ size_t cbLeft = cbCheck;
+ RTSGBUF SgBufTmp;
+
+ RTSgBufClone(&SgBufTmp, pSgBuf);
+
+ while (cbLeft)
+ {
+ size_t cbThisCheck = cbLeft;
+ void *pvBuf = sgBufGet(&SgBufTmp, &cbThisCheck);
+
+ if (!cbThisCheck)
+ break;
+
+ /* Use optimized inline assembler if possible. */
+ if ( !(cbThisCheck % 4)
+ && (cbThisCheck * 8 <= UINT32_MAX))
+ {
+ if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)cbThisCheck * 8) != -1)
+ {
+ fIsZero = false;
+ break;
+ }
+ }
+ else
+ {
+ for (unsigned i = 0; i < cbThisCheck; i++)
+ {
+ char *pbBuf = (char *)pvBuf;
+ if (*pbBuf)
+ {
+ fIsZero = false;
+ break;
+ }
+ pvBuf = pbBuf + 1;
+ }
+
+ if (!fIsZero)
+ break;
+ }
+
+ cbLeft -= cbThisCheck;
+ }
+
+ return fIsZero;
+}
+