Compare commits

..

8 Commits

Author SHA1 Message Date
12ef2e6510 Fix bug 59462 2022-11-24 18:11:20 +03:00
da3a6b3189 Fix bugs with cache 2022-11-18 12:20:05 +03:00
81e03f64db Add support print custom pages in pdf/xps/djvu 2022-11-17 19:24:11 +03:00
0aed94b748 Fix ios/android build 2022-11-17 10:19:34 +03:00
5af4ebba9e Fix bug with caches 2022-11-16 23:25:19 +03:00
a8f0c12d0f Merge pull request #1068 from ONLYOFFICE/feature/cacheJS
Feature/cache js
2022-11-16 20:46:01 +03:00
e5351899c5 Refactoring js cache directory 2022-11-16 18:58:48 +03:00
fa094e152c Create js caches for server 2022-11-16 17:34:45 +03:00
11 changed files with 693 additions and 361 deletions

View File

@ -99,8 +99,7 @@ namespace NSDoctRenderer
std::wstring m_sJsonParams;
int m_nLcid;
int m_nRendererParams;
bool m_bIsCachedScripts;
std::wstring m_sScriptsCacheDirectory;
std::vector<int> m_arThemesThumbnailsParams;
public:
@ -124,9 +123,7 @@ namespace NSDoctRenderer
m_nMailMergeIndexEnd = -1;
m_nLcid = -1;
m_bIsCachedScripts = true;
m_nRendererParams = 0;
m_sScriptsCacheDirectory = L"";
}
~CExecuteParams()
{
@ -180,9 +177,7 @@ namespace NSDoctRenderer
m_nLcid = oNode.ReadValueInt(L"Lcid", -1);
m_sJsonParams = oNode.ReadValueString(L"JsonParams");
m_nRendererParams = oNode.ReadValueInt(L"DoctParams", 0);
if (0x01 == (0x01 & m_nRendererParams))
m_bIsCachedScripts = false;
m_sScriptsCacheDirectory = oNode.ReadValueString(L"ScriptsCacheDirectory", L"");
m_arThemesThumbnailsParams.clear();
std::wstring sThemesThumbnailsParams = oNode.ReadValueString(L"ThemesThumbnailsParams");
@ -1099,22 +1094,32 @@ namespace NSDoctRenderer
std::string strScript = "";
for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i)
{
#if 0
if (m_arrFiles[i].find(L"AllFonts.js") != std::wstring::npos)
continue;
#endif
strScript += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]);
strScript += "\n\n";
}
std::wstring sCachePath = L"";
if (NULL != arSdkFiles)
if (arSdkFiles && (0 < arSdkFiles->size()))
{
if (m_pInternal->m_oParams.m_bIsCachedScripts && (0 < arSdkFiles->size()))
if (m_pInternal->m_oParams.m_sScriptsCacheDirectory.empty())
{
sCachePath = NSFile::GetDirectoryName(*arSdkFiles->begin()) + L"/sdk-all.cache";
}
else if (m_pInternal->m_oParams.m_sScriptsCacheDirectory != L"empty")
{
sCachePath = m_pInternal->m_oParams.m_sScriptsCacheDirectory;
wchar_t lastSymbol = sCachePath.back();
if (lastSymbol != '\\' && lastSymbol != '/')
sCachePath += L"/";
wchar_t editorFirst = m_pInternal->m_strEditorType.at(0);
if (editorFirst == 'd')
sCachePath += L"word";
else if (editorFirst == 'p')
sCachePath += L"slide";
else
sCachePath += L"cell";
}
for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++)
{
@ -1145,6 +1150,96 @@ namespace NSDoctRenderer
{
return m_pInternal->m_arImagesInChanges;
}
void CDoctrenderer::CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir)
{
#ifndef JS_ENGINE_JAVASCRIPTCORE
LoadConfig(NSFile::GetProcessDirectory(), sAllFontsPath);
std::wstring sCacheDirectory = sCacheDir;
if (sCacheDirectory.empty() && m_pInternal->m_arDoctSDK.size() > 0)
{
sCacheDirectory = NSFile::GetDirectoryName(m_pInternal->m_arDoctSDK[0]);
sCacheDirectory = NSFile::GetDirectoryName(sCacheDirectory);
}
if (sCacheDirectory.empty())
return;
std::string strScriptAll = "";
for (size_t i = 0; i < m_pInternal->m_arrFiles.size(); ++i)
{
strScriptAll += m_pInternal->ReadScriptFile(m_pInternal->m_arrFiles[i]);
strScriptAll += "\n\n";
}
for (int i = 0; i < 3; ++i)
{
std::string strScript = strScriptAll;
std::wstring sCachePath = sCacheDirectory;
std::vector<std::wstring>* arSdkFiles = NULL;
switch (i)
{
case 0:
{
arSdkFiles = &m_pInternal->m_arDoctSDK;
sCachePath += L"/word/sdk-all.cache";
break;
}
case 1:
{
arSdkFiles = &m_pInternal->m_arPpttSDK;
sCachePath += L"/slide/sdk-all.cache";
break;
}
case 2:
{
arSdkFiles = &m_pInternal->m_arXlstSDK;
sCachePath += L"/cell/sdk-all.cache";
break;
}
default:
break;
}
if (NSFile::CFileBinary::Exists(sCachePath))
NSFile::CFileBinary::Remove(sCachePath);
for (std::vector<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++)
{
strScript += m_pInternal->ReadScriptFile(*i);
strScript += "\n\n";
}
if (2 == i)
strScript += "\n$.ready();";
JSSmart<CJSContext> context = new CJSContext();
context->Initialize();
if (true)
{
JSSmart<CJSIsolateScope> isolate_scope = context->CreateIsolateScope();
JSSmart<CJSLocalScope> handle_scope = context->CreateLocalScope();
context->CreateGlobalForContext();
CNativeControlEmbed::CreateObjectBuilderInContext("CreateNativeEngine", context);
CGraphicsEmbed::CreateObjectInContext("CreateNativeGraphics", context);
NSJSBase::CreateDefaults(context);
context->CreateContext();
JSSmart<CJSContextScope> context_scope = context->CreateContextScope();
JSSmart<CJSTryCatch> try_catch = context->GetExceptions();
context->runScript(strScript, try_catch, sCachePath);
}
context->Dispose();
}
#endif
}
}
bool Doct_renderer_SaveFile_ForBuilder(int nFormat, const std::wstring& strDstFile,

View File

@ -67,6 +67,7 @@ namespace NSDoctRenderer
public:
bool Execute(const std::wstring& strXml, std::wstring& strError);
std::vector<std::wstring> GetImagesInChanges();
void CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir);
private:
CDoctRenderer_Private* m_pInternal;

