-
Notifications
You must be signed in to change notification settings - Fork 6
/
IArchiveImpl.h
114 lines (93 loc) · 3.83 KB
/
IArchiveImpl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#pragma once
#include "Archive.h"
#include "Allocation.h"
#include <queue>
#include <unordered_map>
namespace leap {
struct create_delete;
class IArchiveImpl:
public IArchiveRegistry
{
public:
/// <summary>
/// Constructs an archive implementation around the specified stream operator
/// </summary>
/// <param name="is">The underlying input stream</param>
IArchiveImpl(IInputStream& is);
IArchiveImpl(std::istream& is);
virtual ~IArchiveImpl(void);
struct deserialization_task {
deserialization_task(
const field_serializer* serializer,
uint32_t id,
void* pObject
) :
serializer(serializer),
id(id),
pObject(pObject)
{}
// Descriptor, identifier, and object pointer
const field_serializer* serializer;
uint32_t id;
void* pObject;
};
private:
// Underlying input stream
IInputStream& is;
// If any additional (flat) memory was required to construct the output stream reference, this is it
void* const pIsMem = nullptr;
void(*const pfnDtor)(void*) = nullptr;
// Number of bytes read so far:
uint64_t m_count = 0;
struct entry {
// A pointer to the raw object
void* pObject;
// Caller-specified context field, if Release was called, otherwise nullptr
std::shared_ptr<void> pContext;
// A pointer to the routine that will be used to clean up the object
void(*pfnFree)(void*);
};
// Map of objects (as we encounter them) to their identifiers. We use this
// to reconcile cycles
std::unordered_map<uint32_t, entry> objMap;
// Identifiers remaining to be deserialized:
std::queue<deserialization_task> work;
ReleasedMemory Release(ReleasedMemory(*pfnAlloc)(), const field_serializer& serializer, uint32_t objId);
void* Lookup(const create_delete& cd, const field_serializer& serializer, uint32_t objId);
bool IsReleased(uint32_t objId);
/// <summary>
/// Moves ownership of all deletable entities to the specified allocator type
/// </summary>
/// <remarks>
/// The internal object map is cleared as a result of this operation
/// </remarks>
void Transfer(internal::AllocationBase& alloc);
/// <summary>
/// Destroys all objects that define deleters and clears the object map
/// </summary>
/// <returns>The number of objects destroyed</returns>
size_t ClearObjectTable(void);
/// <summary>
/// Recursively processes deserialization tasks, starting with the one passed, until none are left
/// </summary>
void Process(const deserialization_task& task);
public:
void* ReadObjectReference(const create_delete& cd, const field_serializer& sz) override;
// IArchive overrides:
void Skip(uint64_t ncb) override;
uint64_t Count(void) const override { return m_count; }
void ReadObject(const field_serializer& sz, void* pObj, internal::AllocationBase* pOwner) override;
ReleasedMemory ReadObjectReferenceResponsible(ReleasedMemory(*pfnAlloc)(), const field_serializer& sz, bool isUnique) override;
void ReadByteArray(void* pBuf, uint64_t ncb) override;
void ReadString(std::function<void*(uint64_t)> getBufferFn, uint8_t charSize, uint64_t ncb) override;
bool ReadBool() override;
uint64_t ReadInteger(uint8_t ncb) override;
void ReadFloat(float& value) override { ReadByteArray(&value, sizeof(value)); }
void ReadFloat(double& value) override { ReadByteArray(&value, sizeof(value)); }
void ReadFloat(long double& value) override { ReadByteArray(&value, sizeof(value)); }
void ReadDescriptor(const descriptor& descriptor, void* pObj, uint64_t ncb) override;
void ReadArray(IArrayAppender&& ary) override;
void ReadDictionary(IDictionaryInserter&& dictionary) override;
};
}