示例#1
0
文件: riff.cpp 项目: kierank/qaac
void RIFFParser::parse()
{
    next();
    if (chunk_id() != 'RIFF' && chunk_id() != 'RF64')
	throw std::runtime_error("Not a RIFF file");
    set_format_id(down());
    if (chunk_id() == 'RF64')
	parse_datasize64();
}
示例#2
0
 /**
  * Is the Id in the set?
  *
  * @param id The Id to check.
  */
 bool get(T id) const noexcept override final {
     if (chunk_id(id) >= m_data.size()) {
         return false;
     }
     auto* r = m_data[chunk_id(id)].get();
     if (!r) {
         return false;
     }
     return (r[offset(id)] & bitmask(id)) != 0;
 }
示例#3
0
文件: riff.cpp 项目: kierank/qaac
void RIFFParser::parse_datasize64()
{
    next();
    if (chunk_id() != 'ds64')
	throw std::runtime_error("Invalid RF64 format");

    check_eof(stream().seek_forward(8) == 8);

    uint32_t x, y;
    check_eof(stream().read32le(&x));
    check_eof(stream().read32le(&y));
    m_chunk_size_map['data'] = ((static_cast<uint64_t>(y) << 32) | x);

    check_eof(stream().seek_forward(8) == 8);

    uint32_t len;
    check_eof(stream().read32le(&len));

    for (uint32_t i = 0; i < len; ++i) {
	char buff[4];
	check_eof(stream().read(buff, 4) == 4);
	check_eof(stream().read32le(&x));
	check_eof(stream().read32le(&y));
	m_chunk_size_map[fourcc(buff)]
	    = ((static_cast<uint64_t>(y) << 32) | x);
    }
    done_chunk();
}
示例#4
0
文件: riff.cpp 项目: kierank/qaac
bool RIFFParser::get_chunkinfo(uint32_t *fcc, uint64_t *size)
{
    char buff[4];
    if (stream().read(buff, 4) < 4)
	return false;
    *fcc = fourcc(buff);
    uint32_t x;
    check_eof(stream().read32le(&x));
    *size = x;
    // RF64 support
    chunk_map_t::const_iterator it = m_chunk_size_map.find(chunk_id());
    if (it != m_chunk_size_map.end())
	*size = it->second;
    return true;
}
void HandleMaps::issue_command_() {
    bool assigned = false; //Describes status of current chunk (file)
    while(assigned == false) {
       try {
          saga::stream::stream worker = service_->serve();
          std::string message("Established connection to ");
          message += worker.get_url().get_string();
          log_->write(message, MR_LOGLEVEL_INFO);

          // Ask worker for state.
          worker.write(saga::buffer(MASTER_QUESTION_STATE, 6));
          if (!SagaStreamUtils::TimedWaitForRead(
                   worker, job_.get_attribute("protocol.read_timeout", 10))) {
            log_->write("Worker didn't respond -- retrying.", MR_LOGLEVEL_DEBUG);
            delete service_;
            service_ = new saga::stream::server(serverURL_);
            continue;
          }

          char buff[MSG_BUFFER_SIZE];
          saga::ssize_t read_bytes = worker.read(saga::buffer(buff));
          std::string state(buff, read_bytes);

          message.clear();
          message = "Worker: " + worker.get_url().get_string() + " has state " + state;
          log_->write(message, MR_LOGLEVEL_INFO);

          if(state == WORKER_STATE_IDLE)
          {
             if(finished_.size() == totalChunks_ || unassigned_.size() == 0)
             {
                //Prevent unneccessary work assignments
                worker.write(saga::buffer(MASTER_REQUEST_IDLE, 5));
                saga::ssize_t read_bytes = worker.read(saga::buffer(buff));
                if(std::string(buff, read_bytes) != WORKER_RESPONSE_ACKNOWLEDGE)
                {
                   log_->write(std::string("Misbehaving worker!"), MR_LOGLEVEL_WARNING);
                }
                return;
             }
             std::string chunk_id(getCandidate_(worker));
             //Worker is idle
             message.clear();
             message = "Attempting to issue worker ";
             message += worker.get_url().get_string();
             message += " to map " + chunk_id;
             message += " ...";
             log_->write(message, MR_LOGLEVEL_INFO);

             //ask where their advert is
             worker.write(saga::buffer(MASTER_QUESTION_ADVERT, 7));
             memset(buff, 0, MSG_BUFFER_SIZE);
             read_bytes = worker.read(saga::buffer(buff));
             saga::url advert = saga::url(std::string(buff, read_bytes));
             // Store URL->advert mapping.
             worker_adverts_[worker.get_url().get_string()] = advert;

             message.clear();
             message += worker.get_url().get_string();
             message += " <==> " + std::string(buff);
             message += " ... ";
             log_->write(message, MR_LOGLEVEL_INFO); 

             //Tell worker about data
             worker.write(saga::buffer(WORKER_COMMAND_MAP, 3));
             memset(buff, 0, MSG_BUFFER_SIZE);
             read_bytes = worker.read(saga::buffer(buff));
             if(std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE)
             {
                worker.write(saga::buffer(WORKER_CHUNK, 5));
                memset(buff, 0, MSG_BUFFER_SIZE);
                read_bytes = worker.read(saga::buffer(buff));
                if(std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE)
                {
                  // Get chunk pointer for ID.
                  InputChunk* chunk = chunk_assignments_[chunk_id];
                  // Give serialized JobDescription, chunk_id and chunk to worker.
                  // FIXME: shouldn't we store chunk ID with the chunk/jobdesc?
                  std::string command;
                  {
                    StringOutputStream sos(&command);
                    SerializationHandler<JobDescription>::Serialize(
                      const_cast<JobDescription*>(&job_), &sos);
                    SerializationHandler<std::string>::Serialize(&chunk_id, &sos);
                    input_format_->SerializeInputChunk(chunk, &sos);
                  }
                   worker.write(saga::buffer(command, command.size()));
                   memset(buff, 0, MSG_BUFFER_SIZE);
                   read_bytes = worker.read(saga::buffer(buff));
                   if (std::string(buff, read_bytes) == WORKER_RESPONSE_ACKNOWLEDGE)
                   {
                      // Add to assigned set.
                      assigned_.insert(chunk_id);
                      //Remove from unassigned.
                      unassigned_.erase(chunk_id);
                   }
                }
             }
             else
             {
                message = std::string("Worker did not accept chunk!");
                log_->write(message, MR_LOGLEVEL_WARNING);
                break;
             }

             message.clear();
             message += "Success: ";
             message += advert.get_string() + " is comparing chunk ";
             message += chunk_id;
             log_->write(message, MR_LOGLEVEL_INFO);

             assigned = true;
          }
          else if(state == WORKER_STATE_DONE_MAP)
          {
             worker.write(saga::buffer(MASTER_QUESTION_RESULT, 7));
             memset(buff, 0, MSG_BUFFER_SIZE);
             read_bytes = worker.read(saga::buffer(buff));
             std::string result_message(buff, read_bytes);
             worker.write(saga::buffer(MASTER_REQUEST_IDLE, 5));
             // Parse result message.
             size_t split_point = result_message.find_first_of(' ');
             std::string chunk_id = result_message.substr(0, split_point);
             std::string worker_advert = result_message.substr(split_point+1);
             message.clear();
             message += "Worker ";
             message += worker.get_url().get_string() + " finished chunk ";
             message += chunk_id;
             log_->write(message, MR_LOGLEVEL_INFO);

             // Note which worker completed this chunk.
             message.clear();
             message += "Noted " + worker_advert + " for " + chunk_id;
             committed_chunks_[chunk_id] = worker_advert;
             // If in assigned, remove it.
             assigned_.erase(chunk_id);
             // Put into finished set.
             finished_.insert(chunk_id);
          }
       }
       catch(saga::exception const & e) {
          std::string message(e.what());
          log_->write(message, MR_LOGLEVEL_ERROR);
       }
    }
}