annotate foosdk/sdk/foobar2000/SDK/file_cached_impl.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "foobar2000-sdk-pch.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "filesystem.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #define FILE_CACHED_DEBUG_LOG 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 class file_cached_impl_v2 : public service_multi_inherit< file_v2, service_multi_inherit< file_cached, file_lowLevelIO > > {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 enum {minBlockSize = 4096};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 enum {maxSkipSize = 128*1024};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 file_cached_impl_v2(size_t maxBlockSize) : m_maxBlockSize(maxBlockSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 //m_buffer.set_size(blocksize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 size_t get_cache_block_size() override {return m_maxBlockSize;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 void suggest_grow_cache(size_t suggestSize) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 if (m_maxBlockSize < suggestSize) m_maxBlockSize = suggestSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 void initialize(service_ptr_t<file> p_base,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 m_base = p_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 m_can_seek = m_base->can_seek();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 _reinit(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 t_filestats2 get_stats2(uint32_t f, abort_callback& a) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 return m_base->get_stats2_(f, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 size_t lowLevelIO(const GUID & guid, size_t arg1, void * arg2, size_t arg2size, abort_callback & abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 file_lowLevelIO::ptr ll;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 if ( ll &= m_base ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 return ll->lowLevelIO(guid, arg1, arg2, arg2size, abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 void _reinit(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 if (m_can_seek) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 m_position_base = m_base->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 m_position_base = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 m_size = m_base->get_size(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 t_filesize skip(t_filesize p_bytes,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 if (p_bytes > maxSkipSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 const t_filesize size = get_size(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 if (size != filesize_invalid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 const t_filesize position = get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 const t_filesize toskip = pfc::min_t( p_bytes, size - position );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 seek(position + toskip,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 return toskip;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 return skip_( p_bytes, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 t_filesize skip_(t_filesize p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 FB2K_DebugLog() << "Skipping bytes: " << p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 t_filesize todo = p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 size_t inBuffer = this->bufferRemaining();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 size_t delta = (size_t) pfc::min_t<t_filesize>(inBuffer, todo);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 m_bufferReadPtr += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 m_position += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 todo -= delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 if (todo == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 this->m_bufferState = 0; // null it early to leave in a consistent state if base read fails
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 this->m_bufferReadPtr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 m_readSize = pfc::min_t<size_t>(m_readSize << 1, this->m_maxBlockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 if (m_readSize < minBlockSize) m_readSize = minBlockSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 FB2K_DebugLog() << "Growing read size: " << m_readSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 m_buffer.grow_size(m_readSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 m_bufferState = m_base->read(m_buffer.get_ptr(), m_readSize, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 if (m_bufferState == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 m_position_base += m_bufferState;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 return p_bytes - todo;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 FB2K_DebugLog() << "Reading bytes: " << p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 t_uint8 * outptr = (t_uint8*)p_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 size_t todo = p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 size_t inBuffer = this->bufferRemaining();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 size_t delta = pfc::min_t<size_t>(inBuffer, todo);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 memcpy(outptr, this->m_buffer.get_ptr() + m_bufferReadPtr, delta);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 m_bufferReadPtr += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 m_position += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 todo -= delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 if (todo == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 outptr += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 this->m_bufferState = 0; // null it early to leave in a consistent state if base read fails
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 this->m_bufferReadPtr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 m_readSize = pfc::min_t<size_t>(m_readSize << 1, this->m_maxBlockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 if (m_readSize < minBlockSize) m_readSize = minBlockSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 FB2K_DebugLog() << "Growing read size: " << m_readSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 m_buffer.grow_size(m_readSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 m_bufferState = m_base->read(m_buffer.get_ptr(), m_readSize, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 if (m_bufferState == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 m_position_base += m_bufferState;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 return p_bytes - todo;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 FB2K_DebugLog() << "Writing bytes: " << p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 m_base->write(p_buffer,p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 m_position_base = m_position = m_position + p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 if (m_size < m_position) m_size = m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 t_filesize get_size(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 return m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 t_filesize get_position(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 PFC_ASSERT( m_position <= m_size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 return m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 void set_eof(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 m_base->set_eof(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 void seek(t_filesize p_position,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 FB2K_DebugLog() << "Seeking: " << p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 if (!m_can_seek) throw exception_io_object_not_seekable();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 if (p_position > m_size) throw exception_io_seek_out_of_range();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 int64_t delta = p_position - m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 // special case
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 if (delta >= 0 && delta <= this->minBlockSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 FB2K_DebugLog() << "Skip-seeking: " << p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 t_filesize skipped = this->skip_( delta, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 PFC_ASSERT( skipped == (t_filesize)delta ); (void) skipped;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 m_position = p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 // within currently buffered data?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 if ((delta >= 0 && (uint64_t) delta <= bufferRemaining()) || (delta < 0 && (uint64_t)(-delta) <= m_bufferReadPtr)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 FB2K_DebugLog() << "Quick-seeking: " << p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 m_bufferReadPtr += (ptrdiff_t)delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 #if FILE_CACHED_DEBUG_LOG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 FB2K_DebugLog() << "Slow-seeking: " << p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 this->flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 void reopen(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 if (this->m_can_seek) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 seek(0,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 this->m_base->reopen( p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 this->_reinit( p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 bool can_seek() override {return m_can_seek;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 bool get_content_type(pfc::string_base & out) override {return m_base->get_content_type(out);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 void on_idle(abort_callback & p_abort) override {p_abort.check();m_base->on_idle(p_abort);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 t_filetimestamp get_timestamp(abort_callback & p_abort) override {p_abort.check(); return m_base->get_timestamp(p_abort);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 bool is_remote() override {return m_base->is_remote();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 void resize(t_filesize p_size,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 m_base->resize(p_size,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 if (m_position > m_size) m_position = m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 if (m_position_base > m_size) m_position_base = m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 size_t bufferRemaining() const {return m_bufferState - m_bufferReadPtr;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 void baseSeek(t_filesize p_target,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 if (p_target != m_position_base) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 m_base->seek(p_target,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 m_position_base = p_target;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 void flush_buffer() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 m_bufferState = m_bufferReadPtr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 m_readSize = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 service_ptr_t<file> m_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 t_filesize m_position,m_position_base,m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 bool m_can_seek;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 size_t m_bufferState, m_bufferReadPtr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 pfc::array_t<t_uint8> m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 size_t m_maxBlockSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 size_t m_readSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 class file_cached_impl : public service_multi_inherit< file_v2, service_multi_inherit< file_cached, file_lowLevelIO > > {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 file_cached_impl(t_size blocksize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 m_buffer.set_size(blocksize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 size_t get_cache_block_size() override {return m_buffer.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 void suggest_grow_cache(size_t) override {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 void initialize(service_ptr_t<file> p_base,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 m_base = p_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 m_can_seek = m_base->can_seek();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 _reinit(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 void _reinit(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 m_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 if (m_can_seek) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 m_position_base = m_base->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 m_position_base = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 m_size = m_base->get_size(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 t_filestats2 get_stats2(uint32_t f, abort_callback& a) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 return m_base->get_stats2_(f, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 size_t lowLevelIO(const GUID & guid, size_t arg1, void * arg2, size_t arg2size, abort_callback & abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 file_lowLevelIO::ptr ll;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 if ( ll &= m_base ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 return ll->lowLevelIO(guid, arg1, arg2, arg2size, abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 t_uint8 * outptr = (t_uint8*)p_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 t_size done = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 while(done < p_bytes && m_position < m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 if (m_position >= m_buffer_position && m_position < m_buffer_position + m_buffer_status) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 t_size delta = pfc::min_t<t_size>((t_size)(m_buffer_position + m_buffer_status - m_position),p_bytes - done);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 t_size bufptr = (t_size)(m_position - m_buffer_position);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 memcpy(outptr+done,m_buffer.get_ptr()+bufptr,delta);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 done += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 m_position += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 if (m_buffer_status != m_buffer.get_size() && done < p_bytes) break;//EOF before m_size is hit
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 m_buffer_position = m_position - m_position % m_buffer.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 baseSeek(m_buffer_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 m_buffer_status = m_base->read(m_buffer.get_ptr(),m_buffer.get_size(),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 m_position_base += m_buffer_status;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 if (m_buffer_status <= (t_size)(m_position - m_buffer_position)) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 return done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 m_base->write(p_buffer,p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 m_position_base = m_position = m_position + p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 if (m_size < m_position) m_size = m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 t_filesize get_size(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 return m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 t_filesize get_position(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 return m_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 void set_eof(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 baseSeek(m_position,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 m_base->set_eof(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 void seek(t_filesize p_position,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 if (!m_can_seek) throw exception_io_object_not_seekable();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 if (p_position > m_size) throw exception_io_seek_out_of_range();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 m_position = p_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 void reopen(abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 if (this->m_can_seek) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 seek(0,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 this->m_base->reopen( p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 this->_reinit( p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 bool can_seek() override {return m_can_seek;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 bool get_content_type(pfc::string_base & out) override {return m_base->get_content_type(out);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 void on_idle(abort_callback & p_abort) override {p_abort.check();m_base->on_idle(p_abort);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 t_filetimestamp get_timestamp(abort_callback & p_abort) override {p_abort.check(); return m_base->get_timestamp(p_abort);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 bool is_remote() override {return m_base->is_remote();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 void resize(t_filesize p_size,abort_callback & p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 flush_buffer();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 m_base->resize(p_size,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 if (m_position > m_size) m_position = m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 if (m_position_base > m_size) m_position_base = m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 void baseSeek(t_filesize p_target,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 if (p_target != m_position_base) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 m_base->seek(p_target,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 m_position_base = p_target;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 void flush_buffer() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 m_buffer_status = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 m_buffer_position = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 service_ptr_t<file> m_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 t_filesize m_position,m_position_base,m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 bool m_can_seek;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 t_filesize m_buffer_position;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 t_size m_buffer_status;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 pfc::array_t<t_uint8> m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 file::ptr file_cached::g_create(service_ptr_t<file> p_base,abort_callback & p_abort, t_size blockSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 if (p_base->is_in_memory()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 return p_base; // do not want
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 { // do not duplicate cache layers, check if the file we're being handed isn't already cached
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 file_cached::ptr c;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 if (p_base->service_query_t(c)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 c->suggest_grow_cache(blockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 return p_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 auto obj = fb2k::service_new< file_cached_impl_v2 >(blockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 obj->initialize(p_base,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 file_v2* asdf = obj.get_ptr();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 return asdf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 void file_cached::g_create(service_ptr_t<file> & p_out,service_ptr_t<file> p_base,abort_callback & p_abort, t_size blockSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 p_out = g_create(p_base, p_abort, blockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 void file_cached::g_decodeInitCache(file::ptr & theFile, abort_callback & abort, size_t blockSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 if (theFile->is_remote() || !theFile->can_seek()) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 g_create(theFile, theFile, abort, blockSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 }