Example #1
0
void ZStreamWPos_String::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten)
	{
	size_t neededSpace = ZStream::sClampedSize(fPosition + iCount);
	if (fString.size() < neededSpace)
		{
		try
			{
			fString.resize(neededSpace);
			}
		catch (...)
			{}
		}

	if (size_t countToWrite = ZStream::sClampedSize(iCount, fString.size(), fPosition))
		{
		sMemCopy(&fString.at(fPosition), iSource, countToWrite);
		fPosition += countToWrite;
		if (oCountWritten)
			*oCountWritten = countToWrite;
		}
	else if (oCountWritten)
		{
		*oCountWritten = 0;
		}
	}
Example #2
0
void ZStreamW_Memory::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten)
	{
	sMemCopy(fAddress, iSource, iCount);
	fAddress += iCount;
	if (oCountWritten)
		*oCountWritten = iCount;
	}
Example #3
0
void ZStreamR_Memory::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
	{
	sMemCopy(oDest, fAddress, iCount);
	fAddress += iCount;
	if (oCountRead)
		*oCountRead = iCount;
	}
Example #4
0
void ZStrimU_StreamUTF8Buffered::Imp_ReadUTF32(UTF32* oDest, size_t iCount, size_t* oCount)
{
    // Optimize the common case -- single CU, with data in the buffer.
    if (iCount == 1 && fFeedOut < fFeedIn)
    {
        *oDest = fBuffer[fFeedOut++];
        if (oCount)
            *oCount = 1;
        return;
    }

    UTF32* localDest = oDest;
    while (iCount)
    {
        if (fFeedOut < fFeedIn)
        {
            const size_t countWritten = min(iCount, fFeedIn - fFeedOut);
            sMemCopy(localDest, &fBuffer[fFeedOut], countWritten * sizeof(UTF32));
            fFeedOut += countWritten;
            localDest += countWritten;
            iCount -= countWritten;
        }
        else
        {
            size_t countToRead;
            UTF32* utf32Buffer;
            if (fFeedOut)
            {
                // Remember the last CP in fBuffer[0]
                fBuffer[0] = fBuffer[fFeedOut - 1];

                // Start writing to &fBuffer[1]
                utf32Buffer = &fBuffer[1];
                countToRead = fBufferCount - 1;
                fFeedIn = 1;
                fFeedOut = 1;
            }
            else
            {
                utf32Buffer = &fBuffer[0];
                countToRead = fBufferCount;
                fFeedIn = 0;
                fFeedOut = 0;
            }

            size_t utf8Read;
            fStreamR.Read(&fBuffer_UTF8[0], countToRead, &utf8Read);
            if (not utf8Read)
                break;

            size_t destCU;
            spUTF8ToUTF32(&fBuffer_UTF8[0], utf8Read, utf32Buffer, countToRead, destCU);
            fFeedIn += destCU;
        }
    }

    if (oCount)
        *oCount = localDest - oDest;
}
Example #5
0
void ZStreamRPos_Memory::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
	{
	size_t countToCopy = ZStream::sClampedSize(iCount, fSize, fPosition);
	sMemCopy(oDest, fAddress + fPosition, countToCopy);
	fPosition += countToCopy;
	if (oCountRead)
		*oCountRead = countToCopy;
	}
Example #6
0
PixelDescRep_Indexed::PixelDescRep_Indexed(const RGBA* iColors,
	uint32* iPixvals, size_t iCount, bool iStripAlpha)
