1/*
2 * file_handle.cpp - File handle
3 *
4 *  Copyright (c) 2016-2017 Intel Corporation
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 * Author: Yinhang Liu <yinhangx.liu@intel.com>
19 * Author: Wind Yuan <feng.yuan@intel.com>
20 */
21
22#include "file_handle.h"
23
24#define INVALID_SIZE (size_t)(-1)
25
26namespace XCam {
27
28FileHandle::FileHandle ()
29    : _fp (NULL)
30    , _file_name (NULL)
31    , _file_size (INVALID_SIZE)
32{}
33
34FileHandle::FileHandle (const char *name, const char *option)
35    : _fp (NULL)
36    , _file_name (NULL)
37    , _file_size (INVALID_SIZE)
38{
39    open (name, option);
40}
41
42FileHandle::~FileHandle ()
43{
44    close ();
45}
46
47bool
48FileHandle::end_of_file()
49{
50    if (!is_valid ())
51        return true;
52
53    return feof (_fp);
54}
55
56XCamReturn
57FileHandle::open (const char *name, const char *option)
58{
59    XCAM_ASSERT (name);
60    if (!name)
61        return XCAM_RETURN_ERROR_FILE;
62
63    close ();
64    XCAM_ASSERT (!_file_name && !_fp);
65    _fp = fopen (name, option);
66
67    if (!_fp)
68        return XCAM_RETURN_ERROR_FILE;
69    _file_name = strndup (name, 512);
70
71    return XCAM_RETURN_NO_ERROR;
72}
73
74XCamReturn
75FileHandle::close ()
76{
77    if (_fp) {
78        fclose (_fp);
79        _fp = NULL;
80    }
81
82    if (_file_name) {
83        xcam_free (_file_name);
84        _file_name = NULL;
85    }
86
87    _file_size = INVALID_SIZE;
88    return XCAM_RETURN_NO_ERROR;
89}
90
91XCamReturn
92FileHandle::rewind ()
93{
94    if (!is_valid ())
95        return XCAM_RETURN_ERROR_FILE;
96    return (fseek (_fp, 0L, SEEK_SET) == 0) ? XCAM_RETURN_NO_ERROR : XCAM_RETURN_ERROR_FILE;
97}
98
99XCamReturn
100FileHandle::get_file_size (size_t &size)
101{
102    if (_file_size != INVALID_SIZE) {
103        size = _file_size;
104        return XCAM_RETURN_NO_ERROR;
105    }
106
107    fpos_t cur_pos;
108    long file_size;
109
110    if (fgetpos (_fp, &cur_pos) < 0)
111        goto read_error;
112
113    if (fseek (_fp, 0L, SEEK_END) != 0)
114        goto read_error;
115
116    if ((file_size = ftell (_fp)) <= 0)
117        goto read_error;
118
119    if (fsetpos (_fp, &cur_pos) < 0)
120        goto read_error;
121
122    _file_size = file_size;
123    size = file_size;
124    return XCAM_RETURN_NO_ERROR;
125
126read_error:
127    XCAM_LOG_ERROR ("get file size failed with errno:%d", errno);
128    return XCAM_RETURN_ERROR_FILE;
129}
130
131XCamReturn
132FileHandle::read_file (void *buf, const size_t &size)
133{
134    XCamReturn ret = XCAM_RETURN_NO_ERROR;
135
136    if (fread (buf, 1, size, _fp) != size) {
137        if (end_of_file ()) {
138            ret = XCAM_RETURN_BYPASS;
139        } else {
140            XCAM_LOG_ERROR ("read file failed, size doesn't match");
141            ret = XCAM_RETURN_ERROR_FILE;
142        }
143    }
144
145    return ret;
146}
147
148XCamReturn
149FileHandle::write_file (const void *buf, const size_t &size)
150{
151    XCamReturn ret = XCAM_RETURN_NO_ERROR;
152
153    if (fwrite (buf, 1, size, _fp) != size) {
154        XCAM_LOG_ERROR ("write file failed, size doesn't match");
155        ret = XCAM_RETURN_ERROR_FILE;
156    }
157
158    return ret;
159}
160
161}
162