Add support macos < 10.12

This commit is contained in:
Oleg.Korshul
2020-12-05 19:25:33 +03:00
parent ebb1fc7f98
commit 7f253cc138
8 changed files with 226 additions and 27 deletions

View File

@ -686,7 +686,7 @@ namespace NSDoctRenderer
int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath());
JSSmart<CJSValue> args_open[4];
args_open[0] = oWorkerLoader.GetDataFull()->toObject()->toValue();
args_open[0] = oWorkerLoader.GetDataFull()->toValue();
args_open[1] = CJSContext::createInt(nVersion);
std::wstring sXlsx = NSCommon::GetDirectoryName(pNative->GetFilePath()) + L"/Editor.xlsx";
args_open[2] = NSFile::CFileBinary::Exists(sXlsx) ? CJSContext::createString(sXlsx) : CJSContext::createUndefined();
@ -733,7 +733,7 @@ namespace NSDoctRenderer
bool bIsFull = (nCurrentIndex == m_oParams.m_arChanges.size()) ? true : false;
JSSmart<CJSValue> args_changes[2];
args_changes[0] = oWorker.GetData()->toObject()->toValue();
args_changes[0] = oWorker.GetData()->toValue();
args_changes[1] = CJSContext::createBool(bIsFull);
js_objectApi->call_func("asc_nativeApplyChanges2", 2, args_changes);
if (try_catch->Check())

View File

@ -111,6 +111,7 @@ namespace NSJSBase
virtual int getCount() = 0;
virtual const BYTE* getData() = 0;
virtual JSSmart<CJSValue> toValue() = 0;
};
class CJSFunction : public CJSValue
@ -211,6 +212,7 @@ namespace NSJSBase
public:
static void ExternalInitialize();
static void ExternalDispose();
static bool IsSupportNativeTypedArrays();
};
}

View File

@ -21,6 +21,7 @@ namespace NSJSBase
public:
JSContext* context;
static bool g_oldVersion;
static JSContext* g_lockedContext;
public:
@ -289,11 +290,16 @@ namespace NSJSBase
class CJSTypedArrayJSC : public CJSValueJSCTemplate<CJSTypedArray>
{
private:
BYTE* data_old_version;
public:
CJSTypedArrayJSC(JSContext* _context, BYTE* data = NULL, int count = 0)
{
data_old_version = NULL;
context = _context;
if (0 < count)
if (0 >= count)
return;
if (!CJSContextPrivate::g_oldVersion)
{
JSObjectRef object = JSObjectMakeTypedArrayWithBytesNoCopy(context.JSGlobalContextRef,
kJSTypedArrayTypeUint8Array,
@ -304,9 +310,20 @@ namespace NSJSBase
value = [JSValue valueWithJSValueRef:object inContext:context];
}
}
else
{
char* pDst = NULL;
int nDstLen = 0;
NSFile::CBase64Converter::Encode(data, count, pDst, nDstLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sCode = "jsc_fromBase64(\"" + std::string(pDst, nDstLen) + "\", " + std::to_string(count) + ");";
RELEASEARRAYOBJECTS(pDst);
value = [_context evaluateScript:[NSString stringWithAString:sCode]];
}
}
virtual ~CJSTypedArrayJSC()
{
RELEASEARRAYOBJECTS(data_old_version);
value = nil;
context = nil;
}
@ -318,14 +335,45 @@ namespace NSJSBase
virtual int getCount()
{
JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL);
return (int)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL);
if (nil == value)
return 0;
if (!CJSContextPrivate::g_oldVersion)
{
JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL);
return (int)JSObjectGetTypedArrayByteLength(context.JSGlobalContextRef, obj, NULL);
}
JSValue* _ret = [value valueForProperty:@"length"];
if (nil != _ret && NO == [_ret isUndefined])
return [_ret toInt32];
return 0;
}
virtual const BYTE* getData()
{
JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL);
return (BYTE*)JSObjectGetTypedArrayBytesPtr(context.JSGlobalContextRef, obj, NULL);
if (!CJSContextPrivate::g_oldVersion)
{
JSObjectRef obj = JSValueToObject(context.JSGlobalContextRef, value.JSValueRef, NULL);
return (BYTE*)JSObjectGetTypedArrayBytesPtr(context.JSGlobalContextRef, obj, NULL);
}
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:value];
JSValue* dataBase64 = [context[@"jsc_toBase64"] callWithArguments:arr];
std::string sBase64Data = [[dataBase64 toString] stdstring];
RELEASEARRAYOBJECTS(data_old_version);
int nDstLen = 0;
NSFile::CBase64Converter::Decode(sBase64Data.c_str(), (int)sBase64Data.length(), data_old_version, nDstLen);
return data_old_version;
}
virtual JSSmart<CJSValue> toValue()
{
CJSValueJSC* _value = new CJSValueJSC();
_value->value = value;
_value->context = context;
return _value;
}
};

