Line data Source code
1 : //
2 : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
3 : //
4 : // Copyright: See COPYING file that comes with this distribution
5 : //
6 :
7 : #ifndef VSET_VSET_BUFFER_PERSISTENT_FILESYNC_AD_SYNC_HPP
8 : #define VSET_VSET_BUFFER_PERSISTENT_FILESYNC_AD_SYNC_HPP
9 :
10 : #include <fas/system/nullptr.hpp>
11 : #include <vset/buffer/tags.hpp>
12 : #include <vset/buffer/persistent/tags.hpp>
13 : #include <iostream>
14 :
15 : namespace vset { namespace buffer { namespace persistent{ namespace filesync{
16 :
17 3 : struct ad_sync
18 : {
19 : template<typename T>
20 2 : size_t operator()( T& t, size_t offset, size_t limit) const
21 : {
22 2 : return _write(t, offset, limit);
23 : }
24 :
25 : template<typename T>
26 6 : size_t operator()( T& t) const
27 : {
28 6 : size_t offset = 0;
29 6 : size_t limit = t.get_aspect().template get<_size_>()(t);
30 6 : return _write(t, offset, limit);
31 : }
32 :
33 : private:
34 :
35 : template<typename T>
36 8 : size_t _write( T& t, size_t offset, size_t limit) const
37 : {
38 : typedef typename T::aspect::template advice_cast<_head_type_>::type head_type;
39 8 : size_t buffer_size = t.get_aspect().template get<_buffer_size_>();
40 :
41 8 : if ( buffer_size < sizeof(head_type) )
42 0 : throw;
43 :
44 8 : const head_type* head = t.get_aspect().template get<_head_>()(t);
45 8 : if ( head == fas_nullptr )
46 0 : throw;
47 :
48 8 : size_t head_offset = head->offset();
49 8 : if ( buffer_size < head->offset() )
50 0 : throw;
51 :
52 8 : size_t size = head->size();
53 :
54 8 : if ( offset >= size && offset!=0 )
55 0 : return 0;
56 :
57 8 : if ( offset + limit > size )
58 1 : limit = size - offset;
59 :
60 8 : size_t real_size = limit;
61 8 : size_t real_offset = offset;
62 :
63 8 : if ( offset==0 )
64 8 : real_size += head_offset;
65 : else
66 0 : real_offset += head_offset;
67 :
68 8 : if ( offset + real_size > buffer_size)
69 1 : real_size = buffer_size - offset;
70 :
71 :
72 8 : const char *buff = t.get_aspect().template get<_buffer_>();
73 :
74 8 : t.get_aspect().template get<_write_file_>()(
75 : t,
76 : buff + real_offset,
77 : real_size,
78 : real_offset
79 8 : );
80 :
81 8 : return real_offset + real_size >= buffer_size ? 0 : offset + limit;
82 : }
83 : };
84 :
85 : }}}}
86 :
87 : #endif
|