1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 #include "fastserializer.h"
7 #include "diagnosticsipc.h"
9 #ifdef FEATURE_PERFTRACING
11 // Event Pipe has previously implemented a feature called "forward references"
12 // As a result of work on V3 of Event Pipe (https://github.com/Microsoft/perfview/pull/532) it got removed
13 // if you need it, please use git to restore it
15 IpcStreamWriter::IpcStreamWriter(uint64_t id, IpcStream *pStream) : _pStream(pStream)
22 PRECONDITION(_pStream != nullptr);
26 if (_pStream == nullptr)
29 uint32_t nBytesWritten = 0;
30 bool fSuccess = _pStream->Write(&id, sizeof(id), nBytesWritten);
38 IpcStreamWriter::~IpcStreamWriter()
51 bool IpcStreamWriter::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const
58 PRECONDITION(lpBuffer != nullptr);
59 PRECONDITION(nBytesToWrite > 0);
63 if (_pStream == nullptr)
65 if (lpBuffer == nullptr || nBytesToWrite == 0)
67 return _pStream->Write(lpBuffer, nBytesToWrite, nBytesWritten);
70 FileStreamWriter::FileStreamWriter(const SString &outputFilePath)
79 m_pFileStream = new CFileStream();
80 if (FAILED(m_pFileStream->OpenForWrite(outputFilePath)))
82 _ASSERTE(!"Unable to open file for write.");
89 FileStreamWriter::~FileStreamWriter()
102 bool FileStreamWriter::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const
109 PRECONDITION(lpBuffer != nullptr);
110 PRECONDITION(nBytesToWrite > 0);
114 if (m_pFileStream == nullptr)
118 HRESULT hResult = m_pFileStream->Write(lpBuffer, nBytesToWrite, &outCount);
119 nBytesWritten = static_cast<uint32_t>(outCount);
120 return hResult == S_OK;
123 FastSerializer::FastSerializer(StreamWriter *pStreamWriter) : m_pStreamWriter(pStreamWriter)
130 PRECONDITION(m_pStreamWriter != NULL);
134 m_writeErrorEncountered = false;
139 FastSerializer::~FastSerializer()
149 delete m_pStreamWriter;
152 void FastSerializer::WriteObject(FastSerializableObject *pObject)
159 PRECONDITION(pObject != NULL);
163 WriteTag(FastSerializerTags::BeginObject);
165 WriteSerializationType(pObject);
167 // Ask the object to serialize itself using the current serializer.
168 pObject->FastSerialize(this);
170 WriteTag(FastSerializerTags::EndObject);
173 void FastSerializer::WriteBuffer(BYTE *pBuffer, unsigned int length)
180 PRECONDITION(pBuffer != NULL);
181 PRECONDITION(length > 0);
185 if (m_writeErrorEncountered || m_pStreamWriter == NULL)
191 bool fSuccess = m_pStreamWriter->Write(pBuffer, length, outCount);
194 size_t prevPos = m_currentPos;
196 m_currentPos += outCount;
198 // This will cause us to stop writing to the file.
199 // The file will still remain open until shutdown so that we don't
200 // have to take a lock at this level when we touch the file stream.
201 m_writeErrorEncountered = (length != outCount) || !fSuccess;
204 _ASSERTE(m_writeErrorEncountered || (prevPos < m_currentPos));
209 m_writeErrorEncountered = true;
211 EX_END_CATCH(SwallowAllExceptions);
214 void FastSerializer::WriteSerializationType(FastSerializableObject *pObject)
221 PRECONDITION(pObject != NULL);
225 // Write the BeginObject tag.
226 WriteTag(FastSerializerTags::BeginObject);
228 // Write a NullReferenceTag, which implies that the following fields belong to SerializationType.
229 WriteTag(FastSerializerTags::NullReference);
231 // Write the SerializationType version fields.
232 int serializationType[2] = {
233 pObject->GetObjectVersion(),
234 pObject->GetMinReaderVersion()};
235 WriteBuffer((BYTE *)&serializationType, sizeof(serializationType));
237 // Write the SerializationType TypeName field.
238 const char *strTypeName = pObject->GetTypeName();
239 unsigned int length = (unsigned int)strlen(strTypeName);
241 WriteString(strTypeName, length);
243 // Write the EndObject tag.
244 WriteTag(FastSerializerTags::EndObject);
247 void FastSerializer::WriteTag(FastSerializerTags tag, BYTE *payload, unsigned int payloadLength)
257 WriteBuffer((BYTE *)&tag, sizeof(tag));
260 _ASSERTE(payloadLength > 0);
261 WriteBuffer(payload, payloadLength);
265 void FastSerializer::WriteFileHeader()
275 const char *strSignature = "!FastSerialization.1"; // the consumer lib expects exactly the same string, it must not be changed
276 unsigned int length = (unsigned int)strlen(strSignature);
277 WriteString(strSignature, length);
280 void FastSerializer::WriteString(const char *strContents, unsigned int length)
290 // Write the string length .
291 WriteBuffer((BYTE *)&length, sizeof(length));
293 // Write the string contents.
294 WriteBuffer((BYTE *)strContents, length);
297 #endif // FEATURE_PERFTRACING