コード例 #1
0
ファイル: create.hpp プロジェクト: AnthonyNystrom/r17
  void from_recordset_stream(const std::string &reliable_storage_local_root,
                              const std::string &reliable_storage_remote_root,
                              Input_Stream &input, Output_Stream &output,
                              const std::vector<rel::rlang::token> &tokens) {
    /* Get the headers. */
    record headings(input.parse_headings());

    // Get the resource id field id, this is the only field that we're interested
    // in, the rest are just placeholders.
    size_t resource_id_field_id = headings.mandatory_find_field(
                                      NP1_REL_DISTRIBUTED_RESOURCE_ID_FIELD_NAME);

    // Create the target recordset.
    std::string target_recordset_name(rel::rlang::compiler::eval_to_string_only(tokens));
    np1::io::reliable_storage::id target_recordset_resource_id(target_recordset_name);

    np1::io::reliable_storage rs(reliable_storage_local_root, reliable_storage_remote_root);
    np1::io::reliable_storage::stream target_recordset_stream(rs);
    NP1_ASSERT(rs.create_wo(target_recordset_resource_id, target_recordset_stream),
                "Unable to create recordset " + target_recordset_name);


    // Read all the input recordset chunks ids and write them to the recordset file.
    input.parse_records(
      shallow_copy_chunk_record_callback(
        rs, target_recordset_stream,  resource_id_field_id, headings.ref()));

    NP1_ASSERT(target_recordset_stream.close(),
                "Unable to close target recordset stream");
  }
コード例 #2
0
ファイル: remote.hpp プロジェクト: barrbrain/r17
  static void run(io::unbuffered_stream_base &input, io::unbuffered_stream_base &output,
                  const rstd::vector<rel::rlang::token> &tokens) {
    // Split the arguments into a hostname and the rest.
    rstd::vector<rstd::vector<rel::rlang::token> > expressions = rel::rlang::compiler::split_expressions(tokens);
    NP1_ASSERT(expressions.size() >= 2, "meta.remote expects a hostname argument and a script argument");
    rstd::string hostname = rel::rlang::compiler::eval_to_string_only(expressions[0]);

    // Get the rest of the arguments as a string.
    rstd::vector<rstd::vector<rel::rlang::token> >::const_iterator i = expressions.begin();
    ++i; // Skip over the hostname.
    rstd::vector<rstd::vector<rel::rlang::token> >::const_iterator iz = expressions.end();

    rstd::string r17_script;
    io::string_output_stream r17_script_sos(r17_script);
    
    for (; i != iz; ++i) {
      rel::rlang::io::token_writer::mandatory_write(r17_script_sos, *i);      
    }

    r17_script_sos.write(';');

    // Escape the string for use on a bash command line.
    rstd::string escaped_r17_script;
    io::string_output_stream escaped_r17_script_sos(escaped_r17_script);
    str::write_bash_escaped_string(r17_script, escaped_r17_script_sos);

    // Prepare the arguments ready for the exec.
    rstd::vector<rstd::string> exec_args;
    exec_args.push_back("ssh");
    exec_args.push_back(hostname);
    exec_args.push_back("r17");
    exec_args.push_back(escaped_r17_script);

    // Fork then exec so that we can return just like the other operators do and
    // so we can do useful things with stderr.
    int stderr_pipe[2];
    process::mandatory_pipe_create(stderr_pipe);
    pid_t ssh_child_pid = process::mandatory_fork();
    if (0 == ssh_child_pid) {
      // Child.
      close(stderr_pipe[0]);

      // If the host is localhost then just execute the script without the cost
      // of an exec
      if (str::cmp(hostname, "localhost") == 0) {
        io::file output_file;
        dup2(stderr_pipe[1], 2);
        script_run(input, output, r17_script, false);
        exit(0);
      } else {
        process::mandatory_execvp(exec_args, input.handle(), output.handle(), stderr_pipe[1]);
        NP1_ASSERT(false, "Unreachable code after mandatory_execvp");
      }
    }

    // Parent. Read stderr stream.
    close(stderr_pipe[1]);
    read_and_prefix_stderr(hostname, stderr_pipe[0]);
    process::mandatory_wait_for_child(ssh_child_pid);
  }
