Пример #1
0
void ZRefCountedWithFinalization::Finalize()
	{
	ZAssertStopf(1, 1 == ZThreadSafe_Get(fRefCount),
		("Refcount is not 1, it is %d", ZThreadSafe_Get(fRefCount)));
	this->FinalizationComplete();
	delete this;
	}
Пример #2
0
void ZTextEncoder_Mac::Encode(const UTF32* iSource, size_t iSourceCU, size_t* oSourceCU,
					void* iDest, size_t iDestBytes, size_t* oDestBytes)
	{
	// utf16Buffer is the source for calls to ConvertFromUnicodeToText, we use
	// ZUnicode::sUTF32ToUTF16 to populate it from the UTF-32 we're passed.
	UniChar utf16Buffer[kBufSize];

	const UTF32* localSource = iSource;
	uint8* localDest = static_cast<uint8*>(iDest);

	// We allow the use of fallbacks, but have installed a custom fallback handler
	// that emits no code units. So Unicode code points which the encoder can't
	// handle are simply skipped, in line with our normal practice.
	OptionBits flags = kUnicodeUseFallbacksMask;
	if (fIsReset)
		fIsReset = false;
	else
		flags |= kUnicodeKeepInfoMask;

	while (iSourceCU && iDestBytes)
		{
		size_t utf32Consumed;
		size_t utf16Generated;
		ZUnicode::sUTF32ToUTF16(localSource, iSourceCU, &utf32Consumed,
						reinterpret_cast<UTF16*>(utf16Buffer), kBufSize, &utf16Generated,
						nil);

		ByteCount utf16Consumed;
		ByteCount destGenerated;
		OSStatus err = ::ConvertFromUnicodeToText(fInfo, utf16Generated * 2, utf16Buffer, 
						flags,
						0, nil, nil, nil, // Offset array stuff.
						iDestBytes, &utf16Consumed, &destGenerated, localDest);

		ZAssertStopf(1, (utf16Consumed & 1) == 0, ("utf16Consumed should be even")); 
		utf16Consumed /= 2;
		if (utf16Generated > utf16Consumed)
			{
			// We were not able to consume all the intermediary UTF-16 that was generated.
			// Turn the number of complete code points consumed back into the number of
			// corresponding UTF-32 code units.
			size_t codePoints = ZUnicode::sCUToCP(
				reinterpret_cast<const UTF16*>(utf16Buffer), utf16Consumed);

			utf32Consumed = ZUnicode::sCPToCU(localSource, codePoints);
			}
		localSource += utf32Consumed;
		iSourceCU -= utf32Consumed;
		localDest += destGenerated;
		iDestBytes -= destGenerated;
		}

	if (oSourceCU)
		*oSourceCU = localSource - iSource;
	if (oDestBytes)
		*oDestBytes = localDest - static_cast<uint8*>(iDest);
	}
Пример #3
0
static void spWCToMB(UINT iDestCodePage, const WCHAR* iSource, size_t iSourceCU, size_t& oSourceCU,
			CHAR* oDest, size_t iDestCU, size_t& oDestCU)
	{
	ZAssertStop(1, iSourceCU && iDestCU);
	if (iSourceCU > iDestCU)
		{
		// We've got more UTF-16 than destination bytes, so discover how much space we would need.
		for (;;)
			{
			int result = ::WideCharToMultiByte(
				iDestCodePage, 0, iSource, iSourceCU, oDest, 0, nullptr, nullptr);

			if (result <= iDestCU)
				break;
			// There is insufficient space. Scale the source count to match. This is of course
			// only approximate, but will get us in the right ballpark immediately.
			iSourceCU = size_t(iSourceCU * (double(iDestCU) / double(result)));
			}
		}

	for (;;)
		{
		if (int result = ::WideCharToMultiByte(
			iDestCodePage, 0, iSource, iSourceCU, oDest, iDestCU, nullptr, nullptr))
			{
			oSourceCU = iSourceCU;
			oDestCU = result;
			break;
			}
		else
			{
			DWORD err = ::GetLastError();
			if (err == ERROR_INSUFFICIENT_BUFFER)
				{
				// We don't have enough space, and don't know how much we need.
				// Just halve the source amount.
				iSourceCU /= 2;
				ZAssertStopf(0, iSourceCU, ("iSourceCU went to zero."));
				if (not iSourceCU)
					break;
				}
			else
				{
				ZDebugStopf(0, ("MultiByteToWideChar returned an unexpected error"));
				}
			}
		}
	}
