summaryrefslogtreecommitdiff
path: root/Runtime/Serialize/TransferFunctions/StreamedBinaryRead.h
blob: 81a015c5be8a6313edf622644cd83791d180ed33 (plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#ifndef STREAMEDBINARYREAD_H
#define STREAMEDBINARYREAD_H

#include "Runtime/Serialize/TransferFunctions/TransferBase.h"
#include "Runtime/Serialize/CacheWrap.h"
#include "Runtime/Serialize/SwapEndianBytes.h"


template<bool kSwapEndianess>
class StreamedBinaryRead : public TransferBase
{
	CachedReader	m_Cache;

	friend class MonoBehaviour;

public:

	CachedReader& Init (int flags)	{ m_UserData = NULL; m_Flags = flags; return m_Cache; }

	bool IsReading ()                 { return true; }
	bool IsReadingPPtr ()             { return true; }
	bool NeedsInstanceIDRemapping ()          { return m_Flags & kNeedsInstanceIDRemapping; }
	bool ConvertEndianess ()          { return kSwapEndianess; }

	bool DidReadLastProperty ()       { return true; }
	bool DidReadLastPPtrProperty ()   { return true; }

	void EnableResourceImage (ActiveResourceImage targetResourceImage) { m_Cache.BeginResourceImage(targetResourceImage); }
	bool ReadStreamingInfo(StreamingInfo* streamingInfo);

	bool ShouldChannelOverride ();
	CachedReader& GetCachedReader () { return m_Cache; }

	const char* GetSerializedFilePathName() { return m_Cache.GetSerializedFilePathName(); }

	template<class T>
	void Transfer (T& data, const char* name, TransferMetaFlags metaFlag = kNoTransferFlags);
	template<class T>
	void TransferWithTypeString (T& data, const char* name, const char* typeName, TransferMetaFlags metaFlag = kNoTransferFlags);

	void TransferTypeless (unsigned* byteSize, const char* name, TransferMetaFlags metaFlag = kNoTransferFlags);

	// markerID is the id that was given by TransferTypeless.
	// optional copyData: is a pointer to where the data will be written or read from
	void TransferTypelessData (unsigned byteSize, void* copyData, int metaData = 0);

	/// Reads byteSize bytes into data. This may onle be used if UseOptimizedReading returns true.
	void EXPORT_COREMODULE ReadDirect (void* data, int byteSize);

	void EXPORT_COREMODULE Align ();

	template<class T>
	void TransferBasicData (T& data);

	template<class T>
	void TransferPtr (bool, ReduceCopyData*){}

	template<class T>
	void TransferSTLStyleArray (T& data, TransferMetaFlags metaFlag = kNoTransferFlags);

	template<class T>
	void TransferSTLStyleMap (T& data, TransferMetaFlags metaFlag = kNoTransferFlags);
};

template <bool kSwapEndianess>
bool StreamedBinaryRead<kSwapEndianess>::ReadStreamingInfo(StreamingInfo* streamingInfo)
{
	Assert(streamingInfo != NULL);

	if (!m_Cache.IsReadingResourceImage())
		return false;

	// Read the size & offset values from the serialized file
	// The size & offset describes where the data is in the streamed file
	UInt32 offset, size;
	Transfer (size, "ri_size");
	Transfer (offset, "ri_offset");

	m_Cache.GetStreamingInfo (offset, size, streamingInfo);
	return true;
}



template<bool kSwapEndianess>
template<class T>
void StreamedBinaryRead<kSwapEndianess>::TransferSTLStyleArray (T& data, TransferMetaFlags /*metaFlags*/)
{
	if (m_Cache.IsReadingResourceImage())
	{
		// Read the size & offset from the serialized file
		UInt32 offset, size;
		Transfer (size, "ri_size");
		Transfer (offset, "ri_offset");

		// Fetch the pointer from the pre-loaded resource image.
		unsigned bufferSize = sizeof (typename T::value_type) * size;
		UInt8* buffer = m_Cache.FetchResourceImageData (offset, bufferSize);
		SerializeTraits<T>::resource_image_assign_external (data, buffer, buffer + bufferSize);

		m_Cache.EndResourceImage();
	}
	else
	{
		SInt32 size;
		Transfer (size, "size");

		SerializeTraits<T>::ResizeSTLStyleArray (data, size);

		if (!kSwapEndianess && SerializeTraits<typename T::value_type>::AllowTransferOptimization () && SerializeTraits<T>::IsContinousMemoryArray ())
		{
			//AssertIf (size != distance (data.begin (), data.end ()));
			if( size != 0 )
				ReadDirect (&*data.begin (), size * sizeof (typename T::value_type));
		}
		else
		{
			typename T::iterator i;
			typename T::iterator end = data.end ();
			//AssertIf (size != distance (data.begin (), end));
			for (i = data.begin ();i != end;++i)
				Transfer (*i, "data");
		}
	}
}

template<bool kSwapEndianess>
template<class T>
void StreamedBinaryRead<kSwapEndianess>::TransferSTLStyleMap (T& data, TransferMetaFlags)
{
	SInt32 size;
	Transfer (size, "size");

	// maps value_type is: pair<const First, Second>
	// So we have to write to maps non-const value type
	typename NonConstContainerValueType<T>::value_type p;

	data.clear ();
	for (int i=0;i<size;i++)
	{
		Transfer (p, "data");
		data.insert (p);
	}
}

template<bool kSwapEndianess>
template<class T>
void StreamedBinaryRead<kSwapEndianess>::Transfer (T& data, const char*, TransferMetaFlags)
{
	SerializeTraits<T>::Transfer (data, *this);
}

template<bool kSwapEndianess>
template<class T>
void StreamedBinaryRead<kSwapEndianess>::TransferWithTypeString (T& data, const char*, const char*, TransferMetaFlags)
{
	SerializeTraits<T>::Transfer (data, *this);
}

template<bool kSwapEndianess>
template<class T> inline
void StreamedBinaryRead<kSwapEndianess>::TransferBasicData (T& data)
{
	AssertIf (sizeof (T) > 8);
	m_Cache.Read (data);
	if (kSwapEndianess)
	{
		SwapEndianBytes (data);
	}
}
#endif