:	fCheckedAlpha(true),
	fHasAlpha(false)
	{
	ZAssertStop(kDebug_PixmapNS, iCount <= 256);

	ZAssertStopf(1, iStripAlpha, ("This constructor is only used when stripping alpha"));

	Pixval2RGBA_Indexed::fPixvals = nullptr;
	RGBA2Pixval_Indexed::fPixvals = nullptr;
	fReverseLookup = nullptr;

	vector<RGBA> vectorColors;
	vector<uint32> vectorPixvals;
	for (size_t x = 0; x < iCount; ++x)
		{
		vector<uint32>::iterator insertIter =
			lower_bound(vectorPixvals.begin(), vectorPixvals.end(), iPixvals[x]);

		insertIter = vectorPixvals.insert(insertIter, iPixvals[x]);
		vectorColors.insert(
			vectorColors.begin() + (insertIter - vectorPixvals.begin()), iColors[x]);
		}

	fCount = iCount;
	fColors = new RGBA[iCount];

	try
		{
		Pixval2RGBA_Indexed::fPixvals = new uint32[iCount];
		RGBA2Pixval_Indexed::fPixvals = Pixval2RGBA_Indexed::fPixvals;
		}
	catch (...)
		{
		delete fColors;
		throw;
		}

	sMemCopy(fColors, &vectorColors[0], iCount * sizeof(RGBA));
	sMemCopy(Pixval2RGBA_Indexed::fPixvals, &vectorPixvals[0], iCount * sizeof(uint32));

	// Set the alpha value to be completely opaque.
	for (size_t x = 0; x < iCount; ++x)
		sAlpha(fColors[x]) = 1.0;
	}
Example #7
0
void ZStreamWPos_Memory::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten)
	{
	size_t countToCopy = ZStream::sClampedSize(iCount, fCapacity, fPosition);
	sMemCopy(fAddress + fPosition, iSource, countToCopy);
	fPosition += countToCopy;
	if (fSize < fPosition)
		fSize = fPosition;
	if (oCountWritten)
		*oCountWritten = countToCopy;
	}
Example #8
0
void ZStreamRPos_PageBuffered::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
	{
	char* localDest = reinterpret_cast<char*>(oDest);
	iCount = ZStream::sClampedSize(iCount, fStreamReal.GetSize(), fPosition);
	while (iCount)
		{
		// Do we have the offset in our buffers?
		Buffer* buffer_Found = fBuffer_Head;
		while (buffer_Found)
			{
			if (buffer_Found->fStartPosition <= fPosition
				&& buffer_Found->fStartPosition + fBufferSize > fPosition)
				{
				break;
				}
			buffer_Found = buffer_Found->fNext;
			}

		if (buffer_Found == nullptr)
			{
			buffer_Found = fBuffer_Tail;
			buffer_Found->fStartPosition = fPosition - (fPosition % fBufferSize);
			fStreamReal.SetPosition(buffer_Found->fStartPosition);
			fStreamReal.Read(buffer_Found->fData, fBufferSize, nullptr);
			}

		size_t offsetInBuffer = fPosition % fBufferSize;
		size_t copySize = min(iCount, fBufferSize - offsetInBuffer);
		sMemCopy(localDest, buffer_Found->fData + offsetInBuffer, copySize);
		iCount -= copySize;
		fPosition += copySize;
		localDest += copySize;

		if (fBuffer_Head != buffer_Found)
			{
			// Move buffer_Found to the head of the list by removing it
			if (buffer_Found->fPrev)
				buffer_Found->fPrev->fNext = buffer_Found->fNext;
			if (buffer_Found->fNext)
				buffer_Found->fNext->fPrev = buffer_Found->fPrev;
			if (fBuffer_Head == buffer_Found)
				fBuffer_Head = buffer_Found->fNext;
			if (fBuffer_Tail == buffer_Found)
				fBuffer_Tail = buffer_Found->fPrev;

			// and inserting it
			buffer_Found->fPrev = nullptr;
			buffer_Found->fNext = fBuffer_Head;
			fBuffer_Head->fPrev = buffer_Found;
			fBuffer_Head = buffer_Found;
			}
		}
	if (oCountRead)
		*oCountRead = localDest - reinterpret_cast<char*>(oDest);
	}
Example #9
0
PixelDescRep_Indexed::PixelDescRep_Indexed(const RGBA* iColors,
	uint32* iPixvals, size_t iCount)