Пример #4
0
static void spMBToWC(UINT iSourceCodePage, const CHAR* iSource, size_t iSourceCU, size_t& oSourceCU,
			WCHAR* oDest, size_t iDestCU, size_t& oDestCU)
	{
	ZAssertStop(1, iSourceCU && iDestCU);

	if (iSourceCU >= 2 * iDestCU)
		{
		// We've got at least twice as many source bytes as space for destination code units.
		// The odds are higher that we'd overflow the destination buffer. So discover how
		// much space we would need.
		for (;;)
			{
			int result = ::MultiByteToWideChar(iSourceCodePage, 0, iSource, iSourceCU, oDest, 0);
			if (result <= iDestCU)
				break;
			// There is insufficient space. Scale the source count to match. This is of course
			// only approximate, but will get us in the right ballpark immediately.
			iSourceCU = size_t(iSourceCU * (size_t(double(iDestCU) / double(result))));
			}
		}

	for (;;)
		{
		if (int result = ::MultiByteToWideChar(
			iSourceCodePage, 0, iSource, iSourceCU, oDest, iDestCU))
			{
			oSourceCU = iSourceCU;
			oDestCU = result;
			break;
			}
		else
			{
			DWORD err = ::GetLastError();
			if (err == ERROR_INSUFFICIENT_BUFFER)
				{
				// We don't have enough space, and don't know how much we need.
				// Just halve the source amount.
				iSourceCU /= 2;
				ZAssertStopf(0, iSourceCU, ("iSourceCU went to zero."));
				}
			else
				{
				ZDebugStopf(0, ("MultiByteToWideChar returned an unexpected error"));
				}
			}
		}
	}
Пример #5
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;
	}
Пример #6
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;
	}
Пример #7
0
void ZRefCountedWithFinalization::Initialize()
	{
	ZAssertStopf(1, 1 == ZThreadSafe_Get(fRefCount),
		("Refcount is not 1, it is %d", ZThreadSafe_Get(fRefCount)));
	}
