void ZRefCountedWithFinalization::Finalize() { ZAssertStopf(1, 1 == ZThreadSafe_Get(fRefCount), ("Refcount is not 1, it is %d", ZThreadSafe_Get(fRefCount))); this->FinalizationComplete(); delete this; }
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); }
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")); } } } }
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")); } } } }
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; }
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; }
void ZRefCountedWithFinalization::Initialize() { ZAssertStopf(1, 1 == ZThreadSafe_Get(fRefCount), ("Refcount is not 1, it is %d", ZThreadSafe_Get(fRefCount))); }
ZRefCountedWithFinalization::~ZRefCountedWithFinalization() { ZAssertStopf(1, 0 == ZThreadSafe_Get(fRefCount), ("Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount))); }
ZRefCounted::~ZRefCounted() { ZAssertStopf(1, ZThreadSafe_Get(fRefCount) == 0, ("Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount))); }
ZCountedWithoutFinalize::~ZCountedWithoutFinalize() { ZAssertStopf(1, ZThreadSafe_Get(fRefCount) == 0, "Non-zero refcount at destruction, it is %d", ZThreadSafe_Get(fRefCount)); }
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; }