Imported Upstream version 17.22.0
[platform/upstream/libzypp.git] / zypp / base / ZckStream.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 #include "zypp/base/ZckStream.h"
10 #include "zypp/base/String.h"
11
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <errno.h>
17
18 extern "C" {
19 #include <zck.h>
20 }
21
22 namespace zypp {
23
24   namespace detail {
25
26     zckstreambufimpl::~zckstreambufimpl()
27     {
28       closeImpl();
29     }
30
31     bool zckstreambufimpl::openImpl( const char *name_r, std::ios_base::openmode mode_r )
32     {
33       if ( isOpen() )
34         return false;
35
36       if ( mode_r == std::ios_base::in ) {
37         _fd = ::open( name_r, O_RDONLY | O_CLOEXEC );
38         _isReading = true;
39
40       } else if ( mode_r == std::ios_base::out ) {
41         _fd = ::open( name_r, O_WRONLY|O_CREAT|O_CLOEXEC, 0666 );
42         _isReading = false;
43       } else {
44         //unsupported mode
45         _lastErr = str::Format("ZChunk backend does not support the given open mode.");
46         return false;
47       }
48
49       if ( _fd < 0 ) {
50         const int errSrv = errno;
51         _lastErr = str::Format("Opening file failed: %1%") % ::strerror( errSrv );
52         return false;
53       }
54
55       _zContext = ::zck_create();
56       if ( !_zContext ) {
57         setError();
58         return false;
59       }
60
61       if ( _isReading ) {
62         if ( !::zck_init_read( _zContext, _fd ) ) {
63           setError();
64           return false;
65         }
66       } else {
67         if ( !::zck_init_write( _zContext, _fd ) ) {
68           setError();
69           return false;
70         }
71       }
72
73       _currfp = 0;
74       return true;
75     }
76
77     bool zckstreambufimpl::closeImpl()
78     {
79       if ( !isOpen() )
80         return true;
81
82       bool success = true;
83
84       if ( !zck_close( _zContext ) ) {
85         setError();
86         success = false;
87       }
88
89       zck_free( &_zContext );
90       _zContext = nullptr;
91       ::close( _fd );
92       _fd = -1;
93       return success;
94     }
95
96     void zckstreambufimpl::setError()
97     {
98       if ( !zck_is_error( _zContext ) )
99         return;
100       _lastErr = zck_get_error( _zContext );
101       zck_clear_error( _zContext );
102     }
103
104     std::streamsize zckstreambufimpl::readData(char *buffer_r, std::streamsize maxcount_r)
105     {
106       if ( !isOpen() || !canRead() )
107         return -1;
108
109       ssize_t read = zck_read( _zContext, buffer_r, maxcount_r );
110       if ( read > 0 )
111         _currfp += read;
112       else
113         setError();
114
115       return read;
116     }
117
118     bool zckstreambufimpl::writeData(const char *buffer_r, std::streamsize count_r)
119     {
120       if ( !isOpen() || !canWrite() )
121         return false;
122
123       ssize_t wrote = zck_write( _zContext, buffer_r, count_r );
124       if ( wrote > 0 )
125         _currfp += wrote;
126       else
127         setError();
128
129       return wrote;
130     }
131
132     bool zckstreambufimpl::isOpen() const
133     {
134       return ( _fd >= 0 );
135     }
136
137     bool zckstreambufimpl::canRead() const
138     {
139       return _isReading;
140     }
141
142     bool zckstreambufimpl::canWrite() const
143     {
144       return !_isReading;
145     }
146
147     bool zckstreambufimpl::canSeek( std::ios_base::seekdir ) const
148     {
149       return false;
150     }
151
152     off_t zckstreambufimpl::seekTo(off_t, std::ios_base::seekdir , std::ios_base::openmode)
153     {
154       return -1;
155     }
156
157     off_t zckstreambufimpl::tell() const
158     {
159       return _currfp;
160     }
161   }
162
163 }