View File

@ -188,4 +188,8 @@ namespace NSDoctRenderer
std::vector<std::wstring> stub;
return stub;
}
void CDoctrenderer::CreateCache(const std::wstring& sAllFontsPath, const std::wstring& sCacheDir)
{
}
}

View File

@ -75,4 +75,6 @@ use_javascript_core {
LIBS += -framework JavaScriptCore
DEFINES += JS_ENGINE_JAVASCRIPTCORE
}

View File

@ -2,379 +2,446 @@
v8::Local<v8::String> CreateV8String(v8::Isolate* i, const char* str, const int& len)
{
return v8::String::NewFromUtf8(i, str, kV8NormalString, len).ToLocalChecked();
return v8::String::NewFromUtf8(i, str, kV8NormalString, len).ToLocalChecked();
}
v8::Local<v8::String> CreateV8String(v8::Isolate* i, const std::string& str)
{
return v8::String::NewFromUtf8(i, str.c_str(), kV8NormalString, (int)str.length()).ToLocalChecked();
return v8::String::NewFromUtf8(i, str.c_str(), kV8NormalString, (int)str.length()).ToLocalChecked();
}
std::wstring CV8Worker::m_sExternalDirectory = L"";
namespace NSJSBase
{
class CCacheDataScript
{
private:
BYTE* Data;
int Length;
class CCacheDataScript
{
private:
BYTE* Data;
int Length;
v8::ScriptCompiler::Source* Source;
v8::ScriptCompiler::CachedData* CachedData;
std::wstring Path;
std::wstring Path;
public:
CCacheDataScript(const std::wstring& sPath)
{
Data = NULL;
Length = 0;
public:
CCacheDataScript(const std::wstring& sPath)
{
Data = NULL;
Length = 0;
Path = sPath;
if (!sPath.empty())
{
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(sPath, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
}
Source = NULL;
CachedData = NULL;
Path = sPath;
}
~CCacheDataScript()
{
//RELEASEOBJECT(Source);
//RELEASEOBJECT(CachedData);
RELEASEARRAYOBJECTS(Data);
}
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
if (NULL == Data)
{
Source = new v8::ScriptCompiler::Source(source);
script = v8::ScriptCompiler::Compile(_context, Source, kV8ProduceCodeCache).ToLocalChecked();
const v8::ScriptCompiler::CachedData* _cachedData = Source->GetCachedData();
NSFile::CFileBinary oFileTest;
if (_cachedData && oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(_cachedData->data, (DWORD)_cachedData->length);
oFileTest.CloseFile();
}
}
else
{
CachedData = new v8::ScriptCompiler::CachedData(Data, Length);
Source = new v8::ScriptCompiler::Source(source, CachedData);
script = v8::ScriptCompiler::Compile(_context, Source, v8::ScriptCompiler::kConsumeCodeCache).ToLocalChecked();
}
return script;
}
bool IsInit()
{
return Data != NULL && Length > 0;
}
};
class CJSIsolateScopeV8 : public CJSIsolateScope
{
public:
v8::Isolate::Scope isolate_scope;
v8::Locker isolate_locker;
public:
CJSIsolateScopeV8(v8::Isolate* isolate) : CJSIsolateScope(),
isolate_scope(isolate),
isolate_locker(isolate)
{
}
virtual ~CJSIsolateScopeV8()
{
}
};
class CJSContextScopeV8 : public CJSContextScope
{
public:
v8::Context::Scope m_scope;
public:
CJSContextScopeV8(v8::Local<v8::Context> context) : m_scope(context)
{
}
virtual ~CJSContextScopeV8()
{
}
};
class CJSLocalScopeV8 : public CJSLocalScope
{
public:
v8::HandleScope m_scope;
public:
CJSLocalScopeV8() : m_scope(CV8Worker::GetCurrent())
{
}
virtual ~CJSLocalScopeV8()
{
}
};
CJSContext::CJSContext()
{
m_internal = new CJSContextPrivate();
}
CJSContext::~CJSContext()
{
RELEASEOBJECT(m_internal);
}
CJSTryCatch* CJSContext::GetExceptions()
{
return new CV8TryCatch();
}
void CJSContext::Initialize()
{
m_internal->m_isolate = CV8Worker::getInitializer().CreateNew();
}
void CJSContext::Dispose()
{
#ifdef V8_INSPECTOR
v8_debug::disposeInspector(m_internal->m_context);
#ifndef V8_VERSION_89_PLUS
if (!sPath.empty())
{
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(sPath, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
}
#endif
m_internal->m_isolate->Dispose();
m_internal->m_isolate = NULL;
}
}
~CCacheDataScript()
{
RELEASEARRAYOBJECTS(Data);
}
void CJSContext::CreateContext()
{
m_internal->m_context = v8::Context::New(CV8Worker::GetCurrent(), NULL, m_internal->m_global);
}
#ifdef V8_VERSION_89_PLUS
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
void CJSContext::CreateGlobalForContext()
{
m_internal->m_global = v8::ObjectTemplate::New(CV8Worker::GetCurrent());
}
if (Path.empty())
{
// no cache
v8::ScriptCompiler::Source oSource(source);
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kNoCompileOptions);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
CJSObject* CJSContext::GetGlobal()
{
CJSObjectV8* ret = new CJSObjectV8();
ret->value = m_internal->m_context->Global();
return ret;
}
return script;
}
CJSIsolateScope* CJSContext::CreateIsolateScope()
{
return new CJSIsolateScopeV8(m_internal->m_isolate);
}
if (NSFile::CFileBinary::Exists(Path))
{
// load cache from file
BYTE* _data = NULL;
DWORD _data_length = 0;
if (NSFile::CFileBinary::ReadAllBytes(Path, &_data, _data_length))
{
Data = _data;
Length = (int)_data_length;
}
CJSContextScope* CJSContext::CreateContextScope()
{
CJSContextScope* pScope = new CJSContextScopeV8(m_internal->m_context);
// compile with cache
v8::ScriptCompiler::CachedData* pCacheData = new v8::ScriptCompiler::CachedData(Data, Length);
v8::ScriptCompiler::Source oSource(source, pCacheData);
JSSmart<CJSObject> global = GetCurrent()->GetGlobal();
global->set("window", global.GetPointer());
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kConsumeCodeCache);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
}
else
{
v8::ScriptCompiler::CachedData* pCacheData = nullptr;
return pScope;
}
// save cache to file
NSFile::CFileBinary oFileTest;
if (oFileTest.CreateFileW(Path))
{
// create cache data
v8::ScriptCompiler::Source oSource(source);
v8::Local<v8::Script> pScriptCache = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kNoCompileOptions).ToLocalChecked();
pCacheData = v8::ScriptCompiler::CreateCodeCache(pScriptCache->GetUnboundScript());
CJSLocalScope* CJSContext::CreateLocalScope()
{
return new CJSLocalScopeV8();
}
if (pCacheData)
{
// save cache to file
NSFile::CFileBinary oFileTest;
if (oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(pCacheData->data, (DWORD)pCacheData->length);
oFileTest.CloseFile();
}
}
}
CJSValue* CJSContext::createUndefined()
{
CJSValueV8* _value = new CJSValueV8();
_value->doUndefined();
return _value;
}
// compile with/without(if pCacheData === NULL) cache data
v8::ScriptCompiler::Source oSource2(source, pCacheData);
v8::ScriptCompiler::CompileOptions compileOptions = (nullptr == pCacheData) ? v8::ScriptCompiler::kNoCompileOptions : v8::ScriptCompiler::kConsumeCodeCache;
CJSValue* CJSContext::createNull()
{
CJSValueV8* _value = new CJSValueV8();
_value->doNull();
return _value;
}
v8::MaybeLocal<v8::Script> sctiptMB = v8::ScriptCompiler::Compile(_context, &oSource2, compileOptions);
if (!sctiptMB.IsEmpty())
script = sctiptMB.ToLocalChecked();
}
return script;
}
#else
v8::Local<v8::Script> Compile(const v8::Local<v8::Context>& _context, const v8::Local<v8::String>& source)
{
v8::Local<v8::Script> script;
if (NULL == Data)
{
v8::ScriptCompiler::Source oSource(source);
script = v8::ScriptCompiler::Compile(_context, &oSource, kV8ProduceCodeCache).ToLocalChecked();
CJSValue* CJSContext::createBool(const bool& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Boolean::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createInt(const int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createUInt(const unsigned int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::NewFromUnsigned(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createDouble(const double& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Number::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createString(const char* value, const int& length)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value, length);
return _value;
}
CJSValue* CJSContext::createString(const wchar_t* value, const int& length)
{
std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value));
return createString((const char*)sUtf8.c_str(), (int)sUtf8.length());
}
CJSValue* CJSContext::createString(const std::string& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value.c_str(), (int)value.length());
return _value;
}
CJSValue* CJSContext::createString(const std::wstring& value)
{
std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(value);
return createString(sReturn);
}
CJSObject* CJSContext::createObject()
{
CJSObjectV8* _value = new CJSObjectV8();
_value->value = v8::Object::New(CV8Worker::GetCurrent());
return _value;
}
CJSArray* CJSContext::createArray(const int& count)
{
CJSArrayV8* _value = new CJSArrayV8();
_value->value = v8::Array::New(CV8Worker::GetCurrent(), count);
_value->m_count = count;
return _value;
}
CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize)
{
CJSTypedArrayV8* _value = new CJSTypedArrayV8(data, count, isExternalize);
return _value;
}
JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath)
{
#ifdef V8_INSPECTOR
v8_debug::before(m_internal->m_context, CV8Worker::getInitializer()->getPlatform(), "");
const v8::ScriptCompiler::CachedData* _cachedData = oSource.GetCachedData();
NSFile::CFileBinary oFileTest;
if (_cachedData && oFileTest.CreateFileW(Path))
{
oFileTest.WriteFile(_cachedData->data, (DWORD)_cachedData->length);
oFileTest.CloseFile();
}
}
else
{
v8::ScriptCompiler::CachedData* pCachedData = new v8::ScriptCompiler::CachedData(Data, Length);
v8::ScriptCompiler::Source oSource(source, pCachedData);
script = v8::ScriptCompiler::Compile(_context, &oSource, v8::ScriptCompiler::kConsumeCodeCache).ToLocalChecked();
}
return script;
}
#endif
LOGGER_START
v8::Local<v8::String> _source = CreateV8String(CV8Worker::GetCurrent(), script.c_str());
v8::Local<v8::Script> _script;
if(!scriptPath.empty())
{
std::wstring sCachePath = scriptPath.substr(0, scriptPath.rfind(L".")) + L".cache";
CCacheDataScript oCachedScript(sCachePath);
_script = oCachedScript.Compile(m_internal->m_context, _source);
}
else
{
v8::MaybeLocal<v8::Script> _scriptRetValue = v8::Script::Compile(V8ContextFirstArg _source);
if (!_scriptRetValue.IsEmpty())
_script = _scriptRetValue.ToLocalChecked();
}
bool IsInit()
{
return Data != NULL && Length > 0;
}
};
LOGGER_LAP("compile")
CJSValueV8* _return = new CJSValueV8();
v8::MaybeLocal<v8::Value> retValue;
if (exception.is_init())
{
if (!exception->Check())
retValue = _script->Run(V8ContextOneArg);
}
else
{
retValue = _script->Run(V8ContextOneArg);
}
class CJSIsolateScopeV8 : public CJSIsolateScope
{
public:
v8::Isolate::Scope isolate_scope;
v8::Locker isolate_locker;
if (!retValue.IsEmpty())
_return->value = retValue.ToLocalChecked();
public:
CJSIsolateScopeV8(v8::Isolate* isolate) : CJSIsolateScope(),
isolate_scope(isolate),
isolate_locker(isolate)
{
}
virtual ~CJSIsolateScopeV8()
{
}
};
LOGGER_LAP("run")
return _return;
}
class CJSContextScopeV8 : public CJSContextScope
{
public:
v8::Context::Scope m_scope;
CJSContext* CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
ret->m_internal->m_isolate = CV8Worker::GetCurrent();
ret->m_internal->m_context = ret->m_internal->m_isolate->GetCurrentContext();
// global???
return ret;
}
public:
CJSContextScopeV8(v8::Local<v8::Context> context) : m_scope(context)
{
}
virtual ~CJSContextScopeV8()
{
}
};
CJSValue* CJSContext::JSON_Parse(const char *sTmp)
{
CJSValueV8* _value = new CJSValueV8();
#ifndef V8_OS_XP
v8::MaybeLocal<v8::Value> retValue = v8::JSON::Parse(m_internal->m_context, CreateV8String(CV8Worker::GetCurrent(), sTmp));
if (!retValue.IsEmpty())
_value->value = retValue.ToLocalChecked();
else
_value->doUndefined();
#else
_value->value = v8::JSON::Parse(CreateV8String(CV8Worker::GetCurrent(), sTmp));
#endif
return _value;
}
class CJSLocalScopeV8 : public CJSLocalScope
{
public:
v8::HandleScope m_scope;
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
{
// none
}
public:
CJSLocalScopeV8() : m_scope(CV8Worker::GetCurrent())
{
}
virtual ~CJSLocalScopeV8()
{
}
};
void CJSContext::ExternalInitialize(const std::wstring& sDirectory)
{
CV8Worker::m_sExternalDirectory = sDirectory;
}
void CJSContext::ExternalDispose()
{
CV8Worker::Dispose();
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return true;
}
unsigned char* NSAllocator::Alloc(const size_t& size)
{
return (unsigned char*)CV8Worker::getInitializer().getAllocator()->AllocateUninitialized(size);
}
void NSAllocator::Free(unsigned char* data, const size_t& size)
{
CV8Worker::getInitializer().getAllocator()->Free(data, size);
}
CJSContext::CJSContext()
{
m_internal = new CJSContextPrivate();
}
CJSContext::~CJSContext()
{
RELEASEOBJECT(m_internal);
}
CJSTryCatch* CJSContext::GetExceptions()
{
return new CV8TryCatch();
}
void CJSContext::Initialize()
{
m_internal->m_isolate = CV8Worker::getInitializer().CreateNew();
}
void CJSContext::Dispose()
{
#ifdef V8_INSPECTOR
v8_debug::disposeInspector(m_internal->m_context);
#endif
m_internal->m_isolate->Dispose();
m_internal->m_isolate = NULL;
}
void CJSContext::CreateContext()
{
m_internal->m_context = v8::Context::New(CV8Worker::GetCurrent(), NULL, m_internal->m_global);
}
void CJSContext::CreateGlobalForContext()
{
m_internal->m_global = v8::ObjectTemplate::New(CV8Worker::GetCurrent());
}
CJSObject* CJSContext::GetGlobal()
{
CJSObjectV8* ret = new CJSObjectV8();
ret->value = m_internal->m_context->Global();
return ret;
}
CJSIsolateScope* CJSContext::CreateIsolateScope()
{
return new CJSIsolateScopeV8(m_internal->m_isolate);
}
CJSContextScope* CJSContext::CreateContextScope()
{
CJSContextScope* pScope = new CJSContextScopeV8(m_internal->m_context);
JSSmart<CJSObject> global = GetCurrent()->GetGlobal();
global->set("window", global.GetPointer());
return pScope;
}
CJSLocalScope* CJSContext::CreateLocalScope()
{
return new CJSLocalScopeV8();
}
CJSValue* CJSContext::createUndefined()
{
CJSValueV8* _value = new CJSValueV8();
_value->doUndefined();
return _value;
}
CJSValue* CJSContext::createNull()
{
CJSValueV8* _value = new CJSValueV8();
_value->doNull();
return _value;
}
CJSValue* CJSContext::createBool(const bool& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Boolean::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createInt(const int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createUInt(const unsigned int& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Integer::NewFromUnsigned(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createDouble(const double& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = v8::Number::New(CV8Worker::GetCurrent(), value);
return _value;
}
CJSValue* CJSContext::createString(const char* value, const int& length)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value, length);
return _value;
}
CJSValue* CJSContext::createString(const wchar_t* value, const int& length)
{
std::string sUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(value, (length != -1) ? (LONG)length : (LONG)wcslen(value));
return createString((const char*)sUtf8.c_str(), (int)sUtf8.length());
}
CJSValue* CJSContext::createString(const std::string& value)
{
CJSValueV8* _value = new CJSValueV8();
_value->value = CreateV8String(CV8Worker::GetCurrent(), value.c_str(), (int)value.length());
return _value;
}
CJSValue* CJSContext::createString(const std::wstring& value)
{
std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(value);
return createString(sReturn);
}
CJSObject* CJSContext::createObject()
{
CJSObjectV8* _value = new CJSObjectV8();
_value->value = v8::Object::New(CV8Worker::GetCurrent());
return _value;
}
CJSArray* CJSContext::createArray(const int& count)
{
CJSArrayV8* _value = new CJSArrayV8();
_value->value = v8::Array::New(CV8Worker::GetCurrent(), count);
_value->m_count = count;
return _value;
}
CJSTypedArray* CJSContext::createUint8Array(BYTE* data, int count, const bool& isExternalize)
{
CJSTypedArrayV8* _value = new CJSTypedArrayV8(data, count, isExternalize);
return _value;
}
JSSmart<CJSValue> CJSContext::runScript(const std::string& script, JSSmart<CJSTryCatch> exception, const std::wstring& scriptPath)
{
#ifdef V8_INSPECTOR
v8_debug::before(m_internal->m_context, CV8Worker::getInitializer()->getPlatform(), "");
#endif
LOGGER_START
v8::Local<v8::String> _source = CreateV8String(CV8Worker::GetCurrent(), script.c_str());
v8::Local<v8::Script> _script;
if(!scriptPath.empty())
{
std::wstring sCachePath = scriptPath.substr(0, scriptPath.rfind(L".")) + L".cache";
CCacheDataScript oCachedScript(sCachePath);
_script = oCachedScript.Compile(m_internal->m_context, _source);
}
else
{
v8::MaybeLocal<v8::Script> _scriptRetValue = v8::Script::Compile(V8ContextFirstArg _source);
if (!_scriptRetValue.IsEmpty())
_script = _scriptRetValue.ToLocalChecked();
}
LOGGER_LAP("compile")
CJSValueV8* _return = new CJSValueV8();
v8::MaybeLocal<v8::Value> retValue;
if (exception.is_init())
{
if (!exception->Check())
retValue = _script->Run(V8ContextOneArg);
}
else
{
retValue = _script->Run(V8ContextOneArg);
}
if (!retValue.IsEmpty())
_return->value = retValue.ToLocalChecked();
LOGGER_LAP("run")
return _return;
}
CJSContext* CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
ret->m_internal->m_isolate = CV8Worker::GetCurrent();
ret->m_internal->m_context = ret->m_internal->m_isolate->GetCurrentContext();
// global???
return ret;
}
CJSValue* CJSContext::JSON_Parse(const char *sTmp)
{
CJSValueV8* _value = new CJSValueV8();
#ifndef V8_OS_XP
v8::MaybeLocal<v8::Value> retValue = v8::JSON::Parse(m_internal->m_context, CreateV8String(CV8Worker::GetCurrent(), sTmp));
if (!retValue.IsEmpty())
_value->value = retValue.ToLocalChecked();
else
_value->doUndefined();
#else
_value->value = v8::JSON::Parse(CreateV8String(CV8Worker::GetCurrent(), sTmp));
#endif
return _value;
}
void CJSContext::MoveToThread(ASC_THREAD_ID* id)
{
// none
}
void CJSContext::ExternalInitialize(const std::wstring& sDirectory)
{
CV8Worker::m_sExternalDirectory = sDirectory;
}
void CJSContext::ExternalDispose()
{
CV8Worker::Dispose();
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return true;
}
unsigned char* NSAllocator::Alloc(const size_t& size)
{
return (unsigned char*)CV8Worker::getInitializer().getAllocator()->AllocateUninitialized(size);
}
void NSAllocator::Free(unsigned char* data, const size_t& size)
{
CV8Worker::getInitializer().getAllocator()->Free(data, size);
}
}

