예제 #1
0
void stream::write(value const &data) {
  if (data.is_string()) {
    string text = data.get_string();
    char const *str = text.c_str();
    streambuf_->sputn(text.c_str(), std::strlen(str));
  } else if (data.is_object()) {
    binary &b = flusspferd::get_native<binary>(data.get_object());
    streambuf_->sputn((char const*) &b.get_data()[0], b.get_length());
  } else {
    throw exception("Cannot write non-object non-string value to Stream");
  }
  //TODO slow?
  if (get_property("autoFlush").to_boolean())
    flush();
}
예제 #2
0
object base_parser::parse(value source) {
  if (source.is_object()) {
    object o = source.get_object();

    if (is_native<io::stream>(o)) {
      io::stream &s = flusspferd::get_native<io::stream>(o);

      // TODO: Work out if the stream is readable or not!
      std::ifstream stream;
      dynamic_cast<std::ios&>(stream).rdbuf( s.streambuf() );
      sax_source is;
      is.setByteStream(stream);
      return parse_source(is);
    }
    /*else if (is_native<binary>(o)) {
      // Couldn't get this working. Compile errors
      binary &b = flusspferd::get_native<flusspferd::binary>(o);

      call_context c;
      c.arg.push_back(b);
      create<io::binary_stream>(c);
      root_object s(b_s);

      std::ifstream stream;
      dynamic_cast<std::ios&>(stream).rdbuf( b_s.streambuf() );
      sax_source is;
      is.setByteStream(stream);
      return parse_source(is);
    }*/
  }

  std::string str = source.to_std_string();

  security &sec = security::get();
  if (!sec.check_path(str, security::READ)) {
    throw exception(
      format("xml.Parser#parse: could not open file: 'denied by security' (%s)")
             % str
    );
  }

  sax_source is;
  is.setSystemId(str);

