Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 49 additions & 23 deletions BoyerMoore.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void prepare_goodsuffix_heuristic(const uint8_t *normal, const size_t size, int
/*
* Boyer-Moore search algorithm
*/
const uint8_t *boyermoore_search(const uint8_t *haystack, size_t haystack_len, const uint8_t *needle, size_t needle_len) {
const uint8_t *boyermoore_search(const uint8_t *haystack, size_t haystack_len, const uint8_t *needle, size_t needle_len, bool reverse = false) {
/*
* Simple checks
*/
Expand All @@ -96,28 +96,54 @@ const uint8_t *boyermoore_search(const uint8_t *haystack, size_t haystack_len, c
/*
* Boyer-Moore search
*/
size_t s = 0;
while(s <= (haystack_len - needle_len))
{
size_t j = needle_len;
while(j > 0 && needle[j-1] == haystack[s+j-1])
j--;

if(j > 0)
{
int k = badcharacter[haystack[s+j-1]];
int m;
if(k < (int)j && (m = j-k-1) > goodsuffix[j])
s+= m;
else
s+= goodsuffix[j];
}
else
{
delete[] goodsuffix;
return haystack + s;
}
}
size_t len = haystack_len - needle_len;
if (!reverse) {
size_t s = 0;
while(s <= len)
{
size_t j = needle_len;
while(j > 0 && needle[j-1] == haystack[s+j-1])
j--;

if(j > 0)
{
int k = badcharacter[haystack[s+j-1]];
int m;
if(k < (int)j && (m = j-k-1) > goodsuffix[j])
s+= m;
else
s+= goodsuffix[j];
}
else
{
delete[] goodsuffix;
return haystack + s;
}
}
} else {
ptrdiff_t s = haystack_len;
while(s >= 0)
{
size_t j = needle_len;
while(j > 0 && needle[j-1] == haystack[s+(j-needle_len)-(s == haystack_len ? 1 : 0)])
--j;

if(j > 0)
{
int k = badcharacter[haystack[s+(j-needle_len)-(s == haystack_len ? 1 : 0)]];
int m;
if(k < (int)j && (m = j-k-1) > goodsuffix[j])
s-= m - (s == haystack_len ? 1 : 0);
else
s-= goodsuffix[j];
}
else
{
delete[] goodsuffix;
return haystack + (s - needle_len) + (s == haystack_len ? 0 : 1);
}
}
}

delete[] goodsuffix;
/* not found */
Expand Down
33 changes: 33 additions & 0 deletions buffertools.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,34 @@ struct IndexOfAction: BinaryAction<IndexOfAction> {
}
};

struct LastIndexOfAction: BinaryAction<LastIndexOfAction> {
Handle<Value> apply(Handle<Object>& buffer, const uint8_t* data2, size_t size2, const Arguments& args, HandleScope& scope) {
const uint8_t* data = (const uint8_t*) Buffer::Data(buffer);
const size_t size = Buffer::Length(buffer);
size_t len = 0;
int32_t start;

if (args[1]->IsInt32()) {
start = args[1]->Int32Value();

if (start < 0)
start = size - std::min<size_t>(size, -start);
else if (static_cast<size_t>(start) > size)
start = size;

if (start > 0)
len = size - start;
} else
len = size;

const uint8_t* p = boyermoore_search(
data, len, data2, size2, true);

const ptrdiff_t offset = p ? (p - data) : -1;
return scope.Close(Integer::New(offset));
}
};

static char toHexTable[] = "0123456789abcdef";

// CHECKME is this cache efficient?
Expand Down Expand Up @@ -276,6 +304,10 @@ Handle<Value> IndexOf(const Arguments& args) {
return IndexOfAction()(args);
}

Handle<Value> LastIndexOf(const Arguments& args) {
return LastIndexOfAction()(args);
}

Handle<Value> FromHex(const Arguments& args) {
return FromHexAction()(args);
}
Expand Down Expand Up @@ -341,6 +373,7 @@ void RegisterModule(Handle<Object> target) {
target->Set(String::NewSymbol("equals"), FunctionTemplate::New(Equals)->GetFunction());
target->Set(String::NewSymbol("compare"), FunctionTemplate::New(Compare)->GetFunction());
target->Set(String::NewSymbol("indexOf"), FunctionTemplate::New(IndexOf)->GetFunction());
target->Set(String::NewSymbol("lastIndexOf"), FunctionTemplate::New(LastIndexOf)->GetFunction());
target->Set(String::NewSymbol("fromHex"), FunctionTemplate::New(FromHex)->GetFunction());
target->Set(String::NewSymbol("toHex"), FunctionTemplate::New(ToHex)->GetFunction());
}
Expand Down