diff options
Diffstat (limited to 'src/VBox/Runtime/common/misc/sg.cpp')
-rw-r--r-- | src/VBox/Runtime/common/misc/sg.cpp | 58 |
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; +} + |