diff --git a/Makefile b/Makefile index 3becb40..a7b965a 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,8 @@ SRCS = src/App.cpp \ src/MainWindow.cpp \ src/MediaPlayer.cpp \ src/ReplicantView.cpp \ - src/Song.cpp + src/Song.cpp \ + src/TextFile.cpp # Specify the resource definition files to use. Full or relative paths can be # used. diff --git a/src/Song.cpp b/src/Song.cpp index 550d123..75a7fee 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -5,13 +5,13 @@ #include "Song.h" -#include - #include #include #include #include +#include "TextFile.h" + Song::Song() { @@ -35,18 +35,17 @@ Song::InitCheck() status_t Song::Lyrics(BString* buffer) { - BFile file(_LyricsPath().Path(), B_READ_ONLY); + TextFile file(_LyricsPath().Path(), B_READ_ONLY); - off_t size = 0; - char* buf = NULL; - if (file.InitCheck() == B_OK && file.GetSize(&size) == B_OK) { - buf = (char*)malloc((size_t)size); - file.Read(buf, size); - *buffer << buf; - free(buf); - } else - *buffer = "No lyrics available.\n"; - return B_OK; + if (file.InitCheck() == B_OK) { + const char* line = file.ReadLine(); + while (line != NULL) { + *buffer << line << '\n'; + line = file.ReadLine(); + } + } + + return file.InitCheck(); } diff --git a/src/TextFile.cpp b/src/TextFile.cpp new file mode 100644 index 0000000..ca4ef0e --- /dev/null +++ b/src/TextFile.cpp @@ -0,0 +1,109 @@ +/* + TextFile.cpp: Buffered line-based access to text files + Written by DarkWyrm, Copyright 2007 + Released under the MIT license. +*/ +#include "TextFile.h" +#include +#include +#include + +TextFile::TextFile(void) + : BFile() +{ + InitObject(); +} + + +TextFile::TextFile(const char *path, const uint32 &openmode) + : BFile(path,openmode) +{ + InitObject(); +} + + +TextFile::TextFile(const entry_ref &ref, const uint32 &openmode) + : BFile(&ref,openmode) +{ + InitObject(); +} + + +TextFile::~TextFile(void) +{ + delete [] fBuffer; + delete [] fReadBuffer; +} + + +void +TextFile::InitObject(void) +{ + fReadBuffer = new char[4096]; + fReadBufferSize = 4096; + + if (InitCheck() == B_OK) { + GetSize(&fBufferSize); + fBuffer = new char[fBufferSize+1]; + + Read(fBuffer,fBufferSize); + Seek(0,SEEK_SET); + + fBuffer[fBufferSize]=0; + } else { + fBuffer = NULL; + fBufferSize = 0; + } +} + + +const char * +TextFile::ReadLine(void) +{ + off_t pos = Position(); + off_t size = -1; + if (GetSize(&size) != B_OK || pos >= size) + return NULL; + + + char *c = fBuffer; + c += sizeof(char) * pos; + + char *eol = strchr(c,'\n'); + + if (!eol) { + // This means that there are no more linefeeds before the the + // end of the file + eol = strchr(c,'\0'); + if (!eol) + return NULL; + } + + int32 length = eol-c; + + if (length > fReadBufferSize) { + fReadBufferSize = length; + delete fReadBuffer; + fReadBuffer = new char[fReadBufferSize]; + } + + strncpy(fReadBuffer,c,length); + fReadBuffer[length] = 0; + + Seek(length + 1, SEEK_CUR); + + // do we need to add a \0? + return fReadBuffer; +} + + +ssize_t +TextFile::WriteString(const char *string) +{ + if (!string) + return B_ERROR; + + size_t size = strlen(string); + return Write(string, size); +} + diff --git a/src/TextFile.h b/src/TextFile.h new file mode 100644 index 0000000..0cb0a89 --- /dev/null +++ b/src/TextFile.h @@ -0,0 +1,30 @@ +/* + TextFile.h: Buffered line-based access to text files + Written by DarkWyrm, Copyright 2007 + Released under the MIT license. +*/ +#ifndef TEXTFILE_H +#define TEXTFILE_H + +#include + +class TextFile : public BFile +{ +public: + TextFile(void); + TextFile(const char *path, const uint32 &openmode); + TextFile(const entry_ref &ref, const uint32 &openmode); + ~TextFile(void); + const char * ReadLine(void); + ssize_t WriteString(const char *string); + +private: + void InitObject(void); + + char *fBuffer; + off_t fBufferSize; + char *fReadBuffer; + int32 fReadBufferSize; +}; + +#endif