View File

@ -54,9 +54,15 @@ bool CSVGTransformer::OpenFromFile(const std::wstring& file)
m_internal->m_oRender.SetWorkingDirectory(sDirectory);
m_internal->m_oStorage.SetWorkingDirectory(sDirectory);
if (0 == m_internal->m_oXmlParser.LoadFromFile(file, &m_internal->m_oStorage))
try
{
if (!m_internal->m_oXmlParser.LoadFromFile(file, &m_internal->m_oStorage))
return false;
}
catch(...)
{
return false;
}
return true;
}
bool CSVGTransformer::Load(const std::wstring& content)

View File

@ -3584,7 +3584,121 @@ namespace NExtractTools
}
return nRes;
}
_UINT32 PdfDjvuXpsToRenderer(IOfficeDrawingFile** ppReader, IRenderer* pRenderer, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, NSFonts::IApplicationFonts* pApplicationFonts)
std::string checkPrintPages(InputParams& params)
{
if (NULL == params.m_sJsonParams)
return "";
std::wstring::size_type posNativeOptions = params.m_sJsonParams->find(L"\"nativeOptions\"");
if (std::wstring::npos == posNativeOptions)
return "";
std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions);
if (std::wstring::npos == posNativePages)
return "";
posNativePages += 9;
std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages);
if (std::wstring::npos == posNativePages2)
return "";
std::wstring sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages);
if (L"all" == sPages)
return "";
if (L"current" == sPages)
{
std::wstring::size_type posCurrentPage = params.m_sJsonParams->find(L"\"currentPage\":", posNativeOptions);
if (std::wstring::npos == posCurrentPage)
return "";
posCurrentPage += 14;
std::wstring::size_type posCurrentPage2 = params.m_sJsonParams->find(L",", posCurrentPage);
std::wstring::size_type posCurrentPage3 = params.m_sJsonParams->find(L"}", posCurrentPage);
if (std::wstring::npos == posCurrentPage2)
{
if (std::wstring::npos == posCurrentPage3)
return "";
posCurrentPage2 = posCurrentPage3;
}
else if (std::wstring::npos != posCurrentPage3 && posCurrentPage3 < posCurrentPage2)
posCurrentPage2 = posCurrentPage3;
if (std::wstring::npos == posCurrentPage2)
return "";
sPages = params.m_sJsonParams->substr(posCurrentPage, posCurrentPage2 - posCurrentPage);
}
return U_TO_UTF8(sPages);
}
std::vector<bool> getPrintPages(const std::string& sPages, int nPagesCount)
{
const char* buffer = sPages.c_str();
size_t nCur = 0;
size_t nLen = sPages.length();
std::vector<bool> arPages;
for (int i = 0; i < nPagesCount; ++i)
arPages.push_back(false);
while (nCur < nLen)
{
size_t cur = nCur;
while (cur < nLen && buffer[cur] != ',')
++cur;
int nStart = 0;
int nEnd = 0;
size_t curRec = nCur;
while (curRec < cur)
{
char c = buffer[curRec++];
if (c >= '0' && c <= '9')
nStart = 10 * nStart + (c - '0');
if (c == '-')
break;
}
if (nStart == 0)
nStart = 1;
if (curRec == cur)
nEnd = nStart;
else
{
while (curRec < cur)
{
char c = buffer[curRec++];
if (c >= '0' && c <= '9')
nEnd = 10 * nEnd + (c - '0');
if (c == '-')
break;
}
if (0 == nEnd || nEnd > nPagesCount)
nEnd = nPagesCount;
}
for (int i = nStart; i <= nEnd; ++i)
arPages[i - 1] = true;
nCur = cur;
if (nCur < nLen)
++nCur;
}
return arPages;
}
_UINT32 PdfDjvuXpsToRenderer(IOfficeDrawingFile** ppReader, IRenderer* pRenderer, const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params, NSFonts::IApplicationFonts* pApplicationFonts, const std::string& sPages = "")
{
_UINT32 nRes = 0;
IOfficeDrawingFile* pReader = NULL;
@ -3613,8 +3727,17 @@ namespace NExtractTools
if(bResult)
{
int nPagesCount = pReader->GetPagesCount();
bool bIsUsePages = sPages.empty() ? false : true;
std::vector<bool> arPages;
if (bIsUsePages)
arPages = getPrintPages(sPages, nPagesCount);
for (int i = 0; i < nPagesCount; ++i)
{
if (bIsUsePages && !arPages[i])
continue;
pRenderer->NewPage();
pRenderer->BeginCommand(c_nPageType);
@ -4722,6 +4845,7 @@ namespace NExtractTools
}
return nRes;
}
_UINT32 fromCrossPlatform(const std::wstring &sFrom, int nFormatFrom, const std::wstring &sTo, int nFormatTo, const std::wstring &sTemp, const std::wstring &sThemeDir, bool bPaid, InputParams& params)
{
_UINT32 nRes = 0;
@ -4729,7 +4853,9 @@ namespace NExtractTools
initApplicationFonts(pApplicationFonts, params);
if(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)
{
if(nFormatFrom == nFormatTo && !params.getIsPDFA() && params.getPassword() == params.getSavePassword())
std::string sPages = checkPrintPages(params);
if(nFormatFrom == nFormatTo && !params.getIsPDFA() && params.getPassword() == params.getSavePassword() && sPages.empty())
{
NSFile::CFileBinary::Copy(sFrom, sTo);
}
@ -4748,7 +4874,7 @@ namespace NExtractTools
pdfWriter.SetPassword(password);
IOfficeDrawingFile* pReader = NULL;
nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts);
nRes = PdfDjvuXpsToRenderer(&pReader, &pdfWriter, sFrom, nFormatFrom, sTo, sTemp, params, pApplicationFonts, sPages);
pdfWriter.SaveToFile(sTo);
RELEASEOBJECT(pReader);
}
@ -5611,7 +5737,7 @@ namespace NExtractTools
}
//clean up v8
NSDoctRenderer::CDocBuilder::Dispose();
NSDoctRenderer::CDocBuilder::Dispose();
if (SUCCEEDED_X2T(result) && oInputParams.m_bOutputConvertCorrupted)
{
return AVS_FILEUTILS_ERROR_CONVERT_CORRUPTED;
@ -5622,6 +5748,16 @@ namespace NExtractTools
}
}
void createJSCaches()
{
NSDoctRenderer::CDocBuilder::Initialize();
NSDoctRenderer::CDoctrenderer oDoctRenderer;
oDoctRenderer.CreateCache(L"", L"");
NSDoctRenderer::CDocBuilder::Dispose();
}
_UINT32 FromFile(const std::wstring& file)
{
InputParams oInputParams;

View File

@ -228,6 +228,8 @@ namespace NExtractTools
_UINT32 fromInputParams(InputParams& oInputParams);
_UINT32 detectMacroInFile(InputParams& oInputParams);
void createJSCaches();
X2T_DECL_EXPORT _UINT32 FromFile(const std::wstring& file);
X2T_DECL_EXPORT _UINT32 FromXml(const std::wstring& xml);

View File

@ -446,6 +446,12 @@ namespace NExtractTools
oBuilder.WriteEncodeXmlString(sJsonParams);
oBuilder.WriteString(_T("</JsonParams>"));
}
if (NULL != params.m_sScriptsCacheDirectory)
{
oBuilder.WriteString(_T("<ScriptsCacheDirectory>"));
oBuilder.WriteEncodeXmlString(*params.m_sScriptsCacheDirectory);
oBuilder.WriteString(_T("</ScriptsCacheDirectory>"));
}
oBuilder.WriteString(_T("<Changes TopItem=\""));
oBuilder.AddInt(nTopIndex);
oBuilder.WriteString(_T("\">"));

