Initial commit.
[pdfium.git] / fpdfsdk / src / javascript / JS_Value.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4  \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../include/javascript/JavaScript.h"\r
8 #include "../../include/javascript/JS_Define.h"\r
9 #include "../../include/javascript/JS_Object.h"\r
10 #include "../../include/javascript/JS_Value.h"\r
11 \r
12 /* ---------------------------- CJS_Value ---------------------------- */\r
13 \r
14 CJS_Value::CJS_Value(v8::Isolate* isolate) : m_isolate(isolate),m_eType(VT_unknown)\r
15 {\r
16 }\r
17 CJS_Value::CJS_Value(v8::Isolate* isolate, v8::Handle<v8::Value> pValue,FXJSVALUETYPE t) :m_isolate(isolate), m_pValue(pValue) , m_eType(t)\r
18 {\r
19 }\r
20 \r
21 CJS_Value::CJS_Value(v8::Isolate* isolate, const int &iValue):m_isolate(isolate)\r
22 {\r
23         operator =(iValue);\r
24 }\r
25 \r
26 CJS_Value::CJS_Value(v8::Isolate* isolate, const bool &bValue):m_isolate(isolate)\r
27 {\r
28         operator =(bValue);\r
29 }\r
30 \r
31 CJS_Value::CJS_Value(v8::Isolate* isolate, const float &fValue):m_isolate(isolate)\r
32 {\r
33         operator =(fValue);\r
34 }\r
35 \r
36 CJS_Value::CJS_Value(v8::Isolate* isolate, const double &dValue):m_isolate(isolate) \r
37 {\r
38         operator =(dValue);\r
39 }\r
40 \r
41 CJS_Value::CJS_Value(v8::Isolate* isolate, JSFXObject  pJsObj):m_isolate(isolate) \r
42 {\r
43         operator =(pJsObj);\r
44 }\r
45 \r
46 CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Object * pJsObj):m_isolate(isolate) \r
47 {\r
48         operator =(pJsObj);\r
49 }\r
50 \r
51 CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCWSTR pWstr):m_isolate(isolate) \r
52 {\r
53         operator =(pWstr);\r
54 }\r
55 \r
56 CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCSTR pStr):m_isolate(isolate) \r
57 {\r
58         operator = (pStr);\r
59 }\r
60 \r
61 CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Array& array):m_isolate(isolate) \r
62 {\r
63         operator = (array);\r
64 }\r
65 \r
66 CJS_Value::~CJS_Value()\r
67 {\r
68 }\r
69 \r
70 void CJS_Value::Attach(v8::Handle<v8::Value> pValue,FXJSVALUETYPE t)\r
71 {\r
72         m_pValue = pValue;\r
73         m_eType = t;\r
74 }\r
75 \r
76 void CJS_Value::Attach(CJS_Value *pValue)\r
77 {\r
78         if (pValue)\r
79                 Attach(pValue->ToJSValue(),pValue->GetType());\r
80 }\r
81 \r
82 void CJS_Value::Detach()\r
83 {\r
84         m_pValue = v8::Handle<v8::Value>();\r
85         m_eType = VT_unknown;\r
86 }\r
87 \r
88 /* ---------------------------------------------------------------------------------------- */\r
89 \r
90 CJS_Value::operator int() const\r
91 {\r
92 \r
93         return JS_ToInt32(m_pValue);\r
94 \r
95 }\r
96 \r
97 CJS_Value::operator bool() const\r
98 {\r
99 \r
100         return JS_ToBoolean(m_pValue);\r
101         \r
102 }\r
103 \r
104 CJS_Value::operator double() const\r
105 {\r
106 \r
107         return JS_ToNumber(m_pValue);\r
108         \r
109 }\r
110 \r
111 CJS_Value::operator float() const\r
112 {\r
113 \r
114         return (float)JS_ToNumber(m_pValue);\r
115 \r
116 }\r
117 \r
118 CJS_Value::operator CJS_Object *() const\r
119 {\r
120 \r
121         v8::Handle<v8::Object>  pObj = JS_ToObject(m_pValue);\r
122         return (CJS_Object*)JS_GetPrivate(m_isolate, pObj);\r
123 }\r
124 \r
125 CJS_Value::operator v8::Handle<v8::Object>() const\r
126 {\r
127         return JS_ToObject(m_pValue);\r
128 }\r
129 \r
130 CJS_Value::operator CFX_WideString() const\r
131 {\r
132         return JS_ToString(m_pValue);\r
133 }\r
134 \r
135 CJS_Value::operator CFX_ByteString() const\r
136 {\r
137         return CFX_ByteString::FromUnicode(operator CFX_WideString());\r
138 }\r
139 \r
140 v8::Handle<v8::Value> CJS_Value::ToJSValue()\r
141 {\r
142         return m_pValue;\r
143 }\r
144 \r
145 \r
146 CJS_Value::operator v8::Handle<v8::Array>() const\r
147 {\r
148         if (IsArrayObject())\r
149                 return v8::Handle<v8::Array>::Cast(JS_ToObject(m_pValue));\r
150         return v8::Handle<v8::Array>();\r
151 }\r
152 \r
153 /* ---------------------------------------------------------------------------------------- */\r
154 \r
155 void CJS_Value::operator =(int iValue)\r
156 {\r
157         m_pValue = JS_NewNumber(m_isolate, iValue);\r
158 \r
159         m_eType = VT_number;\r
160 }\r
161 \r
162 void CJS_Value::operator =(bool bValue)\r
163 {\r
164         m_pValue = JS_NewBoolean(m_isolate, bValue);\r
165 \r
166         m_eType = VT_boolean;\r
167 }\r
168 \r
169 void CJS_Value::operator =(double dValue)\r
170 {\r
171         m_pValue = JS_NewNumber(m_isolate,dValue);\r
172 \r
173         m_eType = VT_number;\r
174 }\r
175 \r
176 void CJS_Value::operator = (float fValue)\r
177 {\r
178         m_pValue = JS_NewNumber(m_isolate,fValue);\r
179         m_eType = VT_number;\r
180 }\r
181 \r
182 void CJS_Value::operator =(v8::Handle<v8::Object> pObj)\r
183 {\r
184 \r
185         m_pValue = JS_NewObject(m_isolate,pObj);\r
186 \r
187         m_eType = VT_fxobject;\r
188 }\r
189 \r
190 void CJS_Value::operator =(CJS_Object * pObj)\r
191 {\r
192         if (pObj)\r
193                 operator = ((JSFXObject)*pObj);\r
194 }\r
195 \r
196 void CJS_Value::operator =(FX_LPCWSTR pWstr)\r
197 {\r
198         m_pValue = JS_NewString(m_isolate,(wchar_t *)pWstr);\r
199 \r
200         m_eType = VT_string;\r
201 }\r
202 \r
203 void CJS_Value::SetNull()\r
204 {\r
205         m_pValue = JS_NewNull();\r
206 \r
207         m_eType = VT_null;\r
208 }\r
209 \r
210 void CJS_Value::operator = (FX_LPCSTR pStr)\r
211 {       \r
212         operator = (CFX_WideString::FromLocal(pStr));\r
213 }\r
214 \r
215 void CJS_Value::operator = (CJS_Array & array)\r
216 {\r
217         m_pValue = JS_NewObject2(m_isolate,(v8::Handle<v8::Array>)array);\r
218 \r
219         m_eType = VT_object;\r
220 }\r
221 \r
222 void CJS_Value::operator = (CJS_Date & date)\r
223 {\r
224         m_pValue = JS_NewDate(m_isolate, (double)date);\r
225 \r
226         m_eType = VT_date;\r
227 }\r
228 \r
229 void CJS_Value::operator = (CJS_Value value)\r
230 {\r
231         m_pValue = value.ToJSValue();\r
232 \r
233         m_eType = value.m_eType;\r
234 }\r
235 \r
236 /* ---------------------------------------------------------------------------------------- */\r
237 \r
238 FXJSVALUETYPE CJS_Value::GetType() const\r
239 {\r
240         if(m_pValue.IsEmpty()) return VT_unknown;\r
241         if(m_pValue->IsString()) return VT_string;\r
242         if(m_pValue->IsNumber()) return VT_number;\r
243         if(m_pValue->IsBoolean()) return VT_boolean;\r
244         if(m_pValue->IsDate()) return VT_date;\r
245         if(m_pValue->IsObject()) return VT_object;\r
246         if(m_pValue->IsNull()) return VT_null;\r
247         if(m_pValue->IsUndefined()) return VT_undefined;\r
248         return VT_unknown;\r
249 }\r
250 \r
251 FX_BOOL CJS_Value::IsArrayObject() const \r
252 {\r
253         if(m_pValue.IsEmpty()) return FALSE;\r
254         return m_pValue->IsArray();\r
255 }\r
256 \r
257 FX_BOOL CJS_Value::IsDateObject() const\r
258 {\r
259         if(m_pValue.IsEmpty()) return FALSE;\r
260         return m_pValue->IsDate();\r
261 }\r
262 \r
263 //CJS_Value::operator CJS_Array()\r
264 FX_BOOL CJS_Value::ConvertToArray(CJS_Array &array) const\r
265 {\r
266         if (IsArrayObject())\r
267         {\r
268                 array.Attach(JS_ToArray(m_pValue));\r
269                 return TRUE;\r
270         }\r
271 \r
272         return FALSE;\r
273 }\r
274 \r
275 FX_BOOL CJS_Value::ConvertToDate(CJS_Date &date) const\r
276 {\r
277 //      if (GetType() == VT_date)\r
278 //      {\r
279 //              date = (double)(*this);\r
280 //              return TRUE;\r
281 //      }\r
282 \r
283         if (IsDateObject())\r
284         {\r
285                 date.Attach(m_pValue);\r
286                 return TRUE;\r
287         }\r
288 \r
289         return FALSE;   \r
290 }\r
291 \r
292 /* ---------------------------- CJS_PropValue ---------------------------- */\r
293 \r
294 CJS_PropValue::CJS_PropValue(const CJS_Value &value) : \r
295         CJS_Value(value),\r
296         m_bIsSetting(0)\r
297 {\r
298 }\r
299 \r
300 CJS_PropValue::CJS_PropValue(v8::Isolate* isolate) : CJS_Value(isolate),\r
301                                  m_bIsSetting(0)\r
302 {\r
303 }\r
304 \r
305 CJS_PropValue::~CJS_PropValue()\r
306 {\r
307 }\r
308 \r
309 FX_BOOL CJS_PropValue::IsSetting()\r
310 {\r
311         return m_bIsSetting;\r
312 }\r
313 \r
314 FX_BOOL CJS_PropValue::IsGetting()\r
315 {\r
316         return !m_bIsSetting;\r
317 }\r
318 \r
319 void CJS_PropValue::operator <<(int iValue)\r
320 {\r
321         ASSERT(!m_bIsSetting);\r
322         CJS_Value::operator =(iValue);\r
323 }\r
324 \r
325 void CJS_PropValue::operator >>(int & iValue) const\r
326 {\r
327         ASSERT(m_bIsSetting);\r
328         iValue = CJS_Value::operator int();\r
329 }\r
330 \r
331 \r
332 void CJS_PropValue::operator <<(bool bValue)\r
333 {\r
334         ASSERT(!m_bIsSetting);\r
335         CJS_Value::operator =(bValue);\r
336 }\r
337 \r
338 void CJS_PropValue::operator >>(bool &bValue) const\r
339 {\r
340         ASSERT(m_bIsSetting);\r
341         bValue = CJS_Value::operator bool();\r
342 \r
343 }\r
344 \r
345 void CJS_PropValue::operator <<(double dValue)\r
346 {\r
347         ASSERT(!m_bIsSetting);\r
348         CJS_Value::operator =(dValue);\r
349 }\r
350 \r
351 void CJS_PropValue::operator >>(double &dValue) const\r
352 {\r
353         ASSERT(m_bIsSetting);\r
354         dValue = CJS_Value::operator double();\r
355 }\r
356 \r
357 void CJS_PropValue::operator <<(CJS_Object *pObj)\r
358 {\r
359         ASSERT(!m_bIsSetting);\r
360         CJS_Value::operator = (pObj);\r
361 }\r
362 \r
363 void CJS_PropValue::operator >>(CJS_Object *&ppObj) const\r
364 {\r
365         ASSERT(m_bIsSetting);\r
366         ppObj = CJS_Value::operator CJS_Object *();\r
367 }\r
368 \r
369 void CJS_PropValue::operator<<(JSFXObject pObj)\r
370 {\r
371         ASSERT(!m_bIsSetting);\r
372         CJS_Value::operator = (pObj);\r
373 }\r
374 \r
375 void CJS_PropValue::operator>>(JSFXObject &ppObj) const\r
376 {\r
377         ASSERT(m_bIsSetting);\r
378         ppObj = CJS_Value::operator JSFXObject ();\r
379 }\r
380 \r
381 \r
382 void CJS_PropValue::StartSetting()\r
383 {\r
384         m_bIsSetting = 1;\r
385 }\r
386 \r
387 void CJS_PropValue::StartGetting()\r
388 {\r
389         m_bIsSetting = 0;\r
390 }\r
391 void CJS_PropValue::operator <<(CFX_ByteString string)\r
392 {\r
393         ASSERT(!m_bIsSetting);\r
394         CJS_Value::operator =((FX_LPCSTR)string);\r
395 }\r
396 \r
397 void CJS_PropValue::operator >>(CFX_ByteString &string) const\r
398 {\r
399         ASSERT(m_bIsSetting);\r
400         string = CJS_Value::operator CFX_ByteString();\r
401 }\r
402 \r
403 void CJS_PropValue::operator <<(FX_LPCWSTR c_string)\r
404 {\r
405         ASSERT(!m_bIsSetting);\r
406         CJS_Value::operator =(c_string);\r
407 }\r
408 \r
409 void CJS_PropValue::operator >>(CFX_WideString &wide_string) const\r
410 {\r
411         ASSERT(m_bIsSetting);\r
412         wide_string = CJS_Value::operator CFX_WideString();\r
413 }\r
414 \r
415 void CJS_PropValue::operator <<(CFX_WideString wide_string)\r
416 {\r
417         ASSERT(!m_bIsSetting);\r
418         CJS_Value::operator = (wide_string);\r
419 }\r
420 \r
421 void CJS_PropValue::operator >>(CJS_Array &array) const\r
422 {\r
423         ASSERT(m_bIsSetting);\r
424         ConvertToArray(array);\r
425 }\r
426 \r
427 void CJS_PropValue::operator <<(CJS_Array &array)\r
428 {\r
429         ASSERT(!m_bIsSetting);\r
430         CJS_Value::operator=(array);\r
431 }\r
432 \r
433 void CJS_PropValue::operator>>(CJS_Date &date) const\r
434 {\r
435         ASSERT(m_bIsSetting);\r
436         ConvertToDate(date);\r
437 }\r
438 \r
439 void CJS_PropValue::operator<<(CJS_Date &date)\r
440 {\r
441         ASSERT(!m_bIsSetting);\r
442         CJS_Value::operator=(date);\r
443 }\r
444 \r
445 CJS_PropValue::operator v8::Handle<v8::Value>() const\r
446 {\r
447         return m_pValue;\r
448 }\r
449 \r
450 /* ======================================== CJS_Array ========================================= */\r
451 CJS_Array::CJS_Array(v8::Isolate* isolate):m_isolate(isolate)\r
452 {\r
453 }\r
454 \r
455 CJS_Array::~CJS_Array()\r
456 {               \r
457 }\r
458 \r
459 void CJS_Array::Attach(v8::Handle<v8::Array> pArray)\r
460 {\r
461         m_pArray = pArray;\r
462 }\r
463 \r
464 FX_BOOL CJS_Array::IsAttached()\r
465 {\r
466         return FALSE;\r
467 }\r
468 \r
469 void CJS_Array::GetElement(unsigned index,CJS_Value &value)\r
470 {\r
471         if (m_pArray.IsEmpty())\r
472                 return;\r
473         v8::Handle<v8::Value>  p = JS_GetArrayElemnet(m_pArray,index);\r
474         value.Attach(p,VT_object);\r
475 }\r
476 \r
477 void CJS_Array::SetElement(unsigned index,CJS_Value value)\r
478 {\r
479         if (m_pArray.IsEmpty())\r
480                 m_pArray = JS_NewArray(m_isolate);\r
481 \r
482         JS_PutArrayElement(m_pArray,index,value.ToJSValue(),value.GetType());\r
483 }\r
484 \r
485 int CJS_Array::GetLength()\r
486 {\r
487         if (m_pArray.IsEmpty())\r
488                 return 0;\r
489         return JS_GetArrayLength(m_pArray);\r
490 }\r
491 \r
492 CJS_Array:: operator v8::Handle<v8::Array>()\r
493 {\r
494         if (m_pArray.IsEmpty())\r
495                 m_pArray = JS_NewArray(m_isolate);\r
496 \r
497         return m_pArray;\r
498 }\r
499 \r
500 /* ======================================== CJS_Date ========================================= */\r
501 \r
502 CJS_Date::CJS_Date(v8::Isolate* isolate) :m_isolate(isolate)\r
503 {\r
504 }\r
505 \r
506 CJS_Date::CJS_Date(v8::Isolate* isolate,double dMsec_time) \r
507 {\r
508         m_isolate = isolate;\r
509         m_pDate = JS_NewDate(isolate,dMsec_time);               \r
510 }\r
511 \r
512 CJS_Date::CJS_Date(v8::Isolate* isolate,int year, int mon, int day,int hour, int min, int sec) \r
513 {\r
514         m_isolate = isolate;\r
515         m_pDate = JS_NewDate(isolate,MakeDate(year,mon,day,hour,min,sec,0));    \r
516 }\r
517 \r
518 double CJS_Date::MakeDate(int year, int mon, int day,int hour, int min, int sec,int ms)\r
519 {\r
520         return JS_MakeDate(JS_MakeDay(year,mon,day), JS_MakeTime(hour,min,sec,ms));\r
521 }\r
522 \r
523 CJS_Date::~CJS_Date()\r
524 {\r
525 }\r
526 \r
527 FX_BOOL CJS_Date::IsValidDate()\r
528 {\r
529         if(m_pDate.IsEmpty()) return FALSE;\r
530         return !JS_PortIsNan(JS_ToNumber(m_pDate));\r
531 }\r
532 \r
533 void CJS_Date::Attach(v8::Handle<v8::Value> pDate)\r
534 {\r
535         m_pDate = pDate;\r
536 }\r
537 \r
538 int CJS_Date::GetYear()\r
539 {\r
540         if (IsValidDate())\r
541                 return JS_GetYearFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
542 \r
543         return 0;\r
544 }\r
545 \r
546 void CJS_Date::SetYear(int iYear)\r
547 {\r
548         double date = MakeDate(iYear,GetMonth(),GetDay(),GetHours(),GetMinutes(),GetSeconds(),0);\r
549         JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date));\r
550 }\r
551 \r
552 int CJS_Date::GetMonth()\r
553 {\r
554         if (IsValidDate())\r
555                 return JS_GetMonthFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
556 \r
557         return 0;\r
558 }\r
559 \r
560 void CJS_Date::SetMonth(int iMonth)\r
561 {\r
562 \r
563         double date = MakeDate(GetYear(),iMonth,GetDay(),GetHours(),GetMinutes(),GetSeconds(),0);\r
564         JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date));\r
565 \r
566 }\r
567 \r
568 int CJS_Date::GetDay()\r
569 {\r
570         if (IsValidDate())\r
571                 return JS_GetDayFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
572 \r
573         return 0;\r
574 }\r
575 \r
576 void CJS_Date::SetDay(int iDay)\r
577 {\r
578 \r
579         double date = MakeDate(GetYear(),GetMonth(),iDay,GetHours(),GetMinutes(),GetSeconds(),0);\r
580         JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));\r
581 \r
582 }\r
583 \r
584 int CJS_Date::GetHours()\r
585 {\r
586         if (IsValidDate())\r
587                 return JS_GetHourFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
588 \r
589         return 0;\r
590 }\r
591 \r
592 void CJS_Date::SetHours(int iHours)\r
593 {\r
594         double date = MakeDate(GetYear(),GetMonth(),GetDay(),iHours,GetMinutes(),GetSeconds(),0);\r
595         JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));\r
596 }\r
597 \r
598 int CJS_Date::GetMinutes()\r
599 {\r
600         if (IsValidDate())\r
601                 return JS_GetMinFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
602 \r
603         return 0;\r
604 }\r
605 \r
606 void CJS_Date::SetMinutes(int minutes)\r
607 {\r
608         double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),minutes,GetSeconds(),0);\r
609         JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));\r
610 }\r
611 \r
612 int CJS_Date::GetSeconds()\r
613 {\r
614         if (IsValidDate())\r
615                 return JS_GetSecFromTime(JS_LocalTime(JS_ToNumber(m_pDate)));\r
616 \r
617         return 0;\r
618 }\r
619 \r
620 void CJS_Date::SetSeconds(int seconds)\r
621 {\r
622         double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),GetMinutes(),seconds,0);\r
623         JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));\r
624 }\r
625 \r
626 CJS_Date::operator v8::Handle<v8::Value>()\r
627 {\r
628         return m_pDate;\r
629 }\r
630 \r
631 CJS_Date::operator double() const\r
632 {\r
633         if(m_pDate.IsEmpty())\r
634                 return 0.0;\r
635         return JS_ToNumber(m_pDate);\r
636 }\r
637 \r
638 CFX_WideString CJS_Date::ToString() const\r
639 {\r
640         if(m_pDate.IsEmpty())\r
641                 return L"";\r
642         return JS_ToString(m_pDate);\r
643 }\r