void dump_plist(CFMutableDictionaryRef properties) { CFWriteStreamRef stdoutStream = NULL; CFURLRef devStdout = CFURLCreateWithFileSystemPath( NULL, CFSTR("/dev/stdout"), kCFURLPOSIXPathStyle, false ); stdoutStream = CFWriteStreamCreateWithFile(NULL, devStdout); CFRelease(devStdout); if (stdoutStream == NULL) errx(1,"cannot create CFWriteStream for /dev/stdout"); if (!CFWriteStreamOpen(stdoutStream)) errx(1,"cannot open CFWriteStream for /dev/stdout"); CFPropertyListWrite( properties, stdoutStream, kCFPropertyListXMLFormat_v1_0, 0, NULL ); CFWriteStreamClose(stdoutStream); CFRelease(stdoutStream); }
RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation() { RetainPtr<CFDictionaryRef> propertyList = createPropertyListRepresentation(this); ASSERT(propertyList); if (!propertyList) { LOG(Archives, "LegacyWebArchive - Failed to create property list for archive, returning no data"); return nullptr; } RetainPtr<CFWriteStreamRef> stream = adoptCF(CFWriteStreamCreateWithAllocatedBuffers(0, 0)); CFWriteStreamOpen(stream.get()); CFPropertyListWrite(propertyList.get(), stream.get(), kCFPropertyListBinaryFormat_v1_0, 0, 0); RetainPtr<CFDataRef> plistData = adoptCF(static_cast<CFDataRef>(CFWriteStreamCopyProperty(stream.get(), kCFStreamPropertyDataWritten))); ASSERT(plistData); CFWriteStreamClose(stream.get()); if (!plistData) { LOG(Archives, "LegacyWebArchive - Failed to convert property list into raw data, returning no data"); return nullptr; } return plistData; }
RefPtr<API::Data> encodeLegacySessionState(const SessionState& sessionState) { auto sessionHistoryDictionary = encodeSessionHistory(sessionState.backForwardListState); auto provisionalURLString = sessionState.provisionalURL.isNull() ? nullptr : sessionState.provisionalURL.string().createCFString(); RetainPtr<CFNumberRef> renderTreeSizeNumber(adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sessionState.renderTreeSize))); RetainPtr<CFDictionaryRef> stateDictionary; if (provisionalURLString) { stateDictionary = createDictionary({ { sessionHistoryKey, sessionHistoryDictionary.get() }, { provisionalURLKey, provisionalURLString.get() }, { renderTreeSizeKey, renderTreeSizeNumber.get() } }); } else { stateDictionary = createDictionary({ { sessionHistoryKey, sessionHistoryDictionary.get() }, { renderTreeSizeKey, renderTreeSizeNumber.get() } }); } auto writeStream = adoptCF(CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, nullptr)); if (!writeStream) return nullptr; if (!CFWriteStreamOpen(writeStream.get())) return nullptr; if (!CFPropertyListWrite(stateDictionary.get(), writeStream.get(), kCFPropertyListBinaryFormat_v1_0, 0, nullptr)) return nullptr; auto data = adoptCF(static_cast<CFDataRef>(CFWriteStreamCopyProperty(writeStream.get(), kCFStreamPropertyDataWritten))); CFIndex length = CFDataGetLength(data.get()); size_t bufferSize = length + sizeof(uint32_t); auto buffer = MallocPtr<uint8_t>::malloc(bufferSize); // Put the session state version number at the start of the buffer buffer.get()[0] = (sessionStateDataVersion & 0xff000000) >> 24; buffer.get()[1] = (sessionStateDataVersion & 0x00ff0000) >> 16; buffer.get()[2] = (sessionStateDataVersion & 0x0000ff00) >> 8; buffer.get()[3] = (sessionStateDataVersion & 0x000000ff); // Copy in the actual session state data CFDataGetBytes(data.get(), CFRangeMake(0, length), buffer.get() + sizeof(uint32_t)); return API::Data::createWithoutCopying(buffer.leakPtr(), bufferSize, [] (unsigned char* buffer, const void* context) { fastFree(buffer); }, nullptr); }