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