コード例 #3
0
ファイル: fn.hpp プロジェクト: AnthonyNystrom/r17
  inline static dt::string call(vm_heap &heap, const dt::string &command) {
    // Set stdout to be a temporary file.
    FILE *tmpfp = tmpfile();
    NP1_ASSERT(tmpfp, "Unable to create temporary file for meta.shell function");
    ::np1::io::file tmpf;
    tmpf.from_handle(fileno(tmpfp));
    int saved_stdout = dup(1);
    dup2(tmpf.handle(), 1);

    // Execute the command.
    NP1_ASSERT(system(command.to_string().c_str()) >= 0, "system() failed for meta.shell");

    // Set stdout back to what it was and read the whole file.
    dup2(saved_stdout, 1);
    close(saved_stdout);
    tmpf.rewind();
    ::np1::io::mandatory_input_stream<np1::io::file> mandatory_tmpf(tmpf);
    ::np1::io::ext_heap_buffer_output_stream<vm_heap> command_output(heap, TEMP_FILE_READ_BUFFER_SIZE);
    mandatory_tmpf.copy(command_output);
    
    // Ensure that the command output is valid UTF-8.
    char *command_output_p = (char *)command_output.ptr();
    size_t command_output_size = command_output.size();
    str::replace_invalid_utf8_sequences(command_output_p, command_output_size, '?');

    return dt::string(command_output_p, command_output_size);
  }
コード例 #4
0
ファイル: create.hpp プロジェクト: AnthonyNystrom/r17
    bool operator()(const record_ref &r) {
      // Open the current output chunk stream (if not opened) and write its name to the
      // file that lists the chunks in the recordset.
      if (!m_mandatory_current_target_chunk_stream.is_open()) {
        m_current_target_chunk_id = np1::io::reliable_storage::id::generate();

        NP1_ASSERT(m_rs.create_wo(m_current_target_chunk_id, m_current_target_chunk_stream),
                    "Unable to create recordset stream chunk "
                      + m_current_target_chunk_id.to_string());

        NP1_ASSERT(m_target_recordset_stream.write(m_current_target_chunk_id)
                    && m_target_recordset_stream.write("\n"),
                    "Unable to write to recordset");

        m_headings.write(m_mandatory_current_target_chunk_stream);
        m_current_target_chunk_size = 0;
      }

      // Write the record to the output chunk stream, and close the stream
      // if it's big enough.
      size_t record_byte_size = r.byte_size();
      r.write(m_mandatory_current_target_chunk_stream);
      m_current_target_chunk_size += record_byte_size;

      if (m_current_target_chunk_size > m_approx_max_chunk_size) {
        m_mandatory_current_target_chunk_stream.close();
      }

      return true;
    }    
コード例 #5
0
ファイル: utf16_to_utf8.hpp プロジェクト: barrbrain/r17
    void operator()(Input_Stream &input, Output_Stream &output, const rstd::vector<rel::rlang::token> &args) {
        // Sort out the arguments.
        NP1_ASSERT(args.size() == 0, "text.utf16_to_utf8 expects no arguments.");

        io::utf16_input_stream<Input_Stream> utf16_input(input);

        NP1_ASSERT(str::convert_utf16_to_utf8(utf16_input, output), "Invalid UTF-16 stream");
    }
コード例 #6
0
ファイル: ip_endpoint.hpp プロジェクト: barrbrain/r17
 void initialize(const char *str) {
   const char *colon_p = strchr(str, ':');
   NP1_ASSERT(colon_p, "Malformed IP endpoint string: " + rstd::string(str));
   int64_t i64 = str::dec_to_int64(colon_p + 1);
   NP1_ASSERT((i64 > 0) && (i64 < MAX_PORT), "Malformed IP endpoint string: " + rstd::string(str));
   *((char *)colon_p) = '\0';
   initialize(str, (int)i64);
   *((char *)colon_p) = ':';
 }