:	fCheckedAlpha(false)
	{
	ZAssertStop(kDebug_PixmapNS, iCount <= 256);

	Pixval2RGBA_Indexed::fPixvals = nullptr;
	RGBA2Pixval_Indexed::fPixvals = nullptr;
	fReverseLookup = nullptr;

	vector<RGBA> vectorColors;
	vector<uint32> vectorPixvals;
	for (size_t x = 0; x < iCount; ++x)
		{
		vector<uint32>::iterator insertIter =
			lower_bound(vectorPixvals.begin(), vectorPixvals.end(), iPixvals[x]);

		insertIter = vectorPixvals.insert(insertIter, iPixvals[x]);
		vectorColors.insert(
			vectorColors.begin() + (insertIter - vectorPixvals.begin()), iColors[x]);
		}

	fCount = iCount;
	fColors = new RGBA[iCount];

	try
		{
		Pixval2RGBA_Indexed::fPixvals = new uint32[iCount];
		RGBA2Pixval_Indexed::fPixvals = Pixval2RGBA_Indexed::fPixvals;
		}
	catch (...)
		{
		delete fColors;
		throw;
		}

	sMemCopy(fColors, &vectorColors[0], iCount * sizeof(RGBA));
	sMemCopy(Pixval2RGBA_Indexed::fPixvals, &vectorPixvals[0], iCount * sizeof(uint32));
	}
Example #10
0
PixelDescRep_Indexed::PixelDescRep_Indexed(const RGBA* iColors, size_t iCount)
:	fCheckedAlpha(false)
	{
	ZAssertStop(kDebug_PixmapNS, iCount <= 256);

	Pixval2RGBA_Indexed::fPixvals = nullptr;
	RGBA2Pixval_Indexed::fPixvals = nullptr;
	fReverseLookup = nullptr;

	fCount = iCount;
	fColors = new RGBA[iCount];
	sMemCopy(fColors, iColors, iCount * sizeof(RGBA));
	}
Example #11
0
void ZStreamRPos_String::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
	{
	if (size_t countToRead = ZStream::sClampedSize(iCount, fString.size(), fPosition))
		{
		sMemCopy(oDest, &fString.at(fPosition), countToRead);
		fPosition += countToRead;
		if (oCountRead)
			*oCountRead = countToRead;
		}
	else if (oCountRead)
		{
		*oCountRead = 0;
		}
	}
Example #12
0
PixelDescRep_Indexed::PixelDescRep_Indexed(const RGBA* iColors,
	size_t iCount, bool iStripAlpha)
:	fCheckedAlpha(true),
	fHasAlpha(false)
	{
	ZAssertStop(kDebug_PixmapNS, iCount <= 256);

	ZAssertStopf(1, iStripAlpha, "This constructor is only used when stripping alpha");

	Pixval2RGBA_Indexed::fPixvals = nullptr;
	RGBA2Pixval_Indexed::fPixvals = nullptr;
	fReverseLookup = nullptr;

	fCount = iCount;
	fColors = new RGBA[iCount];
	sMemCopy(fColors, iColors, iCount * sizeof(RGBA));

	// Set the alpha value to be completely opaque.
	for (size_t x = 0; x < iCount; ++x)
		sAlpha(fColors[x]) = 1.0;
	}