  return parse_source(is);
}
예제 #3
0
array binary::split(value delim, object options) {
  local_root_scope scope;
  std::vector<binary*> delims;

  // Parse the delimiter into the vector of delims.
  if (delim.is_int()) { // single Number
    if (delim.get_int() < 0 || delim.get_int() > 255)
      throw exception("Outside byte range", "RangeError");
    element_type e = delim.get_int();
    delims.push_back(&create(&e, 1));
  } else if (delim.is_object()) {
    object obj = delim.get_object();

    if (obj.is_array()) { // Array
      array arr(obj);
      std::size_t n = arr.length();

      for (std::size_t i = 0; i < n; ++i) {
        binary &new_delim =
          flusspferd::create<byte_string>(
            fusion::vector2<element_type*, std::size_t>(0, 0));
        arguments arg;
        arg.push_back(arr.get_element(i));
        new_delim.do_append(arg);
        if (new_delim.get_length() > 0)
          delims.push_back(&new_delim);
      }
    } else { // Binary
      binary &b = flusspferd::get_native<binary>(obj);
      if (b.get_length() > 0)
        delims.push_back(&b);
    }
  }

  if (delims.empty())
    throw exception("Need at least one valid delimiter");

  // Options
  std::size_t count = std::numeric_limits<std::size_t>::max();
  bool include_delimiter = false;

  // (only search options if the options object is not null)
  if (!options.is_null()) {
    // "count" option
    value count_ = options.get_property("count");
    if (!count_.is_undefined_or_null())
      count = count_.to_number();

    // "includeDelimiter" option
    value include_delimiter_ = options.get_property("includeDelimiter");
    if (!include_delimiter_.is_undefined_or_null())
      include_delimiter = include_delimiter_.to_boolean();
  }

  // Main loop

  typedef vector_type::iterator iterator;
  iterator pos = v_data.begin();

  array results = flusspferd::create<array>();

  // Loop only through the first count-1 elements
  for (std::size_t n = 1; n < count; ++n) {
    // Search for the first occurring delimiter
    std::size_t delim_id = delims.size();
    iterator first_found = v_data.end();
    for (std::size_t i = 0; i < delims.size(); ++i) {
      binary &delim = *delims[i];
      iterator found = std::search(
        pos, v_data.end(),
        delim.get_data().begin(), delim.get_data().end());
      if (found < first_found) {
        first_found = found;
        delim_id = i;
      }
    }

    // No delimiter found
    if (delim_id == delims.size())
      break;

    binary &elem = create_range(pos, first_found);

    // Add element
    results.push(elem);

    // Possible add delimiter
    if (include_delimiter)
      results.push(*delims[delim_id]);

    // Advance position _after_ the delimiter.
    pos = first_found + delims[delim_id]->get_length();
  }

  // Add last element, possibly containing delimiters
  results.push(create_range(pos, v_data.end()));

  return results;
}
예제 #4
0
void file::open(char const *name, value options) {
  security &sec = security::get();

  if (boost::filesystem::is_directory(std::string(name))) {
    throw exception(
      std::string("Could not open file: it is a directory (")+ name + ")"
    );
  }

  std::ios::openmode open_mode = std::ios::openmode();

  bool exclusive = false, create = false;

  if (options.is_string()) {
    // String modes always set create

    std::string mode = options.to_std_string();
    if (mode == "r")
      open_mode = std::ios::in;
    else if (mode == "r+")
      open_mode = std::ios::in | std::ios::out;
    else if (mode == "r+x") {
      open_mode = std::ios::in | std::ios::out;
      exclusive = create = true;
    }
    else if (mode == "w") {
      open_mode = std::ios::out;
      create = true;
    }
    else if (mode == "wx") {
      open_mode = std::ios::out;
      exclusive = create = true;
    }
    else if (mode == "w+x") {
      open_mode = std::ios::out | std::ios::in | std::ios::trunc;
      exclusive = create = true;
    }
    else {
      throw exception(format("File.open: mode '%s' not supported (yet?)") % mode);
    }
  }else if (options.is_object()) {
    object obj = options.get_object();

    create = obj.get_property("create").to_boolean();

    if (obj.get_property("read").to_boolean())
      open_mode |= std::ios::in;
    if (obj.get_property("write").to_boolean())
      open_mode |= std::ios::out;
    if (obj.get_property("truncate").to_boolean())
      open_mode |= std::ios::trunc;
    if (obj.get_property("append").to_boolean()) {
      if (!(open_mode & std::ios::out)) {
        throw exception("File.open: append mode can only be used with write");
      }
      open_mode |= std::ios::app | std::ios::out;
    }
    if (obj.get_property("exclusive").to_boolean()) {
      if (!create)
        throw exception("File.open: exclusive mode can only be used with create");
      exclusive = create = true;
    }

  }else if (options.is_undefined_or_null()) {
    open_mode = std::ios::in;
  }else {
    throw exception("File.open: Invalid options argument", "TypeError");
  }

  unsigned sec_mode = 0;

  if (open_mode & std::ios::in)  sec_mode |= security::READ;
  if (open_mode & std::ios::out) sec_mode |= security::WRITE;
  if (create)                    sec_mode |= security::CREATE;

  if (!sec.check_path(name, sec_mode)) {
    throw exception(
      format("File.open: could not open file: 'denied by security' (%s)") % name
    );
  }

  if (create) {
    // C++ streams don't support O_EXCL|O_CREAT modes. Fall back to open
    unsigned o_mode = exclusive
                    ? O_CREAT|O_EXCL
                    : O_CREAT;
    int fd = ::open(name, o_mode, 0666);
    if (fd == -1)
      throw exception(compose_error_message("File.open: couldn't create file", name));

    // Done  - got the file (exclusively) created.
    ::close(fd);
  }

  p->stream.open(name, open_mode);

  if (!p->stream)
    throw exception(compose_error_message("Could not open file", name));

  define_property("fileName", string(name),
                  permanent_property | read_only_property );
}