コード例 #7
0
ファイル: create.hpp プロジェクト: AnthonyNystrom/r17
  void from_data_stream(const std::string &reliable_storage_local_root,
                          const std::string &reliable_storage_remote_root,
                          Input_Stream &input, Output_Stream &output,
                          const std::vector<rel::rlang::token> &tokens) {
    /* Get the headers. */
    record headings(input.parse_headings());

    // Interpret the arguments.
    std::vector<std::pair<std::string, rlang::dt::data_type> > args = rel::rlang::compiler::eval_to_strings(tokens);
    NP1_ASSERT((args.size() > 0) && (args.size() <= 2), "Incorrect number of arguments to rel.recordset.create");
    tokens[0].assert(rlang::dt::data_type::TYPE_STRING == args[0].second,
                      "First argument to rel.recordset.create is not a string");
    std::string target_recordset_name = args[0].first;

    uint64_t approx_max_chunk_size = DEFAULT_APPROX_MAX_CHUNK_SIZE_BYTES;
    if (args.size() > 1) {
      tokens[0].assert((rlang::dt::data_type::TYPE_INT == args[1].second)
                        || (rlang::dt::data_type::TYPE_UINT == args[1].second),
                        "Second argument to rel.recordset.create is not an integer");
      approx_max_chunk_size = str::dec_to_int64(args[1].first);
    }

    // Get the stream that will hold the recordset.
    np1::io::reliable_storage::id target_recordset_resource_id(target_recordset_name);

    np1::io::reliable_storage rs(reliable_storage_local_root, reliable_storage_remote_root);
    np1::io::reliable_storage::stream target_recordset_stream(rs);
    NP1_ASSERT(rs.create_wo(target_recordset_resource_id, target_recordset_stream),
                "Unable to create recordset " + target_recordset_name
                  + " in reliable storage '" + reliable_storage_local_root + "'");

    np1::io::reliable_storage::stream current_target_chunk_stream(rs);
    buffered_reliable_storage_stream_type buffered_current_target_chunk_stream(
                                            current_target_chunk_stream);

    mandatory_reliable_storage_stream_type mandatory_current_target_chunk_stream(
                                            buffered_current_target_chunk_stream);

    np1::io::reliable_storage::id current_target_chunk_id;
    uint64_t current_target_chunk_size = 0;

    // Read all the input data and redistribute it into recordset chunks.
    input.parse_records(
        chunk_data_record_callback(
          rs, target_recordset_stream, current_target_chunk_id,
          current_target_chunk_stream, mandatory_current_target_chunk_stream,
          current_target_chunk_size, approx_max_chunk_size, headings.ref()));

    // Close everything.
    mandatory_current_target_chunk_stream.close();

    NP1_ASSERT(target_recordset_stream.close(),
                "Unable to close target recordset stream");
  }
コード例 #8
0
ファイル: fn.hpp プロジェクト: AnthonyNystrom/r17
  static dt::uinteger parse(const str::ref &time_s, const str::ref &format_s) {
    //TODO: do without this null-char-putting.
    char *time_ptr = (char *)time_s.ptr();
    char *end_time_ptr = time_ptr + time_s.length();
    char prev_end_time_char = *end_time_ptr;
    *end_time_ptr = '\0';

    char *format_ptr = (char *)format_s.ptr();
    char *end_format_ptr = format_ptr + format_s.length();
    char prev_end_format_char = *end_format_ptr;
    *end_format_ptr = '\0';

    struct tm tm_buf;
    // If we don't memset then any fields uninitialized by the time string won't be initialized by strptime
    // in release mode.
    memset(&tm_buf, 0, sizeof(tm_buf));

    // We need to set the daylight savings time to "I don't know" otherwise mktime will think that it _is_ in effect
    // if the string doesn't specify what the timezone is.
    tm_buf.tm_isdst = -1;

    char *result = strptime(time_ptr, format_ptr, &tm_buf);
    *end_time_ptr = prev_end_time_char;
    *end_format_ptr = prev_end_format_char;

    NP1_ASSERT(result, "strptime failed on time string: '" + time_s.to_string()
                        + "'  format string: '" + format_s.to_string() + "'");

    return time::sec_to_usec(mktime(&tm_buf));
  }
コード例 #9
0
ファイル: shell.hpp プロジェクト: matthewnourse/r17
  static void run(io::unbuffered_stream_base &input, io::unbuffered_stream_base &output,
                  const rstd::string &command) {
  
    // Set stdin to be the supplied input stream.
    int saved_stdin = dup(0);
    dup2(input.handle(), 0);

    // Set stdout to be the supplied output stream.
    int saved_stdout = dup(1);
    dup2(output.handle(), 1);

    // Execute the command.
    int system_result = system(command.c_str());
    if (system_result < 0) {
      rstd::string message("meta.shell failed.  command: ");
      message.append(command);
      NP1_ASSERT(false, message);
    }

    // Set stdin & stdout back to what they were.
    dup2(saved_stdin, 0);
    dup2(saved_stdout, 1);
    close(saved_stdin);
    close(saved_stdout);   
  }
