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