std::string ImageReaderWriter::local_insertReference(const std::string& fileName, unsigned int res, float width, float height, bool backPage) { std::stringstream ostr; ostr<<"res_"<<res<<"_"<<fileName; std::string myReference = ostr.str(); _dataReferences[myReference] = DataReference(fileName,res,width,height,backPage); return myReference; }
bool ArgumentDecoder::decodeVariableLengthByteArray(DataReference& dataReference) { uint64_t size; if (!decode(size)) return false; if (!alignBufferPosition(1, size)) return false; uint8_t* data = m_bufferPos; m_bufferPos += size; dataReference = DataReference(data, size); return true; }
bool ArgumentDecoder::decodeBytes(DataReference& dataReference) { uint64_t size; if (!decodeUInt64(size)) return false; if (!alignBufferPosition(1, size)) return false; uint8_t* data = m_bufferPos; m_bufferPos += size; dataReference = DataReference(data, size); return true; }
void Connection::readEventHandler() { if (m_connectionPipe == INVALID_HANDLE_VALUE) return; while (true) { // Check if we got some data. DWORD numberOfBytesRead = 0; if (!::GetOverlappedResult(m_connectionPipe, &m_readState, &numberOfBytesRead, FALSE)) { DWORD error = ::GetLastError(); switch (error) { case ERROR_BROKEN_PIPE: connectionDidClose(); return; case ERROR_MORE_DATA: { // Read the rest of the message out of the pipe. DWORD bytesToRead = 0; if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) { DWORD error = ::GetLastError(); if (error == ERROR_BROKEN_PIPE) { connectionDidClose(); return; } ASSERT_NOT_REACHED(); return; } // ::GetOverlappedResult told us there's more data. ::PeekNamedPipe shouldn't // contradict it! ASSERT(bytesToRead); if (!bytesToRead) break; m_readBuffer.grow(m_readBuffer.size() + bytesToRead); if (!::ReadFile(m_connectionPipe, m_readBuffer.data() + numberOfBytesRead, bytesToRead, 0, &m_readState)) { DWORD error = ::GetLastError(); ASSERT_NOT_REACHED(); return; } continue; } // FIXME: We should figure out why we're getting this error. case ERROR_IO_INCOMPLETE: return; default: ASSERT_NOT_REACHED(); } } if (!m_readBuffer.isEmpty()) { // We have a message, let's dispatch it. // The messageID is encoded at the end of the buffer. // Note that we assume here that the message is the same size as m_readBuffer. We can // assume this because we always size m_readBuffer to exactly match the size of the message, // either when receiving ERROR_MORE_DATA from ::GetOverlappedResult above or when // ::PeekNamedPipe tells us the size below. We never set m_readBuffer to a size larger // than the message. ASSERT(m_readBuffer.size() >= sizeof(MessageID)); size_t realBufferSize = m_readBuffer.size() - sizeof(MessageID); unsigned messageID = *reinterpret_cast<unsigned*>(m_readBuffer.data() + realBufferSize); OwnPtr<MessageDecoder> decoder = MessageDecoder::create(DataReference(m_readBuffer.data(), realBufferSize)); processIncomingMessage(MessageID::fromInt(messageID), decoder.release()); } // Find out the size of the next message in the pipe (if there is one) so that we can read // it all in one operation. (This is just an optimization to avoid an extra pass through the // loop (if we chose a buffer size that was too small) or allocating extra memory (if we // chose a buffer size that was too large).) DWORD bytesToRead = 0; if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) { DWORD error = ::GetLastError(); if (error == ERROR_BROKEN_PIPE) { connectionDidClose(); return; } ASSERT_NOT_REACHED(); } if (!bytesToRead) { // There's no message waiting in the pipe. Schedule a read of the first byte of the // next message. We'll find out the message's actual size when it arrives. (If we // change this to read more than a single byte for performance reasons, we'll have to // deal with m_readBuffer potentially being larger than the message we read after // calling ::GetOverlappedResult above.) bytesToRead = 1; } m_readBuffer.resize(bytesToRead); // Either read the next available message (which should occur synchronously), or start an // asynchronous read of the next message that becomes available. BOOL result = ::ReadFile(m_connectionPipe, m_readBuffer.data(), m_readBuffer.size(), 0, &m_readState); if (result) { // There was already a message waiting in the pipe, and we read it synchronously. // Process it. continue; } DWORD error = ::GetLastError(); if (error == ERROR_IO_PENDING) { // There are no messages in the pipe currently. readEventHandler will be called again once there is a message. return; } if (error == ERROR_MORE_DATA) { // Either a message is available when we didn't think one was, or the message is larger // than ::PeekNamedPipe told us. The former seems far more likely. Probably the message // became available between our calls to ::PeekNamedPipe and ::ReadFile above. Go back // to the top of the loop to use ::GetOverlappedResult to retrieve the available data. continue; } // FIXME: We need to handle other errors here. ASSERT_NOT_REACHED(); } }
bool Connection::processMessage() { if (m_readBufferSize < sizeof(MessageInfo)) return false; uint8_t* messageData = m_readBuffer.data(); MessageInfo messageInfo; memcpy(&messageInfo, messageData, sizeof(messageInfo)); messageData += sizeof(messageInfo); size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isMessageBodyIsOutOfLine() ? 0 : messageInfo.bodySize()); if (m_readBufferSize < messageLength) return false; size_t attachmentFileDescriptorCount = 0; size_t attachmentCount = messageInfo.attachmentCount(); std::unique_ptr<AttachmentInfo[]> attachmentInfo; if (attachmentCount) { attachmentInfo = std::make_unique<AttachmentInfo[]>(attachmentCount); memcpy(attachmentInfo.get(), messageData, sizeof(AttachmentInfo) * attachmentCount); messageData += sizeof(AttachmentInfo) * attachmentCount; for (size_t i = 0; i < attachmentCount; ++i) { switch (attachmentInfo[i].getType()) { case Attachment::MappedMemoryType: case Attachment::SocketType: if (!attachmentInfo[i].isNull()) attachmentFileDescriptorCount++; break; case Attachment::Uninitialized: default: ASSERT_NOT_REACHED(); break; } } if (messageInfo.isMessageBodyIsOutOfLine()) attachmentCount--; } Vector<Attachment> attachments(attachmentCount); AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments); RefPtr<WebKit::SharedMemory> oolMessageBody; size_t fdIndex = 0; for (size_t i = 0; i < attachmentCount; ++i) { int fd = -1; switch (attachmentInfo[i].getType()) { case Attachment::MappedMemoryType: if (!attachmentInfo[i].isNull()) fd = m_fileDescriptors[fdIndex++]; attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].getSize()); break; case Attachment::SocketType: if (!attachmentInfo[i].isNull()) fd = m_fileDescriptors[fdIndex++]; attachments[attachmentCount - i - 1] = Attachment(fd); break; case Attachment::Uninitialized: attachments[attachmentCount - i - 1] = Attachment(); default: break; } } if (messageInfo.isMessageBodyIsOutOfLine()) { ASSERT(messageInfo.bodySize()); if (attachmentInfo[attachmentCount].isNull()) { ASSERT_NOT_REACHED(); return false; } WebKit::SharedMemory::Handle handle; handle.adoptFromAttachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].getSize()); oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly); if (!oolMessageBody) { ASSERT_NOT_REACHED(); return false; } } ASSERT(attachments.size() == (messageInfo.isMessageBodyIsOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount())); uint8_t* messageBody = messageData; if (messageInfo.isMessageBodyIsOutOfLine()) messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data()); auto decoder = std::make_unique<MessageDecoder>(DataReference(messageBody, messageInfo.bodySize()), std::move(attachments)); processIncomingMessage(std::move(decoder)); if (m_readBufferSize > messageLength) { memmove(m_readBuffer.data(), m_readBuffer.data() + messageLength, m_readBufferSize - messageLength); m_readBufferSize -= messageLength; } else m_readBufferSize = 0; if (attachmentFileDescriptorCount) { if (m_fileDescriptorsSize > attachmentFileDescriptorCount) { size_t fileDescriptorsLength = attachmentFileDescriptorCount * sizeof(int); memmove(m_fileDescriptors.data(), m_fileDescriptors.data() + fileDescriptorsLength, m_fileDescriptorsSize - fileDescriptorsLength); m_fileDescriptorsSize -= fileDescriptorsLength; } else m_fileDescriptorsSize = 0; } return true; }
static PassOwnPtr<MessageDecoder> createMessageDecoder(mach_msg_header_t* header) { if (!(header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) { // We have a simple message. uint8_t* body = reinterpret_cast<uint8_t*>(header + 1); size_t bodySize = header->msgh_size - sizeof(mach_msg_header_t); return MessageDecoder::create(DataReference(body, bodySize)); } bool messageBodyIsOOL = header->msgh_id & MessageBodyIsOOL; mach_msg_body_t* body = reinterpret_cast<mach_msg_body_t*>(header + 1); mach_msg_size_t numDescriptors = body->msgh_descriptor_count; ASSERT(numDescriptors); // Build attachment list Deque<Attachment> attachments; uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1); // If the message body was sent out-of-line, don't treat the last descriptor // as an attachment, since it is really the message body. if (messageBodyIsOOL) --numDescriptors; for (mach_msg_size_t i = 0; i < numDescriptors; ++i) { mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); switch (descriptor->type.type) { case MACH_MSG_PORT_DESCRIPTOR: attachments.append(Attachment(descriptor->port.name, descriptor->port.disposition)); descriptorData += sizeof(mach_msg_port_descriptor_t); break; case MACH_MSG_OOL_DESCRIPTOR: attachments.append(Attachment(descriptor->out_of_line.address, descriptor->out_of_line.size, descriptor->out_of_line.copy, descriptor->out_of_line.deallocate)); descriptorData += sizeof(mach_msg_ool_descriptor_t); break; default: ASSERT(false && "Unhandled descriptor type"); } } if (messageBodyIsOOL) { mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); ASSERT(descriptor->type.type == MACH_MSG_OOL_DESCRIPTOR); Attachment messageBodyAttachment(descriptor->out_of_line.address, descriptor->out_of_line.size, descriptor->out_of_line.copy, descriptor->out_of_line.deallocate); uint8_t* messageBody = static_cast<uint8_t*>(messageBodyAttachment.address()); size_t messageBodySize = messageBodyAttachment.size(); OwnPtr<MessageDecoder> decoder; if (attachments.isEmpty()) decoder = MessageDecoder::create(DataReference(messageBody, messageBodySize)); else decoder = MessageDecoder::create(DataReference(messageBody, messageBodySize), attachments); vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(messageBodyAttachment.address()), messageBodyAttachment.size()); return decoder.release(); } uint8_t* messageBody = descriptorData; size_t messageBodySize = header->msgh_size - (descriptorData - reinterpret_cast<uint8_t*>(header)); return MessageDecoder::create(DataReference(messageBody, messageBodySize), attachments); }
void StringReference::encode(ArgumentEncoder& encoder) const { encoder << DataReference(reinterpret_cast<const uint8_t*>(m_data), m_size); }
static void encodeGKeyFile(ArgumentEncoder& encoder, GKeyFile* keyFile) { gsize dataSize; GOwnPtr<char> data(g_key_file_to_data(keyFile, &dataSize, 0)); encoder << DataReference(reinterpret_cast<uint8_t*>(data.get()), dataSize); }