コード例 #10
0
 void *alloc(size_t sz) {
   NP1_ASSERT(m_free_list, "fixed_homogenous_heap out of space!");
   
   void *p = (void *)(m_free_list + 1);
   m_free_list = m_free_list->m_next;
   return p;
 }
コード例 #11
0
        bool operator()(const rel::record_ref &r) const {
            rstd::string file_name = r.mandatory_field(m_file_name_field_id).to_string();
            rstd::string host_name = r.mandatory_field(m_host_name_field_id).to_string();

            // Prefix the tokens with the host name and a command to read the file.
            rstd::vector<rel::rlang::token> file_read_tokens;
            file_read_tokens.push_back(rel::rlang::token(host_name.c_str(), rel::rlang::token::TYPE_STRING));
            file_read_tokens.push_back(rel::rlang::token(",", rel::rlang::token::TYPE_COMMA));
            file_read_tokens.push_back(rel::rlang::token("io.file.read", rel::rlang::token::TYPE_IDENTIFIER_VARIABLE));
            file_read_tokens.push_back(rel::rlang::token("(", rel::rlang::token::TYPE_OPEN_PAREN));
            file_read_tokens.push_back(rel::rlang::token(file_name.c_str(), rel::rlang::token::TYPE_STRING));
            file_read_tokens.push_back(rel::rlang::token(")", rel::rlang::token::TYPE_CLOSE_PAREN));
            file_read_tokens.push_back(rel::rlang::token("|", rel::rlang::token::TYPE_OPERATOR));

            rstd::vector<rel::rlang::token> remote_tokens(file_read_tokens);
            remote_tokens.append(m_tokens);

            // Create a temporary file for the use of the child.
            FILE *child_output_fp = tmpfile();
            NP1_ASSERT(child_output_fp, "Unable to create temporary file for child process output");

            // Add into the process pool, to be processed asap.
            m_process_pool_map.add(
                host_name,
                child_process_f(child_output_fp, remote_tokens),
                on_child_process_exit(child_output_fp, m_final_output, m_output_headings_written));

            return true;
        }
コード例 #12
0
ファイル: remote.hpp プロジェクト: barrbrain/r17
 // Read the file descriptor, copying to stderr and prefixing each line with helpful info.
 static void read_and_prefix_stderr(const rstd::string &hostname, int fd) {
   FILE *fp = fdopen(fd, "r");
   NP1_ASSERT(fp, "meta.remote: fdopen failed");
   char line[256 * 1024];
   while (fgets(line, sizeof(line)-1, fp)) {
     fprintf(stderr, "meta.remote(%s): %s", hostname.c_str(), line);
   }
 }
コード例 #13
0
ファイル: create.hpp プロジェクト: AnthonyNystrom/r17
    bool operator()(const record_ref &r) { 
      np1::io::reliable_storage::id input_chunk_id(r.mandatory_field(m_resource_id_field_id));
      NP1_ASSERT(m_target_recordset_stream.write(input_chunk_id)
                  && m_target_recordset_stream.write("\n"),
                  "Unable to write to recordset");

      return true;
    }        
コード例 #14
0
ファイル: ip_endpoint.hpp プロジェクト: barrbrain/r17
 void initialize(const char *str, int port) {
   memset(&m_addr, 0, sizeof(m_addr));
   unsigned long ip_addr_num = inet_addr(str);
   NP1_ASSERT(INADDR_NONE != ip_addr_num,
               "Unable to convert IP address string '" + rstd::string(str) + "' to IP address");
 
   initialize(ip_addr_num, port);
 }
コード例 #15
0
  size_t read(void *buf, size_t bytes_to_read) {
    size_t bytes_read = 0;
    if (!m_stream.read(buf, bytes_to_read, &bytes_read)) {
      NP1_ASSERT(false, "Stream " + m_stream.name() + ": Unable to read from stream");
    }

    return bytes_read;
  }
コード例 #16
0
ファイル: record_count.hpp プロジェクト: barrbrain/r17
  void operator()(Input_Stream &input, Output_Stream &output,
                  const rstd::vector<rel::rlang::token> &tokens) {
    NP1_ASSERT(tokens.size() == 0, "rel.record_count accepts no arguments"); 

    // Read & discard the headings.
    input.parse_headings();

    uint64_t number_records = 0;    
    input.parse_records(record_counter_callback(number_records));
    output.write(str::to_dec_str(number_records).c_str());
  }
