Skip to content

Instantly share code, notes, and snippets.

@gipi
Created July 1, 2012 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gipi/3028454 to your computer and use it in GitHub Desktop.
Save gipi/3028454 to your computer and use it in GitHub Desktop.
Cef JS Extension
#include <cstdlib>
#include <string>
#include "include/cef_v8.h"
#include "cefclient/js_user_notes.h"
#include "cefclient/sqlcipher.h"
class Note : public Cipher {
public:
Note(){Initialize("note.db", "");}
~Note() {};
bool Save(std::string key, std::string value) {
int skey = key.size();
int svalue = value.size();
// allocate string big enough (256 is random choosed)
char* query = (char*)malloc(256 + skey + svalue);
sprintf(query, "INSERT INTO note (key, value) VALUES ('%s', '%s')", key.c_str(), value.c_str());
if (sqlite3_exec(db_, query, NULL, NULL, NULL) != SQLITE_OK) {
state_ = CIPHER_ERROR;
free(query);
throw GetLastErrorMsg();
}
free(query);
return true;
}
std::string Load(std::string key) {
char query[256];
sqlite3_stmt* statement;
sprintf(query, "SELECT value FROM note WHERE key='%s';", key.c_str());
if (sqlite3_prepare(db_, query, -1, &statement, NULL) != SQLITE_OK) {
state_ = CIPHER_ERROR;
throw GetLastErrorMsg();
}
// FIXME: qui necessito di una riga sola
if (sqlite3_step(statement) != SQLITE_ROW) {
state_ = CIPHER_ERROR;
throw GetLastErrorMsg();
}
return std::string((const char*)sqlite3_column_text(statement, 0));
}
};
class ClientV8UserNotesHandler : public CefV8Handler {
public:
ClientV8UserNotesHandler() {};
virtual ~ClientV8UserNotesHandler() {}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) {
Note n;
if (name == "SaveObject") {
if (arguments.size() != 2 ||
!arguments[0]->IsString() ||
!arguments[1]->IsString()
) {
exception = "internal: argument passed are wrong type or number";
// without returning true the exception is not passed to JS
return true;
}
try {
n.Save(arguments[0]->GetStringValue(), arguments[1]->GetStringValue());
} catch (std::string errMsg) {
exception = errMsg;
return true;
}
return true;
} else if ("LoadObject") {
if (arguments.size() != 1 || !arguments[0]->IsString()) {
exception = "internal: argument passed are wrong type or number";
// without returning true the exception is not passed to JS
return true;
}
std::string value;
try {
value = n.Load(arguments[0]->GetStringValue());
} catch (std::string errMsg) {
exception = errMsg;
return true;
}
retval = CefV8Value::CreateString(value);
return true;
}
}
private:
IMPLEMENT_REFCOUNTING(ClientV8UserNotesHandler);
};
void InitUserNoteExtension() {
// Register a V8 extension with the below JavaScript code that calls native
// methods implemented in ClientV8ExtensionHandler.
std::string code = "var note;"
"if (!note)"
" note = {};"
"(function() {"
" note.saveObject = function(key, value) {"
" native function SaveObject();"
" return SaveObject(key, value);"
" };"
" note.loadObject = function(key) {"
" native function LoadObject();"
" return LoadObject(key);"
" };"
"})();";
CefRegisterExtension("v8/note", code, new ClientV8UserNotesHandler());
}
@paulocoutinhox
Copy link

Hi,

Very nice. How to run load/save on new thread?

thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment