int msc_regexec_ex(RE2 &re, const char *s, unsigned int slen, int startoffset, int *ovector, int ovecsize) { size_t startpos = startoffset; const size_t endpos = slen; // Total # of submatches in the regex pattern int num_submatch = 1 + re.NumberOfCapturingGroups(); // Index of the last non empty submatch int last_nonempty_submatch = num_submatch - 1; re2::StringPiece submatches[num_submatch]; // If the string does not match the pattern if (!re.Match(s, startpos, endpos, RE2::UNANCHORED, submatches, num_submatch)) { return -1; } // Find the last non empty submatch while (!submatches[last_nonempty_submatch].data()) { last_nonempty_submatch--; } int count = min(last_nonempty_submatch + 1, ovecsize / 3); // Extract submatch information as much as possible for (int i = 0; i < count; i++) { // An empty submatch if (!submatches[i].data()) { ovector[2 * i] = -1; ovector[2 * i + 1] = -1; } else { ovector[2 * i] = submatches[i].data() - s; ovector[2 * i + 1] = ovector[2 * i] + submatches[i].length(); } } // The output vector has enough space to store the information of // all non empty submatches + empty submatches among non empty submatches if (last_nonempty_submatch + 1 <= ovecsize / 3) { return last_nonempty_submatch + 1; } // Truncate empty submatches at the tail of 'ovector' if (!submatches[ovecsize / 3 - 1].data()) { for (int i = ovecsize / 3 - 2; i >= 0; i--) { if (submatches[i].data()) { return i + 1; } } } return 0; }
JNIEXPORT jboolean JNICALL Java_com_logentries_re2_RE2Matcher_findImpl (JNIEnv *env, jclass cls, jobject matcher, jlong re2_pointer, jlong str_pointer, jint ngroups, jint start, jint end) { RE2 *regex = reinterpret_cast<RE2*>(re2_pointer); char *str = reinterpret_cast<char*>(str_pointer); StringPiece* groups; StringPiece stackgroups[stackSize]; StringPiece* heapgroups = NULL; if (ngroups <= stackSize) { groups = stackgroups; } else { groups = new StringPiece[ngroups]; heapgroups = groups; } StringPiece text(str); const bool res = regex->Match(text, start, end, RE2::UNANCHORED, groups, ngroups); if (res) { jclass matcher_class = env->FindClass("com/logentries/re2/RE2Matcher"); jmethodID addID = env->GetStaticMethodID(matcher_class, "addGroup", "(Lcom/logentries/re2/RE2Matcher;II)V"); for (int i=0; i<ngroups; i++) { if (groups[i] != NULL) { env->CallStaticObjectMethod( matcher_class, addID, matcher, static_cast<jint>(groups[i].data() - str), static_cast<jint>(groups[i].data() - str + groups[i].size()) ); } else { env->CallStaticObjectMethod(matcher_class, addID, matcher, static_cast<jint>(-1), static_cast<jint>(-1)); } } } delete[] heapgroups; return static_cast<jboolean>(res); }