static unsigned long sk_stream_read(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count ) { SkStream* str = (SkStream*)stream->descriptor.pointer; if (count) { if (!str->rewind()) { return 0; } else { unsigned long ret; if (offset) { ret = str->read(NULL, offset); if (ret != offset) { return 0; } } ret = str->read(buffer, count); if (ret != count) { return 0; } count = ret; } } return count; }
bool SkXMLParser::parse(SkStream& input) { size_t len = input.read(NULL, 0); SkAutoMalloc am(len); char* doc = (char*)am.get(); input.rewind(); size_t len2 = input.read(doc, len); SkASSERT(len2 == len); return this->parse(doc, len2); }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // should have been provided by CreateFromStream() *ttcIndex = 0; SkAutoTUnref<SkStream> dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } // TODO: update interface use, remove the following code in this block. size_t length = stream->getLength(); const void* memory = stream->getMemoryBase(); if (NULL != memory) { return new SkMemoryStream(memory, length, true); } SkAutoTMalloc<uint8_t> allocMemory(length); stream->rewind(); if (length == stream->read(allocMemory.get(), length)) { SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream()); copyStream->setMemoryOwned(allocMemory.detach(), length); return copyStream.detach(); } stream->rewind(); stream->ref(); } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }
static FPDFEMB_RESULT file_readblock(FPDFEMB_FILE_ACCESS* file, void* dst, unsigned int offset, unsigned int size) { SkStream* stream = (SkStream*)file->user; // SkDebugf("---- readblock %p %p %d %d\n", stream, dst, offset, size); if (!stream->rewind()) { SkDebugf("---- rewind failed\n"); return FPDFERR_ERROR; } if (stream->skip(offset) != offset) { SkDebugf("---- skip failed\n"); return FPDFERR_ERROR; } if (stream->read(dst, size) != size) { SkDebugf("---- read failed\n"); return FPDFERR_ERROR; } return FPDFERR_SUCCESS; }
size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag, size_t offset, size_t length, void* data) { SkStream* stream = SkFontHost::OpenStream(fontID); if (NULL == stream) { return 0; } SkAutoUnref au(stream); SfntHeader header; if (!header.init(stream)) { return 0; } for (int i = 0; i < header.fCount; i++) { if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) { size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset); size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength); // now sanity check the caller's offset/length if (offset >= realLength) { return 0; } // if the caller is trusting the length from the file, then a // hostile file might choose a value which would overflow offset + // length. if (offset + length < offset) { return 0; } if (offset + length > realLength) { length = realLength - offset; } // skip the stream to the part of the table we want to copy from stream->rewind(); size_t bytesToSkip = realOffset + offset; if (stream->skip(bytesToSkip) != bytesToSkip) { return 0; } if (stream->read(data, length) != length) { return 0; } return length; } } return 0; }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // TODO: fix issue 1176. // As of now open_stream will return a stream and unwind it, but the // SkStream is not thread safe, and if two threads use the stream they // may collide and print preview for example could still fail, // or there could be some failures in rendering if this stream is used // there. stream->rewind(); stream->ref(); // should have been provided by CreateFromStream() *ttcIndex = 0; } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }