-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathMemoryStream.cpp
80 lines (73 loc) · 2.02 KB
/
MemoryStream.cpp
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
#include "MemoryStream.hpp"
#include "MemoryFile.hpp"
#include "PartFile.hpp"
#include <string.h>
#include <algorithm>
BEGIN_INANITY
MemoryStream::MemoryStream(size_t initialSize) : dataSize(0), lastDataSize(0), files(1)
{
files[0] = NEW(MemoryFile(initialSize));
}
void MemoryStream::Write(const void* data, size_t size)
{
//цикл копирования
while(size)
{
File* file = files[files.size() - 1];
size_t lastFileSize = file->GetSize();
//если в последнем файле есть место
if(lastDataSize < lastFileSize)
{
//скопировать данные
size_t toCopy = std::min(size, lastFileSize - lastDataSize);
memcpy((char*)file->GetData() + lastDataSize, data, toCopy);
data = (char*)data + toCopy;
size -= toCopy;
dataSize += toCopy;
lastDataSize += toCopy;
}
//иначе места нет
else
{
//выделить новый файл
files.push_back(NEW(MemoryFile(dataSize)));
lastDataSize = 0;
}
}
}
void MemoryStream::Compact()
{
//если файлов больше одного
if(files.size() > 1)
{
//создать файл для всех данных
ptr<File> file = NEW(MemoryFile(dataSize));
//скопировать в него данные всех файлов
char* data = (char*)file->GetData();
for(size_t i = 0; i < files.size(); ++i)
{
File* file = &*files[i];
size_t size = (i < files.size() - 1) ? file->GetSize() : lastDataSize;
memcpy(data, file->GetData(), size);
data += size;
}
//заменить все файлы на один
files.assign(1, file);
//указать действительные размеры данных
lastDataSize = dataSize;
}
}
ptr<File> MemoryStream::ToFile()
{
Compact();
return dataSize < files[0]->GetSize() ? NEW(PartFile(files[0], files[0]->GetData(), dataSize)) : files[0];
}
void MemoryStream::Clear()
{
// сжать все данные в не более чем один файл
Compact();
// очистить
dataSize = 0;
lastDataSize = 0;
}
END_INANITY