Example #13
0
void ZStreamR_Boundary::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
	{
	if (not fBuffer)
		{
		fStreamSource.Read(oDest, iCount, oCountRead);
		}
	else
		{
		const size_t boundarySize = fBoundary.size();
		uint8* localDest = reinterpret_cast<uint8*>(oDest);
		while (iCount)
			{
			if (fDataEnd > fDataStart)
				{
				size_t countToMove = min(fDataEnd - fDataStart, iCount);
				sMemCopy(localDest, fBuffer + fDataStart, countToMove);
				fDataStart += countToMove;
				localDest += countToMove;
				iCount -= countToMove;
				}
			else
				{
				if (fHitBoundary)
					break;

				// Shuffle existing stuff to beginning of buffer.
				sMemMove(fBuffer, fBuffer + fDataEnd, boundarySize - fDataEnd);

				// Top up the tail.
				size_t countRead;
				fStreamSource.Read(fBuffer + boundarySize - fDataEnd, fDataEnd, &countRead);

				if (countRead < fDataEnd)
					{
					// The source stream has gone empty without our having already seen the
					// boundary. Shuffle the data we do have so the last byte aligns with
					// the end of the buffer.
					sMemMove(fBuffer + fDataEnd - countRead, fBuffer,
						boundarySize - (fDataEnd - countRead));

					// The first returnable byte is at fDataStart, and the last is at
					// the end of the buffer.
					fDataStart = fDataEnd - countRead;
					fDataEnd = boundarySize;
					if (countRead == 0)
						{
						// We read nothing at all, so fDataStart will equal fDataEnd,
						// which will be the end of the buffer. And we should bail.
						break;
						}
					}
				else
					{
					// Do Boyer-Moore search on the full buffer.
					int xx;
					for (xx = boundarySize - 1; xx >= 0 && fBuffer[xx] == fBoundary[xx]; --xx)
						{}

					if (xx < 0)
						{
						// We found the boundary.
						fHitBoundary = true;
						fDataStart = boundarySize;
						fDataEnd = boundarySize;
						}
					else
						{
						// We didn't find the boundary. The shift distance is precisely the number
						// of bytes at the start of the buffer that *cannot* match the boundary,
						// which are bytes that can be returned as our output.
						fDataStart = 0;
						fDataEnd = fDistance[fBuffer[boundarySize - 1]];
						}
					}
				}
			}
		if (oCountRead)
			*oCountRead = localDest - reinterpret_cast<uint8*>(oDest);
		}
	}
Example #14
0
void ZStreamRWPos_PageBuffered::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten)
	{
	const char* localSource = reinterpret_cast<const char*>(iSource);
	while (iCount)
		{
		// Do we have the offset in our buffers?
		Buffer* buffer_Found = fBuffer_Head;
		while (buffer_Found)
			{
			if (buffer_Found->fStartPosition <= fPosition
				&& buffer_Found->fStartPosition + fBufferSize > fPosition)
				{
				break;
				}
			buffer_Found = buffer_Found->fNext;
			}

		size_t offsetInBuffer = fPosition % fBufferSize;
		if (buffer_Found == nullptr)
			{
			// We didn't find a buffer encompassing the position
			if (fBuffer_Tail->fDirty)
				{
				fStreamReal.SetPosition(fBuffer_Tail->fStartPosition);
				fStreamReal.Write(fBuffer_Tail->fData,
					min(uint64(fBufferSize), fStreamReal.GetSize() - fBuffer_Tail->fStartPosition));
				}
			buffer_Found = fBuffer_Tail;
			buffer_Found->fStartPosition = fPosition - offsetInBuffer;

			size_t countToFillBuffer = min(uint64(fBufferSize),
				fStreamReal.GetSize() - buffer_Found->fStartPosition);

			if (offsetInBuffer || iCount < countToFillBuffer)
				{
				// We need to read the original data because we're either not going to write
				// starting at the beginning of the buffer, or we're not going to overwrite
				// the entire valid contents of the buffer (or both).
				fStreamReal.SetPosition(buffer_Found->fStartPosition);
				fStreamReal.Read(buffer_Found->fData, countToFillBuffer);
				}
			}

		size_t copySize = min(iCount, fBufferSize - offsetInBuffer);
		sMemCopy(buffer_Found->fData + offsetInBuffer, localSource, copySize);
		buffer_Found->fDirty = true;

		iCount -= copySize;
		fPosition += copySize;
		localSource += copySize;

		if (fBuffer_Head != buffer_Found)
			{
			// Move buffer_Found to the head of the list by removing it
			if (buffer_Found->fPrev)
				buffer_Found->fPrev->fNext = buffer_Found->fNext;
			if (buffer_Found->fNext)
				buffer_Found->fNext->fPrev = buffer_Found->fPrev;
			if (fBuffer_Head == buffer_Found)
				fBuffer_Head = buffer_Found->fNext;
			if (fBuffer_Tail == buffer_Found)
				fBuffer_Tail = buffer_Found->fPrev;

			// and inserting it
			buffer_Found->fPrev = nullptr;
			buffer_Found->fNext = fBuffer_Head;
			fBuffer_Head->fPrev = buffer_Found;
			fBuffer_Head = buffer_Found;
			}
		}
	if (oCountWritten)
		*oCountWritten = localSource - reinterpret_cast<const char*>(iSource);
	}
