File: FileInputBuffer.cpp

package info (click to toggle)
perm 0.4.0-8
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 976 kB
  • sloc: cpp: 13,499; makefile: 98; sh: 12
file content (168 lines) | stat: -rw-r--r-- 6,312 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "stdafx.h"
#include "FileInputBuffer.h"

FileInputBuffer::FileInputBuffer(void)
{
    this->uiCapacity = 0;
    this->uiPtrIndex = 0;
    this->caBuffer = NULL;
    this->caBufp = NULL;//Don't delete this, this is a pointer to caBuffer.
    this->pbuf = NULL;
}
FileInputBuffer::FileInputBuffer(unsigned int uiCapacity, ifstream* pifile)
{
    this->initialize(uiCapacity, pifile);
}
FileInputBuffer::~FileInputBuffer(void)
{
    delete [] this->caBuffer;
    //Don't delete this->caBufp.. it points to middle of caBuffer
    if (this->pbuf != NULL) {
        if (this->pbuf->is_open()) {
            // LOG_INFO("Info %d: Close file when FileInput is deleted\n", FINE_LOG);
            this->pbuf->close();//Reach the end of the file
        }
    }
    //this->pbuf is not new in class. This is return from ifstream class. Don't delete it.
    this->pbuf = NULL;
    // cout << "Delete File input Buffer" << endl;
}
void FileInputBuffer::initialize(unsigned int uiCapacity, ifstream* pifile)
{
    this->uiCapacity = uiCapacity;
    this->caBuffer = new char [uiCapacity];
    this->pbuf = pifile->rdbuf();
    this->uiPtrIndex = 0;
    //point to start
    this->caBufp = this->caBuffer;
    this->fflush();
}
void FileInputBuffer::fflush()
{
    //Load file directly to the buffer
    memset(this->caBuffer, 0x00, sizeof(char)*this->uiCapacity);
    //load this->uiCapacity - 1 character, so the last one will be 0
    pbuf->sgetn(this->caBuffer, this->uiCapacity - 1);
    this->caBufp = this->caBuffer;//Get new content from file
    this->uiPtrIndex = 0;
    if (this->caBuffer[this->uiCapacity - 2] == 0) { //this must be the end of the file
        if (this->pbuf->is_open())
            // LOG_INFO("Info %d: Close file when fflush to the end\n", FINE_LOG);
            this->pbuf->close();//Reach the end of the file
    }
}
unsigned int FileInputBuffer::Getline(char* caArray, unsigned int uiMax_Char_Per_Line)
{
    //If the file is not ended, return 1, if it is ended of the file return 0
    unsigned int i = uiPtrIndex, j = 0; //j is how many char has been read this time
    while (this->caBuffer[i] <= 126) { //if the character is not strange (The last character of the caBuffer should be 0.
        //If There is a new line or larger than the maximum output line, return current get string
        if (this->caBuffer[i] == '\n' || j >= uiMax_Char_Per_Line) {
            if (this->caBuffer[i] == '\n')
                i++;//next position to avoid '\n';
            this->uiPtrIndex = i;
            this->caBufp = &(this->caBuffer[i]);
            caArray[j] = '\0';
            return(1);//Successfully get a line
        } else if (this->caBuffer[i] == EOF ||
                   ((this->caBuffer[i] == 0) && (!this->pbuf->is_open()))) {		//The end of the file
            //this->caBufp=&(this->caBuffer[this->uiCapacity-1]); //Use less to point to the end
            this->pbuf->close(); //close the file
            caArray[j] = '\0'; //put the end of the array
            this->uiPtrIndex = 0;
            return(0);
        } else if (i >= (uiCapacity - 1)  || this->caBuffer[i] == 0) {  //The buffer content is run out, try to refresh
            if (this->pbuf->is_open()) {
                this->fflush();
                i = 0;//Keep going
            } else {	//The end of the file
                caArray[j] = '\0';
                return(0);//It is end of the file, but it is end of the buffer and end of file
            }
        } else { //Copy the string to buffer
            caArray[j++] = this->caBuffer[i++];
        }
    }
    cout << "sChracter " << caBuffer[i] << "Regard as EOF" << endl;
    // Put the file pointer at the end
    this->caBufp = &(this->caBuffer[this->uiCapacity-1]);
    this->pbuf->close();
    caArray[j] = '\0';//Return null array
    this->uiPtrIndex = 0;
    return(0);
}
bool FileInputBuffer::ready2Read()
{
    bool isReady2Read = false;
    //if the buffer is not empty or the file is still open to read
    isReady2Read = (this->caBufp[0] != 0 || this->pbuf->is_open()); //should test if not come to EOF
    return(isReady2Read);
}

// return the file size in bytes
unsigned long long getFileSize(const char* fileName)
{
// TODO Fix the potential bug that has file size larger than long
    unsigned long long filesize = 0;
// If compiled by Microsoft visual c++
#ifdef __MSVC__
    // Copy from others and need to be test
    bool fOk;
    WIN32_FILE_ATTRIBUTE_DATA   fileInfo;
    if (NULL == fileName)
        return -1;
    fOk = GetFileAttributesEx(fileName, GetFileExInfoStandard, (void*) & fileInfo);
    if (!fOk)
        return -1;
    assert(0 == fileInfo.nFileSizeHigh);
    return (unsigned long long)fileInfo.nFileSizeLow;
#elif defined _MSC_VER
    FILE * stream = fopen(fileName, "r");
    fseek(stream, 0L, SEEK_END);
    filesize = (unsigned long long)ftell(stream);
    fclose(stream);
#endif
#ifdef __GNUC__
    FILE * stream = fopen(fileName, "r");
    fseek(stream, 0L, SEEK_END);
    filesize = (unsigned long long)ftell(stream);
    fclose(stream);
#endif
    return(filesize);
}

unsigned long long getNumberOfLineInAFile(const char* fileName)
{
    unsigned long long estimatedNoOfLines = 1;
    // count how many lines are there
    ifstream ifile;
    ifile.open(fileName, ifstream::in);
    char BUFFER[MAX_INPUT_BUFFER_SIZE];
    memset(BUFFER, 0x00, sizeof(char)*MAX_INPUT_BUFFER_SIZE);
    ifile.getline(BUFFER, MAX_INPUT_BUFFER_SIZE);
    if (ifile.bad()) {
        cout << " Can't open file " << fileName << endl;
    }
    (ifile.rdbuf())->sgetn(BUFFER, MAX_INPUT_BUFFER_SIZE - 1);
    for (unsigned int i = 0; i < MAX_INPUT_BUFFER_SIZE; i++) {
        if (BUFFER[i] == EOF || !ifile.good()) {
            cout << "Total No of lines:" << (int)estimatedNoOfLines << endl;
            break;
        } else if (BUFFER[i] == '\n') {
            estimatedNoOfLines++;
        } else if (BUFFER[i] == 0) {
            if (i ==  MAX_INPUT_BUFFER_SIZE - 1) {
                memset(BUFFER, 0x00, sizeof(char)*MAX_INPUT_BUFFER_SIZE);
                (ifile.rdbuf())->sgetn(BUFFER, MAX_INPUT_BUFFER_SIZE - 1);
                i = 0;
            } else {
                break;
            }
        } else {
            //DO nothing;
        }
    }
    ifile.close();
    return(estimatedNoOfLines);
}