~ubuntu-branches/ubuntu/oneiric/strigi/oneiric

« back to all changes in this revision

Viewing changes to src/streams/skippingfileinputstream.cpp

  • Committer: Package Import Robot
  • Author(s): Fathi Boudra
  • Date: 2011-09-20 08:50:25 UTC
  • mto: (1.1.20 upstream) (5.1.6 sid)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: package-import@ubuntu.com-20110920085025-wszfu6x8rshrjq0e
ImportĀ upstreamĀ versionĀ 0.7.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This file is part of Strigi Desktop Search
2
 
 *
3
 
 * Copyright (C) 2009 Jos van den Oever <jos@vandenoever.info>
4
 
 *
5
 
 * This library is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU Library General Public
7
 
 * License as published by the Free Software Foundation; either
8
 
 * version 2 of the License, or (at your option) any later version.
9
 
 *
10
 
 * This library is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * Library General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU Library General Public License
16
 
 * along with this library; see the file COPYING.LIB.  If not, write to
17
 
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
 
 * Boston, MA 02110-1301, USA.
19
 
 */
20
 
#include "skippingfileinputstream.h"
21
 
#include <config.h>
22
 
#include <strigi/strigiconfig.h>
23
 
#include <iostream>
24
 
#include <algorithm>
25
 
#include <cerrno>
26
 
#include <cstring>
27
 
#include <cstdlib>
28
 
#include <algorithm>
29
 
 
30
 
using namespace Strigi;
31
 
using namespace std;
32
 
 
33
 
SkippingFileInputStream::SkippingFileInputStream(const char* filepath) :p(0) {
34
 
    buffer = 0;
35
 
    buffersize = 0;
36
 
    if (filepath == 0) {
37
 
        file = 0;
38
 
        m_error = "No filename was provided.";
39
 
        m_status = Error;
40
 
        return;
41
 
    }
42
 
    FILE* f = fopen(filepath, "rb");
43
 
    open(f, filepath);
44
 
}
45
 
void
46
 
SkippingFileInputStream::open(FILE* f, const char* path) {
47
 
    // try to open the file for reading
48
 
    file = f;
49
 
    filepath.assign(path);
50
 
    if (file == 0) {
51
 
        // handle error
52
 
        m_error = "Could not read file '";
53
 
        m_error += filepath;
54
 
        m_error += "': ";
55
 
        m_error += strerror(errno);
56
 
        m_status = Error;
57
 
        return;
58
 
    }
59
 
    // determine file size. if the stream is not seekable, the size will be -1
60
 
    if (fseeko(file, 0, SEEK_END) == -1) {
61
 
        m_size = -1;
62
 
    } else {
63
 
        m_size = ftello(file);
64
 
        fseeko(file, 0, SEEK_SET);
65
 
        // if the file has size 0, make sure that it's really empty
66
 
        // this is useful for filesystems like /proc that report files as size 0
67
 
        // for files that do contain content
68
 
        if (m_size == 0) {
69
 
            char dummy[1];
70
 
            size_t n = fread(dummy, 1, 1, file);
71
 
            if (n == 1) {
72
 
                m_size = -1;
73
 
                fseeko(file, 0, SEEK_SET);
74
 
            } else {
75
 
                fclose(file);
76
 
                file = 0;
77
 
                return;
78
 
            }
79
 
        }
80
 
    }
81
 
}
82
 
SkippingFileInputStream::~SkippingFileInputStream() {
83
 
    if (file) {
84
 
        if (fclose(file)) {
85
 
            // handle error
86
 
            m_error = "Could not close file '" + filepath + "'.";
87
 
        }
88
 
    }
89
 
    free(buffer);
90
 
}
91
 
int32_t
92
 
SkippingFileInputStream::read(const char*& start, int32_t _min, int32_t _max) {
93
 
    int32_t n = max(_min, _max);
94
 
    if (n > buffersize) {
95
 
        buffer = (char*)realloc(buffer, n);
96
 
    }
97
 
    int32_t nr = (int32_t)fread(buffer, 1, n, file);
98
 
    m_position = ftell(file);
99
 
    if (nr != n) {
100
 
        if (ferror(file)) {
101
 
            m_status = Error;
102
 
        } else {
103
 
            m_status = Eof;
104
 
            if (m_size == -1) {
105
 
                m_size = m_position;
106
 
            }
107
 
        }
108
 
    }
109
 
    start = buffer;
110
 
    return nr;
111
 
}
112
 
int64_t
113
 
SkippingFileInputStream::skip(int64_t ntoskip) {
114
 
    int64_t oldpos = m_position;
115
 
    if (reset(m_position + ntoskip) == -2) return -2;
116
 
    return m_position - oldpos;
117
 
}
118
 
int64_t
119
 
SkippingFileInputStream::reset(int64_t pos) {
120
 
    if (m_size >= 0 && pos > m_size) pos = m_size;
121
 
    if (fseek(file, pos, SEEK_SET)) {
122
 
        m_status = Error;
123
 
        return -2;
124
 
    }
125
 
    m_position = ftell(file);
126
 
    m_status = (m_position == m_size) ?Eof :Ok;
127
 
    return m_position;
128
 
}