View File

@ -477,6 +477,7 @@ namespace NExtractTools
boost::unordered_map<int, std::vector<InputLimit>> m_mapInputLimits;
bool* m_bIsPDFA;
std::wstring* m_sConvertToOrigin;
std::wstring* m_sScriptsCacheDirectory;
//output params
mutable bool m_bOutputConvertCorrupted;
mutable bool m_bMacro;
@ -510,6 +511,7 @@ namespace NExtractTools
m_bIsNoBase64 = NULL;
m_bIsPDFA = NULL;
m_sConvertToOrigin = NULL;
m_sScriptsCacheDirectory = NULL;
m_bOutputConvertCorrupted = false;
m_bMacro = false;
@ -543,6 +545,7 @@ namespace NExtractTools
RELEASEOBJECT(m_bIsNoBase64);
RELEASEOBJECT(m_bIsPDFA);
RELEASEOBJECT(m_sConvertToOrigin);
RELEASEOBJECT(m_sScriptsCacheDirectory);
}
bool FromXmlFile(const std::wstring& sFilename)
@ -727,6 +730,11 @@ namespace NExtractTools
RELEASEOBJECT(m_sConvertToOrigin);
m_sConvertToOrigin = new std::wstring(sValue);
}
else if (_T("m_sScriptsCacheDirectory") == sName)
{
RELEASEOBJECT(m_sScriptsCacheDirectory);
m_sScriptsCacheDirectory = new std::wstring(sValue);
}
}
else if(_T("m_nCsvDelimiterChar") == sName)
{

View File

@ -173,6 +173,11 @@ static std::wstring utf8_to_unicode(const char *src)
result = NExtractTools::detectMacroInFile(oInputParams);
}
else if (sArg1 == L"-create-js-cache")
{
NExtractTools::createJSCaches();
return 0;
}
else
{
InputParams oInputParams;