コード例 #17
0
  void copy(const std::string &file_name, bool overwrite) {
    io::file file;    
    const char *name = file_name.c_str();
    bool open_result =
          overwrite ? file.create_or_open_wo_trunc(name)
                    : file.create_or_open_wo_append(name);

    NP1_ASSERT(open_result, "Unable to open output file " + file_name);
    mandatory_output_stream<io::file> mandatory_output(file);
    copy(mandatory_output);
  }
コード例 #18
0
ファイル: dispatch.hpp プロジェクト: AnthonyNystrom/r17
  // Just pass the whole program argument list here.
  static int from_main(int argc, const char *argv[]) {
    const char *real_program_name = argv[0];
  
    NP1_ASSERT(argc >= 2, get_usage(real_program_name));
    NP1_ASSERT(str::is_valid_utf8(argc, argv), "Arguments are not valid UTF-8 strings");
  
    int fake_argc = argc - 1;
    const char **fake_argv = &argv[1];

    std::vector<std::string> args = str::argv_to_string_vector(fake_argc, fake_argv);

    io::file stdin_f;
    stdin_f.from_stdin();

    io::file stdout_f;
    stdout_f.from_stdout();

    run_once(stdin_f, stdout_f, args);
  
    return 0;
  }
コード例 #19
0
ファイル: order_by.hpp プロジェクト: AnthonyNystrom/r17
  void operator()(Input_Stream &input, Output_Stream &output,
                  const std::vector<rel::rlang::token> &tokens,
                  sort_type_type sort_type,
                  sort_order_type sort_order) {
    NP1_ASSERT(tokens.size() > 0, "Unexpected empty stream operator argument list");

    // Read the first line of input, we need it to add meaning to the arguments.
    record headings(input.parse_headings()); 

    std::vector<std::string> arg_headings;

    rlang::compiler::compile_heading_name_list(
                      tokens, headings.ref(), arg_headings);

    // Create the compare specs.
    detail::compare_specs comp_specs(headings, arg_headings);

    // Write out the headings then do the actual sorting.
    headings.write(output);

    less_than lt(comp_specs);
    greater_than gt(comp_specs);
    switch (sort_type) {
    case TYPE_MERGE_SORT:
      switch (sort_order) {
        case ORDER_ASCENDING:
          sort<detail::merge_sort>(input, output, lt);
          break;
        
        case ORDER_DESCENDING:
          sort<detail::merge_sort>(input, output, gt);
          break;
      }
      break;

    case TYPE_QUICK_SORT:
      //TODO: why the dickens isn't this quick sort and why is quick sort broken?
      switch (sort_order) {
        case ORDER_ASCENDING:
          sort<detail::merge_sort>(input, output, lt);
          break;
        
        case ORDER_DESCENDING:
          sort<detail::merge_sort>(input, output, gt);
          break;
      }
      break;
    }
  }
コード例 #20
0
ファイル: ip_endpoint.hpp プロジェクト: barrbrain/r17
  // Convert to a string, crash on error.
  rstd::string to_string() const {
    char temp[256];
    memset(temp, 0, sizeof(temp));

#ifdef _WIN32
    /* There's no inet_ntop in WinXP & earlier. TODO: move to Windows vista/7 or 
       define own inet_ntop.  The Windows documentation says that the statically
       allocated buffer is allocated per-thread. */
    const char *addr_string = inet_ntoa(m_addr.sin_addr);
    NP1_ASSERT((strlen(addr_string) < sizeof(temp)-1),
                "Unable to convert IP endpoint to string, resulting string is too long");
    strcpy(temp, addr_string);
#else
    NP1_ASSERT(inet_ntop(AF_INET, &m_addr.sin_addr, temp, sizeof(temp)-1),
                "Unable to convert IP endpoint to string");
#endif
    char *p = temp + strlen(temp);
    NP1_ASSERT((p + 7 < temp + sizeof(temp)),
                "Unable to add port to end of IP endpoint string");

    *p++ = ':';
    str::to_dec_str(p, port());
    return temp;
  }
