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);
}
|