Example #15
0
void ZStreamRWCon_SSL_Win::Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten)
{
    ZAcqMtx acq(fMtx_W);

    if (oCountWritten)
        *oCountWritten = 0;

    SecPkgContext_StreamSizes theSizes;
    if (FAILED(spPSFT->QueryContextAttributesA(
                   &fCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &theSizes)))
    {
        // QueryContextAttributesA really shouldn't ever fail.
        ZAssert(false);
        return;
    }

    // Local buffer that will hold the message header, cyphertext and message trailer
    vector<char> buffer(theSizes.cbHeader
                        + min(iCount, size_t(theSizes.cbMaximumMessage))
                        + theSizes.cbTrailer,
                        '\0');

    // Encryption happens in-place, copy the plaintext to the appropriate offset of the buffer.
    const size_t countToEncrypt = min(iCount, size_t(theSizes.cbMaximumMessage));
    sMemCopy(&buffer[theSizes.cbHeader], iSource, countToEncrypt);

    SecBuffer outSB[4];
    outSB[0].cbBuffer = theSizes.cbHeader;
    outSB[0].pvBuffer = &buffer[0];
    outSB[0].BufferType = SECBUFFER_STREAM_HEADER;

    outSB[1].cbBuffer = countToEncrypt;
    outSB[1].pvBuffer = &buffer[theSizes.cbHeader];
    outSB[1].BufferType = SECBUFFER_DATA;

    outSB[2].cbBuffer = theSizes.cbTrailer;
    outSB[2].pvBuffer = &buffer[theSizes.cbHeader + countToEncrypt];
    outSB[2].BufferType = SECBUFFER_STREAM_TRAILER;

    outSB[3].BufferType = SECBUFFER_EMPTY;

    SecBufferDesc outSBD;
    outSBD.pBuffers = outSB;
    outSBD.cBuffers = 4;
    outSBD.ulVersion = SECBUFFER_VERSION;

    SECURITY_STATUS result = spPSFT->EncryptMessage(&fCtxtHandle, 0, &outSBD, 0);
    if (SUCCEEDED(result))
    {
        if (spWriteFully(outSB[0], fStreamW)
                && spWriteFully(outSB[1], fStreamW)
                && spWriteFully(outSB[2], fStreamW))
        {
            if (oCountWritten)
                *oCountWritten = countToEncrypt;
            return;
        }
    }

    fSendOpen = false;
}
Example #16
0
void ZStreamRWCon_SSL_Win::Imp_Read(void* oDest, size_t iCount, size_t* oCountRead)
{
    ZAcqMtx acq(fMtx_R);

    char* localDest = static_cast<char*>(oDest);

    while (iCount)
    {
        if (fBufferPlain.size())
        {
            // We've got some data to return.
            size_t countToRead = min(iCount, fBufferPlain.size());
            deque<char>::iterator begin = fBufferPlain.begin();
            deque<char>::iterator end = begin + countToRead;
            std::copy(begin, end, static_cast<char*>(localDest));
            fBufferPlain.erase(begin, end);
            localDest += countToRead;
            iCount -= countToRead;
        }

        if (localDest != oDest)
        {
            // We've somehow managed to read some data, just above or down
            // below, and so can bail from the loop.
            break;
        }

        if (not fReceiveOpen)
            break;

        // We pass four buffers. inSB[0] references the available encrypted
        // data. inSB[1] through inSB[3] are marked as being empty, and may
        // be modified by DecryptMessage.
        SecBuffer inSB[4];
        inSB[0].cbBuffer = fBufferEnc.size();
        inSB[0].pvBuffer = ZUtil_STL::sFirstOrNil(fBufferEnc);
        inSB[0].BufferType = SECBUFFER_DATA;

        inSB[1].BufferType = SECBUFFER_EMPTY;
        inSB[2].BufferType = SECBUFFER_EMPTY;
        inSB[3].BufferType = SECBUFFER_EMPTY;

        SecBufferDesc inSBD;
        inSBD.cBuffers = 4;
        inSBD.pBuffers = inSB;
        inSBD.ulVersion = SECBUFFER_VERSION;

        SECURITY_STATUS scRet = spPSFT->DecryptMessage(&fCtxtHandle, &inSBD, 0, nullptr);

        if (scRet == SEC_E_INCOMPLETE_MESSAGE || (FAILED(scRet) && fBufferEnc.empty()))
        {
            // fBufferEnc holds an incomplete chunk, DecryptMessage needs
            // more data before it can do the decrypt.
            if (not spReadMore(fBufferEnc, fStreamR))
            {
                // We couldn't read any more encrypted data. Mark
                // our receive as being closed.
                fReceiveOpen = false;
            }
            continue;
        }

        if (scRet == SEC_I_CONTEXT_EXPIRED)
        {
            // SSL-level disconnect has been sent by the other side.
            fReceiveOpen = false;
            continue;
        }

        if (scRet == SEC_I_RENEGOTIATE)
        {
            // We need to re-handshake.
            if (not this->pHandshake())
            {
                fReceiveOpen = false;
                fSendOpen = false;
            }
            continue;
        }

        if (FAILED(scRet))
        {
            // We failed for some other reason.
            fReceiveOpen = false;
            continue;
        }

        // If DecryptMessage did any work, inSB[0] through inSB[2] will now reference
        // the header, decrypted data and trailer. inSB[3] will indicate how many
        // bytes at the end of fBufferEnc were unused by this decrypt, and so
        // must be preserved for subsequent use.
        // This assignment of information to buffers is only something I've determined
        // by inspection, so for safety we walk through them to find the two we care
        // about -- the decrypted data and any unused encrypted data.

        SecBuffer* decrypted = nullptr;
        SecBuffer* encrypted = nullptr;

        // Pickup any decrypted data
        for (size_t x = 0; x < 4; ++x)
        {
            if (inSB[x].BufferType == SECBUFFER_DATA && ! decrypted)
                decrypted = &inSB[x];
            if (inSB[x].BufferType == SECBUFFER_EXTRA && ! encrypted)
                encrypted = &inSB[x];
        }

        // The decryption happens in-place, ie in fBufferEnc. Therefore
        // we must copy out the decrypted data before munging fBufferEnc to
        // reference only the unused data.

        if (decrypted)
        {
            // Copy some decrypted data to our destination.
            const size_t countToCopy = std::min(iCount, size_t(decrypted->cbBuffer));
            sMemCopy(localDest, decrypted->pvBuffer, countToCopy);
            localDest += countToCopy;
            iCount -= countToCopy;

            // Anything remaining we put in fBufferPlain, which must be
            // empty otherwise we wouldn't have got to this point.
            const char* data = static_cast<const char*>(decrypted->pvBuffer);
            fBufferPlain.insert(fBufferPlain.begin(),
                                data + countToCopy, data + decrypted->cbBuffer);
        }

        if (encrypted)
        {
            // There is some unused data, move it to the front of fBufferEnc,
            // and resize fBufferEnc to reference only that data.
            sMemMove(&fBufferEnc[0], encrypted->pvBuffer, encrypted->cbBuffer);
            fBufferEnc.resize(encrypted->cbBuffer);
        }
        else
        {
            // There was no unused data.
            fBufferEnc.clear();
        }
    }

    if (oCountRead)
        *oCountRead = localDest - static_cast<char*>(oDest);
}