View File

@ -1,8 +1,10 @@
#import "jsc_base.h"
#include <iostream>
using namespace NSJSBase;
JSContext* NSJSBase::CJSContextPrivate::g_lockedContext = nil;
bool NSJSBase::CJSContextPrivate::g_oldVersion = false;
template<typename T>
bool CJSValueJSCTemplate<T>::isUndefined()
@ -110,6 +112,18 @@ namespace NSJSBase
void CJSContext::Initialize()
{
m_internal->context = [[JSContext alloc] init];
#ifndef _IOS
if (@available(macOS 10.12, *))
{
// none
}
else
{
CJSContextPrivate::g_oldVersion = true;
[m_internal->context evaluateScript:@"var Uint8Array=Array;function jsc_toBase64(r){for(var o=[\"A\",\"B\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"I\",\"J\",\"K\",\"L\",\"M\",\"N\",\"O\",\"P\",\"Q\",\"R\",\"S\",\"T\",\"U\",\"V\",\"W\",\"X\",\"Y\",\"Z\",\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\"n\",\"o\",\"p\",\"q\",\"r\",\"s\",\"t\",\"u\",\"v\",\"w\",\"x\",\"y\",\"z\",\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"+\",\"/\"],a=r.length,f=4*(a/3>>0),n=f/76>>0,t=19,v=0,e=[],i=\"\",s=0;s<=n;s++){s==n&&(t=f%76/4>>0);for(var u=0;u<t;u++){for(var c=0,h=0;h<3;h++)c|=r[0+v++],c<<=8;i=\"\";for(var A=0;A<4;A++){i+=o[c>>>26&255],c<<=6,c&=4294967295}e.push(i)}}if(n=a%3!=0?a%3+1:0){for(c=0,h=0;h<3;h++)h<a%3&&(c|=r[0+v++]),c<<=8;i=\"\";for(A=0;A<n;A++){i+=o[c>>>26&255],c<<=6}t=0!=n?4-n:0;for(u=0;u<t;u++)i+=\"=\";e.push(i)}return e.join(\"\")}function jsc_fromBase64(r,o){for(var a,f=r.length,n=0,t=new Array(void 0===o?f:o),v=t,e=0,i=0;e<f;){for(var s=0,u=0,c=0;c<4&&!(f<=e);c++){var h=65<=(a=r.charCodeAt(e++))&&a<=90?a-65:97<=a&&a<=122?a-71:48<=a&&a<=57?a+4:43==a?62:47==a?63:-1;-1!=h?(s<<=6,s|=h,u+=6):c--}for(s<<=24-u,i=u>>>3,c=0;c<i;c++)v[n++]=(16711680&s)>>>16,s<<=8}return t}\n"];
}
#endif
}
void CJSContext::Dispose()
{
@ -268,6 +282,10 @@ namespace NSJSBase
void CJSContext::ExternalDispose()
{
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return (CJSContextPrivate::g_oldVersion == false) ? true : false;
}
CJSValue* CJSContext::JSON_Parse(const char *sTmp)
{
@ -294,9 +312,8 @@ namespace NSJSBase
return false;
NSString* pExсeption = [[context exception] toString];
#if 1
std::cerr << [pExсeption stdstring] << std::endl;
NSLog(@"%@", pExсeption);
#endif
return true;
}
}

View File

