1 //**********************************************************************************
2 //EncryptPad Copyright 2016 Evgeny Pokhilko
3 //<http://www.evpo.net/encryptpad>
4 //
5 //This file is part of EncryptPad
6 //
7 //EncryptPad is free software: you can redistribute it and/or modify
8 //it under the terms of the GNU General Public License as published by
9 //the Free Software Foundation, either version 2 of the License, or
10 //(at your option) any later version.
11 //
12 //EncryptPad is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with EncryptPad.  If not, see <http://www.gnu.org/licenses/>.
19 //**********************************************************************************
20 #pragma once
21 #include <string>
22 #include <cstdio>
23 
24 namespace EncryptPad
25 {
26     class NonCopyableNonMovable
27     {
28         NonCopyableNonMovable(const NonCopyableNonMovable&) = delete;
29         const NonCopyableNonMovable &operator=(const NonCopyableNonMovable&) = delete;
30         NonCopyableNonMovable(const NonCopyableNonMovable&&) = delete;
31         const NonCopyableNonMovable &operator=(const NonCopyableNonMovable&&) = delete;
32 
33     public:
34         NonCopyableNonMovable() = default;
35     };
36 
37     template<typename F, typename DecayF=typename std::decay<F>::type>
38     class CleanUp : private NonCopyableNonMovable
39     {
40         DecayF f_;
41     public:
42         template<typename T>
CleanUp(T && f)43         CleanUp(T &&f)
44             :f_(std::forward<T>(f))
45         {}
46 
~CleanUp()47         ~CleanUp()
48         {
49             f_();
50         }
51     };
52 
53     bool LoadStringFromDescriptor(int descriptor, std::string &content);
54 
55     bool LoadStringFromFile(const std::string &file_name, std::string &content);
56 
57     template<typename Handle, typename Traits>
58     class UniqueHandler
59     {
60     private:
61         Handle handle_;
62     public:
handle_(handle)63         UniqueHandler(Handle handle = Traits::InvalidHandle()):handle_(handle)
64         {
65         }
66 
UniqueHandler(UniqueHandler && uh)67         UniqueHandler(UniqueHandler &&uh)
68         {
69             handle_ = uh.handle_;
70             uh.handle_ = Traits::InvalidHandle();
71         }
72 
~UniqueHandler()73         ~UniqueHandler()
74         {
75             if(handle_ == Traits::InvalidHandle())
76                 return;
77             Traits::Close(handle_);
78         }
79 
UniqueHandler(UniqueHandler & uh)80         UniqueHandler(UniqueHandler &uh)
81         {
82             handle_ = uh.handle_;
83             uh.handle_ = Traits::InvalidHandle();
84         }
85 
86         const UniqueHandler &operator=(UniqueHandler &uh)
87         {
88             handle_ = uh.handle_;
89             uh.handle_ = Traits::InvalidHandle();
90             return *this;
91         }
92 
get()93         Handle get() const
94         {
95             return handle_;
96         }
97 
98         explicit operator bool() const
99         {
100             return handle_ != Traits::InvalidHandle();
101         }
102 
Valid()103         bool Valid() const
104         {
105             return operator bool();
106         }
107     };
108 
109     class FileTraits
110     {
111     public:
InvalidHandle()112         static FILE *InvalidHandle()
113         {
114             return nullptr;
115         }
116 
Close(FILE * f)117         static void Close(FILE *f)
118         {
119             if(f == stdin || f == stdout)
120             {
121                 fflush(f);
122             }
123             else
124             {
125                 fclose(f);
126             }
127         }
128     };
129 
130     typedef UniqueHandler<FILE *, FileTraits> FileHndl;
131 }
132