Пример #8
0
ZRefCountedWithFinalization::~ZRefCountedWithFinalization()
	{
	ZAssertStopf(1, 0 == ZThreadSafe_Get(fRefCount),
		("Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount)));
	}
Пример #9
0
ZRefCounted::~ZRefCounted()
	{
	ZAssertStopf(1, ZThreadSafe_Get(fRefCount) == 0,
		("Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount)));
	}
Пример #10
0
ZCountedWithoutFinalize::~ZCountedWithoutFinalize()
	{
	ZAssertStopf(1, ZThreadSafe_Get(fRefCount) == 0,
		"Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount));
	}
Пример #11
0
bool ZTextDecoder_Mac::Decode(
	const void* iSource, size_t iSourceBytes, size_t* oSourceBytes, size_t* oSourceBytesSkipped,
	UTF32* iDest, size_t iDestCU, size_t* oDestCU)
	{
	// When we're working with a destination buffer that can't hold all the source material
	// we have ConvertFromTextToUnicode write into the local array 'offsets' the byte
	// offsets that correspond to each UTF-16 intermediate code unit generated.
	// sSourceOffsets is used to tell ConvertFromTextToUnicode which offsets are
	// 'significant', in our case that means all of them. We populate sSourceOffsets
	// the first time we need to use it, it's then available for use in all
	// subsequent invocations.
	ByteOffset offsets[kBufSize];
	ByteCount countOffsets;

	// utf16Buffer is the target for calls to ConvertFromTextToUnicode,
	// we use ZUnicode::sUTF16ToUTF32 to further transcribe the generated UTF-16
	// into the UTF-32 we need.
	UniChar utf16Buffer[kBufSize];

	const uint8* localSource = static_cast<const uint8*>(iSource);
	UTF32* localDest = iDest;
	bool sourceComplete = true;

	size_t sourceBytesSkipped = 0;

	OptionBits flags = 0;
	if (fIsReset)
		fIsReset = false;
	else
		flags |= kUnicodeKeepInfoMask;

	while (iSourceBytes && iDestCU)
		{
		ByteCount sourceConsumed;
		ByteCount utf16Generated;
		OSStatus err;
		if (iDestCU < iSourceBytes && iDestCU < kBufSize)
			{
			// We have space for fewer UTF-32 code units than we have source code units,
			// so it's at least feasible that we'd overflow the destination. We also
			// have space for fewer code units than we have for intermediate UTF-16
			// code units and so this iteration may be the one where we have to
			// bail out early. So we pass the offset array to ConvertFromTextToUnicode in
			// order to discover where any truncation in the source occurred.
			if (!sInitedSourceOffsets)
				{
				// This is thread safe, even if two threads execute this at the same time
				// the end result will be the same -- an array of kBufSize elements containing
				// values from 0 to kBufSize - 1, and sInitedSourceOffsets being true.
				for (size_t x = 0; x < kBufSize; ++x)
					sSourceOffsets[x] = x;
				sInitedSourceOffsets = true;
				}
			size_t countToConvert = min(iSourceBytes, kBufSize);
			err = ::ConvertFromTextToUnicode(fInfo, countToConvert, localSource, 
				flags,
				countToConvert, sSourceOffsets, &countOffsets, offsets,
				kBufSize * sizeof(UniChar), &sourceConsumed, &utf16Generated, utf16Buffer);
			}
		else
			{
			err = ::ConvertFromTextToUnicode(fInfo, iSourceBytes, localSource, 
				flags,
				0, nil, nil, nil, // Offset array stuff.
				kBufSize * sizeof(UniChar), &sourceConsumed, &utf16Generated, utf16Buffer);
			}

		if (sourceConsumed == 0)
			{
			// ConvertFromTextToUnicode was unable to consume any source data.
			if (err == noErr)
				{
				// This is actually an unlikely return value. Let's flag it for now and see.
				ZDebugStopf(1, ("ConvertFromTextToUnicode returned noErr"));
				break;
				}
			else if (err == kTECPartialCharErr)
				{
				// An incomplete sequence was all that was present in the source. 
				sourceComplete = false;
				break;
				}
			else if (err == kTextMalformedInputErr)
				{
				// Bad source data. Skip a byte and try again.
				++localSource;
				--iSourceBytes;
				++sourceBytesSkipped;
				}
			else if (err == kTECUsedFallbacksStatus)
				{
				// Ignore.
				}
			else if (err == kTECBufferBelowMinimumSizeErr)
				{
				// This shouldn't ever happen as we have a fair sized
				// intermediate buffer, and we're not decomposing source characters
				// into multiple Unicode characters.
				sourceComplete = false;
				break;
				}
			else
				{
				ZDebugStopf(1, ("ConvertFromTextToUnicode returned err %d", err));
				}
			}
		else
			{
			ZAssertStopf(1, (utf16Generated & 1) == 0, ("utf16Generated should be even")); 
			utf16Generated /= 2;

			size_t utf16Consumed;
			size_t utf32Generated;
			ZUnicode::sUTF16ToUTF32(
				reinterpret_cast<const UTF16*>(utf16Buffer), utf16Generated, &utf16Consumed,
				localDest, iDestCU, &utf32Generated);

			if (utf16Generated > utf16Consumed)
				{
				// We were not able to consume all the utf16 data generated by
				// ConvertFromTextToUnicode. So the number of source code units
				// consumed is *not* sourceConsumed, but some lesser number.
				ZAssertStop(1, iDestCU < iSourceBytes && iDestCU < kBufSize);
				sourceConsumed = offsets[utf16Consumed - 1];
				}
			localSource += sourceConsumed;
			iSourceBytes -= sourceConsumed;
			localDest += utf32Generated;
			iDestCU -= utf32Generated;
			}
		}
	if (oSourceBytes)
		*oSourceBytes = localSource - static_cast<const uint8*>(iSource);
	if (oSourceBytesSkipped)
		*oSourceBytesSkipped = sourceBytesSkipped;
	if (oDestCU)
		*oDestCU = localDest - iDest;
	return true;
	}