コード例 #21
0
ファイル: pattern_cache.hpp プロジェクト: barrbrain/r17
  pattern &do_get(const str::ref &pattern_str, bool case_sensitive) {
    size_t pattern_str_len = pattern_str.length();
    uint64_t hval = hash::fnv1a64::add(pattern_str.ptr(),
                                        pattern_str_len, hash::fnv1a64::init());
    size_t offset = (size_t)hval & (CACHE_HASH_TABLE_SIZE-1);
    entry *e = &m_entries[offset];
    if ((str::cmp(pattern_str, e->m_pattern_string) != 0) || (case_sensitive != e->m_is_case_sensitive)) {    
      // As this is just a cache, overwrite the existing pattern.
      e->m_pattern.clear();
      bool compile_result = case_sensitive ? e->m_pattern.compile(pattern_str)
                              : e->m_pattern.icompile(pattern_str);
      
      NP1_ASSERT(compile_result,
                  "Unable to compile pattern: " + pattern_str.to_string());
      e->m_pattern_string = pattern_str.to_string();
      e->m_is_case_sensitive = case_sensitive;
    }

    return e->m_pattern;
  }
コード例 #22
0
ファイル: shell.hpp プロジェクト: AnthonyNystrom/r17
  static void run(io::unbuffered_stream_base &input, io::unbuffered_stream_base &output,
                  const std::vector<rel::rlang::token> &tokens) {
    std::string command = rel::rlang::compiler::eval_to_string_only(tokens);

    // Set stdin to be the supplied input stream.
    int saved_stdin = dup(0);
    dup2(input.handle(), 0);

    // Set stdout to be the supplied output stream.
    int saved_stdout = dup(1);
    dup2(output.handle(), 1);

    // Execute the command.
    NP1_ASSERT(system(command.c_str()) >= 0, "system() failed for meta.shell stream operator.");

    // Set stdin & stdout back to what they were.
    dup2(saved_stdin, 0);
    dup2(saved_stdout, 1);
    close(saved_stdin);
    close(saved_stdout);   
  }
コード例 #23
0
  static bool read_all_line_by_line(Unbuffered_Stream &input, Callback line_callback) {
    enum { BUFFER_SIZE = 256 * 1024 };
    unsigned char buffer[BUFFER_SIZE + 1];            
    unsigned char *buffer_end = buffer + BUFFER_SIZE;
    unsigned char *buffer_read_pos = buffer;
    const unsigned char *start_line = buffer_read_pos;
    ssize_t number_bytes_read;
    uint64_t line_number = 1;
    mandatory_input_stream<Unbuffered_Stream> mandatory_input(input);        
    const unsigned char *buffer_data_end = 0;
  
    while ((number_bytes_read =
              mandatory_input.read_some(buffer_read_pos, 
                                        buffer_end - buffer_read_pos)) > 0) {        
      buffer_data_end = buffer_read_pos + number_bytes_read;        
      const unsigned char *end_line;
      
      // Find the end of the line to make sure that we have the whole thing in the buffer. 
      while ((end_line = (const unsigned char *)memchr(start_line, '\n', buffer_data_end - start_line))) {
        // We have the whole line.  Call the callback to deal with the line.
        if (!line_callback(str::ref((const char *)start_line, end_line - start_line), line_number)) {
          return false;
        }
                        
        // Now go around again.            
        start_line = end_line + 1;
        ++line_number;
      }

      // There's probably an incomplete line left in the buffer.  Move it to the start of the buffer.
      ssize_t remainder_length = buffer_data_end - start_line; 
      NP1_ASSERT(remainder_length < BUFFER_SIZE, "Stream " + input.name()
                   + ": line is too long.  Remainder length: " + str::to_dec_str(remainder_length));
      memmove(buffer, start_line, remainder_length);
      buffer_read_pos = buffer + remainder_length;
      start_line = buffer;
    }

    return true;
  }
コード例 #24
0
ファイル: fn.hpp プロジェクト: AnthonyNystrom/r17
  static dt::string format(vm_heap &h, const dt::uinteger &time_epoch, const str::ref &format_s) {
    //TODO: do without this null-char-putting.
    char *format_ptr = (char *)format_s.ptr();
    char *end_format_ptr = format_ptr + format_s.length();
    char prev_end_format_char = *end_format_ptr;
    *end_format_ptr = '\0';

    time_t time_sec = lib::int64::divide(time_epoch, 1000000);
    struct tm *tm_p = localtime(&time_sec);
    const size_t size_to_alloc = 1024;
    char *formatted_buf = h.alloc(size_to_alloc);
    const size_t max_formatted_length = size_to_alloc - 1;
    size_t bytes_written = strftime(formatted_buf, max_formatted_length, format_ptr, tm_p);

    *end_format_ptr = prev_end_format_char;

    NP1_ASSERT(
      bytes_written != 0,
      "Max formatted time length exceeded.  Max size is " + str::to_dec_str(max_formatted_length) + " bytes.");

    return dt::string(formatted_buf, bytes_written);
  }
