BEGIN_POV_BASE_NAMESPACE ITextStream::ITextStream(const char *sname, unsigned int stype) { if(sname == NULL) throw int(kParamErr); stream = New_IStream(sname, stype); if(stream == NULL) throw int(kCannotOpenFileErr); filename = new char[strlen(sname) + 1]; strcpy(filename, sname); lineno = 1; bufferoffset = 0; maxbufferoffset = 0; filelength = 0; ungetbuffer = EOF; curpos = 0 ; stream->seekg(0, IOBase::seek_end); filelength = stream->tellg(); stream->seekg(0, IOBase::seek_set); RefillBuffer(); }
void Indexer::BuildFromLines() { assert(m_pos == m_bufferStart); m_hasSequenceIds = false; size_t lines = 0; int64_t offset = GetFileOffset(); while (!m_done) { m_pos = (char*)memchr(m_pos, ROW_DELIMITER, m_bufferEnd - m_pos); if (m_pos) { SequenceDescriptor sd = {}; sd.m_id = lines; sd.m_numberOfSamples = 1; sd.m_isValid = true; sd.m_fileOffsetBytes = offset; offset = GetFileOffset() + 1; sd.m_byteSize = offset - sd.m_fileOffsetBytes; // TODO: ignore empty lines. AddSequence(sd); ++m_pos; ++lines; } else { RefillBuffer(); } } }
bool ITextStream::seekg(ITextStream::FilePos fp) { bool result = true; if((fp.offset < curpos) && ((curpos - fp.offset) < maxbufferoffset)) { bufferoffset = maxbufferoffset - (curpos - fp.offset); lineno = fp.lineno; ungetbuffer = EOF; } else { result = (stream->seekg(fp.offset) != 0); if(result == true) { lineno = fp.lineno; bufferoffset = 0; maxbufferoffset = 0; ungetbuffer = EOF; curpos = fp.offset ; RefillBuffer(); } else curpos = stream->tellg() ; } return result; }
bool cOggStream::playback() { printf("cOggStream::playback\n"); if (IsPlaying()) { printf("cOggStream::playback already playing, returning true\n"); return true; } for (size_t i = 0; i < BUFFER_NUMBER; i++) { if (!RefillBuffer(buffers[i])) { LOG<<"cOggStream::playback RefillBuffer buffer["<<i<<"] FAILED, returning false"<<std::endl; return false; } } printf("cOggStream::playback queueing buffers\n"); alSourceQueueBuffers(source, BUFFER_NUMBER, buffers); printf("cOggStream::playback playing source\n"); alSourcePlay(source); printf("cOggStream::playback successfully started playback, returning true\n"); return true; }
bool Indexer::TryGetSequenceId(size_t& id) { bool found = false; id = 0; while (!m_done) { while (m_pos != m_bufferEnd) { char c = *m_pos; if (!isdigit(c)) { // Stop as soon as there's a non-digit character return found; } found |= true; id = id * 10 + (c - '0'); ++m_pos; } RefillBuffer(); } // reached EOF without hitting the pipe character, // ignore it for not, parser will have to deal with it. return false; }
static inline bool CheckFileSpace ( XMP_IO* fileRef, IOBuffer* ioBuf, size_t neededLen ) { if ( size_t(ioBuf->limit - ioBuf->ptr) < size_t(neededLen) ) { // ! Avoid VS.Net compare warnings. RefillBuffer ( fileRef, ioBuf ); } return (size_t(ioBuf->limit - ioBuf->ptr) >= size_t(neededLen)); }
void Sound::Impl::DoFrame() { if (!m_initialized) return; ALint state; int num_buffers_processed; if (alcGetCurrentContext() && (m_music_name.size() > 0)) { alGetSourcei(m_sources[0], AL_BUFFERS_PROCESSED, &num_buffers_processed); while (num_buffers_processed > 0) { ALuint buffer_name_yay; alSourceUnqueueBuffers (m_sources[0], 1, &buffer_name_yay); if (RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, buffer_name_yay, BUFFER_SIZE, m_music_loops)) { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise break; /// this happens if RefillBuffer returns 1, meaning it encountered EOF and the file shouldn't be repeated } alSourceQueueBuffers(m_sources[0], 1, &buffer_name_yay); num_buffers_processed--; } alGetSourcei(m_sources[0], AL_SOURCE_STATE, &state); if (state == AL_STOPPED) /// this may happen if the source plays all its buffers before we manage to refill them alSourcePlay(m_sources[0]); } }
void Indexer::SkipLine() { while (!m_done) { m_pos = (char*)memchr(m_pos, ROW_DELIMITER, m_bufferEnd - m_pos); if (m_pos) { //found a new-line character if (++m_pos == m_bufferEnd) { RefillBuffer(); } return; } RefillBuffer(); } }
int ITextStream::getchar() { int chr = 0; if(ungetbuffer != EOF) { chr = ungetbuffer; ungetbuffer = EOF; } else { if(bufferoffset >= maxbufferoffset) chr = EOF; else { chr = buffer[bufferoffset]; bufferoffset++; } } if(((chr == 10) || (chr == 13)) && (bufferoffset >= maxbufferoffset)) RefillBuffer(); if(chr == 10) { if(buffer[bufferoffset] == 13) bufferoffset++; chr = '\n'; lineno++; } else if(chr == 13) { if(buffer[bufferoffset] == 10) bufferoffset++; chr = '\n'; lineno++; } if(bufferoffset >= maxbufferoffset) RefillBuffer(); return chr; }
bool Indexer::GetNextSequenceId(size_t& id) { bool found = false; id = 0; while (!m_done) { while (m_pos != m_bufferEnd) { char c = *m_pos; // a well-formed sequence id must end in either a column delimiter // or a name prefix if (c == COLUMN_DELIMITER || c == NAME_PREFIX) { return found; } if (!isdigit(c)) { // TODO: ignore malformed sequences RuntimeError("Unexpected character('%c')" " while reading a sequence id" " at the offset = %" PRIi64 "\n", c, GetFileOffset()); } found |= true; size_t temp = id; id = id * 10 + (c - '0'); if (temp > id) { // TODO: ignore malformed sequences RuntimeError("Size_t overflow while reading a sequence id" " at the offset = %" PRIi64 "\n", GetFileOffset()); } ++m_pos; } RefillBuffer(); } // TODO: ignore malformed sequences // reached EOF without hitting the pipe character. RuntimeError("Reached the end of file " " while reading a sequence id" " at the offset = %" PRIi64 "\n", GetFileOffset()); }
bool cOggStream::update() { int processed; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); bool active = true; while (processed--) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); ReportError(); active = RefillBuffer(buffer); alSourceQueueBuffers(source, 1, &buffer); ReportError(); } return active; }
ITextStream::ITextStream(const UCS2 *sname, IStream *sstream) { if(sname == NULL) throw POV_EXCEPTION_CODE(kParamErr); if(sstream == NULL) throw POV_EXCEPTION_CODE(kParamErr); stream = sstream; filename = UCS2String(sname); lineno = 1; bufferoffset = 0; maxbufferoffset = 0; filelength = 0; ungetbuffer = EOF; curpos = 0 ; stream->seekg(0, IOBase::seek_end); filelength = stream->tellg(); stream->seekg(0, IOBase::seek_set); RefillBuffer(); }
ITextStream::ITextStream(const UCS2 *sname, unsigned int stype) { if(sname == NULL) throw POV_EXCEPTION_CODE(kParamErr); stream = NewIStream(sname, stype); if(stream == NULL) throw POV_EXCEPTION(kCannotOpenFileErr, string("Cannot open file '") + UCS2toASCIIString(sname) + "' for input."); filename = UCS2String(sname); lineno = 1; bufferoffset = 0; maxbufferoffset = 0; filelength = 0; ungetbuffer = EOF; curpos = 0 ; stream->seekg(0, IOBase::seek_end); filelength = stream->tellg(); stream->seekg(0, IOBase::seek_set); RefillBuffer(); }
ITextStream::ITextStream(const char *sname, IStream *sstream) { if(sname == NULL) throw int(kParamErr); if(sstream == NULL) throw int(kParamErr); stream = sstream; filename = new char[strlen(sname) + 1]; strcpy(filename, sname); lineno = 1; bufferoffset = 0; maxbufferoffset = 0; filelength = 0; ungetbuffer = EOF; curpos = 0 ; stream->seekg(0, IOBase::seek_end); filelength = stream->tellg(); stream->seekg(0, IOBase::seek_set); RefillBuffer(); }
void Indexer::BuildFromLines(CorpusDescriptorPtr corpus) { assert(m_pos == m_bufferStart); m_hasSequenceIds = false; size_t lines = 0; int64_t offset = GetFileOffset(); while (!m_done) { m_pos = (char*)memchr(m_pos, ROW_DELIMITER, m_bufferEnd - m_pos); if (m_pos) { SequenceDescriptor sd = {}; sd.m_numberOfSamples = 1; sd.m_fileOffsetBytes = offset; offset = GetFileOffset() + 1; sd.m_byteSize = offset - sd.m_fileOffsetBytes; AddSequenceIfIncluded(corpus, lines, sd); ++m_pos; ++lines; } else { RefillBuffer(); } } if (offset < m_fileOffsetEnd) { // There's a number of characters, not terminated by a newline, // add a sequence to the index, parser will have to deal with it. SequenceDescriptor sd = {}; sd.m_numberOfSamples = 1; sd.m_fileOffsetBytes = offset; sd.m_byteSize = m_fileOffsetEnd - sd.m_fileOffsetBytes; AddSequenceIfIncluded(corpus, lines, sd); } }
void Sound::Impl::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/) { if (!m_initialized || !GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled())) return; std::string filename = PathString(path); ALuint current_buffer; ALenum source_state; ALsizei ogg_freq; FILE *file = nullptr; int m_i; bool found_buffer = false; bool found_source = false; #ifdef FREEORION_WIN32 ov_callbacks callbacks = { (size_t (*)(void *, size_t, size_t, void *)) fread, (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, (int (*)(void *)) fclose, (long (*)(void *)) ftell }; #endif if (alcGetCurrentContext()) { /* First check if the sound data of the file we want to play is already buffered somewhere */ std::map<std::string, ALuint>::iterator it = m_buffers.find(filename); if (it != m_buffers.end()) { current_buffer = it->second; found_buffer = true; } else { if ((file = fopen(filename.c_str(), "rb")) != nullptr) { // make sure we CAN open it OggVorbis_File ogg_file; vorbis_info *vorbis_info; ALenum ogg_format; #ifdef FREEORION_WIN32 if (!(ov_test_callbacks(file, &ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg #else if (!(ov_test(file, &ogg_file, nullptr, 0))) // check if it's a proper ogg #endif { ov_test_open(&ogg_file); // it is, now fully open the file /* now we need to take some info we will need later */ vorbis_info = ov_info(&ogg_file, -1); if (vorbis_info->channels == 1) ogg_format = AL_FORMAT_MONO16; else ogg_format = AL_FORMAT_STEREO16; ogg_freq = vorbis_info->rate; ogg_int64_t byte_size = ov_pcm_total(&ogg_file, -1) * vorbis_info->channels * 2; if (byte_size <= 1024 * 1024 * 1024) { /* fill up the buffers and queue them up for the first time */ ALuint sound_handle; alGenBuffers(1, &sound_handle); int loop = 0; RefillBuffer(&ogg_file, ogg_format, ogg_freq, sound_handle, byte_size, loop); current_buffer = sound_handle; found_buffer = true; m_buffers.insert(std::make_pair(filename, sound_handle)); } else { ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n"; } ov_clear(&ogg_file); } else { ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n"; } } } if (found_buffer) { /* Now that we have the buffer, we need to find a source to send it to */ for (m_i = 1; m_i < NUM_SOURCES; ++m_i) { // as we're playing sounds we start at 1. 0 is reserved for music alGetSourcei(m_sources[m_i], AL_SOURCE_STATE, &source_state); if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) { found_source = true; alSourcei(m_sources[m_i], AL_BUFFER, current_buffer); alSourcePlay(m_sources[m_i]); break; // so that the sound won't block all the sources } } if (!found_source) ErrorLogger() << "PlaySound: Could not find aviable source - playback aborted\n"; } source_state = alGetError(); if (source_state != AL_NONE) ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(source_state); /* it's important to check for errors, as some functions won't work properly if * they're called when there is a unchecked previous error. */ } }
void Sound::Impl::PlayMusic(const boost::filesystem::path& path, int loops /* = 0*/) { if (!m_initialized) return; ALenum m_openal_error; std::string filename = PathString(path); FILE* m_f = nullptr; vorbis_info* vorbis_info; m_music_loops = 0; #ifdef FREEORION_WIN32 ov_callbacks callbacks = { (size_t (*)(void *, size_t, size_t, void *)) fread, (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, (int (*)(void *)) fclose, (long (*)(void *)) ftell }; #endif if (alcGetCurrentContext()) { if (m_music_name.size() > 0) StopMusic(); if ((m_f = fopen(filename.c_str(), "rb")) != nullptr) // make sure we CAN open it { #ifdef FREEORION_WIN32 if (!(ov_test_callbacks(m_f, &m_ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg #else if (!(ov_test(m_f, &m_ogg_file, nullptr, 0))) // check if it's a proper ogg #endif { ov_test_open(&m_ogg_file); // it is, now fully open the file /* now we need to take some info we will need later */ vorbis_info = ov_info(&m_ogg_file, -1); if (vorbis_info->channels == 1) m_ogg_format = AL_FORMAT_MONO16; else m_ogg_format = AL_FORMAT_STEREO16; m_ogg_freq = vorbis_info->rate; m_music_loops = loops; /* fill up the buffers and queue them up for the first time */ if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[0], BUFFER_SIZE, m_music_loops)) { alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[0]); // queue up the buffer if we manage to fill it if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[1], BUFFER_SIZE, m_music_loops)) { alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[1]); m_music_name = filename; // yup, we're playing something that takes up more than 2 buffers } else { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise } alSourcePlay(m_sources[0]); // play if at least one buffer is queued } else { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise } } else { ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n"; m_music_name.clear(); //just in case ov_clear(&m_ogg_file); } } else ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " I/O Error. Aborting\n"; } m_openal_error = alGetError(); if (m_openal_error != AL_NONE) ErrorLogger() << "PlayMusic: OpenAL ERROR: " << alGetString(m_openal_error); }
void Indexer::Build(CorpusDescriptorPtr corpus) { if (!m_index.IsEmpty()) { return; } m_index.Reserve(filesize(m_file)); RefillBuffer(); // read the first block of data if (m_done) { RuntimeError("Input file is empty"); } if ((m_bufferEnd - m_bufferStart > 3) && (m_bufferStart[0] == '\xEF' && m_bufferStart[1] == '\xBB' && m_bufferStart[2] == '\xBF')) { // input file contains UTF-8 BOM value, skip it. m_pos += 3; m_fileOffsetStart += 3; m_bufferStart += 3; } // check the first byte and decide what to do next if (!m_hasSequenceIds || m_bufferStart[0] == NAME_PREFIX) { // skip sequence id parsing, treat lines as individual sequences BuildFromLines(corpus); return; } size_t id = 0; int64_t offset = GetFileOffset(); // read the very first sequence id if (!TryGetSequenceId(id)) { RuntimeError("Expected a sequence id at the offset %" PRIi64 ", none was found.", offset); } SequenceDescriptor sd = {}; sd.m_fileOffsetBytes = offset; size_t currentKey = id; while (!m_done) { SkipLine(); // ignore whatever is left on this line. offset = GetFileOffset(); // a new line starts at this offset; sd.m_numberOfSamples++; if (!m_done && TryGetSequenceId(id) && id != currentKey) { // found a new sequence, which starts at the [offset] bytes into the file sd.m_byteSize = offset - sd.m_fileOffsetBytes; AddSequenceIfIncluded(corpus, currentKey, sd); sd = {}; sd.m_fileOffsetBytes = offset; currentKey = id; } } // calculate the byte size for the last sequence sd.m_byteSize = m_fileOffsetEnd - sd.m_fileOffsetBytes; AddSequenceIfIncluded(corpus, currentKey, sd); }
void Indexer::Build() { if (!m_chunks.empty()) { return; } if (m_maxChunkSize > 0) { auto fileSize = filesize(m_file); m_chunks.reserve((fileSize + m_maxChunkSize - 1) / m_maxChunkSize); } m_chunks.push_back({}); RefillBuffer(); // read the first block of data if (m_done) { RuntimeError("Input file is empty"); } if ((m_bufferEnd - m_bufferStart > 3) && (m_bufferStart[0] == '\xEF' && m_bufferStart[1] == '\xBB' && m_bufferStart[2] == '\xBF')) { // input file contains UTF-8 BOM value, skip it. m_pos += 3; m_fileOffsetStart += 3; m_bufferStart += 3; } // check the first byte and decide what to do next if (!m_hasSequenceIds || m_bufferStart[0] == NAME_PREFIX) { // skip sequence id parsing, treat lines as individual sequences BuildFromLines(); return; } size_t id = 0; int64_t offset = GetFileOffset(); // read the very first sequence id if (!GetNextSequenceId(id)) { RuntimeError("Expected a sequence id at the offset %" PRIi64 ", none was found.", offset); } SequenceDescriptor sd = {}; sd.m_id = id; sd.m_fileOffsetBytes = offset; sd.m_isValid = true; while (!m_done) { SkipLine(); // ignore whatever is left on this line. offset = GetFileOffset(); // a new line starts at this offset; sd.m_numberOfSamples++; if (!m_done && GetNextSequenceId(id) && id != sd.m_id) { // found a new sequence, which starts at the [offset] bytes into the file sd.m_byteSize = offset - sd.m_fileOffsetBytes; AddSequence(sd); sd = {}; sd.m_id = id; sd.m_fileOffsetBytes = offset; sd.m_isValid = true; } } // calculate the byte size for the last sequence sd.m_byteSize = m_fileOffsetEnd - sd.m_fileOffsetBytes; AddSequence(sd); }