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();
}
Example #2
0
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;
}
Example #4
0
    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;
    }
Example #5
0
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;
}
Example #6
0
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));
}
Example #7
0
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]);
    }
} 
Example #8
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;
}
Example #10
0
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());
}
Example #11
0
    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;
    }
Example #12
0
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();
}
Example #13
0
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();
}
Example #15
0
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);
    }
}
Example #16
0
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. */
    }
}
Example #17
0
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);
}
Example #18
0
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);
}
Example #19
0
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);
}