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); }
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 ); }