1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/src/foxitlib.h" 8 #include "xfa/src/fxfa/src/common/xfa_utils.h" 9 #include "xfa/src/fxfa/src/common/xfa_object.h" 10 #include "xfa/src/fxfa/src/common/xfa_document.h" 11 #include "xfa/src/fxfa/src/common/xfa_parser.h" 12 #include "xfa/src/fxfa/src/common/xfa_script.h" 13 #include "xfa/src/fxfa/src/common/xfa_docdata.h" 14 #include "xfa/src/fxfa/src/common/xfa_doclayout.h" 15 #include "xfa/src/fxfa/src/common/xfa_localemgr.h" 16 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" 17 #include "xfa_basic_imp.h" 18 extern const XFA_PACKETINFO g_XFAPacketData[]; 19 extern const int32_t g_iXFAPacketCount; 20 extern const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[]; 21 extern const int32_t g_iXFAEnumCount; 22 extern const XFA_ATTRIBUTEINFO g_XFAAttributeData[]; 23 extern const int32_t g_iXFAAttributeCount; 24 extern const XFA_ELEMENTINFO g_XFAElementData[]; 25 extern const int32_t g_iXFAElementCount; 26 extern const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[]; 27 extern const FX_WORD g_XFAElementChildrenData[]; 28 extern const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[]; 29 extern const uint8_t g_XFAElementAttributeData[]; 30 extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[]; 31 extern const int32_t g_iXFANotsureCount; 32 extern const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[]; 33 extern const XFA_PROPERTY g_XFAElementPropertyData[]; 34 extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[]; 35 extern const XFA_METHODINFO g_SomMethodData[]; 36 extern const int32_t g_iSomMethodCount; 37 extern const XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[]; 38 extern const int32_t g_iSomAttributeCount; 39 XFA_LPCPACKETINFO XFA_GetPacketByName(const CFX_WideStringC& wsName) { 40 int32_t iLength = wsName.GetLength(); 41 if (iLength == 0) { 42 return NULL; 43 } 44 uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength); 45 int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1; 46 do { 47 int32_t iMid = (iStart + iEnd) / 2; 48 XFA_LPCPACKETINFO pInfo = g_XFAPacketData + iMid; 49 if (uHash == pInfo->uHash) { 50 return pInfo; 51 } else if (uHash < pInfo->uHash) { 52 iEnd = iMid - 1; 53 } else { 54 iStart = iMid + 1; 55 } 56 } while (iStart <= iEnd); 57 return NULL; 58 } 59 XFA_LPCPACKETINFO XFA_GetPacketByID(FX_DWORD dwPacket) { 60 int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1; 61 do { 62 int32_t iMid = (iStart + iEnd) / 2; 63 FX_DWORD dwFind = (g_XFAPacketData + iMid)->eName; 64 if (dwPacket == dwFind) { 65 return g_XFAPacketData + iMid; 66 } else if (dwPacket < dwFind) { 67 iEnd = iMid - 1; 68 } else { 69 iStart = iMid + 1; 70 } 71 } while (iStart <= iEnd); 72 return NULL; 73 } 74 XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByName( 75 const CFX_WideStringC& wsName) { 76 int32_t iLength = wsName.GetLength(); 77 if (iLength == 0) { 78 return NULL; 79 } 80 uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength); 81 int32_t iStart = 0, iEnd = g_iXFAEnumCount - 1; 82 do { 83 int32_t iMid = (iStart + iEnd) / 2; 84 XFA_LPCATTRIBUTEENUMINFO pInfo = g_XFAEnumData + iMid; 85 if (uHash == pInfo->uHash) { 86 return pInfo; 87 } else if (uHash < pInfo->uHash) { 88 iEnd = iMid - 1; 89 } else { 90 iStart = iMid + 1; 91 } 92 } while (iStart <= iEnd); 93 return NULL; 94 } 95 XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) { 96 return g_XFAEnumData + eName; 97 } 98 int32_t XFA_GetAttributeCount() { 99 return g_iXFAAttributeCount; 100 } 101 XFA_LPCATTRIBUTEINFO XFA_GetAttributeByName(const CFX_WideStringC& wsName) { 102 int32_t iLength = wsName.GetLength(); 103 if (iLength == 0) { 104 return NULL; 105 } 106 uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength); 107 int32_t iStart = 0, iEnd = g_iXFAAttributeCount - 1; 108 do { 109 int32_t iMid = (iStart + iEnd) / 2; 110 XFA_LPCATTRIBUTEINFO pInfo = g_XFAAttributeData + iMid; 111 if (uHash == pInfo->uHash) { 112 return pInfo; 113 } else if (uHash < pInfo->uHash) { 114 iEnd = iMid - 1; 115 } else { 116 iStart = iMid + 1; 117 } 118 } while (iStart <= iEnd); 119 return NULL; 120 } 121 XFA_LPCATTRIBUTEINFO XFA_GetAttributeByID(XFA_ATTRIBUTE eName) { 122 return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName) : NULL; 123 } 124 FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue, 125 XFA_ELEMENT eElement, 126 XFA_ATTRIBUTE eAttribute, 127 XFA_ATTRIBUTETYPE eType, 128 FX_DWORD dwPacket) { 129 XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute); 130 if (pInfo == NULL) { 131 return FALSE; 132 } 133 if (dwPacket && (dwPacket & pInfo->dwPackets) == 0) { 134 return FALSE; 135 } 136 if (pInfo->eType == eType) { 137 pValue = pInfo->pDefValue; 138 return TRUE; 139 } else if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) { 140 XFA_LPCNOTSUREATTRIBUTE pAttr = 141 XFA_GetNotsureAttribute(eElement, eAttribute, eType); 142 if (pAttr) { 143 pValue = pAttr->pValue; 144 return TRUE; 145 } 146 } 147 return FALSE; 148 } 149 XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement, 150 XFA_ATTRIBUTE eAttribute, 151 FX_DWORD dwPacket) { 152 void* pValue; 153 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, 154 XFA_ATTRIBUTETYPE_Enum, dwPacket)) { 155 return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue; 156 } 157 return XFA_ATTRIBUTEENUM_Unknown; 158 } 159 CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement, 160 XFA_ATTRIBUTE eAttribute, 161 FX_DWORD dwPacket) { 162 void* pValue; 163 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, 164 XFA_ATTRIBUTETYPE_Cdata, dwPacket)) { 165 return (const FX_WCHAR*)pValue; 166 } 167 return NULL; 168 } 169 FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement, 170 XFA_ATTRIBUTE eAttribute, 171 FX_DWORD dwPacket) { 172 void* pValue; 173 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, 174 XFA_ATTRIBUTETYPE_Boolean, dwPacket)) { 175 return (FX_BOOL)(uintptr_t)pValue; 176 } 177 return FALSE; 178 } 179 int32_t XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement, 180 XFA_ATTRIBUTE eAttribute, 181 FX_DWORD dwPacket) { 182 void* pValue; 183 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, 184 XFA_ATTRIBUTETYPE_Integer, dwPacket)) { 185 return (int32_t)(uintptr_t)pValue; 186 } 187 return 0; 188 } 189 CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement, 190 XFA_ATTRIBUTE eAttribute, 191 FX_DWORD dwPacket) { 192 void* pValue; 193 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, 194 XFA_ATTRIBUTETYPE_Measure, dwPacket)) { 195 return *(CXFA_Measurement*)pValue; 196 } 197 return CXFA_Measurement(); 198 } 199 int32_t XFA_GetElementCount() { 200 return g_iXFAElementCount; 201 } 202 XFA_LPCELEMENTINFO XFA_GetElementByName(const CFX_WideStringC& wsName) { 203 int32_t iLength = wsName.GetLength(); 204 if (iLength == 0) { 205 return NULL; 206 } 207 uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength); 208 int32_t iStart = 0, iEnd = g_iXFAElementCount - 1; 209 do { 210 int32_t iMid = (iStart + iEnd) / 2; 211 XFA_LPCELEMENTINFO pInfo = g_XFAElementData + iMid; 212 if (uHash == pInfo->uHash) { 213 return pInfo; 214 } else if (uHash < pInfo->uHash) { 215 iEnd = iMid - 1; 216 } else { 217 iStart = iMid + 1; 218 } 219 } while (iStart <= iEnd); 220 return NULL; 221 } 222 XFA_LPCELEMENTINFO XFA_GetElementByID(XFA_ELEMENT eName) { 223 return (eName < g_iXFAElementCount) ? (g_XFAElementData + eName) : NULL; 224 } 225 const FX_WORD* XFA_GetElementChildren(XFA_ELEMENT eElement, int32_t& iCount) { 226 if (eElement >= g_iXFAElementCount) { 227 return NULL; 228 } 229 XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementChildrenIndex + eElement; 230 iCount = pElement->wCount; 231 return g_XFAElementChildrenData + pElement->wStart; 232 } 233 const uint8_t* XFA_GetElementAttributes(XFA_ELEMENT eElement, int32_t& iCount) { 234 if (eElement >= g_iXFAElementCount) { 235 return NULL; 236 } 237 XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementAttributeIndex + eElement; 238 iCount = pElement->wCount; 239 return g_XFAElementAttributeData + pElement->wStart; 240 } 241 XFA_LPCATTRIBUTEINFO XFA_GetAttributeOfElement(XFA_ELEMENT eElement, 242 XFA_ATTRIBUTE eAttribute, 243 FX_DWORD dwPacket) { 244 int32_t iCount = 0; 245 const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount); 246 if (pAttr == NULL || iCount < 1) { 247 return NULL; 248 } 249 CFX_DSPATemplate<uint8_t> search; 250 int32_t index = search.Lookup(eAttribute, pAttr, iCount); 251 if (index < 0) { 252 return NULL; 253 } 254 XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute); 255 ASSERT(pInfo != NULL); 256 if (dwPacket == XFA_XDPPACKET_UNKNOWN) { 257 return pInfo; 258 } 259 return (dwPacket & pInfo->dwPackets) ? pInfo : NULL; 260 } 261 XFA_LPCELEMENTINFO XFA_GetChildOfElement(XFA_ELEMENT eElement, 262 XFA_ELEMENT eChild, 263 FX_DWORD dwPacket) { 264 int32_t iCount = 0; 265 const FX_WORD* pChild = XFA_GetElementChildren(eElement, iCount); 266 if (pChild == NULL || iCount < 1) { 267 return NULL; 268 } 269 CFX_DSPATemplate<FX_WORD> search; 270 int32_t index = search.Lookup(eChild, pChild, iCount); 271 if (index < 0) { 272 return NULL; 273 } 274 XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eChild); 275 ASSERT(pInfo != NULL); 276 if (dwPacket == XFA_XDPPACKET_UNKNOWN) { 277 return pInfo; 278 } 279 return (dwPacket & pInfo->dwPackets) ? pInfo : NULL; 280 } 281 XFA_LPCPROPERTY XFA_GetElementProperties(XFA_ELEMENT eElement, 282 int32_t& iCount) { 283 if (eElement >= g_iXFAElementCount) { 284 return NULL; 285 } 286 XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementPropertyIndex + eElement; 287 iCount = pElement->wCount; 288 return g_XFAElementPropertyData + pElement->wStart; 289 } 290 XFA_LPCPROPERTY XFA_GetPropertyOfElement(XFA_ELEMENT eElement, 291 XFA_ELEMENT eProperty, 292 FX_DWORD dwPacket) { 293 int32_t iCount = 0; 294 XFA_LPCPROPERTY pProperty = XFA_GetElementProperties(eElement, iCount); 295 if (pProperty == NULL || iCount < 1) { 296 return NULL; 297 } 298 int32_t iStart = 0, iEnd = iCount - 1, iMid; 299 do { 300 iMid = (iStart + iEnd) / 2; 301 XFA_ELEMENT eName = (XFA_ELEMENT)pProperty[iMid].eName; 302 if (eProperty == eName) { 303 break; 304 } else if (eProperty < eName) { 305 iEnd = iMid - 1; 306 } else { 307 iStart = iMid + 1; 308 } 309 } while (iStart <= iEnd); 310 if (iStart > iEnd) { 311 return NULL; 312 } 313 XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eProperty); 314 ASSERT(pInfo != NULL); 315 if (dwPacket == XFA_XDPPACKET_UNKNOWN) { 316 return pProperty + iMid; 317 } 318 return (dwPacket & pInfo->dwPackets) ? (pProperty + iMid) : NULL; 319 } 320 XFA_LPCNOTSUREATTRIBUTE XFA_GetNotsureAttribute(XFA_ELEMENT eElement, 321 XFA_ATTRIBUTE eAttribute, 322 XFA_ATTRIBUTETYPE eType) { 323 int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1; 324 do { 325 int32_t iMid = (iStart + iEnd) / 2; 326 XFA_LPCNOTSUREATTRIBUTE pAttr = g_XFANotsureAttributes + iMid; 327 if (eElement == pAttr->eElement) { 328 if (pAttr->eAttribute == eAttribute) { 329 if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) { 330 return pAttr; 331 } 332 return NULL; 333 } else { 334 int32_t iBefore = iMid - 1; 335 if (iBefore >= 0) { 336 pAttr = g_XFANotsureAttributes + iBefore; 337 while (eElement == pAttr->eElement) { 338 if (pAttr->eAttribute == eAttribute) { 339 if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) { 340 return pAttr; 341 } 342 return NULL; 343 } 344 iBefore--; 345 if (iBefore < 0) { 346 break; 347 } 348 pAttr = g_XFANotsureAttributes + iBefore; 349 } 350 } 351 int32_t iAfter = iMid + 1; 352 if (iAfter <= g_iXFANotsureCount - 1) { 353 pAttr = g_XFANotsureAttributes + iAfter; 354 while (eElement == pAttr->eElement) { 355 if (pAttr->eAttribute == eAttribute) { 356 if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) { 357 return pAttr; 358 } 359 return NULL; 360 } 361 iAfter++; 362 if (iAfter > g_iXFANotsureCount - 1) { 363 break; 364 } 365 pAttr = g_XFANotsureAttributes + iAfter; 366 } 367 } 368 return NULL; 369 } 370 } else if (eElement < pAttr->eElement) { 371 iEnd = iMid - 1; 372 } else { 373 iStart = iMid + 1; 374 } 375 } while (iStart <= iEnd); 376 return NULL; 377 } 378 int32_t XFA_GetMethodCount() { 379 return g_iSomMethodCount; 380 } 381 XFA_LPCMETHODINFO XFA_GetMethodByName(XFA_ELEMENT eElement, 382 const CFX_WideStringC& wsMethodName) { 383 int32_t iLength = wsMethodName.GetLength(); 384 if (iLength == 0) { 385 return NULL; 386 } 387 int32_t iElementIndex = eElement; 388 while (iElementIndex != -1) { 389 XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex; 390 int32_t icount = scriptIndex->wMethodCount; 391 if (icount == 0) { 392 iElementIndex = scriptIndex->wParentIndex; 393 continue; 394 } 395 uint32_t uHash = FX_HashCode_String_GetW(wsMethodName.GetPtr(), iLength); 396 int32_t iStart = scriptIndex->wMethodStart, iEnd = iStart + icount - 1; 397 do { 398 int32_t iMid = (iStart + iEnd) / 2; 399 XFA_LPCMETHODINFO pInfo = g_SomMethodData + iMid; 400 if (uHash == pInfo->uHash) { 401 return pInfo; 402 } else if (uHash < pInfo->uHash) { 403 iEnd = iMid - 1; 404 } else { 405 iStart = iMid + 1; 406 } 407 } while (iStart <= iEnd); 408 iElementIndex = scriptIndex->wParentIndex; 409 } 410 return NULL; 411 } 412 XFA_LPCSCRIPTATTRIBUTEINFO XFA_GetScriptAttributeByName( 413 XFA_ELEMENT eElement, 414 const CFX_WideStringC& wsAttributeName) { 415 int32_t iLength = wsAttributeName.GetLength(); 416 if (iLength == 0) { 417 return NULL; 418 } 419 int32_t iElementIndex = eElement; 420 while (iElementIndex != -1) { 421 XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex; 422 int32_t icount = scriptIndex->wAttributeCount; 423 if (icount == 0) { 424 iElementIndex = scriptIndex->wParentIndex; 425 continue; 426 } 427 uint32_t uHash = FX_HashCode_String_GetW(wsAttributeName.GetPtr(), iLength); 428 int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1; 429 do { 430 int32_t iMid = (iStart + iEnd) / 2; 431 XFA_LPCSCRIPTATTRIBUTEINFO pInfo = g_SomAttributeData + iMid; 432 if (uHash == pInfo->uHash) { 433 return pInfo; 434 } else if (uHash < pInfo->uHash) { 435 iEnd = iMid - 1; 436 } else { 437 iStart = iMid + 1; 438 } 439 } while (iStart <= iEnd); 440 iElementIndex = scriptIndex->wParentIndex; 441 } 442 return NULL; 443 } 444 void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) { 445 if (wsMeasure.IsEmpty()) { 446 m_fValue = 0; 447 m_eUnit = XFA_UNIT_Unknown; 448 return; 449 } 450 int32_t iUsedLen = 0; 451 int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0; 452 FX_FLOAT fValue = FX_wcstof(wsMeasure.GetPtr() + iOffset, 453 wsMeasure.GetLength() - iOffset, &iUsedLen); 454 XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen)); 455 Set(fValue, eUnit); 456 } 457 FX_BOOL CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const { 458 switch (GetUnit()) { 459 case XFA_UNIT_Mm: 460 wsMeasure.Format(L"%.8gmm", GetValue()); 461 return TRUE; 462 case XFA_UNIT_Pt: 463 wsMeasure.Format(L"%.8gpt", GetValue()); 464 return TRUE; 465 case XFA_UNIT_In: 466 wsMeasure.Format(L"%.8gin", GetValue()); 467 return TRUE; 468 case XFA_UNIT_Cm: 469 wsMeasure.Format(L"%.8gcm", GetValue()); 470 return TRUE; 471 case XFA_UNIT_Mp: 472 wsMeasure.Format(L"%.8gmp", GetValue()); 473 return TRUE; 474 case XFA_UNIT_Pc: 475 wsMeasure.Format(L"%.8gpc", GetValue()); 476 return TRUE; 477 case XFA_UNIT_Em: 478 wsMeasure.Format(L"%.8gem", GetValue()); 479 return TRUE; 480 case XFA_UNIT_Percent: 481 wsMeasure.Format(L"%.8g%%", GetValue()); 482 return TRUE; 483 default: 484 wsMeasure.Format(L"%.8g", GetValue()); 485 return FALSE; 486 } 487 } 488 FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const { 489 fValue = GetValue(); 490 XFA_UNIT eFrom = GetUnit(); 491 if (eFrom == eUnit) { 492 return TRUE; 493 } 494 switch (eFrom) { 495 case XFA_UNIT_Pt: 496 break; 497 case XFA_UNIT_Mm: 498 fValue *= 72 / 2.54f / 10; 499 break; 500 case XFA_UNIT_In: 501 fValue *= 72; 502 break; 503 case XFA_UNIT_Cm: 504 fValue *= 72 / 2.54f; 505 break; 506 case XFA_UNIT_Mp: 507 fValue *= 0.001f; 508 break; 509 case XFA_UNIT_Pc: 510 fValue *= 12.0f; 511 break; 512 default: 513 fValue = 0; 514 return FALSE; 515 } 516 switch (eUnit) { 517 case XFA_UNIT_Pt: 518 return TRUE; 519 case XFA_UNIT_Mm: 520 fValue /= 72 / 2.54f / 10; 521 return TRUE; 522 case XFA_UNIT_In: 523 fValue /= 72; 524 return TRUE; 525 case XFA_UNIT_Cm: 526 fValue /= 72 / 2.54f; 527 return TRUE; 528 case XFA_UNIT_Mp: 529 fValue /= 0.001f; 530 return TRUE; 531 case XFA_UNIT_Pc: 532 fValue /= 12.0f; 533 return TRUE; 534 default: 535 fValue = 0; 536 return FALSE; 537 } 538 return FALSE; 539 } 540 XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) { 541 if (wsUnit == FX_WSTRC(L"mm")) { 542 return XFA_UNIT_Mm; 543 } else if (wsUnit == FX_WSTRC(L"pt")) { 544 return XFA_UNIT_Pt; 545 } else if (wsUnit == FX_WSTRC(L"in")) { 546 return XFA_UNIT_In; 547 } else if (wsUnit == FX_WSTRC(L"cm")) { 548 return XFA_UNIT_Cm; 549 } else if (wsUnit == FX_WSTRC(L"pc")) { 550 return XFA_UNIT_Pc; 551 } else if (wsUnit == FX_WSTRC(L"mp")) { 552 return XFA_UNIT_Mp; 553 } else if (wsUnit == FX_WSTRC(L"em")) { 554 return XFA_UNIT_Em; 555 } else if (wsUnit == FX_WSTRC(L"%")) { 556 return XFA_UNIT_Percent; 557 } else { 558 return XFA_UNIT_Unknown; 559 } 560 } 561 IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer) { 562 return new CXFA_WideTextRead(wsBuffer); 563 } 564 CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString& wsBuffer) 565 : m_wsBuffer(wsBuffer), m_iPosition(0), m_iRefCount(1) {} 566 void CXFA_WideTextRead::Release() { 567 if (--m_iRefCount < 1) { 568 delete this; 569 } 570 } 571 IFX_Stream* CXFA_WideTextRead::Retain() { 572 m_iRefCount++; 573 return this; 574 } 575 FX_DWORD CXFA_WideTextRead::GetAccessModes() const { 576 return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text; 577 } 578 int32_t CXFA_WideTextRead::GetLength() const { 579 return m_wsBuffer.GetLength() * sizeof(FX_WCHAR); 580 } 581 int32_t CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) { 582 switch (eSeek) { 583 case FX_STREAMSEEK_Begin: 584 m_iPosition = iOffset; 585 break; 586 case FX_STREAMSEEK_Current: 587 m_iPosition += iOffset; 588 break; 589 case FX_STREAMSEEK_End: 590 m_iPosition = m_wsBuffer.GetLength() + iOffset; 591 break; 592 } 593 if (m_iPosition < 0) { 594 m_iPosition = 0; 595 } 596 if (m_iPosition > m_wsBuffer.GetLength()) { 597 m_iPosition = m_wsBuffer.GetLength(); 598 } 599 return GetPosition(); 600 } 601 int32_t CXFA_WideTextRead::GetPosition() { 602 return m_iPosition * sizeof(FX_WCHAR); 603 } 604 FX_BOOL CXFA_WideTextRead::IsEOF() const { 605 return m_iPosition >= m_wsBuffer.GetLength(); 606 } 607 int32_t CXFA_WideTextRead::ReadString(FX_WCHAR* pStr, 608 int32_t iMaxLength, 609 FX_BOOL& bEOS, 610 int32_t const* pByteSize) { 611 if (iMaxLength > m_wsBuffer.GetLength() - m_iPosition) { 612 iMaxLength = m_wsBuffer.GetLength() - m_iPosition; 613 } 614 FXSYS_wcsncpy(pStr, (const FX_WCHAR*)m_wsBuffer + m_iPosition, iMaxLength); 615 m_iPosition += iMaxLength; 616 bEOS = IsEOF(); 617 return iMaxLength; 618 } 619 FX_WORD CXFA_WideTextRead::GetCodePage() const { 620 return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE; 621 } 622 FX_WORD CXFA_WideTextRead::SetCodePage(FX_WORD wCodePage) { 623 return GetCodePage(); 624 } 625