@ -0,0 +1,127 @@
var Uint8Array = Array;
function jsc_toBase64(srcData)
{
var arrayBase64 = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
var nOffset = 0;
var nSrcLen = srcData.length;
var nWritten = 0;
var nLen1 = (((nSrcLen / 3) >> 0) * 4);
var nLen2 = (nLen1 / 76) >> 0;
var nLen3 = 19;
var srcInd = 0;
var dstStr = [];
var _s = "";
for (var i = 0; i <= nLen2; i++)
{
if (i == nLen2)
nLen3 = ((nLen1 % 76) / 4) >> 0;
for (var j = 0; j < nLen3; j++)
{
var dwCurr = 0;
for (var n = 0; n < 3; n++)
{
dwCurr |= srcData[srcInd++ + nOffset];
dwCurr <<= 8;
}
_s = "";
for (var k = 0; k < 4; k++)
{
var b = (dwCurr >>> 26) & 0xFF;
_s += arrayBase64[b];
dwCurr <<= 6;
dwCurr &= 0xFFFFFFFF;
}
dstStr.push(_s);
}
}
nLen2 = (nSrcLen % 3 != 0) ? (nSrcLen % 3 + 1) : 0;
if (nLen2)
{
var dwCurr = 0;
for (var n = 0; n < 3; n++)
{
if (n < (nSrcLen % 3))
dwCurr |= srcData[srcInd++ + nOffset];
dwCurr <<= 8;
}
_s = "";
for (var k = 0; k < nLen2; k++)
{
var b = (dwCurr >>> 26) & 0xFF;
_s += arrayBase64[b];
dwCurr <<= 6;
}
nLen3 = (nLen2 != 0) ? 4 - nLen2 : 0;
for (var j = 0; j < nLen3; j++)
{
_s += '=';
}
dstStr.push(_s);
}
return dstStr.join("");
};
function jsc_fromBase64(szSrc, len)
{
function DecodeBase64Char(ch)
{
if (ch >= 65 && ch <= 90)
return ch - 65;
if (ch >= 97 && ch <= 122)
return ch - 71;
if (ch >= 48 && ch <= 57)
return ch + 4;
if (ch == 43)
return 62;
if (ch == 47)
return 63;
return -1;
}
var srcLen = szSrc.length;
var nWritten = 0;
var arr = new Array(len === undefined ? srcLen : len);
var dstPx = arr;
var index = 0;
var limit = 0;
while (index < srcLen)
{
var dwCurr = 0;
var i;
var nBits = 0;
for (i=0; i<4; i++)
{
if (index >= srcLen)
break;
var nCh = DecodeBase64Char(szSrc.charCodeAt(index++));
if (nCh == -1)
{
i--;
continue;
}
dwCurr <<= 6;
dwCurr |= nCh;
nBits += 6;
}
dwCurr <<= 24-nBits;
limit = nBits>>>3;
for (i=0; i<limit; i++)
{
dstPx[nWritten++] = ((dwCurr & 0x00ff0000) >>> 16);
dwCurr <<= 8;
}
}
return arr;
};

View File

@ -325,4 +325,8 @@ namespace NSJSBase
{
CV8Worker::Dispose();
}
bool CJSContext::IsSupportNativeTypedArrays()
{
return true;
}
}

View File

@ -2,6 +2,7 @@
#define _BUILD_NATIVE_CONTROL_V8_BASE_H_
#include "../js_base.h"
#include <iostream>
#include "v8.h"
#include "libplatform/libplatform.h"
@ -563,6 +564,13 @@ namespace NSJSBase
{
return (BYTE*)value->Buffer()->Externalize().Data();
}
virtual JSSmart<CJSValue> toValue()
{
CJSValueV8* _value = new CJSValueV8();
_value->value = value;
return _value;
}
};
class CJSFunctionV8 : public CJSValueV8Template<v8::Function, CJSFunction>
@ -664,17 +672,9 @@ namespace NSJSBase
std::string strCode = _line->toStringA();
std::string strException = _exception->toStringA();
#if 0 && !defined(__ANDROID__)
FILE* f = fopen("D:\\errors.txt", "a+");
fprintf(f, "error: ");
fprintf(f, strCode.c_str());
fprintf(f, "\n");
fprintf(f, strException.c_str());
fprintf(f, "\n");
fclose(f);
#endif
#ifdef __ANDROID__
#ifndef __ANDROID__
std::cerr << strException << std::endl;
#else
LOGE("NSJSBase::CV8TryCatch::Check() - error:");
LOGE(std::to_string(nLineNumber).c_str());
LOGE(strCode.c_str());

View File

@ -516,7 +516,8 @@ public:
m_pData = new BYTE[m_nLen];
m_pDataCur = m_pData;
m_oArrayBuffer = CJSContext::createUint8Array(m_pData, m_nLen);
if (CJSContext::IsSupportNativeTypedArrays())
m_oArrayBuffer = CJSContext::createUint8Array(m_pData, m_nLen);
}
inline int Open(std::vector<std::wstring>& oFiles, int nStart)
@ -628,7 +629,10 @@ public:
JSSmart<CJSTypedArray> GetData()
{
return m_oArrayBuffer;
if (CJSContext::IsSupportNativeTypedArrays())
return m_oArrayBuffer;
size_t len = (size_t)(m_pDataCur - m_pData);
return CJSContext::createUint8Array(m_pData, (int)len);
}
public:
@ -743,7 +747,7 @@ public:
JSSmart<CJSTypedArray> GetDataFull()
{
size_t len = (size_t)(m_pDataCur - m_pData);
JSSmart<CJSTypedArray> _buffer = CJSContext::createUint8Array(m_pData, len);
JSSmart<CJSTypedArray> _buffer = CJSContext::createUint8Array(m_pData, (int)len);
return _buffer;
}
@ -993,10 +997,7 @@ public:
void Lap(const std::string& details)
{
DWORD dwCur = NSTimers::GetTickCount();
FILE* f = fopen("D:\\doctrenderer.speed", "a+");
std::string sTmp = details + ": %d\n";
fprintf(f, sTmp.c_str(), (int)(dwCur - m_dwTime));
fclose(f);
std::cout << details << ": " << (int)(dwCur - m_dwTime) << std::endl;
m_dwTime = dwCur;
}
};