354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync/* $Id$ */
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync/** @file
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * IPRT - S/G buffer handling.
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync */
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2013 Oracle Corporation
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync *
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * available from http://www.virtualbox.org. This file is free software;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * General Public License (GPL) as published by the Free Software
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync *
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * The contents of this file may alternatively be used under the terms
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * of the Common Development and Distribution License Version 1.0
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * VirtualBox OSE distribution, in which case the provisions of the
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * CDDL are applicable instead of those of the GPL.
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync *
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * You may elect to license modified versions of this file under the
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync * terms and conditions of either the GPL or the CDDL or both.
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync */
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync/*******************************************************************************
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync* Header Files *
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync*******************************************************************************/
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync#include <iprt/sg.h>
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync#include <iprt/string.h>
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync#include <iprt/assert.h>
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync#include <iprt/asm.h>
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncstatic void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync size_t cbData;
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync void *pvBuf;
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync /* Check that the S/G buffer has memory left. */
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync if (RT_UNLIKELY( pSgBuf->idxSeg == pSgBuf->cSegs
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync && !pSgBuf->cbSegLeft))
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync {
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync *pcbData = 0;
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync return NULL;
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef RDESKTOP
9df6a850ccaf90fbecc4c7bb6e4e761f6fa2ec12vboxsync AssertReleaseMsg( pSgBuf->cbSegLeft <= 32 * _1M
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync && (uintptr_t)pSgBuf->pvSegCur >= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync && (uintptr_t)pSgBuf->pvSegCur + pSgBuf->cbSegLeft <= (uintptr_t)pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg + pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg,
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync ("pSgBuf->idxSeg=%d pSgBuf->cSegs=%d pSgBuf->pvSegCur=%p pSgBuf->cbSegLeft=%zd pSgBuf->paSegs[%d].pvSeg=%p pSgBuf->paSegs[%d].cbSeg=%zd\n",
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync pSgBuf->idxSeg, pSgBuf->cSegs, pSgBuf->pvSegCur, pSgBuf->cbSegLeft,
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync pSgBuf->idxSeg, pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg, pSgBuf->idxSeg, pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
44a56c2ffd522c0ef282907c9b07641d06dc143avboxsync
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync cbData = RT_MIN(*pcbData, pSgBuf->cbSegLeft);
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync pvBuf = pSgBuf->pvSegCur;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBuf->cbSegLeft -= cbData;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync /* Advance to the next segment if required. */
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (!pSgBuf->cbSegLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBuf->idxSeg++;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
89c28c87cc69edce638703dbfa181d6d67daf17bvboxsync if (pSgBuf->idxSeg < pSgBuf->cSegs)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->pvSegCur = pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->cbSegLeft = pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync *pcbData = cbData;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync else
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->pvSegCur = (uint8_t *)pSgBuf->pvSegCur + cbData;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return pvBuf;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
cb6fa623dea342f8cdb056585d3237e0bffd970avboxsyncRTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, size_t cSegs)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync AssertPtr(pSgBuf);
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync AssertPtr(paSegs);
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync Assert(cSegs > 0);
cb6fa623dea342f8cdb056585d3237e0bffd970avboxsync Assert(cSegs < (~(unsigned)0 >> 1));
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->paSegs = paSegs;
cb6fa623dea342f8cdb056585d3237e0bffd970avboxsync pSgBuf->cSegs = (unsigned)cSegs;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBuf->idxSeg = 0;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->pvSegCur = paSegs[0].pvSeg;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->cbSegLeft = paSegs[0].cbSeg;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(void) RTSgBufReset(PRTSGBUF pSgBuf)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturnVoid(pSgBuf);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBuf->idxSeg = 0;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->pvSegCur = pSgBuf->paSegs[0].pvSeg;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBuf->cbSegLeft = pSgBuf->paSegs[0].cbSeg;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(void) RTSgBufClone(PRTSGBUF pSgBufTo, PCRTSGBUF pSgBufFrom)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync AssertPtr(pSgBufTo);
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync AssertPtr(pSgBufFrom);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBufTo->paSegs = pSgBufFrom->paSegs;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBufTo->cSegs = pSgBufFrom->cSegs;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBufTo->idxSeg = pSgBufFrom->idxSeg;
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pSgBufTo->pvSegCur = pSgBufFrom->pvSegCur;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pSgBufTo->cbSegLeft = pSgBufFrom->cbSegLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsyncRTDECL(void *) RTSgBufGetNextSegment(PRTSGBUF pSgBuf, size_t *pcbSeg)
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync{
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync AssertPtrReturn(pSgBuf, NULL);
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync AssertPtrReturn(pcbSeg, NULL);
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync if (!*pcbSeg)
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync *pcbSeg = pSgBuf->cbSegLeft;
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync return sgBufGet(pSgBuf, pcbSeg);
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync}
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync
6337fd8860ce7d3ae9835f9bee38c15ecbabc86avboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(size_t) RTSgBufCopy(PRTSGBUF pSgBufDst, PRTSGBUF pSgBufSrc, size_t cbCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBufDst, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBufSrc, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbLeft = cbCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync while (cbLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbThisCopy = RT_MIN(RT_MIN(pSgBufDst->cbSegLeft, cbLeft), pSgBufSrc->cbSegLeft);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbTmp = cbThisCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvBufDst;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvBufSrc;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
6bf3b95b543a9eacd1025b4c3c6409f9765099a8vboxsync if (!cbThisCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync break;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pvBufDst = sgBufGet(pSgBufDst, &cbTmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync Assert(cbTmp == cbThisCopy);
6bf3b95b543a9eacd1025b4c3c6409f9765099a8vboxsync pvBufSrc = sgBufGet(pSgBufSrc, &cbTmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync Assert(cbTmp == cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync memcpy(pvBufDst, pvBufSrc, cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync cbLeft -= cbThisCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return cbCopy - cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(int) RTSgBufCmp(PCRTSGBUF pSgBuf1, PCRTSGBUF pSgBuf2, size_t cbCmp)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf1, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf2, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbLeft = cbCmp;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync RTSGBUF SgBuf1;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync RTSGBUF SgBuf2;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync /* Set up the temporary buffers */
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync RTSgBufClone(&SgBuf1, pSgBuf1);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync RTSgBufClone(&SgBuf2, pSgBuf2);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync while (cbLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbThisCmp = RT_MIN(RT_MIN(SgBuf1.cbSegLeft, cbLeft), SgBuf2.cbSegLeft);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbTmp = cbThisCmp;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvBuf1;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvBuf2;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (!cbCmp)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync break;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pvBuf1 = sgBufGet(&SgBuf1, &cbTmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync Assert(cbTmp == cbThisCmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pvBuf2 = sgBufGet(&SgBuf2, &cbTmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync Assert(cbTmp == cbThisCmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
56ccab4900bbf793311dfa586556f766bd504bd2vboxsync int rc = memcmp(pvBuf1, pvBuf2, cbThisCmp);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (rc)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return rc;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync cbLeft -= cbThisCmp;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return 0;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsyncRTDECL(int) RTSgBufCmpEx(PRTSGBUF pSgBuf1, PRTSGBUF pSgBuf2, size_t cbCmp,
018872730d2bb228577f818371b9b3d513168a74vboxsync size_t *pcbOff, bool fAdvance)
018872730d2bb228577f818371b9b3d513168a74vboxsync{
018872730d2bb228577f818371b9b3d513168a74vboxsync AssertPtrReturn(pSgBuf1, 0);
018872730d2bb228577f818371b9b3d513168a74vboxsync AssertPtrReturn(pSgBuf2, 0);
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync size_t cbLeft = cbCmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync size_t cbOff = 0;
018872730d2bb228577f818371b9b3d513168a74vboxsync RTSGBUF SgBuf1Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync RTSGBUF SgBuf2Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync PRTSGBUF pSgBuf1Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync PRTSGBUF pSgBuf2Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync if (!fAdvance)
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync /* Set up the temporary buffers */
018872730d2bb228577f818371b9b3d513168a74vboxsync RTSgBufClone(&SgBuf1Tmp, pSgBuf1);
018872730d2bb228577f818371b9b3d513168a74vboxsync RTSgBufClone(&SgBuf2Tmp, pSgBuf2);
018872730d2bb228577f818371b9b3d513168a74vboxsync pSgBuf1Tmp = &SgBuf1Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync pSgBuf2Tmp = &SgBuf2Tmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync else
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync pSgBuf1Tmp = pSgBuf1;
018872730d2bb228577f818371b9b3d513168a74vboxsync pSgBuf2Tmp = pSgBuf2;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync while (cbLeft)
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync size_t cbThisCmp = RT_MIN(RT_MIN(pSgBuf1Tmp->cbSegLeft, cbLeft), pSgBuf2Tmp->cbSegLeft);
018872730d2bb228577f818371b9b3d513168a74vboxsync size_t cbTmp = cbThisCmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync uint8_t *pbBuf1;
018872730d2bb228577f818371b9b3d513168a74vboxsync uint8_t *pbBuf2;
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync if (!cbCmp)
018872730d2bb228577f818371b9b3d513168a74vboxsync break;
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync pbBuf1 = (uint8_t *)sgBufGet(pSgBuf1Tmp, &cbTmp);
018872730d2bb228577f818371b9b3d513168a74vboxsync Assert(cbTmp == cbThisCmp);
018872730d2bb228577f818371b9b3d513168a74vboxsync pbBuf2 = (uint8_t *)sgBufGet(pSgBuf2Tmp, &cbTmp);
018872730d2bb228577f818371b9b3d513168a74vboxsync Assert(cbTmp == cbThisCmp);
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync int rc = memcmp(pbBuf1, pbBuf2, cbThisCmp);
018872730d2bb228577f818371b9b3d513168a74vboxsync if (rc)
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync if (pcbOff)
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync /* Search for the correct offset */
018872730d2bb228577f818371b9b3d513168a74vboxsync while ( cbThisCmp-- > 0
018872730d2bb228577f818371b9b3d513168a74vboxsync && (*pbBuf1 == *pbBuf2))
018872730d2bb228577f818371b9b3d513168a74vboxsync {
018872730d2bb228577f818371b9b3d513168a74vboxsync pbBuf1++;
018872730d2bb228577f818371b9b3d513168a74vboxsync pbBuf2++;
018872730d2bb228577f818371b9b3d513168a74vboxsync cbOff++;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync *pcbOff = cbOff;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync return rc;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync cbLeft -= cbThisCmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync cbOff += cbThisCmp;
018872730d2bb228577f818371b9b3d513168a74vboxsync }
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync return 0;
018872730d2bb228577f818371b9b3d513168a74vboxsync}
018872730d2bb228577f818371b9b3d513168a74vboxsync
018872730d2bb228577f818371b9b3d513168a74vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(size_t) RTSgBufSet(PRTSGBUF pSgBuf, uint8_t ubFill, size_t cbSet)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbLeft = cbSet;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync while (cbLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbThisSet = cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvBuf = sgBufGet(pSgBuf, &cbThisSet);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (!cbThisSet)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync break;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync memset(pvBuf, ubFill, cbThisSet);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync cbLeft -= cbThisSet;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return cbSet - cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(size_t) RTSgBufCopyToBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pvBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbLeft = cbCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync while (cbLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbThisCopy = cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvSrc = sgBufGet(pSgBuf, &cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (!cbThisCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync break;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync memcpy(pvBuf, pvSrc, cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync cbLeft -= cbThisCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync pvBuf = (void *)((uintptr_t)pvBuf + cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return cbCopy - cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
f5307deb2af02309e5320206881885148c6f48e4vboxsyncRTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, const void *pvBuf, size_t cbCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pvBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbLeft = cbCopy;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync while (cbLeft)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync size_t cbThisCopy = cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync void *pvDst = sgBufGet(pSgBuf, &cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync if (!cbThisCopy)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync break;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync memcpy(pvDst, pvBuf, cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync cbLeft -= cbThisCopy;
f5307deb2af02309e5320206881885148c6f48e4vboxsync pvBuf = (const void *)((uintptr_t)pvBuf + cbThisCopy);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return cbCopy - cbLeft;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsyncRTDECL(size_t) RTSgBufAdvance(PRTSGBUF pSgBuf, size_t cbAdvance)
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync{
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync AssertPtrReturn(pSgBuf, 0);
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync size_t cbLeft = cbAdvance;
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync while (cbLeft)
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync {
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync size_t cbThisAdvance = cbLeft;
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync void *pv = sgBufGet(pSgBuf, &cbThisAdvance);
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync NOREF(pv);
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync if (!cbThisAdvance)
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync break;
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync cbLeft -= cbThisAdvance;
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync }
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync return cbAdvance - cbLeft;
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync}
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
c1e15b3c98815ead93f67b8eb8b116189497cfb4vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsyncRTDECL(size_t) RTSgBufSegArrayCreate(PRTSGBUF pSgBuf, PRTSGSEG paSeg, unsigned *pcSeg, size_t cbData)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync{
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pSgBuf, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync AssertPtrReturn(pcSeg, 0);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync unsigned cSeg = 0;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync size_t cb = 0;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync if (!paSeg)
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync if (pSgBuf->cbSegLeft > 0)
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync size_t idx = pSgBuf->idxSeg;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cSeg = 1;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cb += RT_MIN(pSgBuf->cbSegLeft, cbData);
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cbData -= RT_MIN(pSgBuf->cbSegLeft, cbData);
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync while ( cbData
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync && idx < pSgBuf->cSegs - 1)
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync idx++;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cSeg++;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cb += RT_MIN(pSgBuf->paSegs[idx].cbSeg, cbData);
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cbData -= RT_MIN(pSgBuf->paSegs[idx].cbSeg, cbData);
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync }
889f3471a14a59aa88ab144a0f37543c19aee445vboxsync }
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync }
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync else
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync while ( cbData
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync && cSeg < *pcSeg)
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync size_t cbThisSeg = cbData;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync void *pvSeg = NULL;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync pvSeg = sgBufGet(pSgBuf, &cbThisSeg);
889f3471a14a59aa88ab144a0f37543c19aee445vboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync if (!cbThisSeg)
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync {
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync Assert(!pvSeg);
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync break;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync AssertMsg(cbThisSeg <= cbData, ("Impossible!\n"));
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync paSeg[cSeg].cbSeg = cbThisSeg;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync paSeg[cSeg].pvSeg = pvSeg;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cSeg++;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cbData -= cbThisSeg;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync cb += cbThisSeg;
83a8011f7acdb5bbbd1fe141846dfeeb0a53d94avboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync }
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync *pcSeg = cSeg;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync return cb;
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync}
354c88062085b9c03e4ea164f29c461b2ea842d6vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsyncRTDECL(bool) RTSgBufIsZero(PRTSGBUF pSgBuf, size_t cbCheck)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync{
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync bool fIsZero = true;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync size_t cbLeft = cbCheck;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync RTSGBUF SgBufTmp;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync RTSgBufClone(&SgBufTmp, pSgBuf);
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync while (cbLeft)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync size_t cbThisCheck = cbLeft;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync void *pvBuf = sgBufGet(&SgBufTmp, &cbThisCheck);
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync if (!cbThisCheck)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync break;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync /* Use optimized inline assembler if possible. */
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync if ( !(cbThisCheck % 4)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync && (cbThisCheck * 8 <= UINT32_MAX))
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
0cd76e2baf48b7043ebbd62634ef3eee2b70cb9evboxsync if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)cbThisCheck * 8) != -1)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync fIsZero = false;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync break;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync else
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync for (unsigned i = 0; i < cbThisCheck; i++)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync char *pbBuf = (char *)pvBuf;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync if (*pbBuf)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync {
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync fIsZero = false;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync break;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync pvBuf = pbBuf + 1;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync if (!fIsZero)
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync break;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync cbLeft -= cbThisCheck;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync }
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync return fIsZero;
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync}
c4e7058a3ae47876c97ed660d5377a6346950678vboxsync