コード例 #25
0
  void operator()(const std::string &reliable_storage_local_root,
                  const std::string &reliable_storage_remote_root,
                  const std::string &listen_endpoint,                  
                  Input_Stream &input, Output_Stream &output,
                  const std::vector<rel::rlang::token> &tokens) {
    log_info("Reading headers and compiling expression against headers.");

    /* Get the headers. */
    record headings(input.parse_headings());

    // Compile, just to check that the headings & tokens are likely to work
    // when we distribute.
    record empty_headings;
    rlang::vm vm = rlang::compiler::compile_single_expression(
                      tokens, headings.ref(), empty_headings.ref());

    // Check that the expression is actually a boolean expression.
    NP1_ASSERT(vm.return_type() == rlang::dt::TYPE_BOOL,
                "Expression is not a boolean expression");

    // Do the distribution.
    distributed::distribute(log_id(), headings, headings, "rel.where", reliable_storage_local_root,
                            reliable_storage_remote_root, listen_endpoint, input, output, tokens);
  }
コード例 #26
0
  /// Write a buffer, returns false on error.
  bool write_some(const void *buf, size_t bytes_to_write, size_t *bytes_written_p) {
    NP1_ASSERT(m_buffer_pos <= m_buffer_end, "existing buffer_pos is past buffer_end!");

    unsigned char *new_pos = m_buffer_pos + bytes_to_write;   
    if (new_pos > m_buffer_end) {
      size_t current_size = m_buffer_end - m_buffer;
      size_t new_size = current_size + m_allocation_size;
      if (new_pos > m_buffer + new_size) {
        new_size = current_size + bytes_to_write;
      }

      size_t current_used_size = m_buffer_pos - m_buffer;
      NP1_ASSERT(new_size >= current_used_size, "new buffer is not big enough to hold even the existing data!");
      NP1_ASSERT(new_size >= current_used_size + bytes_to_write,
                  "new buffer is not big enough to hold the existing data plus the new data!");
      unsigned char *new_buffer = (unsigned char *)m_heap.alloc(new_size);
      if (new_buffer > m_buffer) {
        NP1_ASSERT(m_buffer + current_used_size <= new_buffer, "new buffer is not allocated at the correct address!");
      } else {
        NP1_ASSERT(new_buffer + current_used_size <= m_buffer, "new buffer is not big enough or not allocated at the correct address!");
      }

      memcpy(new_buffer, m_buffer, current_used_size);
      m_buffer_pos = new_buffer + current_used_size;
      m_buffer_end = new_buffer + new_size;
      m_heap.free((char *)m_buffer);
      m_buffer = new_buffer;
      new_pos = m_buffer_pos + bytes_to_write;
    }

    NP1_ASSERT(new_pos <= m_buffer_end, "new_pos is past buffer_end!");
    NP1_ASSERT(m_buffer_pos < m_buffer_end, "buffer_pos is past or equal to buffer_end after possible resize");
    memcpy(m_buffer_pos, buf, bytes_to_write);
    m_buffer_pos = new_pos;
    *bytes_written_p = bytes_to_write;
    return true;
  }
コード例 #27
0
 // Put one byte back on the stream.  Fail if a byte is already ungot.
 void unget(int c) {
   NP1_ASSERT(m_ungotc < 0, "Unable to push a byte back on to the stream");
   m_ungotc = c;
 }
コード例 #28
0
ファイル: compare_specs.hpp プロジェクト: AnthonyNystrom/r17
 const compare_spec &at(size_t n) const {
   NP1_ASSERT(n < size(), "compare_spec.at(n): n out of bounds");
   return *(begin() + n);
 }
コード例 #29
0
 bool close() {
   NP1_ASSERT(m_stream.close(), "Stream " + m_stream.name() + ": close() failed");
   return true;
 }
コード例 #30
0
ファイル: ip_endpoint.hpp プロジェクト: barrbrain/r17
 void port(int port) {
   NP1_ASSERT((port > 0) && (port < MAX_PORT), "Invalid port: " + str::to_dec_str(port));
   m_addr.sin_port = htons(port);
 }