mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@59582 954022d7-b5bf-4e40-9824-e11837661b57
1044 lines
25 KiB
C++
1044 lines
25 KiB
C++
#pragma once
|
||
#include "stdafx.h"
|
||
#include "DocRenderer.h"
|
||
|
||
// string convert
|
||
static CString to_cstring(v8::Local<v8::Value> v)
|
||
{
|
||
v8::String::Value data(v);
|
||
const WCHAR* p = (WCHAR*)*data;
|
||
if (NULL == p)
|
||
return _T("");
|
||
return CString(p);
|
||
}
|
||
|
||
static CStringA to_cstringA(v8::Local<v8::Value> v)
|
||
{
|
||
v8::String::Utf8Value data(v);
|
||
const char* p = (char*)*data;
|
||
if (NULL == p)
|
||
return "";
|
||
return CStringA(p);
|
||
}
|
||
|
||
class CNativeControl
|
||
{
|
||
private:
|
||
CString m_strFilePath;
|
||
CString m_strFileId;
|
||
|
||
public:
|
||
CAtlArray<CString>* m_pChanges;
|
||
CString m_strFontsDirectory;
|
||
CString m_strImagesDirectory;
|
||
|
||
CString m_strEditorType;
|
||
|
||
int m_nCurrentChangesNumber;
|
||
int m_nMaxChangesNumber;
|
||
|
||
BYTE* m_pSaveBinary;
|
||
int m_nSaveLen;
|
||
|
||
int m_nSaveBinaryLen;
|
||
CStringA m_sHeader;
|
||
|
||
public:
|
||
CMemoryStream* m_pStream;
|
||
|
||
CNativeControl()
|
||
{
|
||
m_pStream = NULL;
|
||
m_pChanges = NULL;
|
||
|
||
m_nCurrentChangesNumber = -1;
|
||
m_nMaxChangesNumber = -1;
|
||
|
||
m_pSaveBinary = NULL;
|
||
m_nSaveLen = 0;
|
||
m_nSaveBinaryLen = 0;
|
||
}
|
||
~CNativeControl()
|
||
{
|
||
RELEASEOBJECT(m_pStream);
|
||
m_pChanges = NULL;
|
||
|
||
RELEASEARRAYOBJECTS(m_pSaveBinary);
|
||
m_nSaveLen = 0;
|
||
}
|
||
|
||
public:
|
||
|
||
void Save_Alloc(int nLen)
|
||
{
|
||
m_nSaveLen = nLen;
|
||
m_pSaveBinary = new BYTE[m_nSaveLen];
|
||
memset(m_pSaveBinary, 0xFF, m_nSaveLen);
|
||
}
|
||
|
||
void Save_ReAlloc(int pos, int len)
|
||
{
|
||
BYTE* pOld = m_pSaveBinary;
|
||
m_nSaveLen = len;
|
||
m_pSaveBinary = new BYTE[m_nSaveLen];
|
||
|
||
memcpy(m_pSaveBinary, pOld, pos);
|
||
|
||
RELEASEARRAYOBJECTS(pOld);
|
||
}
|
||
|
||
void Save_End(CStringA sHeader, int len)
|
||
{
|
||
m_sHeader = sHeader;
|
||
m_nSaveBinaryLen = len;
|
||
}
|
||
|
||
void Save_Destroy()
|
||
{
|
||
RELEASEARRAYOBJECTS(m_pSaveBinary);
|
||
m_nSaveLen = 0;
|
||
m_nSaveBinaryLen = 0;
|
||
}
|
||
|
||
public:
|
||
void getFileData(CString& strFile, BYTE*& pData, DWORD& dwLen)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(strFile);
|
||
dwLen = (DWORD)oFile.GetFileSize();
|
||
pData = (BYTE*)malloc((size_t)dwLen);
|
||
oFile.ReadFile(pData, dwLen);
|
||
}
|
||
|
||
void SetFilePath(const CString& strPath)
|
||
{
|
||
m_strFilePath = strPath;
|
||
}
|
||
CString GetFilePath()
|
||
{
|
||
return m_strFilePath;
|
||
}
|
||
|
||
void SetFileId(const CString& strId)
|
||
{
|
||
m_strFileId = strId;
|
||
}
|
||
CString GetFileId()
|
||
{
|
||
return m_strFileId;
|
||
}
|
||
|
||
void ConsoleLog(CString& strVal)
|
||
{
|
||
#if 0
|
||
FILE* f = fopen("C:\\log.txt", "a+");
|
||
fprintf(f, (CStringA)strVal);
|
||
fprintf(f, "\n");
|
||
fclose(f);
|
||
#endif
|
||
}
|
||
};
|
||
|
||
// wrap_methods -------------
|
||
CNativeControl* unwrap_nativeobject(v8::Handle<v8::Object> obj)
|
||
{
|
||
v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(obj->GetInternalField(0));
|
||
return static_cast<CNativeControl*>(field->Value());
|
||
}
|
||
|
||
void _GetFilePath(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
args.GetReturnValue().Set(v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), (uint16_t*)pNative->GetFilePath().GetBuffer()));
|
||
}
|
||
void _SetFilePath(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
|
||
if (args.Length() < 1)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
pNative->SetFilePath(to_cstring(args[0]));
|
||
}
|
||
|
||
void _GetFontsDirectory(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
args.GetReturnValue().Set(v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), (uint16_t*)pNative->m_strFontsDirectory.GetBuffer()));
|
||
}
|
||
|
||
void _GetEditorType(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
args.GetReturnValue().Set(v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), (uint16_t*)pNative->m_strEditorType.GetBuffer()));
|
||
}
|
||
|
||
void _GetChangesCount(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
int nCount = 0;
|
||
if (pNative->m_pChanges != NULL)
|
||
nCount = (int)pNative->m_pChanges->GetCount();
|
||
args.GetReturnValue().Set(v8::Integer::New(v8::Isolate::GetCurrent(), nCount));
|
||
}
|
||
void _GetChangesFile(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
if (args.Length() < 1)
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
|
||
v8::Local<v8::Int32> intValue = args[0]->ToInt32();
|
||
int nIndex = (int)intValue->Value();
|
||
|
||
CString strFile = _T("");
|
||
if (pNative->m_pChanges != NULL)
|
||
strFile = pNative->m_pChanges->GetAt((size_t)nIndex);
|
||
|
||
args.GetReturnValue().Set(v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), (uint16_t*)strFile.GetBuffer()));
|
||
}
|
||
|
||
void _GetFileId(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
args.GetReturnValue().Set(v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), (uint16_t*)pNative->GetFileId().GetBuffer()));
|
||
}
|
||
void _SetFileId(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
|
||
if (args.Length() < 1)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
pNative->SetFileId(to_cstring(args[0]));
|
||
}
|
||
|
||
void _CheckNextChange(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
pNative->m_nCurrentChangesNumber++;
|
||
if (-1 != pNative->m_nMaxChangesNumber)
|
||
{
|
||
if (pNative->m_nCurrentChangesNumber >= pNative->m_nMaxChangesNumber)
|
||
{
|
||
args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), false));
|
||
return;
|
||
}
|
||
}
|
||
args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), true));
|
||
}
|
||
|
||
void _GetFileArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
if (args.Length() < 1)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
return;
|
||
}
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
BYTE* pData = NULL;
|
||
DWORD len = 0;
|
||
pNative->getFileData(to_cstring(args[0]), pData, len);
|
||
|
||
v8::Local<v8::ArrayBuffer> _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(_buffer, 0, (size_t)len);
|
||
|
||
args.GetReturnValue().Set(_array);
|
||
}
|
||
|
||
void _GetFontArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
if (args.Length() < 1)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
return;
|
||
}
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
BYTE* pData = NULL;
|
||
DWORD len = 0;
|
||
CString strDir = pNative->m_strFontsDirectory;
|
||
|
||
if (strDir != _T(""))
|
||
strDir += _T("\\");
|
||
|
||
strDir += to_cstring(args[0]);
|
||
pNative->getFileData(strDir, pData, len);
|
||
|
||
v8::Local<v8::ArrayBuffer> _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(_buffer, 0, (size_t)len);
|
||
|
||
args.GetReturnValue().Set(_array);
|
||
}
|
||
|
||
void _GetFileString(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
if (args.Length() < 1)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
return;
|
||
}
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
|
||
BYTE* pData = NULL;
|
||
DWORD len = 0;
|
||
pNative->getFileData(to_cstring(args[0]), pData, len);
|
||
|
||
args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), (char*)pData, v8::String::kNormalString, len));
|
||
}
|
||
|
||
void _Save_AllocNative(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
if (args.Length() < 1)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
v8::Local<v8::Int32> intValue = args[0]->ToInt32();
|
||
int nLen = (int)intValue->Value();
|
||
|
||
pNative->Save_Alloc(nLen);
|
||
|
||
v8::Local<v8::ArrayBuffer> _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen);
|
||
args.GetReturnValue().Set(_array);
|
||
}
|
||
|
||
void _Save_ReAllocNative(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
if (args.Length() < 2)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
int _pos = args[0]->Int32Value();
|
||
int _len = args[1]->Int32Value();
|
||
|
||
pNative->Save_ReAlloc(_pos, _len);
|
||
|
||
v8::Local<v8::ArrayBuffer> _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen);
|
||
args.GetReturnValue().Set(_array);
|
||
}
|
||
|
||
void _Save_End(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
if (args.Length() < 2)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
CStringA sHeader = to_cstringA(args[0]);
|
||
int _len = args[1]->Int32Value();
|
||
|
||
pNative->Save_End(sHeader, _len);
|
||
}
|
||
|
||
void _ConsoleLog(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||
{
|
||
args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent()));
|
||
if (args.Length() < 1)
|
||
return;
|
||
|
||
CNativeControl* pNative = unwrap_nativeobject(args.This());
|
||
pNative->ConsoleLog(to_cstring(args[0]));
|
||
}
|
||
|
||
v8::Handle<v8::ObjectTemplate> CreateNativeControlTemplate(v8::Isolate* isolate)
|
||
{
|
||
//v8::HandleScope handle_scope(isolate);
|
||
|
||
v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New();
|
||
result->SetInternalFieldCount(1); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CNativeControl
|
||
|
||
v8::Isolate* current = v8::Isolate::GetCurrent();
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
result->Set(v8::String::NewFromUtf8(current, "SetFilePath"), v8::FunctionTemplate::New(current, _SetFilePath));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFilePath"), v8::FunctionTemplate::New(current, _GetFilePath));
|
||
result->Set(v8::String::NewFromUtf8(current, "SetFileId"), v8::FunctionTemplate::New(current, _SetFileId));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFileId"), v8::FunctionTemplate::New(current, _GetFileId));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFileBinary"), v8::FunctionTemplate::New(current, _GetFileArrayBuffer));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFontBinary"), v8::FunctionTemplate::New(current, _GetFontArrayBuffer));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFontsDirectory"), v8::FunctionTemplate::New(current, _GetFontsDirectory));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetFileString"), v8::FunctionTemplate::New(current, _GetFileString));
|
||
|
||
result->Set(v8::String::NewFromUtf8(current, "GetEditorType"), v8::FunctionTemplate::New(current, _GetEditorType));
|
||
result->Set(v8::String::NewFromUtf8(current, "CheckNextChange"), v8::FunctionTemplate::New(current, _CheckNextChange));
|
||
|
||
result->Set(v8::String::NewFromUtf8(current, "GetCountChanges"), v8::FunctionTemplate::New(current, _GetChangesCount));
|
||
result->Set(v8::String::NewFromUtf8(current, "GetChangesFile"), v8::FunctionTemplate::New(current, _GetChangesFile));
|
||
|
||
result->Set(v8::String::NewFromUtf8(current, "Save_AllocNative"), v8::FunctionTemplate::New(current, _Save_AllocNative));
|
||
result->Set(v8::String::NewFromUtf8(current, "Save_ReAllocNative"), v8::FunctionTemplate::New(current, _Save_ReAllocNative));
|
||
result->Set(v8::String::NewFromUtf8(current, "Save_End"), v8::FunctionTemplate::New(current, _Save_End));
|
||
|
||
result->Set(v8::String::NewFromUtf8(current, "ConsoleLog"), v8::FunctionTemplate::New(current, _ConsoleLog));
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HandleScope <20> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" HandleScope - handle_scope
|
||
|
||
//return handle_scope.Close(result);
|
||
return result;
|
||
}
|
||
// --------------------------
|
||
|
||
// create work with arraytypes
|
||
class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator
|
||
{
|
||
public:
|
||
virtual void* Allocate(size_t length)
|
||
{
|
||
void* ret = malloc(length);
|
||
memset(ret, 0, length);
|
||
return ret;
|
||
}
|
||
virtual void* AllocateUninitialized(size_t length)
|
||
{
|
||
return malloc(length);
|
||
}
|
||
virtual void Free(void* data, size_t length)
|
||
{
|
||
free(data);
|
||
}
|
||
};
|
||
|
||
static void enableTypedArrays()
|
||
{
|
||
v8::V8::SetArrayBufferAllocator(new MallocArrayBufferAllocator());
|
||
}
|
||
|
||
enum CommandType
|
||
{
|
||
ctPenXML = 0,
|
||
ctPenColor = 1,
|
||
ctPenAlpha = 2,
|
||
ctPenSize = 3,
|
||
ctPenDashStyle = 4,
|
||
ctPenLineStartCap = 5,
|
||
ctPenLineEndCap = 6,
|
||
ctPenLineJoin = 7,
|
||
ctPenDashPatern = 8,
|
||
ctPenDashPatternCount = 9,
|
||
ctPenDashOffset = 10,
|
||
ctPenAlign = 11,
|
||
ctPenMiterLimit = 12,
|
||
|
||
// brush
|
||
ctBrushXML = 20,
|
||
ctBrushType = 21,
|
||
ctBrushColor1 = 22,
|
||
ctBrushColor2 = 23,
|
||
ctBrushAlpha1 = 24,
|
||
ctBrushAlpha2 = 25,
|
||
ctBrushTexturePath = 26,
|
||
ctBrushTextureAlpha = 27,
|
||
ctBrushTextureMode = 28,
|
||
ctBrushRectable = 29,
|
||
ctBrushRectableEnabled = 30,
|
||
ctBrushGradient = 31,
|
||
|
||
// font
|
||
ctFontXML = 40,
|
||
ctFontName = 41,
|
||
ctFontSize = 42,
|
||
ctFontStyle = 43,
|
||
ctFontPath = 44,
|
||
ctFontGID = 45,
|
||
ctFontCharSpace = 46,
|
||
|
||
// shadow
|
||
ctShadowXML = 50,
|
||
ctShadowVisible = 51,
|
||
ctShadowDistanceX = 52,
|
||
ctShadowDistanceY = 53,
|
||
ctShadowBlurSize = 54,
|
||
ctShadowColor = 55,
|
||
ctShadowAlpha = 56,
|
||
|
||
// edge
|
||
ctEdgeXML = 70,
|
||
ctEdgeVisible = 71,
|
||
ctEdgeDistance = 72,
|
||
ctEdgeColor = 73,
|
||
ctEdgeAlpha = 74,
|
||
|
||
// text
|
||
ctDrawText = 80,
|
||
ctDrawTextEx = 81,
|
||
|
||
// pathcommands
|
||
ctPathCommandMoveTo = 91,
|
||
ctPathCommandLineTo = 92,
|
||
ctPathCommandLinesTo = 93,
|
||
ctPathCommandCurveTo = 94,
|
||
ctPathCommandCurvesTo = 95,
|
||
ctPathCommandArcTo = 96,
|
||
ctPathCommandClose = 97,
|
||
ctPathCommandEnd = 98,
|
||
ctDrawPath = 99,
|
||
ctPathCommandStart = 100,
|
||
ctPathCommandGetCurrentPoint = 101,
|
||
ctPathCommandText = 102,
|
||
ctPathCommandTextEx = 103,
|
||
|
||
// image
|
||
ctDrawImage = 110,
|
||
ctDrawImageFromFile = 111,
|
||
|
||
ctSetParams = 120,
|
||
|
||
ctBeginCommand = 121,
|
||
ctEndCommand = 122,
|
||
|
||
ctSetTransform = 130,
|
||
ctResetTransform = 131,
|
||
|
||
ctClipMode = 140,
|
||
|
||
ctCommandLong1 = 150,
|
||
ctCommandDouble1 = 151,
|
||
ctCommandString1 = 152,
|
||
ctCommandLong2 = 153,
|
||
ctCommandDouble2 = 154,
|
||
ctCommandString2 = 155,
|
||
|
||
ctPageWidth = 200,
|
||
ctPageHeight = 201,
|
||
|
||
ctPageStart = 202,
|
||
ctPageEnd = 203,
|
||
|
||
ctError = 255
|
||
};
|
||
|
||
class CChangesWorker
|
||
{
|
||
private:
|
||
BYTE* m_pData;
|
||
BYTE* m_pDataCur;
|
||
int m_nLen;
|
||
|
||
int m_nMaxUnionSize = 100 * 1024 * 1024; // 100Mb
|
||
v8::Local<v8::ArrayBuffer> m_oArrayBuffer;
|
||
|
||
int m_nFileType; // 0 - docx; 1 - excel
|
||
|
||
public:
|
||
CChangesWorker()
|
||
{
|
||
m_pData = NULL;
|
||
m_pDataCur = m_pData;
|
||
m_nLen = 0;
|
||
|
||
m_nFileType = 0;
|
||
}
|
||
~CChangesWorker()
|
||
{
|
||
if (NULL != m_pData)
|
||
delete[] m_pData;
|
||
}
|
||
|
||
void SetFormatChanges(const int& nFileType)
|
||
{
|
||
m_nFileType = nFileType;
|
||
}
|
||
|
||
public:
|
||
|
||
void CheckFiles(CAtlArray<CString>& oFiles)
|
||
{
|
||
int nMax = 0;
|
||
int nLen = 0;
|
||
|
||
int nCount = (int)oFiles.GetCount();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
|
||
int nSize = (int)oFile.GetFileSize();
|
||
|
||
if (nMax < nSize)
|
||
nMax = nSize;
|
||
|
||
nLen += nSize;
|
||
oFile.CloseFile();
|
||
}
|
||
|
||
if (nLen <= m_nMaxUnionSize)
|
||
{
|
||
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
m_nLen = nLen + 4;
|
||
}
|
||
else
|
||
{
|
||
m_nLen = nMax + 4;
|
||
if (m_nLen < m_nMaxUnionSize)
|
||
m_nLen = m_nMaxUnionSize;
|
||
}
|
||
|
||
m_pData = new BYTE[m_nLen];
|
||
m_pDataCur = m_pData;
|
||
|
||
m_oArrayBuffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)m_pData, (size_t)m_nLen);
|
||
}
|
||
|
||
inline int Open(CAtlArray<CString>& oFiles, int nStart)
|
||
{
|
||
return Open_excel(oFiles, nStart);
|
||
}
|
||
|
||
int Open_docx(CAtlArray<CString>& oFiles, int nStart)
|
||
{
|
||
m_pDataCur = m_pData;
|
||
m_pDataCur += 4;
|
||
int nCountData = 0;
|
||
|
||
int nCount = oFiles.GetCount();
|
||
int nLenCurrect = 0;
|
||
int i = nStart;
|
||
for (; i < nCount; i++)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
|
||
int nLen = (int)oFile.GetFileSize();
|
||
nLenCurrect += nLen;
|
||
|
||
if (nLenCurrect > m_nLen)
|
||
break;
|
||
|
||
char* pData = new char[nLen];
|
||
|
||
oFile.ReadFile((BYTE*)pData, nLen);
|
||
|
||
// parse data
|
||
int nCur = 0;
|
||
while (nCur < nLen)
|
||
{
|
||
// Id
|
||
skip_name(pData, nCur, nLen);
|
||
if (nCur >= nLen)
|
||
break;
|
||
|
||
int nId = read_int(pData, nCur, nLen);
|
||
*((int*)m_pDataCur) = nId;
|
||
m_pDataCur += 4;
|
||
|
||
// data
|
||
skip_name(pData, nCur, nLen);
|
||
skip_int2(pData, nCur, nLen);
|
||
|
||
read_base64(pData, nCur, nLen);
|
||
++nCur;
|
||
|
||
++nCountData;
|
||
}
|
||
|
||
delete[]pData;
|
||
}
|
||
|
||
*((int*)m_pData) = nCountData;
|
||
return i;
|
||
}
|
||
|
||
int Open_excel(CAtlArray<CString>& oFiles, int nStart)
|
||
{
|
||
m_pDataCur = m_pData;
|
||
m_pDataCur += 4;
|
||
int nCountData = 0;
|
||
|
||
int nCount = oFiles.GetCount();
|
||
int nLenCurrect = 0;
|
||
int i = nStart;
|
||
for (; i < nCount; i++)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
|
||
int nLen = (int)oFile.GetFileSize();
|
||
nLenCurrect += nLen;
|
||
|
||
if (nLenCurrect > m_nLen)
|
||
break;
|
||
|
||
char* pData = new char[nLen];
|
||
|
||
oFile.ReadFile((BYTE*)pData, nLen);
|
||
|
||
// parse data
|
||
int nCur = 0;
|
||
while (nCur < nLen)
|
||
{
|
||
skip_int2(pData, nCur, nLen);
|
||
|
||
if (nCur >= nLen)
|
||
break;
|
||
|
||
read_base64(pData, nCur, nLen);
|
||
++nCur;
|
||
|
||
++nCountData;
|
||
}
|
||
|
||
delete[]pData;
|
||
}
|
||
|
||
*((int*)m_pData) = nCountData;
|
||
return i;
|
||
}
|
||
|
||
v8::Local<v8::Uint8Array> GetData()
|
||
{
|
||
size_t len = (size_t)(m_pDataCur - m_pData);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(m_oArrayBuffer, 0, len);
|
||
return _array;
|
||
}
|
||
|
||
public:
|
||
void OpenFull(CAtlArray<CString>& oFiles)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int nCount = (int)oFiles.GetCount();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
m_nLen += (int)oFile.GetFileSize();
|
||
oFile.CloseFile();
|
||
}
|
||
|
||
m_pData = new BYTE[m_nLen];
|
||
m_pDataCur = m_pData;
|
||
|
||
m_pDataCur += 4;
|
||
int nCountData = 0;
|
||
|
||
for (int i = 0; i < nCount; i++)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
|
||
int nLen = (int)oFile.GetFileSize();
|
||
char* pData = new char[nLen];
|
||
|
||
oFile.ReadFile((BYTE*)pData, nLen);
|
||
|
||
// parse data
|
||
int nCur = 0;
|
||
while (nCur < nLen)
|
||
{
|
||
// Id
|
||
skip_name(pData, nCur, nLen);
|
||
if (nCur >= nLen)
|
||
break;
|
||
|
||
int nId = read_int(pData, nCur, nLen);
|
||
*((int*)m_pDataCur) = nId;
|
||
m_pDataCur += 4;
|
||
|
||
// data
|
||
skip_name(pData, nCur, nLen);
|
||
skip_int2(pData, nCur, nLen);
|
||
|
||
read_base64(pData, nCur, nLen);
|
||
++nCur;
|
||
|
||
++nCountData;
|
||
}
|
||
|
||
delete[]pData;
|
||
}
|
||
|
||
*((int*)m_pData) = nCountData;
|
||
}
|
||
|
||
void OpenFull_excel(CAtlArray<CString>& oFiles)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int nCount = (int)oFiles.GetCount();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
m_nLen += (int)oFile.GetFileSize();
|
||
oFile.CloseFile();
|
||
}
|
||
|
||
m_pData = new BYTE[m_nLen];
|
||
m_pDataCur = m_pData;
|
||
|
||
m_pDataCur += 4;
|
||
int nCountData = 0;
|
||
|
||
for (int i = 0; i < nCount; i++)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(oFiles[i]);
|
||
|
||
int nLen = (int)oFile.GetFileSize();
|
||
char* pData = new char[nLen];
|
||
|
||
oFile.ReadFile((BYTE*)pData, nLen);
|
||
|
||
// parse data
|
||
int nCur = 0;
|
||
while (nCur < nLen)
|
||
{
|
||
skip_int2(pData, nCur, nLen);
|
||
|
||
if (nCur >= nLen)
|
||
break;
|
||
|
||
read_base64(pData, nCur, nLen);
|
||
++nCur;
|
||
|
||
++nCountData;
|
||
}
|
||
|
||
delete[]pData;
|
||
}
|
||
|
||
*((int*)m_pData) = nCountData;
|
||
}
|
||
|
||
v8::Local<v8::Uint8Array> GetDataFull()
|
||
{
|
||
size_t len = (size_t)(m_pDataCur - m_pData);
|
||
v8::Local<v8::ArrayBuffer> _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)m_pData, len);
|
||
v8::Local<v8::Uint8Array> _array = v8::Uint8Array::New(_buffer, 0, len);
|
||
return _array;
|
||
}
|
||
|
||
int OpenNative(CString strFile)
|
||
{
|
||
CFile oFile;
|
||
oFile.OpenFile(strFile);
|
||
|
||
int nLen = (int)oFile.GetFileSize();
|
||
char* pData = new char[nLen];
|
||
|
||
oFile.ReadFile((BYTE*)pData, nLen);
|
||
|
||
int nCur = 0;
|
||
|
||
// DOCY
|
||
skip_int2(pData, nCur, nLen);
|
||
// v
|
||
skip_no_digit(pData, nCur, nLen);
|
||
int nVersion = read_int2(pData, nCur, nLen);
|
||
|
||
m_nLen = read_int2(pData, nCur, nLen);
|
||
|
||
m_pData = new BYTE[m_nLen];
|
||
m_pDataCur = m_pData;
|
||
|
||
read_base64_2(pData, nCur, nLen);
|
||
|
||
delete[]pData;
|
||
|
||
return nVersion;
|
||
}
|
||
|
||
__forceinline void skip_name(const char* data, int& cur, const int& len)
|
||
{
|
||
int nCount = 0;
|
||
while (cur < len)
|
||
{
|
||
if (data[cur] == '\"')
|
||
++nCount;
|
||
|
||
++cur;
|
||
|
||
if (3 == nCount)
|
||
break;
|
||
}
|
||
}
|
||
|
||
__forceinline int read_int(const char* data, int& cur, const int& len)
|
||
{
|
||
int res = 0;
|
||
while (cur < len)
|
||
{
|
||
if (data[cur] == '\"')
|
||
{
|
||
++cur;
|
||
break;
|
||
}
|
||
|
||
res *= 10;
|
||
res += (data[cur++] - '0');
|
||
}
|
||
|
||
return res;
|
||
}
|
||
__forceinline void skip_int2(const char* data, int& cur, const int& len)
|
||
{
|
||
while (cur < len)
|
||
{
|
||
if (data[cur++] == ';')
|
||
break;
|
||
}
|
||
}
|
||
__forceinline int read_int2(const char* data, int& cur, const int& len)
|
||
{
|
||
int res = 0;
|
||
while (cur < len)
|
||
{
|
||
if (data[cur] == ';')
|
||
{
|
||
++cur;
|
||
break;
|
||
}
|
||
|
||
res *= 10;
|
||
res += (data[cur++] - '0');
|
||
}
|
||
|
||
return res;
|
||
}
|
||
__forceinline void skip_no_digit(const char* data, int& cur, const int& len)
|
||
{
|
||
while (cur < len)
|
||
{
|
||
char _c = data[cur];
|
||
if (_c >= '0' && _c <= '9')
|
||
break;
|
||
++cur;
|
||
}
|
||
}
|
||
|
||
__forceinline void read_base64(const char* data, int& cur, const int& len)
|
||
{
|
||
Base64Decode(data, cur, len);
|
||
}
|
||
__forceinline void read_base64_2(const char* data, int& cur, const int& len)
|
||
{
|
||
Base64Decode2(data, cur, len);
|
||
}
|
||
|
||
private:
|
||
__forceinline int DecodeBase64Char(unsigned int ch)
|
||
{
|
||
// returns -1 if the character is invalid
|
||
// or should be skipped
|
||
// otherwise, returns the 6-bit code for the character
|
||
// from the encoding table
|
||
if (ch >= 'A' && ch <= 'Z')
|
||
return ch - 'A' + 0; // 0 range starts at 'A'
|
||
if (ch >= 'a' && ch <= 'z')
|
||
return ch - 'a' + 26; // 26 range starts at 'a'
|
||
if (ch >= '0' && ch <= '9')
|
||
return ch - '0' + 52; // 52 range starts at '0'
|
||
if (ch == '+')
|
||
return 62;
|
||
if (ch == '/')
|
||
return 63;
|
||
return -1;
|
||
}
|
||
|
||
void Base64Decode(const char* data, int& cur, const int& len)
|
||
{
|
||
// walk the source buffer
|
||
// each four character sequence is converted to 3 bytes
|
||
// CRLFs and =, and any characters not in the encoding table
|
||
// are skiped
|
||
|
||
BYTE* pDataLen = m_pDataCur;
|
||
m_pDataCur += 4;
|
||
|
||
int nWritten = 0;
|
||
while (cur < len && data[cur] != '\"')
|
||
{
|
||
DWORD dwCurr = 0;
|
||
int i;
|
||
int nBits = 0;
|
||
for (i = 0; i<4; i++)
|
||
{
|
||
if (data[cur] == '\"')
|
||
break;
|
||
int nCh = DecodeBase64Char(data[cur++]);
|
||
if (nCh == -1)
|
||
{
|
||
// skip this char
|
||
i--;
|
||
continue;
|
||
}
|
||
dwCurr <<= 6;
|
||
dwCurr |= nCh;
|
||
nBits += 6;
|
||
}
|
||
|
||
// dwCurr has the 3 bytes to write to the output buffer
|
||
// left to right
|
||
dwCurr <<= 24 - nBits;
|
||
for (i = 0; i<nBits / 8; i++)
|
||
{
|
||
*m_pDataCur = (BYTE)((dwCurr & 0x00ff0000) >> 16);
|
||
++m_pDataCur;
|
||
|
||
dwCurr <<= 8;
|
||
nWritten++;
|
||
}
|
||
|
||
}
|
||
|
||
*((int*)pDataLen) = nWritten;
|
||
}
|
||
|
||
void Base64Decode2(const char* data, int& cur, const int& len)
|
||
{
|
||
// walk the source buffer
|
||
// each four character sequence is converted to 3 bytes
|
||
// CRLFs and =, and any characters not in the encoding table
|
||
// are skiped
|
||
|
||
int nWritten = 0;
|
||
while (cur < len && data[cur] != '\"')
|
||
{
|
||
DWORD dwCurr = 0;
|
||
int i;
|
||
int nBits = 0;
|
||
for (i = 0; i<4; i++)
|
||
{
|
||
if (cur >= len)
|
||
break;
|
||
int nCh = DecodeBase64Char(data[cur++]);
|
||
if (nCh == -1)
|
||
{
|
||
// skip this char
|
||
i--;
|
||
continue;
|
||
}
|
||
dwCurr <<= 6;
|
||
dwCurr |= nCh;
|
||
nBits += 6;
|
||
}
|
||
|
||
// dwCurr has the 3 bytes to write to the output buffer
|
||
// left to right
|
||
dwCurr <<= 24 - nBits;
|
||
for (i = 0; i<nBits / 8; i++)
|
||
{
|
||
*m_pDataCur = (BYTE)((dwCurr & 0x00ff0000) >> 16);
|
||
++m_pDataCur;
|
||
|
||
dwCurr <<= 8;
|
||
nWritten++;
|
||
}
|
||
|
||
}
|
||
}
|
||
};
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|