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