-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdriver.cpp
115 lines (80 loc) · 2.73 KB
/
driver.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
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
#include "driver.h"
#include <iostream>
#include <cstdio>
#include <cstring>
Driver* __instance = NULL;
Driver::Driver() {
}
Driver::~Driver() {
this->close();
}
void Driver::open(const char* filename) {
this->fp = fopen(filename, "r+b");
// File doesn't exist.. Create it!
if(this->fp == NULL) {
this->fp = fopen(filename, "w+b");
}
}
void Driver::close() {
if(this->fp) {
fclose(this->fp);
this->fp = NULL;
}
}
Driver* Driver::getInstance() {
if(!__instance)
__instance = new Driver();
return __instance;
}
list<unsigned int> Driver::alloc(unsigned int length) {
unsigned int actual_page_size = PAGE_SIZE - sizeof(unsigned int);
unsigned int num_pages_to_create = length / actual_page_size;
unsigned int num_existing_pages = 0, i = 0, page_len = length;
list<unsigned int> page_list;
// Correct number of pages
if(num_pages_to_create * (PAGE_SIZE - sizeof(unsigned int)) < length)
++num_pages_to_create;
memset(&page_contents_buffer[0], 0, PAGE_SIZE);
fseek(this->fp, 0, SEEK_END);
num_existing_pages = (unsigned int)(ftell(this->fp) / PAGE_SIZE);
page_len = std::min<unsigned int>(PAGE_SIZE, length);
for(i = 0; i < num_pages_to_create; ++i) {
fwrite((unsigned char*)&page_len, 1, sizeof(unsigned int), this->fp);
fwrite(&page_contents_buffer[0], 1, actual_page_size, this->fp);
page_list.push_back(num_existing_pages + i);
page_len = std::min<unsigned int>(PAGE_SIZE, page_len - PAGE_SIZE);
}
return page_list;
}
bool Driver::readPage(unsigned int page_num, unsigned char* data, unsigned int* length) {
if(!this->fp)
return false;
if(fseek(this->fp, getPagePositionOnFile(page_num), SEEK_SET))
return false;
if(fread(&page_contents_buffer[0], sizeof(unsigned char), PAGE_SIZE, this->fp) != PAGE_SIZE)
return false;
unsigned int len = *(unsigned int*)page_contents_buffer;
if(len == (unsigned int)-1)
return false;
memcpy(data, &page_contents_buffer[sizeof(unsigned int)], len);
*length = len;
return true;
}
unsigned int Driver::writePage(unsigned int page_num, unsigned char* data, unsigned int length) {
if(!this->fp)
return 0;
unsigned int len = std::min<unsigned int>(length, PAGE_SIZE - sizeof(unsigned int));
if(fseek(this->fp, getPagePositionOnFile(page_num), SEEK_SET))
return 0;
fwrite((unsigned char*)&len, 1, sizeof(unsigned int), this->fp);
fwrite(data, 1, len, this->fp);
return len;
}
void Driver::deletePage(unsigned int page_num) {
unsigned int tmp = -1;
if(!this->fp)
return;
if(fseek(this->fp, getPagePositionOnFile(page_num), SEEK_SET))
return;
fwrite((unsigned char*)&tmp, 1, sizeof(unsigned int), this->fp);
}