8a8a37dbea45372288040590f307e27c777439a9
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / file-closer.h
1 #ifndef _DALI_INTERNAL_PLATFORM_FILECLOSER_H__
2 #define _DALI_INTERNAL_PLATFORM_FILECLOSER_H__
3 /*
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // INTERNAL INCLUDES
21
22 // EXTERNAL INCLUDES
23 #include <cstdio>
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 namespace Platform
30 {
31 namespace InternalFile
32 {
33   FILE *fmemopen( void *__s, size_t __len, const char *__modes );
34
35   size_t fread( void*  _Buffer, size_t _ElementSize, size_t _ElementCount, FILE*  _Stream );
36   int fclose( FILE *__stream );
37
38   size_t fread( void* buf, size_t eleSize, size_t count, const FILE *fp );
39
40   void fwrite( void *buf, int size, int count, FILE *fp );
41
42   int fseek( FILE *fp, int offset, int origin );
43
44   int ftell( FILE *fp );
45
46   bool feof( FILE *fp );
47 };
48 /**
49  * Opens files and closes them later even if an exception is thrown.
50  */
51 class FileCloser
52 {
53 protected: // prevent this class being directly instantiated
54
55   /**
56    * @brief Construct a FileCloser guarding a new FILE* for accessing the path passed in.
57    */
58   FileCloser( const char * const filename, const char * const mode )
59   : mFile(fopen(filename, mode))
60   {
61     DALI_ASSERT_DEBUG( filename != 0 && "Cant open a null filename." );
62     DALI_ASSERT_DEBUG( mode != 0 && "Null mode is undefined behaviour in spec." );
63
64     if( mFile == 0 )
65     {
66       DALI_LOG_WARNING( "File open failed for: \"%s\" in mode: \"%s\".\n", filename, mode );
67     }
68   }
69
70   /**
71    * @brief Construct a FileCloser guarding a FILE* for reading out of the memory buffer passed in.
72    */
73   FileCloser( uint8_t* buffer, size_t dataSize, const char * const mode )
74   : mFile( InternalFile::fmemopen( buffer, dataSize, mode) )
75   {
76   }
77
78   FileCloser( Dali::Vector<uint8_t>& vector, size_t dataSize, const char * const mode )
79   {
80     // Resize the buffer to ensure any null that gets written by
81     // fmemopen is written past the end of any data that is written to the buffer.
82     // (Workaround for a bug in Ubuntu that overwrites null to the last byte of the
83     // data block regardless of whether binary mode was specified. Tizen doesn't write
84     // null if binary mode is specified).
85     size_t bufferSize = dataSize;
86     ++bufferSize;
87     vector.Resize( bufferSize );
88
89     void * const buffer = &vector[0];
90     mFile = InternalFile::fmemopen( buffer, bufferSize, mode );
91
92     DALI_ASSERT_DEBUG( buffer != 0 && "Cant open file on null buffer." );
93     DALI_ASSERT_DEBUG( dataSize > 0 && "Pointless to open file on empty buffer." );
94     DALI_ASSERT_DEBUG( mode != 0 && "Null mode is undefined behaviour in spec." );
95
96     if( mFile == 0 )
97     {
98       DALI_LOG_WARNING( "File open failed for memory buffer at location: \"%p\", of size: \"%u\", in mode: \"%s\".\n", static_cast<void*>(buffer), static_cast<unsigned>(dataSize), mode );
99     }
100   }
101
102    /**
103     * @brief Destroy the FileCloser and clean up its FILE*.
104     */
105   ~FileCloser()
106   {
107     if( mFile != 0 )
108     {
109       const int closeFailed = InternalFile::fclose( mFile );
110
111       if ( closeFailed )
112       {
113         DALI_LOG_WARNING( "File close failed for FILE: \"%p\".\n", static_cast<void*>(mFile) );
114       }
115       mFile = 0;
116     }
117   }
118
119 public:
120   /**
121    * @return The FILE* guarded by this object.
122    */
123   FILE* GetFile()
124   {
125     return mFile;
126   }
127
128 private:
129
130   // Undefined
131   FileCloser( const FileCloser& fileCloser );
132
133   // Undefined
134   FileCloser& operator=( const FileCloser& fileCloser );
135
136 private:
137   FILE* mFile;
138 };
139
140 } /* namespace Platform */
141 } /* namespace Internal */
142 } /* namespace Dali */
143
144 #endif /* _DALI_INTERNAL_PLATFORM_FILECLOSER_H__ */