Вкусняшки для JavaScriptCore

Jun 22, 2011 21:29

В кое-то веки решил поделиться некоторыми вкусняшками. :)
Если кто работал с WebKit или имел необходимость погонять JavaScript в своих приложениях знают, что одним из легко доступных движков является JavaScript Core от Apple, поставляемый в комплекте WebKit под большинством фреймворков.

В работе с движком есть одна особенность - за собой она тащит кусочек runtime-а от CoreFoundation, в частности строковые типы. При разработке кода на C разработчик не имеет вариантов и вынужден кругом использовать функции для работы с такими строками, что существенно перегружает код и снижает его читаемость. Если же мы обратимся к C++, то у нас найдется вполне элегантный вариант в виде класса-контейнера, скрывающего в себе реализацию JSStringRef:

class JSString
{
  public:
    JSString(const char* value);
    JSString(const std::string& value);
    JSString(const JSStringRef& value);
    JSString(const JSContextRef& context, const JSValueRef& value);
    ~JSString();
    operator JSStringRef();
    operator std::string();
    operator Glib::ustring();

private:
    JSStringRef string;
};

JSString::JSString(const char* value)
{
  string = JSStringCreateWithUTF8CString(value);
}

JSString::JSString(const std::string& value)
{
  string = JSStringCreateWithUTF8CString(value.c_str());
}

JSString::JSString(const JSStringRef& value)
{
  string = value;
  JSStringRetain(string);
}

JSString::JSString(const JSContextRef& context, const JSValueRef& value)
{
  string = JSValueToStringCopy(context, value, NULL);
}

JSString::~JSString()
{
  JSStringRelease(string);
}

JSString::operator JSStringRef()
{
  return string;
}

JSString::operator std::string()
{
  size_t length = JSStringGetMaximumUTF8CStringSize(string);
  gchar buffer[length];
  JSStringGetUTF8CString(string, buffer, length);
  return std::string(buffer);
}

JSString::operator Glib::ustring()
{
  size_t length = JSStringGetMaximumUTF8CStringSize(string);
  char buffer[length];
  JSStringGetUTF8CString(string, buffer, length);
  return Glib::ustring(buffer);
}

Пример использования:

context = JSGlobalContextCreate(NULL);
JSObjectMakeFunctionWithCallback(context, JSString("dnsResolve"), dns_resolve);
JSObjectMakeFunctionWithCallback(context, JSString("myIpAddress"), my_ip);
JSEvaluateScript(context, JSString(proxyConfigureFunctions), NULL, NULL, 1, NULL);
JSEvaluateScript(context, JSString(script), NULL, NULL, 1, NULL);

Как можно заметить из примера, вся реализация управления временем жизни строки делегирована компилятору через создание на стеке анонимного экземпляра нашего класса-контейнера, код элегантен, не допускает утечек и прост для понимания для начинающих разработчиков. Вся сила C++ в элементарных "рюшечках".

js, dev, webkit

Previous post Next post
Up